From 1557fb37ba20eeba9ffca50173a9252710d2a70c Mon Sep 17 00:00:00 2001 From: Philip Graf Date: Wed, 9 Sep 2015 14:23:49 +0200 Subject: [PATCH 01/53] Fix AssetTest so the tests also run on Windows --- src/test/java/org/jbake/app/AssetTest.java | 42 +++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/test/java/org/jbake/app/AssetTest.java b/src/test/java/org/jbake/app/AssetTest.java index fec0fb7aa..e8c277bde 100644 --- a/src/test/java/org/jbake/app/AssetTest.java +++ b/src/test/java/org/jbake/app/AssetTest.java @@ -1,11 +1,14 @@ package org.jbake.app; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; +import java.util.Locale; import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.io.FileUtils; import org.jbake.app.ConfigUtil.Keys; import org.junit.Assert; import org.junit.Before; @@ -18,18 +21,14 @@ public class AssetTest { private CompositeConfiguration config; @Before - public void setup() throws Exception, IOException, URISyntaxException { + public void setup() throws Exception, IOException, URISyntaxException { config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile())); - Assert.assertEquals(".html", config.getString(Keys.OUTPUT_EXTENSION)); - readOnlyFolder.getRoot().setReadOnly(); + Assert.assertEquals(".html", config.getString(Keys.OUTPUT_EXTENSION)); } @Rule public TemporaryFolder folder = new TemporaryFolder(); - @Rule - public TemporaryFolder readOnlyFolder = new TemporaryFolder(); - @Test public void copy() throws Exception { URL assetsUrl = this.getClass().getResource("/assets"); @@ -67,6 +66,7 @@ public void copyIgnore() throws Exception { config.setProperty(Keys.ASSET_IGNORE_HIDDEN, "true"); URL assetsUrl = this.getClass().getResource("/ignorables"); File assets = new File(assetsUrl.getFile()); + hideAssets(assets); Asset asset = new Asset(assets.getParentFile(), folder.getRoot(), config); asset.copy(assets); @@ -78,6 +78,24 @@ public void copyIgnore() throws Exception { Assert.assertTrue("Errors during asset copying", asset.getErrors().isEmpty()); } + /** + * Hides the assets on windows that start with a dot (e.g. .test.txt but not test.txt) so File.isHidden() returns true for those files. + */ + private void hideAssets(File assets) throws IOException, InterruptedException { + if (isWindows()) { + final File[] hiddenFiles = assets.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith("."); + } + }); + for (File file : hiddenFiles) { + final Process process = Runtime.getRuntime().exec(new String[] {"attrib" , "+h", file.getAbsolutePath()}); + process.waitFor(); + } + } + } + /** * Primary intention is to extend test cases to increase coverage. * @@ -87,7 +105,10 @@ public void copyIgnore() throws Exception { public void testWriteProtected() throws Exception { URL assetsUrl = this.getClass().getResource("/assets"); File assets = new File(assetsUrl.getFile()); - Asset asset = new Asset(assets.getParentFile(), readOnlyFolder.getRoot(), config); + final File cssFile = new File(folder.newFolder("css"), "bootstrap.min.css"); + FileUtils.touch(cssFile); + cssFile.setReadOnly(); + Asset asset = new Asset(assets.getParentFile(), folder.getRoot(), config); asset.copy(assets); Assert.assertFalse("At least one error during copy expected", asset.getErrors().isEmpty()); @@ -103,7 +124,12 @@ public void testUnlistable() throws Exception { config.setProperty(Keys.ASSET_FOLDER, "non-existent"); URL assetsUrl = this.getClass().getResource("/"); File assets = new File(assetsUrl.getFile() + File.separatorChar + "non-existent"); - Asset asset = new Asset(assets.getParentFile(), readOnlyFolder.getRoot(), config); + Asset asset = new Asset(assets.getParentFile(), folder.getRoot(), config); asset.copy(assets); } + + private boolean isWindows() { + final String os = System.getProperty("os.name"); + return os != null && os.toLowerCase(Locale.ENGLISH).contains("win"); + } } From a55f82bd310cf1703a8eacf27d9096fdbaa4ef71 Mon Sep 17 00:00:00 2001 From: Philip Graf Date: Wed, 9 Sep 2015 13:01:53 +0200 Subject: [PATCH 02/53] Support absolute paths for asset, content and template folders --- src/main/java/org/jbake/app/Asset.java | 77 +++++++++---------- src/main/java/org/jbake/app/Crawler.java | 3 +- src/main/java/org/jbake/app/Oven.java | 3 +- src/main/java/org/jbake/app/Renderer.java | 2 +- .../java/org/jbake/model/DocumentTypes.java | 12 ++- src/test/java/org/jbake/app/CrawlerTest.java | 16 ++-- .../org/jbake/app/GroovyRendererTest.java | 21 +++-- src/test/java/org/jbake/app/OvenTest.java | 72 +++++++++++++++++ src/test/java/org/jbake/app/RendererTest.java | 18 +++-- .../org/jbake/app/ThymeleafRendererTest.java | 21 +++-- 10 files changed, 172 insertions(+), 73 deletions(-) create mode 100644 src/test/java/org/jbake/app/OvenTest.java diff --git a/src/main/java/org/jbake/app/Asset.java b/src/main/java/org/jbake/app/Asset.java index 60a978c12..c5667748c 100644 --- a/src/main/java/org/jbake/app/Asset.java +++ b/src/main/java/org/jbake/app/Asset.java @@ -23,21 +23,14 @@ public class Asset { private static final Logger LOGGER = LoggerFactory.getLogger(Asset.class); - private File source; - private File destination; - private CompositeConfiguration config; + private final File destination; private final List errors = new LinkedList(); private final boolean ignoreHidden; /** * Creates an instance of Asset. - * - * @param source - * @param destination */ public Asset(File source, File destination, CompositeConfiguration config) { - this.source = source; - this.config = config; this.destination = destination; ignoreHidden = config.getBoolean(ConfigUtil.Keys.ASSET_IGNORE_HIDDEN, false); } @@ -48,41 +41,41 @@ public Asset(File source, File destination, CompositeConfiguration config) { * @param path The starting path */ public void copy(File path) { - File[] assets = path.listFiles(new FileFilter() { - @Override - public boolean accept(File file) { - return !ignoreHidden || !file.isHidden(); - } - }); - if (assets != null) { - Arrays.sort(assets); - for (int i = 0; i < assets.length; i++) { - if (assets[i].isFile()) { - StringBuilder sb = new StringBuilder(); - sb.append("Copying [" + assets[i].getPath() + "]..."); - File sourceFile = assets[i]; - File destFile = new File(sourceFile.getPath().replace(source.getPath()+File.separator+config.getString(ConfigUtil.Keys.ASSET_FOLDER), destination.getPath())); - try { - FileUtils.copyFile(sourceFile, destFile); - sb.append("done!"); - LOGGER.info(sb.toString()); - } catch (IOException e) { - sb.append("failed!"); - LOGGER.error(sb.toString(), e); - e.printStackTrace(); - errors.add(e.getMessage()); - } - } + copy(path, destination); + } - if (assets[i].isDirectory()) { - copy(assets[i]); - } - } - } - } + private void copy(File sourceFolder, File targetFolder) { + final File[] assets = sourceFolder.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + return !ignoreHidden || !file.isHidden(); + } + }); + if (assets != null) { + Arrays.sort(assets); + for (File asset : assets) { + final File target = new File(targetFolder, asset.getName()); + if (asset.isFile()) { + final StringBuilder sb = new StringBuilder(); + sb.append("Copying [").append(asset.getPath()).append("]... "); + try { + FileUtils.copyFile(asset, target); + sb.append("done!"); + LOGGER.info(sb.toString()); + } catch (IOException e) { + sb.append("failed!"); + LOGGER.error(sb.toString(), e); + errors.add(e.getMessage()); + } + } else if (asset.isDirectory()) { + copy(asset, target); + } + } + } + } - public List getErrors() { - return new ArrayList(errors); - } + public List getErrors() { + return new ArrayList(errors); + } } diff --git a/src/main/java/org/jbake/app/Crawler.java b/src/main/java/org/jbake/app/Crawler.java index 49cfa5f2b..5b404d654 100644 --- a/src/main/java/org/jbake/app/Crawler.java +++ b/src/main/java/org/jbake/app/Crawler.java @@ -5,6 +5,7 @@ import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.io.FilenameUtils; import org.jbake.app.ConfigUtil.Keys; import org.jbake.model.DocumentStatus; import org.jbake.model.DocumentTypes; @@ -41,7 +42,7 @@ public class Crawler { public Crawler(ContentStore db, File source, CompositeConfiguration config) { this.db = db; this.config = config; - this.contentPath = source.getPath() + separator + config.getString(ConfigUtil.Keys.CONTENT_FOLDER); + this.contentPath = FilenameUtils.concat(source.getAbsolutePath(), config.getString(ConfigUtil.Keys.CONTENT_FOLDER)); this.parser = new Parser(config, contentPath); } diff --git a/src/main/java/org/jbake/app/Oven.java b/src/main/java/org/jbake/app/Oven.java index de0cae2d9..eb5440009 100644 --- a/src/main/java/org/jbake/app/Oven.java +++ b/src/main/java/org/jbake/app/Oven.java @@ -15,6 +15,7 @@ import com.orientechnologies.orient.core.record.impl.ODocument; import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.io.FilenameUtils; import org.jbake.app.ConfigUtil.Keys; import org.jbake.model.DocumentTypes; import org.slf4j.Logger; @@ -113,7 +114,7 @@ public void setupPaths() { } private File setupPathFromConfig(String key) { - return new File(source, config.getString(key)); + return new File(FilenameUtils.concat(source.getAbsolutePath(), config.getString(key))); } private File setupRequiredFolderFromConfig(final String key) { diff --git a/src/main/java/org/jbake/app/Renderer.java b/src/main/java/org/jbake/app/Renderer.java index d494338dc..bccc98be4 100644 --- a/src/main/java/org/jbake/app/Renderer.java +++ b/src/main/java/org/jbake/app/Renderer.java @@ -93,7 +93,7 @@ public void render(Map content) throws Exception { } catch (Exception e) { sb.append("failed!"); LOGGER.error(sb.toString(), e); - throw new Exception("Failed to render file. Cause: " + e.getMessage()); + throw new Exception("Failed to render file " + outputFile.getAbsolutePath() + ". Cause: " + e.getMessage(), e); } } diff --git a/src/main/java/org/jbake/model/DocumentTypes.java b/src/main/java/org/jbake/model/DocumentTypes.java index 178019937..14ea8a5f1 100644 --- a/src/main/java/org/jbake/model/DocumentTypes.java +++ b/src/main/java/org/jbake/model/DocumentTypes.java @@ -14,7 +14,16 @@ */ public class DocumentTypes { - private static final Set DEFAULT_DOC_TYPES = new LinkedHashSet(Arrays.asList("page", "post", "masterindex", "archive", "feed")); + private static final Set DEFAULT_DOC_TYPES = new LinkedHashSet(); + + static { + resetDocumentTypes(); + } + + public static void resetDocumentTypes() { + DEFAULT_DOC_TYPES.clear(); + DEFAULT_DOC_TYPES.addAll(Arrays.asList("page", "post", "masterindex", "archive", "feed")); + } public static void addDocumentType(String docType) { DEFAULT_DOC_TYPES.add(docType); @@ -23,4 +32,5 @@ public static void addDocumentType(String docType) { public static String[] getDocumentTypes() { return DEFAULT_DOC_TYPES.toArray(new String[DEFAULT_DOC_TYPES.size()]); } + } diff --git a/src/test/java/org/jbake/app/CrawlerTest.java b/src/test/java/org/jbake/app/CrawlerTest.java index 42ccdd488..ee5b41761 100644 --- a/src/test/java/org/jbake/app/CrawlerTest.java +++ b/src/test/java/org/jbake/app/CrawlerTest.java @@ -1,6 +1,8 @@ package org.jbake.app; +import static org.assertj.core.api.Assertions.assertThat; + import java.io.File; import java.io.IOException; import java.net.URISyntaxException; @@ -8,24 +10,28 @@ import java.util.List; import java.util.Map; -import com.orientechnologies.orient.core.record.impl.ODocument; -import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; - import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.jbake.app.ConfigUtil.Keys; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; -import static org.assertj.core.api.Assertions.*; +import com.orientechnologies.orient.core.Orient; +import com.orientechnologies.orient.core.record.impl.ODocument; public class CrawlerTest { private CompositeConfiguration config; private ContentStore db; private File sourceFolder; - + + @BeforeClass + public static void startup() { + Orient.instance().startup(); + } + @Before public void setup() throws Exception, IOException, URISyntaxException { URL sourceUrl = this.getClass().getResource("/"); diff --git a/src/test/java/org/jbake/app/GroovyRendererTest.java b/src/test/java/org/jbake/app/GroovyRendererTest.java index 53d4cb264..fdc8c5510 100644 --- a/src/test/java/org/jbake/app/GroovyRendererTest.java +++ b/src/test/java/org/jbake/app/GroovyRendererTest.java @@ -2,7 +2,12 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Iterator; +import java.util.Map; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FileUtils; @@ -11,17 +16,12 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Iterator; -import java.util.Map; -import java.util.Scanner; +import com.orientechnologies.orient.core.Orient; public class GroovyRendererTest { @@ -34,6 +34,11 @@ public class GroovyRendererTest { private CompositeConfiguration config; private ContentStore db; + @BeforeClass + public static void startup() { + Orient.instance().startup(); + } + @Before public void setup() throws Exception, IOException, URISyntaxException { URL sourceUrl = this.getClass().getResource("/"); diff --git a/src/test/java/org/jbake/app/OvenTest.java b/src/test/java/org/jbake/app/OvenTest.java new file mode 100644 index 000000000..1db9185a5 --- /dev/null +++ b/src/test/java/org/jbake/app/OvenTest.java @@ -0,0 +1,72 @@ +package org.jbake.app; + +import static org.hamcrest.MatcherAssert.assertThat; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.jbake.app.ConfigUtil.Keys; +import org.jbake.model.DocumentTypes; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import com.orientechnologies.orient.core.Orient; + +public class OvenTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @BeforeClass + public static void reset() { + DocumentTypes.resetDocumentTypes(); + } + + @Before + public void startup() { + Orient.instance().startup(); + } + + @Test + public void bakeWithRelativePaths() throws IOException, ConfigurationException { + final File source = new File(OvenTest.class.getResource("/").getFile()); + final File destination = folder.newFolder("destination"); + final CompositeConfiguration configuration = ConfigUtil.load(source); + configuration.setProperty(Keys.DESTINATION_FOLDER, destination.getAbsolutePath()); + + final Oven oven = new Oven(source, destination, configuration, true); + oven.setupPaths(); + oven.bake(); + + assertThat("There shouldn't be any errors: " + oven.getErrors(), oven.getErrors().isEmpty()); + } + + @Test + public void bakeWithAbsolutePaths() throws IOException, ConfigurationException { + final File source = new File(OvenTest.class.getResource("/").getFile()); + final File destination = folder.newFolder("destination"); + final CompositeConfiguration configuration = ConfigUtil.load(source); + makeAbsolute(configuration, source, Keys.TEMPLATE_FOLDER); + makeAbsolute(configuration, source, Keys.CONTENT_FOLDER); + makeAbsolute(configuration, source, Keys.ASSET_FOLDER); + configuration.setProperty(Keys.DESTINATION_FOLDER, destination.getAbsolutePath()); + + final Oven oven = new Oven(source, destination, configuration, true); + oven.setupPaths(); + oven.bake(); + + assertThat("There shouldn't be any errors: " + oven.getErrors(), oven.getErrors().isEmpty()); + } + + private void makeAbsolute(Configuration configuration, File source, String key) { + final File folder = new File(source, configuration.getString(key)); + configuration.setProperty(key, folder.getAbsolutePath()); + } + +} diff --git a/src/test/java/org/jbake/app/RendererTest.java b/src/test/java/org/jbake/app/RendererTest.java index c41546572..fdd1f6815 100644 --- a/src/test/java/org/jbake/app/RendererTest.java +++ b/src/test/java/org/jbake/app/RendererTest.java @@ -1,13 +1,8 @@ package org.jbake.app; -import org.jbake.app.ConfigUtil.Keys; -import org.jbake.model.DocumentTypes; -import org.junit.After; +import static org.assertj.core.api.Assertions.assertThat; import java.io.File; - -import static org.assertj.core.api.Assertions.*; - import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; @@ -15,12 +10,18 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FileUtils; +import org.jbake.app.ConfigUtil.Keys; +import org.jbake.model.DocumentTypes; +import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import com.orientechnologies.orient.core.Orient; + public class RendererTest { @Rule @@ -32,6 +33,11 @@ public class RendererTest { private CompositeConfiguration config; private ContentStore db; + @BeforeClass + public static void startup() { + Orient.instance().startup(); + } + @Before public void setup() throws Exception, IOException, URISyntaxException { URL sourceUrl = this.getClass().getResource("/"); diff --git a/src/test/java/org/jbake/app/ThymeleafRendererTest.java b/src/test/java/org/jbake/app/ThymeleafRendererTest.java index fed656e95..4677e1d15 100644 --- a/src/test/java/org/jbake/app/ThymeleafRendererTest.java +++ b/src/test/java/org/jbake/app/ThymeleafRendererTest.java @@ -2,7 +2,12 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Iterator; +import java.util.Map; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FileUtils; @@ -11,17 +16,12 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Iterator; -import java.util.Map; -import java.util.Scanner; +import com.orientechnologies.orient.core.Orient; public class ThymeleafRendererTest { @@ -34,6 +34,11 @@ public class ThymeleafRendererTest { private CompositeConfiguration config; private ContentStore db; + @BeforeClass + public static void startup() { + Orient.instance().startup(); + } + @Before public void setup() throws Exception, IOException, URISyntaxException { URL sourceUrl = this.getClass().getResource("/"); From b2d24e1144865663a4ff164d60899c58d349fd55 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Fri, 15 Apr 2016 18:23:59 +0200 Subject: [PATCH 03/53] Implements #278, added support for default type --- src/main/java/org/jbake/app/ConfigUtil.java | 9 +++-- .../java/org/jbake/parser/MarkupEngine.java | 7 ++++ src/test/java/org/jbake/app/ParserTest.java | 33 ++++++++++++++++--- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jbake/app/ConfigUtil.java b/src/main/java/org/jbake/app/ConfigUtil.java index a3f0e0d2b..a45b47feb 100644 --- a/src/main/java/org/jbake/app/ConfigUtil.java +++ b/src/main/java/org/jbake/app/ConfigUtil.java @@ -90,7 +90,12 @@ public static interface Keys { * Default status to use (in order to avoid putting it in all files) */ static final String DEFAULT_STATUS = "default.status"; - + + /** + * Default type to use (in order to avoid putting it in all files) + */ + static final String DEFAULT_TYPE = "default.type"; + /** * Folder where rendered files are output */ @@ -195,7 +200,7 @@ public static interface Keys { * How many posts per page on index */ static final String POSTS_PER_PAGE = "index.posts_per_page"; - } + } private final static Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); private final static String LEGACY_CONFIG_FILE = "custom.properties"; diff --git a/src/main/java/org/jbake/parser/MarkupEngine.java b/src/main/java/org/jbake/parser/MarkupEngine.java index 3666be69d..271872678 100644 --- a/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/src/main/java/org/jbake/parser/MarkupEngine.java @@ -99,6 +99,13 @@ public Map parse(Configuration config, File file, String content } } + if (config.getString(Keys.DEFAULT_TYPE) != null) { + if (content.get(Crawler.Attributes.TYPE) == null) { + // file hasn't got status so use default + content.put(Crawler.Attributes.TYPE, config.getString(Keys.DEFAULT_TYPE)); + } + } + if (content.get(Crawler.Attributes.TYPE)==null||content.get(Crawler.Attributes.STATUS)==null) { // output error LOGGER.warn("Error parsing meta data from header (missing type or status value) for file {}!", file); diff --git a/src/test/java/org/jbake/app/ParserTest.java b/src/test/java/org/jbake/app/ParserTest.java index 72ebb4f65..dd38333c9 100644 --- a/src/test/java/org/jbake/app/ParserTest.java +++ b/src/test/java/org/jbake/app/ParserTest.java @@ -9,6 +9,7 @@ import java.util.Map; import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.ConfigurationException; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -31,13 +32,14 @@ public class ParserTest { private File validAsciiDocFileWithoutHeader; private File invalidAsciiDocFileWithoutHeader; private File validAsciiDocFileWithHeaderInContent; - + private File validAsciiDocFileWithoutJBakeMetaData; + private String validHeader = "title=This is a Title = This is a valid Title\nstatus=draft\ntype=post\ndate=2013-09-02\n~~~~~~"; private String invalidHeader = "title=This is a Title\n~~~~~~"; - - - @Before + + + @Before public void createSampleFile() throws Exception { rootPath = new File(this.getClass().getResource(".").getFile()); config = ConfigUtil.load(rootPath); @@ -112,6 +114,15 @@ public void createSampleFile() throws Exception { out.println("~~~~~~"); out.println("----"); out.close(); + + validAsciiDocFileWithoutJBakeMetaData = folder.newFile("validwojbakemetadata.ad"); + out = new PrintWriter(validAsciiDocFileWithoutJBakeMetaData); + out.println("= Hello: AsciiDoc!"); + out.println("Test User "); + out.println("2013-09-02"); + out.println(""); + out.println("JBake now supports AsciiDoc documents without JBake meta data."); + out.close(); } @Test @@ -192,4 +203,18 @@ public void parseValidAsciiDocFileWithExampleHeaderInContent() { .contains("tags=tag1, tag2"); // Assert.assertEquals("
\n
\n
\n

JBake now supports AsciiDoc.

\n
\n
\n
\n
title=Example Header\ndate=2013-02-01\ntype=post\ntags=tag1, tag2\nstatus=published\n~~~~~~
\n
\n
\n
\n
", map.get("body")); } + + @Test + public void parseValidAsciiDocFileWithoutJBakeMetaDataUsingDefaultTypeAndStatus() throws ConfigurationException { + CompositeConfiguration defaultConfig = ConfigUtil.load(rootPath); + defaultConfig.addProperty(ConfigUtil.Keys.DEFAULT_STATUS, "published"); + defaultConfig.addProperty(ConfigUtil.Keys.DEFAULT_TYPE, "page"); + Parser parser = new Parser(defaultConfig,rootPath.getPath()); + Map map = parser.processFile(validAsciiDocFileWithoutJBakeMetaData); + Assert.assertNotNull(map); + Assert.assertEquals("published", map.get("status")); + Assert.assertEquals("page", map.get("type")); + assertThat(map.get("body").toString()) + .contains("

JBake now supports AsciiDoc documents without JBake meta data.

"); + } } From 6fc53eaa78cd7500c10f9c137303929004834cb8 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Fri, 28 Oct 2016 13:57:56 +0200 Subject: [PATCH 04/53] paginate into subfolders The first index.html is rendered into the root directory. Following paginated pages are put into subfolders per page like 1/index.html, 2/index.html etc. closes #308 --- src/main/java/org/jbake/app/Renderer.java | 3 +- .../java/org/jbake/util/PagingHelper.java | 24 +++++---- ...FreemarkerTemplateEngineRenderingTest.java | 4 +- .../java/org/jbake/util/PagingHelperTest.java | 49 +++++++++++++++++++ 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/jbake/app/Renderer.java b/src/main/java/org/jbake/app/Renderer.java index 42632459b..810df8672 100644 --- a/src/main/java/org/jbake/app/Renderer.java +++ b/src/main/java/org/jbake/app/Renderer.java @@ -246,9 +246,8 @@ public void renderIndexPaging(String indexFile) throws Exception { model.put("content", buildSimpleModel("masterindex")); model.put("numberOfPages", pagingHelper.getNumberOfPages()); - db.setLimit(postsPerPage); - try { + db.setLimit(postsPerPage); for (int pageStart = 0, page = 1; pageStart < totalPosts; pageStart += postsPerPage, page++) { String fileName = indexFile; diff --git a/src/main/java/org/jbake/util/PagingHelper.java b/src/main/java/org/jbake/util/PagingHelper.java index 47a6c2404..3384b5628 100644 --- a/src/main/java/org/jbake/util/PagingHelper.java +++ b/src/main/java/org/jbake/util/PagingHelper.java @@ -1,5 +1,7 @@ package org.jbake.util; +import java.io.File; + public class PagingHelper { long totalDocuments; int postsPerPage; @@ -15,9 +17,7 @@ public int getNumberOfPages() { public String getNextFileName(int currentPageNumber, String fileName) { if (currentPageNumber < getNumberOfPages()) { - int index = fileName.lastIndexOf("."); - return fileName.substring(0, index) + (currentPageNumber + 1) + - fileName.substring(index); + return (currentPageNumber + 1) + File.separator + fileName; } else { return null; } @@ -28,9 +28,12 @@ public String getPreviousFileName(int currentPageNumber, String fileName) { if (isFirstPage(currentPageNumber)) { return null; } else { - int index = fileName.lastIndexOf("."); - return fileName.substring(0, index) + (currentPageNumber > 2 ? currentPageNumber - 1 : "") + - fileName.substring(index); + if ( currentPageNumber == 2 ) { + return fileName; + } + else { + return (currentPageNumber - 1) + File.separator + fileName; + } } } @@ -39,9 +42,12 @@ private boolean isFirstPage(int page) { } public String getCurrentFileName(int page, String fileName) { - int index = fileName.lastIndexOf("."); - return fileName.substring(0, index) + (page > 1 ? page : "") + - fileName.substring(index); + if ( isFirstPage(page) ) { + return fileName; + } + else { + return page + File.separator + fileName; + } } } diff --git a/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java index 148a9a5ee..3dac37bbb 100644 --- a/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java @@ -49,13 +49,13 @@ public void renderPaginatedIndex() throws Exception { outputStrings.put("index", Arrays.asList( "index.html\">Previous", - "index3.html\">Next", + "3/index.html\">Next", "2 of 3" )); renderer.renderIndexPaging("index.html"); - File outputFile = new File(destinationFolder, "index2.html"); + File outputFile = new File(destinationFolder, 2 + File.separator + "index.html"); String output = FileUtils.readFileToString(outputFile, Charset.defaultCharset()); for (String string : getOutputStrings("index")) { diff --git a/src/test/java/org/jbake/util/PagingHelperTest.java b/src/test/java/org/jbake/util/PagingHelperTest.java index 1ee2a8dfe..8d3170b34 100644 --- a/src/test/java/org/jbake/util/PagingHelperTest.java +++ b/src/test/java/org/jbake/util/PagingHelperTest.java @@ -3,6 +3,7 @@ import org.junit.Assert; import org.junit.Test; +import static org.hamcrest.core.Is.is; import static org.junit.Assert.*; /** @@ -20,4 +21,52 @@ public void getNumberOfPages() throws Exception { Assert.assertEquals( expected, helper.getNumberOfPages() ); } + @Test + public void shouldReturnRootIndexPage() throws Exception { + PagingHelper helper = new PagingHelper(5,2); + + String previousFileName = helper.getPreviousFileName(2, "index.html"); + + Assert.assertThat("index.html", is( previousFileName) ); + } + + @Test + public void shouldReturnPreviousFileName() throws Exception { + + PagingHelper helper = new PagingHelper(5,2); + + String previousFileName = helper.getPreviousFileName(3, "index.html"); + + Assert.assertThat("2/index.html", is( previousFileName) ); + + } + + @Test + public void shouldReturnNullIfNoPreviousPageAvailable() throws Exception { + PagingHelper helper = new PagingHelper(5,2); + + String previousFileName = helper.getPreviousFileName(1, "index.html"); + + Assert.assertNull( previousFileName ); + } + + @Test + public void shouldReturnNullIfNextPageNotAvailable() throws Exception { + PagingHelper helper = new PagingHelper(5,2); + + String nextFileName = helper.getNextFileName(3, "index.html"); + + Assert.assertNull( nextFileName ); + + } + + @Test + public void shouldReturnNextFileName() throws Exception { + PagingHelper helper = new PagingHelper(5,2); + + String nextFileName = helper.getNextFileName(2, "index.html"); + + Assert.assertThat("3/index.html", is( nextFileName) ); + + } } \ No newline at end of file From ee6e2512108a532ab457bb19fa345ec380af1c2a Mon Sep 17 00:00:00 2001 From: Marcin Grabowski Date: Sat, 19 Nov 2016 02:00:40 +0100 Subject: [PATCH 05/53] Convert Javadoc to be compatible with strict Java 8 build --- pom.xml | 3 -- src/main/java/org/jbake/app/Asset.java | 17 ++++----- src/main/java/org/jbake/app/ConfigUtil.java | 2 +- src/main/java/org/jbake/app/Crawler.java | 5 ++- src/main/java/org/jbake/app/DBUtil.java | 2 ++ src/main/java/org/jbake/app/FileUtil.java | 7 ++-- src/main/java/org/jbake/app/Oven.java | 18 ++++++---- src/main/java/org/jbake/app/Parser.java | 17 +++++---- src/main/java/org/jbake/app/Renderer.java | 20 ++++++----- src/main/java/org/jbake/app/ZipUtil.java | 4 +-- src/main/java/org/jbake/launcher/Init.java | 15 ++++---- .../java/org/jbake/launcher/JettyServer.java | 6 ++-- src/main/java/org/jbake/launcher/Main.java | 14 ++++---- .../java/org/jbake/model/DocumentTypes.java | 11 +++--- .../template/GroovyMarkupTemplateEngine.java | 4 +-- .../org/jbake/template/ModelExtractors.java | 36 +++++++++---------- .../jbake/template/TemplateEngineAdapter.java | 6 ++-- .../org/jbake/template/TemplateEngines.java | 28 ++++++++------- .../template/ThymeleafTemplateEngine.java | 16 ++++----- 19 files changed, 123 insertions(+), 108 deletions(-) diff --git a/pom.xml b/pom.xml index a6c391400..f09f216ce 100644 --- a/pom.xml +++ b/pom.xml @@ -121,9 +121,6 @@ maven-javadoc-plugin - - -Xdoclint:none - attach-javadocs diff --git a/src/main/java/org/jbake/app/Asset.java b/src/main/java/org/jbake/app/Asset.java index d90328827..902bce68b 100644 --- a/src/main/java/org/jbake/app/Asset.java +++ b/src/main/java/org/jbake/app/Asset.java @@ -1,5 +1,10 @@ package org.jbake.app; +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; import java.io.FileFilter; import java.io.IOException; @@ -8,15 +13,10 @@ import java.util.LinkedList; import java.util.List; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * Deals with assets (static files such as css, js or image files). * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com * */ public class Asset { @@ -32,8 +32,9 @@ public class Asset { /** * Creates an instance of Asset. * - * @param source - * @param destination + * @param source Source file for the asset + * @param destination Destination (target) directory for asset file + * @param config Project configuration */ public Asset(File source, File destination, CompositeConfiguration config) { this.source = source; diff --git a/src/main/java/org/jbake/app/ConfigUtil.java b/src/main/java/org/jbake/app/ConfigUtil.java index 089bd7945..26bf5ea32 100644 --- a/src/main/java/org/jbake/app/ConfigUtil.java +++ b/src/main/java/org/jbake/app/ConfigUtil.java @@ -11,7 +11,7 @@ /** * Provides Configuration related functions. * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com */ public class ConfigUtil { diff --git a/src/main/java/org/jbake/app/Crawler.java b/src/main/java/org/jbake/app/Crawler.java index 1e67606fd..c9403d6e0 100644 --- a/src/main/java/org/jbake/app/Crawler.java +++ b/src/main/java/org/jbake/app/Crawler.java @@ -22,7 +22,7 @@ /** * Crawls a file system looking for content. * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com */ public class Crawler { public interface Attributes { @@ -61,6 +61,9 @@ interface Status { /** * Creates new instance of Crawler. + * @param db Database instance for content + * @param source Base directory where content directory is located + * @param config Project configuration */ public Crawler(ContentStore db, File source, CompositeConfiguration config) { this.db = db; diff --git a/src/main/java/org/jbake/app/DBUtil.java b/src/main/java/org/jbake/app/DBUtil.java index 435d50be0..0446bcc96 100644 --- a/src/main/java/org/jbake/app/DBUtil.java +++ b/src/main/java/org/jbake/app/DBUtil.java @@ -37,6 +37,8 @@ public static Map documentToModel(ODocument doc) { /** * Converts a DB list into a String array + * @param entry Entry input to be converted + * @return input entry as String[] */ @SuppressWarnings("unchecked") public static String[] toStringArray(Object entry) { diff --git a/src/main/java/org/jbake/app/FileUtil.java b/src/main/java/org/jbake/app/FileUtil.java index 91842573e..4c3eae0e7 100644 --- a/src/main/java/org/jbake/app/FileUtil.java +++ b/src/main/java/org/jbake/app/FileUtil.java @@ -15,7 +15,7 @@ /** * Provides File related functions * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com */ public class FileUtil { @@ -43,10 +43,9 @@ public static boolean isExistingFolder(File f) { * Works out the folder where JBake is running from. * * @return File referencing folder JBake is running from - * @throws Exception + * @throws Exception when application is not able to work out where is JBake running from */ public static File getRunningLocation() throws Exception { - // work out where JBake is running from String codePath = FileUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath(); String decodedPath = URLDecoder.decode(codePath, "UTF-8"); File codeFile = new File(decodedPath); @@ -80,7 +79,7 @@ public static String fileExt(String name) { * * @param sourceFile the original file or directory * @return an hex string representing the SHA1 hash of the file or directory. - * @throws Exception + * @throws Exception if any IOException of SecurityException occured */ public static String sha1(File sourceFile) throws Exception { byte[] buffer = new byte[1024]; diff --git a/src/main/java/org/jbake/app/Oven.java b/src/main/java/org/jbake/app/Oven.java index 8ef85afe9..2f6ecedaf 100644 --- a/src/main/java/org/jbake/app/Oven.java +++ b/src/main/java/org/jbake/app/Oven.java @@ -1,6 +1,7 @@ package org.jbake.app; import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.ConfigurationException; import org.jbake.app.ConfigUtil.Keys; import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentTypes; @@ -23,7 +24,7 @@ /** * All the baking happens in the Oven! * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com */ public class Oven { @@ -43,16 +44,23 @@ public class Oven { /** * Delegate c'tor to prevent API break for the moment. + * + * @param source Project source directory + * @param destination The destination folder + * @param isClearCache Should the cache be cleaned + * @throws ConfigurationException if configuration is not loaded correctly */ - public Oven(final File source, final File destination, final boolean isClearCache) throws Exception { + public Oven(final File source, final File destination, final boolean isClearCache) throws ConfigurationException { this(source, destination, ConfigUtil.load(source), isClearCache); } /** * Creates a new instance of the Oven with references to the source and destination folders. * - * @param source The source folder - * @param destination The destination folder + * @param source Project source directory + * @param destination The destination folder + * @param config Project configuration + * @param isClearCache Should the cache be cleaned */ public Oven(final File source, final File destination, final CompositeConfiguration config, final boolean isClearCache) { this.source = source; @@ -121,8 +129,6 @@ private File setupRequiredFolderFromConfig(final String key) { /** * All the good stuff happens in here... - * - * @throws JBakeException */ public void bake() { final ContentStore db = DBUtil.createDataStore(config.getString(Keys.DB_STORE), config.getString(Keys.DB_PATH)); diff --git a/src/main/java/org/jbake/app/Parser.java b/src/main/java/org/jbake/app/Parser.java index 5a18ed64c..fb15146b4 100644 --- a/src/main/java/org/jbake/app/Parser.java +++ b/src/main/java/org/jbake/app/Parser.java @@ -1,18 +1,18 @@ package org.jbake.app; -import org.jbake.parser.Engines; -import java.io.File; -import java.util.Map; - import org.apache.commons.configuration.Configuration; +import org.jbake.parser.Engines; import org.jbake.parser.ParserEngine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.util.Map; + /** * Parses a File for content. * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com */ public class Parser { private final static Logger LOGGER = LoggerFactory.getLogger(Parser.class); @@ -22,6 +22,9 @@ public class Parser { /** * Creates a new instance of Parser. + * + * @param config Project configuration + * @param contentPath Content location */ public Parser(Configuration config, String contentPath) { this.config = config; @@ -31,8 +34,8 @@ public Parser(Configuration config, String contentPath) { /** * Process the file by parsing the contents. * - * @param file - * @return The contents of the file + * @param file File input for parsing + * @return The contents of the file */ public Map processFile(File file) { ParserEngine engine = Engines.get(FileUtil.fileExt(file)); diff --git a/src/main/java/org/jbake/app/Renderer.java b/src/main/java/org/jbake/app/Renderer.java index 3d03bbc3a..2cbeb4c79 100644 --- a/src/main/java/org/jbake/app/Renderer.java +++ b/src/main/java/org/jbake/app/Renderer.java @@ -20,7 +20,7 @@ /** * Render output to a file. * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com */ public class Renderer { @@ -125,7 +125,7 @@ public Map getModel() { * @param db The database holding the content * @param destination The destination folder * @param templatesPath The templates folder - * @param config + * @param config Project configuration */ public Renderer(ContentStore db, File destination, File templatesPath, CompositeConfiguration config) { this.destination = destination; @@ -143,8 +143,8 @@ private String findTemplateName(String docType) { /** * Render the supplied content to a file. * - * @param content The content to renderDocument - * @throws Exception + * @param content The content to renderDocument + * @throws Exception if IOException or SecurityException are raised */ public void render(Map content) throws Exception { String docType = (String) content.get(Crawler.Attributes.TYPE); @@ -219,7 +219,7 @@ private void render(RenderingConfig renderConfig) throws Exception { * Render an index file using the supplied content. * * @param indexFile The name of the output file - * @throws Exception + * @throws Exception if IOException or SecurityException are raised */ public void renderIndex(String indexFile) throws Exception { long totalPosts = db.getDocumentCount("post"); @@ -279,7 +279,8 @@ public void renderIndex(String indexFile) throws Exception { /** * Render an XML sitemap file using the supplied content. - * @throws Exception + * @param sitemapFile configuration for site map + * @throws Exception if can't create correct default rendering config * * @see About Sitemaps * @see Sitemap protocol @@ -292,7 +293,7 @@ public void renderSitemap(String sitemapFile) throws Exception { * Render an XML feed file using the supplied content. * * @param feedFile The name of the output file - * @throws Exception + * @throws Exception if default rendering configuration is not loaded correctly */ public void renderFeed(String feedFile) throws Exception { render(new DefaultRenderingConfig(feedFile, "feed")); @@ -302,7 +303,7 @@ public void renderFeed(String feedFile) throws Exception { * Render an archive file using the supplied content. * * @param archiveFile The name of the output file - * @throws Exception + * @throws Exception if default rendering configuration is not loaded correctly */ public void renderArchive(String archiveFile) throws Exception { render(new DefaultRenderingConfig(archiveFile, "archive")); @@ -312,7 +313,8 @@ public void renderArchive(String archiveFile) throws Exception { * Render tag files using the supplied content. * * @param tagPath The output path - * @throws Exception + * @return Nuber of rendered tags + * @throws Exception if cannot render tags correctly */ public int renderTags(String tagPath) throws Exception { int renderedCount = 0; diff --git a/src/main/java/org/jbake/app/ZipUtil.java b/src/main/java/org/jbake/app/ZipUtil.java index 38e87d169..f9ed0f770 100644 --- a/src/main/java/org/jbake/app/ZipUtil.java +++ b/src/main/java/org/jbake/app/ZipUtil.java @@ -10,7 +10,7 @@ /** * Provides Zip file related functions * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com * */ public class ZipUtil { @@ -20,7 +20,7 @@ public class ZipUtil { * * @param is {@link InputStream} InputStream of Zip file * @param outputFolder folder where Zip file should be extracted to - * @throws IOException + * @throws IOException if IOException occurs */ public static void extract(InputStream is, File outputFolder) throws IOException { ZipInputStream zis = new ZipInputStream(is); diff --git a/src/main/java/org/jbake/launcher/Init.java b/src/main/java/org/jbake/launcher/Init.java index e639587bc..de0baf92b 100644 --- a/src/main/java/org/jbake/launcher/Init.java +++ b/src/main/java/org/jbake/launcher/Init.java @@ -1,16 +1,16 @@ package org.jbake.launcher; -import java.io.File; -import java.io.FileInputStream; - import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ConfigUtil.Keys; import org.jbake.app.ZipUtil; +import java.io.File; +import java.io.FileInputStream; + /** * Initialises sample folder structure with pre-defined template * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com * */ public class Init { @@ -24,9 +24,10 @@ public Init(CompositeConfiguration config) { /** * Performs checks on output folder before extracting template file * - * @param outputFolder - * @param templateLocationFolder - * @throws Exception + * @param outputFolder Target directory for extracting template file + * @param templateLocationFolder Source location for template file + * @param templateType Type of the template to be used + * @throws Exception if required folder structure can't be achieved without content overwriting */ public void run(File outputFolder, File templateLocationFolder, String templateType) throws Exception { if (!outputFolder.canWrite()) { diff --git a/src/main/java/org/jbake/launcher/JettyServer.java b/src/main/java/org/jbake/launcher/JettyServer.java index ea4673a76..fe4a5e0aa 100644 --- a/src/main/java/org/jbake/launcher/JettyServer.java +++ b/src/main/java/org/jbake/launcher/JettyServer.java @@ -13,7 +13,7 @@ /** * Provides Jetty server related functions * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com * */ public class JettyServer { @@ -22,8 +22,8 @@ public class JettyServer { /** * Run Jetty web server serving out supplied path on supplied port * - * @param path - * @param port + * @param path Base directory for resourced to be served + * @param port Required server port */ public static void run(String path, String port) { Server server = new Server(); diff --git a/src/main/java/org/jbake/launcher/Main.java b/src/main/java/org/jbake/launcher/Main.java index 9855aa3e5..fd6b76e34 100644 --- a/src/main/java/org/jbake/launcher/Main.java +++ b/src/main/java/org/jbake/launcher/Main.java @@ -1,10 +1,5 @@ package org.jbake.launcher; -import java.io.File; -import java.io.StringWriter; -import java.text.MessageFormat; -import java.util.List; - import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.vfs2.FileObject; @@ -21,10 +16,15 @@ import org.kohsuke.args4j.CmdLineParser; import org.slf4j.bridge.SLF4JBridgeHandler; +import java.io.File; +import java.io.StringWriter; +import java.text.MessageFormat; +import java.util.List; + /** * Launcher for JBake. * - * @author Jonathan Bullock + * @author Jonathan Bullock jonbullock@gmail.com * */ public class Main { @@ -35,7 +35,7 @@ public class Main { /** * Runs the app with the given arguments. * - * @param args + * @param args Application arguments */ public static void main(final String[] args) { try { diff --git a/src/main/java/org/jbake/model/DocumentTypes.java b/src/main/java/org/jbake/model/DocumentTypes.java index d64b2e144..ac4aeeb03 100644 --- a/src/main/java/org/jbake/model/DocumentTypes.java +++ b/src/main/java/org/jbake/model/DocumentTypes.java @@ -1,17 +1,16 @@ package org.jbake.model; +import org.jbake.parser.Engines; + import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; -import org.jbake.parser.Engines; - /** - * Utility class used to determine the list of document types. Currently only supports "page", "post", "index", - * "archive" and "feed". - *

- * Additional document types are added at runtime based on the types found in the configuration. + *

Utility class used to determine the list of document types. Currently only supports "page", "post", "index", + * "archive" and "feed".

+ *

Additional document types are added at runtime based on the types found in the configuration.

* * @author Cédric Champeau */ diff --git a/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java b/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java index 4adb0826b..f3c359e6e 100644 --- a/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java +++ b/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java @@ -16,9 +16,9 @@ /** * Renders documents using the GroovyMarkupTemplateEngine. * - * @see Groovy MarkupTemplateEngine Documentation - * * The file extension to activate this Engine is .tpl + * + * @see Groovy MarkupTemplateEngine Documentation */ public class GroovyMarkupTemplateEngine extends AbstractTemplateEngine { private TemplateConfiguration templateConfiguration; diff --git a/src/main/java/org/jbake/template/ModelExtractors.java b/src/main/java/org/jbake/template/ModelExtractors.java index c1ab3ada5..36ea8e06c 100644 --- a/src/main/java/org/jbake/template/ModelExtractors.java +++ b/src/main/java/org/jbake/template/ModelExtractors.java @@ -1,5 +1,12 @@ package org.jbake.template; +import org.jbake.app.ContentStore; +import org.jbake.model.DocumentTypeUtils; +import org.jbake.template.model.PublishedCustomExtractor; +import org.jbake.template.model.TypedDocumentsExtractor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.net.URL; import java.util.Enumeration; @@ -8,26 +15,21 @@ import java.util.Set; import java.util.TreeMap; -import org.jbake.app.ContentStore; -import org.jbake.model.DocumentTypeUtils; -import org.jbake.template.model.PublishedCustomExtractor; -import org.jbake.template.model.TypedDocumentsExtractor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** *

A singleton class giving access to model extractors. Model extractors are loaded based on classpath. New * rendering may be registered either at runtime (not recommanded) or by putting a descriptor file on classpath - * (recommanded).

The descriptor file must be found in META-INF directory and named - * org.jbake.template.ModelExtractors.properties. The format of the file is easy:

- * org.jbake.template.model.AllPosts=all_posts
org.jbake.template.model.AllContent=all_content

where the key - * is the class of the extractor (must implement {@link ModelExtractor} and the value is the key by which values - * are to be accessed in model.

- *

+ * (recommanded).

+ *

The descriptor file must be found in META-INF directory and named + * org.jbake.template.ModelExtractors.properties. The format of the file is easy:

+ * org.jbake.template.model.AllPosts=all_posts
org.jbake.template.model.AllContent=all_content
+ *

where the key is the class of the extractor (must implement {@link ModelExtractor} and the value is the key + * by which values are to be accessed in model.

+ *

* This class loads the engines only if they are found on classpath. If not, the engine is not registered. This allows * JBake to support multiple rendering engines without the explicit need to have them on classpath. This is a better fit * for embedding. + *

* * @author ndx * @author Cédric Champeau @@ -124,9 +126,8 @@ public Type extractAndTransform(ContentStore db, String key, Map map, Tem } /** - * @param key - * @return - * @category delegate + * @param key Key for lookup + * @return True if the key is contained by this object * @see java.util.Map#containsKey(java.lang.Object) */ public boolean containsKey(Object key) { @@ -134,8 +135,7 @@ public boolean containsKey(Object key) { } /** - * @return - * @category delegate + * @return Set of keys contained in this object * @see java.util.Map#keySet() */ public Set keySet() { diff --git a/src/main/java/org/jbake/template/TemplateEngineAdapter.java b/src/main/java/org/jbake/template/TemplateEngineAdapter.java index e0c53929b..03f125b38 100644 --- a/src/main/java/org/jbake/template/TemplateEngineAdapter.java +++ b/src/main/java/org/jbake/template/TemplateEngineAdapter.java @@ -18,9 +18,9 @@ public Object adapt(String key, Object extractedValue) { /** * Adapt value to expected output - * @param key - * @param extractedValue - * @return + * @param key Template key + * @param extractedValue Value to be used in template model + * @return Value adapted for use in template */ Type adapt(String key, Object extractedValue); diff --git a/src/main/java/org/jbake/template/TemplateEngines.java b/src/main/java/org/jbake/template/TemplateEngines.java index cd1166518..26be48083 100644 --- a/src/main/java/org/jbake/template/TemplateEngines.java +++ b/src/main/java/org/jbake/template/TemplateEngines.java @@ -1,5 +1,11 @@ package org.jbake.template; +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.jbake.app.ContentStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; @@ -11,28 +17,24 @@ import java.util.Map; import java.util.Properties; import java.util.Set; -import org.jbake.app.ContentStore; - -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** *

A singleton class giving access to rendering engines. Rendering engines are loaded based on classpath. New * rendering may be registered either at runtime (not recommanded) or by putting a descriptor file on classpath - * (recommanded).

The descriptor file must be found in META-INF directory and named - * org.jbake.parser.TemplateEngines.properties. The format of the file is easy:

- * org.jbake.parser.FreeMarkerRenderer=ftl
org.jbake.parser.GroovyRenderer=groovy,gsp

where the key - * is the class of the engine (must extend {@link AbstractTemplateEngine} and have a 4-arg constructor and - * the value is a comma-separated list of file extensions that this engine is capable of proceeding.

- *

+ * (recommanded).

+ *

The descriptor file must be found in META-INF directory and named + * org.jbake.parser.TemplateEngines.properties. The format of the file is easy:

+ * org.jbake.parser.FreeMarkerRenderer=ftl
org.jbake.parser.GroovyRenderer=groovy,gsp
+ *

where the key is the class of the engine (must extend {@link AbstractTemplateEngine} and have + * a 4-arg constructor and the value is a comma-separated list of file extensions that this engine is capable + * of proceeding.

*

Rendering engines are singletons, so are typically used to initialize the underlying template engines. - *

+ *

* This class loads the engines only if they are found on classpath. If not, the engine is not registered. This allows * JBake to support multiple rendering engines without the explicit need to have them on classpath. This is a better fit * for embedding. + *

* * @author Cédric Champeau */ diff --git a/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java b/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java index e1b6f71a0..c66cef75f 100644 --- a/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java +++ b/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java @@ -1,12 +1,5 @@ package org.jbake.template; -import java.io.File; -import java.io.Writer; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.locks.ReentrantLock; - import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.lang.LocaleUtils; import org.jbake.app.ConfigUtil.Keys; @@ -16,6 +9,13 @@ import org.thymeleaf.context.Context; import org.thymeleaf.templateresolver.FileTemplateResolver; +import java.io.File; +import java.io.Writer; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + /** *

A template engine which renders pages using Thymeleaf.

* @@ -24,7 +24,7 @@ * *

The default rendering mode is "HTML", but it is possible to use another mode * for each document type, by adding a key in the configuration, for example:

- *

+ * * * template.feed.thymeleaf.mode=XML * From 172af743fbd7a65765df4624adca58e2d639fbde Mon Sep 17 00:00:00 2001 From: "John D. Ament" Date: Sat, 14 Jan 2017 15:32:04 -0500 Subject: [PATCH 06/53] Enhancement for #333, override site.host variable when running the server. --- src/main/java/org/jbake/app/ConfigUtil.java | 20 +++++++++++++++++-- src/main/java/org/jbake/launcher/Main.java | 3 +-- .../java/org/jbake/app/ConfigUtilTest.java | 17 ++++++++++++---- .../java/org/jbake/launcher/MainTest.java | 8 +++----- .../{custom.properties => jbake.properties} | 0 5 files changed, 35 insertions(+), 13 deletions(-) rename src/test/resources/{custom.properties => jbake.properties} (100%) diff --git a/src/main/java/org/jbake/app/ConfigUtil.java b/src/main/java/org/jbake/app/ConfigUtil.java index 089bd7945..9e9d74900 100644 --- a/src/main/java/org/jbake/app/ConfigUtil.java +++ b/src/main/java/org/jbake/app/ConfigUtil.java @@ -3,6 +3,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.SystemConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -200,6 +201,11 @@ public interface Keys { * How many posts per page on index */ String POSTS_PER_PAGE = "index.posts_per_page"; + + /** + * The configured base URI for the hosted content + */ + String SITE_HOST = "site.host"; } private final static Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); @@ -207,8 +213,12 @@ public interface Keys { private final static String CONFIG_FILE = "jbake.properties"; private final static String DEFAULT_CONFIG_FILE = "default.properties"; private static boolean LEGACY_CONFIG_FILE_WARNING_SHOWN = false; - - public static CompositeConfiguration load(File source) throws ConfigurationException { + + public static CompositeConfiguration load(File source) throws ConfigurationException { + return load(source, false); + } + + public static CompositeConfiguration load(File source, boolean isRunServer) throws ConfigurationException { CompositeConfiguration config = new CompositeConfiguration(); config.setListDelimiter(','); File customConfigFile = new File(source, LEGACY_CONFIG_FILE); @@ -225,6 +235,12 @@ public static CompositeConfiguration load(File source) throws ConfigurationExcep config.addConfiguration(new PropertiesConfiguration(customConfigFile)); } config.addConfiguration(new PropertiesConfiguration(DEFAULT_CONFIG_FILE)); + config.addConfiguration(new SystemConfiguration()); + if (isRunServer) { + String port = config.getString(Keys.SERVER_PORT); + config.setProperty(Keys.SITE_HOST, "http://localhost:"+port); + } return config; } + } diff --git a/src/main/java/org/jbake/launcher/Main.java b/src/main/java/org/jbake/launcher/Main.java index 6639f28e4..21a02cae3 100644 --- a/src/main/java/org/jbake/launcher/Main.java +++ b/src/main/java/org/jbake/launcher/Main.java @@ -73,11 +73,10 @@ protected void run(String[] args) { final CompositeConfiguration config; try { - config = ConfigUtil.load( res.getSource() ); + config = ConfigUtil.load( res.getSource(), res.isRunServer() ); } catch( final ConfigurationException e ) { throw new JBakeException( "Configuration error: " + e.getMessage(), e ); } - run(res, config); } diff --git a/src/test/java/org/jbake/app/ConfigUtilTest.java b/src/test/java/org/jbake/app/ConfigUtilTest.java index 63cee9e83..4fcfeca45 100644 --- a/src/test/java/org/jbake/app/ConfigUtilTest.java +++ b/src/test/java/org/jbake/app/ConfigUtilTest.java @@ -2,12 +2,12 @@ import java.io.File; -import junit.framework.Assert; - import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ConfigUtil.Keys; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class ConfigUtilTest { @Test @@ -15,9 +15,18 @@ public void load() throws Exception { CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile())); // check default.properties values exist - Assert.assertEquals("output", config.getString(Keys.DESTINATION_FOLDER)); + assertEquals("output", config.getString(Keys.DESTINATION_FOLDER)); // check custom.properties values exist - Assert.assertEquals("testing123", config.getString("test.property")); + assertEquals("testing123", config.getString("test.property")); + + assertEquals("http://www.jbake.org", config.getString(Keys.SITE_HOST)); + } + + @Test + public void shouldHaveSiteConfiguredWhenServerRunning() throws Exception { + CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile()), true); + + assertEquals("http://localhost:8820", config.getString(Keys.SITE_HOST)); } } diff --git a/src/test/java/org/jbake/launcher/MainTest.java b/src/test/java/org/jbake/launcher/MainTest.java index b2592602e..84915989b 100644 --- a/src/test/java/org/jbake/launcher/MainTest.java +++ b/src/test/java/org/jbake/launcher/MainTest.java @@ -101,7 +101,7 @@ public void launchJettyWithCustomDestViaConfig() throws CmdLineException { @Test public void launchJettyWithCmdlineOverridingProperties() throws CmdLineException { String[] args = {"src/jbake", "build/jbake", "-s"}; - Map properties = new HashMap(){{ + Map properties = new HashMap(){{ put("destination.folder", "target/jbake"); }}; main.run(stubOptions(args), stubConfig(properties)); @@ -119,10 +119,8 @@ private LaunchOptions stubOptions(String[] args) throws CmdLineException { private CompositeConfiguration stubConfig(Map properties) { CompositeConfiguration config = new CompositeConfiguration(); config.addProperty("server.port", "8820"); - Iterator it = properties.entrySet().iterator(); - while(it.hasNext()) { - Map.Entry pair = (Map.Entry)it.next(); - config.addProperty( pair.getKey(), pair.getValue() ); + for (Map.Entry pair : properties.entrySet()) { + config.addProperty(pair.getKey(), pair.getValue()); } return config; } diff --git a/src/test/resources/custom.properties b/src/test/resources/jbake.properties similarity index 100% rename from src/test/resources/custom.properties rename to src/test/resources/jbake.properties From 5193eedcb65502f616fdecb57eac18f33358c87a Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Tue, 24 Jan 2017 19:53:58 +0100 Subject: [PATCH 07/53] update orientdb to 2.2.15 * added -XX:MaxDirectMemorySize=1024m to jbake and jbake.bat script, to prevent warning from orientdb closes #318 --- pom.xml | 9 +- src/main/java/org/jbake/app/ContentStore.java | 14 +-- .../org/jbake/model/DocumentAttributes.java | 2 +- src/main/scripts/jbake | 5 +- src/main/scripts/jbake.bat | 2 +- .../java/org/jbake/FakeDocumentBuilder.java | 99 +++++++++++++++++++ .../java/org/jbake/app/ContentStoreTest.java | 32 +++--- .../java/org/jbake/app/PaginationTest.java | 29 +++--- 8 files changed, 146 insertions(+), 46 deletions(-) create mode 100644 src/test/java/org/jbake/FakeDocumentBuilder.java diff --git a/pom.xml b/pom.xml index 887a76dcb..4aec030dd 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 4.12 1.6.0 8.1.19.v20160209 - 1.7.10 + 2.2.15 2.4.7 1.7.21 1.1.7 @@ -436,12 +436,7 @@ com.orientechnologies - orient-commons - ${orientdb.version} - - - com.orientechnologies - orientdb-core + orientdb-graphdb ${orientdb.version} diff --git a/src/main/java/org/jbake/app/ContentStore.java b/src/main/java/org/jbake/app/ContentStore.java index fee087da5..15ea77f83 100644 --- a/src/main/java/org/jbake/app/ContentStore.java +++ b/src/main/java/org/jbake/app/ContentStore.java @@ -25,6 +25,8 @@ import com.orientechnologies.orient.core.Orient; import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; +import com.orientechnologies.orient.core.db.OPartitionedDatabasePool; +import com.orientechnologies.orient.core.db.OPartitionedDatabasePoolFactory; import com.orientechnologies.orient.core.db.document.ODatabaseDocumentPool; import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; import com.orientechnologies.orient.core.metadata.schema.OClass; @@ -61,7 +63,7 @@ public ContentStore(final String type, String name) { if (!exists) { db.create(); } - db = ODatabaseDocumentPool.global().acquire(type + ":" + name, "admin", "admin"); + db = new OPartitionedDatabasePoolFactory().get(type+":"+name, "admin", "admin").acquire(); ODatabaseRecordThreadLocal.INSTANCE.set(db); if (!exists) { updateSchema(); @@ -157,19 +159,19 @@ public DocumentList getPublishedPages() { } public DocumentList getPublishedContent(String docType) { - String query = "select * from " + docType + " where status='published'"; + String query = "select * from " + docType + " where status='published' order by date desc"; if ((start >= 0) && (limit > -1)) { query += " SKIP " + start + " LIMIT " + limit; } - return query(query + " order by date desc"); + return query(query); } public DocumentList getAllContent(String docType) { - String query = "select * from " + docType; + String query = "select * from " + docType + " order by date desc"; if ((start >= 0) && (limit > -1)) { query += " SKIP " + start + " LIMIT " + limit; } - return query(query + " order by date desc"); + return query(query); } public DocumentList getAllTagsFromPublishedPosts() { @@ -258,8 +260,6 @@ private void createDocType(final OSchema schema, final String doctype) { private void createSignatureType(OSchema schema) { OClass signatures = schema.createClass("Signatures"); - signatures.createProperty(String.valueOf(DocumentAttributes.KEY), OType.STRING).setNotNull(true); - signatures.createIndex("keyIdx", OClass.INDEX_TYPE.NOTUNIQUE, DocumentAttributes.KEY.toString()); signatures.createProperty(String.valueOf(DocumentAttributes.SHA1), OType.STRING).setNotNull(true); signatures.createIndex("sha1Idx", OClass.INDEX_TYPE.UNIQUE, DocumentAttributes.SHA1.toString()); } diff --git a/src/main/java/org/jbake/model/DocumentAttributes.java b/src/main/java/org/jbake/model/DocumentAttributes.java index 2acda40aa..ae698fb1c 100644 --- a/src/main/java/org/jbake/model/DocumentAttributes.java +++ b/src/main/java/org/jbake/model/DocumentAttributes.java @@ -6,7 +6,7 @@ public enum DocumentAttributes { RENDERED("rendered"), CACHED("cached"), STATUS("status"), - KEY("key"); + NAME("name"); private String label; diff --git a/src/main/scripts/jbake b/src/main/scripts/jbake index c1180fc97..e75fc3920 100755 --- a/src/main/scripts/jbake +++ b/src/main/scripts/jbake @@ -7,6 +7,7 @@ fi EXEC_LOC="`dirname "$P"`" EXEC_PARENT="`dirname $EXEC_LOC`" +OPTS="-XX:MaxDirectMemorySize=1024m" CYGWIN=false; case "`uname`" in @@ -15,7 +16,7 @@ esac if $CYGWIN ; then - java -jar $(cygpath -w "${EXEC_PARENT}/jbake-core.jar") $@ + java $OPTS -jar $(cygpath -w "${EXEC_PARENT}/jbake-core.jar") $@ else - java -jar "${EXEC_PARENT}/jbake-core.jar" $@ + java $OPTS -jar "${EXEC_PARENT}/jbake-core.jar" $@ fi \ No newline at end of file diff --git a/src/main/scripts/jbake.bat b/src/main/scripts/jbake.bat index dccbf14a8..5953c91f1 100644 --- a/src/main/scripts/jbake.bat +++ b/src/main/scripts/jbake.bat @@ -1,2 +1,2 @@ @echo off -java -jar "%~dp0\..\jbake-core.jar" %* +java -XX:MaxDirectMemorySize=1024m -jar "%~dp0\..\jbake-core.jar" %* diff --git a/src/test/java/org/jbake/FakeDocumentBuilder.java b/src/test/java/org/jbake/FakeDocumentBuilder.java new file mode 100644 index 000000000..b2bc9d0d5 --- /dev/null +++ b/src/test/java/org/jbake/FakeDocumentBuilder.java @@ -0,0 +1,99 @@ +package org.jbake; + +import com.orientechnologies.orient.core.record.impl.ODocument; +import org.jbake.app.Crawler; +import org.jbake.model.DocumentAttributes; + +import javax.xml.bind.DatatypeConverter; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +public class FakeDocumentBuilder { + + Map fileModel = new HashMap(); + String type; + private boolean hasSourceUri = false; + private boolean hasSha1 = false; + private boolean hasDate = false; + + public FakeDocumentBuilder(String type) { + this.type = type; + } + + public FakeDocumentBuilder withName(String name) { + fileModel.put(DocumentAttributes.NAME.toString(), name); + return this; + } + + public FakeDocumentBuilder withStatus(String status) { + fileModel.put(DocumentAttributes.STATUS.toString(), status); + return this; + } + + public FakeDocumentBuilder withRandomSha1() throws NoSuchAlgorithmException { + fileModel.put(DocumentAttributes.SHA1.toString(), getRandomSha1()); + hasSha1 = true; + return this; + } + + private FakeDocumentBuilder withCurrentDate() { + fileModel.put(Crawler.Attributes.DATE, new Date() ); + return this; + } + + private FakeDocumentBuilder withRandomSourceUri() throws NoSuchAlgorithmException { + String path = "/tmp/" + getRandomSha1() + ".txt"; + fileModel.put(DocumentAttributes.SOURCE_URI.toString(), path); + return this; + } + + public FakeDocumentBuilder withCached(boolean cached) { + fileModel.put(DocumentAttributes.CACHED.toString(), cached); + return this; + } + + public void build() { + + try { + if ( ! hasSourceUri() ) { + this.withRandomSourceUri(); + } + if ( ! hasSha1() ) { + this.withRandomSha1(); + } + if ( ! hasDate() ) { + this.withCurrentDate(); + } + ODocument document = new ODocument(type).fromMap(fileModel); + document.save(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + } + + private String getRandomSha1() throws NoSuchAlgorithmException { + MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1"); + Random random = new Random(); + int size = random.nextInt(1000) + 1000; + byte[] content = new byte[size]; + + random.nextBytes(content); + return DatatypeConverter.printHexBinary(sha1Digest.digest(content)); + } + + private boolean hasDate() { + return hasDate; + } + + private boolean hasSha1() { + return hasSha1; + } + + private boolean hasSourceUri() { + return hasSourceUri; + } +} diff --git a/src/test/java/org/jbake/app/ContentStoreTest.java b/src/test/java/org/jbake/app/ContentStoreTest.java index bfce8c8b0..77b02e308 100644 --- a/src/test/java/org/jbake/app/ContentStoreTest.java +++ b/src/test/java/org/jbake/app/ContentStoreTest.java @@ -1,13 +1,21 @@ package org.jbake.app; import com.orientechnologies.orient.core.record.impl.ODocument; +import org.jbake.FakeDocumentBuilder; +import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentStatus; +import org.jbake.model.DocumentTypes; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import javax.xml.bind.DatatypeConverter; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; +import java.util.Random; import static org.junit.Assert.assertEquals; @@ -30,26 +38,22 @@ public void tearDown() throws Exception { @Test public void shouldGetCountForPublishedDocuments() throws Exception { - Map fileContents = new HashMap(); - for (int i = 0; i < 5; i++) { - fileContents.put("name", "dummyfile" + i); - fileContents.put("status", "published"); - createFakeDocument("post", fileContents); + FakeDocumentBuilder builder = new FakeDocumentBuilder("post"); + builder.withName("dummyfile" + i) + .withStatus("published") + .withRandomSha1() + .build(); } - fileContents.put("name", "draftdummy"); - fileContents.put("status", "draft"); - createFakeDocument("post",fileContents); + FakeDocumentBuilder builder = new FakeDocumentBuilder("post"); + builder.withName("draftdummy") + .withStatus("draft") + .withRandomSha1() + .build(); assertEquals( 6, db.getDocumentCount("post")); assertEquals( 5, db.getPublishedCount("post")); } - private void createFakeDocument(String name, Map fileContents) { - ODocument doc = new ODocument(name); - doc.fields(fileContents); - doc.save(); - } - } \ No newline at end of file diff --git a/src/test/java/org/jbake/app/PaginationTest.java b/src/test/java/org/jbake/app/PaginationTest.java index b23b60e97..fbb1ebd05 100644 --- a/src/test/java/org/jbake/app/PaginationTest.java +++ b/src/test/java/org/jbake/app/PaginationTest.java @@ -25,16 +25,17 @@ import com.orientechnologies.orient.core.record.impl.ODocument; import org.apache.commons.configuration.CompositeConfiguration; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.jbake.FakeDocumentBuilder; +import org.junit.*; import java.io.File; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author jdlee */ @@ -68,18 +69,15 @@ public void cleanup() throws InterruptedException { @Test public void testPagination() { - Map fileContents = new HashMap(); final int TOTAL_POSTS = 5; final int PER_PAGE = 2; for (int i = 1; i <= TOTAL_POSTS; i++) { - fileContents.put("name", "dummyfile" + i); - - ODocument doc = new ODocument("post"); - doc.fields(fileContents); - boolean cached = fileContents.get("cached") != null ? Boolean.valueOf((String) fileContents.get("cached")) : true; - doc.field("cached", cached); - doc.save(); + FakeDocumentBuilder builder = new FakeDocumentBuilder("post"); + builder.withName("dummyfile" + i) + .withCached(true) + .withStatus("published") + .build(); } int pageCount = 1; @@ -90,9 +88,12 @@ public void testPagination() { db.setStart(start); DocumentList posts = db.getAllContent("post"); - int expectedNumber = (pageCount==1)?pageCount:((pageCount%2==0)?pageCount+1:pageCount+PER_PAGE); + assertThat( posts.size() ).isLessThanOrEqualTo( 2 ); + + if( posts.size() > 1 ) { + assertThat((Date) posts.get(0).get("date")).isAfter((Date) posts.get(1).get("date")); + } - Assert.assertEquals("pagcount " +pageCount,"dummyfile" + expectedNumber, posts.get(0).get("name")); pageCount++; start += PER_PAGE; } From 59d1aa90cda18bb3f10de1fb72772ab34bd0f3c2 Mon Sep 17 00:00:00 2001 From: Jonathan Bullock Date: Sun, 7 May 2017 21:52:52 +0100 Subject: [PATCH 08/53] Reset state of DocumentTypes for OvenTest. --- src/main/java/org/jbake/model/DocumentTypes.java | 12 +++++++++++- src/test/java/org/jbake/app/OvenTest.java | 6 +++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jbake/model/DocumentTypes.java b/src/main/java/org/jbake/model/DocumentTypes.java index f62e1f726..e39a9ea50 100644 --- a/src/main/java/org/jbake/model/DocumentTypes.java +++ b/src/main/java/org/jbake/model/DocumentTypes.java @@ -17,9 +17,19 @@ */ public class DocumentTypes { - private static final Set DEFAULT_DOC_TYPES = new LinkedHashSet(Arrays.asList("page", "post", "masterindex", "archive", "feed")); + private static final Set DEFAULT_DOC_TYPES = new LinkedHashSet(); private static final Set LISTENERS = new HashSet(); + static { + resetDocumentTypes(); + } + + public static void resetDocumentTypes() { + DEFAULT_DOC_TYPES.clear(); + DEFAULT_DOC_TYPES.addAll(Arrays.asList("page", "post", "masterindex", "archive", "feed")); + } + + public static void addDocumentType(String docType) { DEFAULT_DOC_TYPES.add(docType); notifyListener(docType); diff --git a/src/test/java/org/jbake/app/OvenTest.java b/src/test/java/org/jbake/app/OvenTest.java index 7ab857687..097228660 100644 --- a/src/test/java/org/jbake/app/OvenTest.java +++ b/src/test/java/org/jbake/app/OvenTest.java @@ -10,6 +10,7 @@ import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.jbake.app.ConfigUtil.Keys; +import org.jbake.model.DocumentTypes; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -25,7 +26,10 @@ public class OvenTest { @Before public void setup() throws Exception { - URL sourceUrl = this.getClass().getResource("/"); + // reset values to known state otherwise previous test case runs can affect the success of this test case + DocumentTypes.resetDocumentTypes(); + + URL sourceUrl = this.getClass().getResource("/"); rootPath = new File(sourceUrl.getFile()); if (!rootPath.exists()) { throw new Exception("Cannot find base path for test!"); From 10e33bc5a8b6aa7bd22e4202e8e519677e9ceee6 Mon Sep 17 00:00:00 2001 From: Jonathan Bullock Date: Wed, 10 May 2017 13:50:14 +0100 Subject: [PATCH 09/53] Correctly set flag to say date has been set. --- src/test/java/org/jbake/FakeDocumentBuilder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/jbake/FakeDocumentBuilder.java b/src/test/java/org/jbake/FakeDocumentBuilder.java index 87e873b5f..faf2c90e6 100644 --- a/src/test/java/org/jbake/FakeDocumentBuilder.java +++ b/src/test/java/org/jbake/FakeDocumentBuilder.java @@ -42,6 +42,7 @@ public FakeDocumentBuilder withRandomSha1() throws NoSuchAlgorithmException { public FakeDocumentBuilder withDate(Date date) { fileModel.put(Crawler.Attributes.DATE, date); + hasDate = true; return this; } From fcbdb6e708958fc5256a2f24cf0690ddfe26e9ec Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 28 Mar 2016 17:47:12 +0200 Subject: [PATCH 10/53] added gradle application distribution * clone and zip example project repositories * add zip files to distribution bundle * moved test fixture resources to src/test/resources/fixture to get tests pass with gradle this.getClass().getResource("/").getFile() resolves to "some/path" whereas this.getClass().getResource("/fixture").getFile() resolves to "other/path" which makes it possible to access the fixtures. --- .gitignore | 2 + build.gradle | 42 +++++ gradle/application.gradle | 73 ++++++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 52271 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 164 ++++++++++++++++++ gradlew.bat | 90 ++++++++++ src/{main => dist/lib}/logging/logback.xml | 0 src/test/java/org/jbake/app/AssetTest.java | 14 +- .../java/org/jbake/app/ConfigUtilTest.java | 24 +-- src/test/java/org/jbake/app/CrawlerTest.java | 21 +-- src/test/java/org/jbake/app/InitTest.java | 118 ++++++------- .../AbstractTemplateEngineRenderingTest.java | 45 ++++- ...oovyMarkupTemplateEngineRenderingTest.java | 12 +- .../resources/assets/css/bootstrap.min.css | 9 - .../assets/css/bootstrap-responsive.min.css | 0 .../fixture/assets/css/bootstrap.min.css | 9 + .../assets/img/glyphicons-halflings-white.png | Bin .../assets/img/glyphicons-halflings.png | Bin .../{ => fixture}/assets/js/bootstrap.min.js | 0 .../{ => fixture}/assets/js/html5shiv.js | 0 .../assets/js/jquery-1.9.1.min.js | 0 .../{ => fixture}/content/about.html | 0 .../{ => fixture}/content/allcontent.html | 0 .../content/blog/2012/first-post.html | 0 .../content/blog/2013/second-post.html | 0 .../content/blog/2016/another-post.html | 0 .../content/blog/2016/draft-post.html | 0 .../content/blog/invalid_header.html | 0 .../{ => fixture}/content/index2.html | 0 .../content/papers/draft-paper.html | 2 +- .../content/papers/published-paper.html | 2 +- .../{ => fixture}/content/projects.html | 0 .../custom.properties} | 0 .../freemarkerTemplates/allcontent.ftl | 0 .../freemarkerTemplates/archive.ftl | 0 .../freemarkerTemplates/feed.ftl | 0 .../freemarkerTemplates/footer.ftl | 0 .../freemarkerTemplates/header.ftl | 0 .../freemarkerTemplates/index.ftl | 0 .../freemarkerTemplates/menu.ftl | 0 .../freemarkerTemplates/page.ftl | 0 .../freemarkerTemplates/post.ftl | 0 .../freemarkerTemplates/sitemap.ftl | 0 .../freemarkerTemplates/tags.ftl | 0 .../groovyMarkupTemplates/allcontent.tpl | 2 + .../groovyMarkupTemplates/archive.tpl | 2 + .../groovyMarkupTemplates/feed.tpl | 2 + .../groovyMarkupTemplates/footer.tpl | 2 + .../groovyMarkupTemplates/header.tpl | 2 + .../groovyMarkupTemplates/index.tpl | 2 + .../groovyMarkupTemplates/layout/main.tpl | 2 + .../groovyMarkupTemplates/menu.tpl | 2 + .../groovyMarkupTemplates/page.tpl | 2 + .../groovyMarkupTemplates/paper.tpl | 2 + .../groovyMarkupTemplates/post.tpl | 2 + .../groovyMarkupTemplates/sitemap.tpl | 2 + .../groovyMarkupTemplates/tags.tpl | 2 + .../groovyTemplates/allcontent.gsp | 0 .../{ => fixture}/groovyTemplates/archive.gsp | 0 .../{ => fixture}/groovyTemplates/feed.gsp | 0 .../{ => fixture}/groovyTemplates/footer.gsp | 0 .../{ => fixture}/groovyTemplates/header.gsp | 0 .../{ => fixture}/groovyTemplates/index.gsp | 0 .../{ => fixture}/groovyTemplates/page.gsp | 0 .../{ => fixture}/groovyTemplates/post.gsp | 0 .../{ => fixture}/groovyTemplates/sitemap.gsp | 0 .../{ => fixture}/groovyTemplates/tags.gsp | 0 .../{ => fixture}/ignorables/.test.txt | 0 .../{ => fixture}/ignorables/test.txt | 0 .../{ => fixture}/jadeTemplates/archive.jade | 0 .../{ => fixture}/jadeTemplates/feed.jade | 0 .../{ => fixture}/jadeTemplates/footer.jade | 0 .../{ => fixture}/jadeTemplates/header.jade | 0 .../{ => fixture}/jadeTemplates/index.jade | 0 .../{ => fixture}/jadeTemplates/layout.jade | 0 .../{ => fixture}/jadeTemplates/page.jade | 0 .../{ => fixture}/jadeTemplates/post.jade | 0 .../{ => fixture}/jadeTemplates/sitemap.jade | 0 .../{ => fixture}/jadeTemplates/tags.jade | 0 src/test/resources/fixture/jbake.properties | 18 ++ .../resources/{ => fixture}/media/favicon.ico | Bin src/test/resources/{ => fixture}/test.zip | Bin .../thymeleafTemplates/allcontent.thyme | 0 .../thymeleafTemplates/archive.thyme | 0 .../thymeleafTemplates/feed.thyme | 0 .../thymeleafTemplates/footer.thyme | 0 .../thymeleafTemplates/header.thyme | 0 .../thymeleafTemplates/index.thyme | 0 .../thymeleafTemplates/page.thyme | 0 .../thymeleafTemplates/post.thyme | 0 .../thymeleafTemplates/sitemap.thyme | 0 .../thymeleafTemplates/tags.thyme | 0 93 files changed, 563 insertions(+), 114 deletions(-) create mode 100644 build.gradle create mode 100644 gradle/application.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat rename src/{main => dist/lib}/logging/logback.xml (100%) delete mode 100644 src/test/resources/assets/css/bootstrap.min.css rename src/test/resources/{ => fixture}/assets/css/bootstrap-responsive.min.css (100%) create mode 100644 src/test/resources/fixture/assets/css/bootstrap.min.css rename src/test/resources/{ => fixture}/assets/img/glyphicons-halflings-white.png (100%) rename src/test/resources/{ => fixture}/assets/img/glyphicons-halflings.png (100%) rename src/test/resources/{ => fixture}/assets/js/bootstrap.min.js (100%) rename src/test/resources/{ => fixture}/assets/js/html5shiv.js (100%) rename src/test/resources/{ => fixture}/assets/js/jquery-1.9.1.min.js (100%) rename src/test/resources/{ => fixture}/content/about.html (100%) rename src/test/resources/{ => fixture}/content/allcontent.html (100%) rename src/test/resources/{ => fixture}/content/blog/2012/first-post.html (100%) rename src/test/resources/{ => fixture}/content/blog/2013/second-post.html (100%) rename src/test/resources/{ => fixture}/content/blog/2016/another-post.html (100%) rename src/test/resources/{ => fixture}/content/blog/2016/draft-post.html (100%) rename src/test/resources/{ => fixture}/content/blog/invalid_header.html (100%) rename src/test/resources/{ => fixture}/content/index2.html (100%) rename src/test/resources/{ => fixture}/content/papers/draft-paper.html (95%) rename src/test/resources/{ => fixture}/content/papers/published-paper.html (95%) rename src/test/resources/{ => fixture}/content/projects.html (100%) rename src/test/resources/{jbake.properties => fixture/custom.properties} (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/allcontent.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/archive.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/feed.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/footer.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/header.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/index.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/menu.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/page.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/post.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/sitemap.ftl (100%) rename src/test/resources/{ => fixture}/freemarkerTemplates/tags.ftl (100%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/allcontent.tpl (83%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/archive.tpl (96%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/feed.tpl (95%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/footer.tpl (87%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/header.tpl (97%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/index.tpl (93%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/layout/main.tpl (90%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/menu.tpl (93%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/page.tpl (92%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/paper.tpl (93%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/post.tpl (93%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/sitemap.tpl (92%) rename src/test/resources/{ => fixture}/groovyMarkupTemplates/tags.tpl (97%) rename src/test/resources/{ => fixture}/groovyTemplates/allcontent.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/archive.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/feed.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/footer.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/header.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/index.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/page.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/post.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/sitemap.gsp (100%) rename src/test/resources/{ => fixture}/groovyTemplates/tags.gsp (100%) rename src/test/resources/{ => fixture}/ignorables/.test.txt (100%) rename src/test/resources/{ => fixture}/ignorables/test.txt (100%) rename src/test/resources/{ => fixture}/jadeTemplates/archive.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/feed.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/footer.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/header.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/index.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/layout.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/page.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/post.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/sitemap.jade (100%) rename src/test/resources/{ => fixture}/jadeTemplates/tags.jade (100%) create mode 100644 src/test/resources/fixture/jbake.properties rename src/test/resources/{ => fixture}/media/favicon.ico (100%) rename src/test/resources/{ => fixture}/test.zip (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/allcontent.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/archive.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/feed.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/footer.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/header.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/index.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/page.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/post.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/sitemap.thyme (100%) rename src/test/resources/{ => fixture}/thymeleafTemplates/tags.thyme (100%) diff --git a/.gitignore b/.gitignore index 069485ec9..dc6be0687 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ /.idea *.iml *~ +build/ +.gradle diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..a982e2b2d --- /dev/null +++ b/build.gradle @@ -0,0 +1,42 @@ +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'maven' +apply from: 'gradle/application.gradle' + +group = 'org.jbake' +version = '2.5.0-SNAPSHOT' + +description = """jbake""" + +sourceCompatibility = 1.6 +targetCompatibility = 1.6 + + +repositories { + jcenter() +} + +dependencies { + compile group: 'commons-io', name: 'commons-io', version:'2.4' + compile group: 'commons-configuration', name: 'commons-configuration', version:'1.9' + compile group: 'com.googlecode.json-simple', name: 'json-simple', version:'1.1.1' + compile group: 'args4j', name: 'args4j', version:'2.0.26' + compile group: 'org.freemarker', name: 'freemarker', version:'2.3.20' + compile group: 'com.orientechnologies', name: 'orient-commons', version:'1.6.4' + compile group: 'com.orientechnologies', name: 'orientdb-core', version:'1.6.4' + compile group: 'org.pegdown', name: 'pegdown', version:'1.4.2' + compile group: 'org.asciidoctor', name: 'asciidoctorj', version:'1.5.2' + compile group: 'org.eclipse.jetty', name: 'jetty-server', version:'8.1.12.v20130726' + compile group: 'org.codehaus.groovy', name: 'groovy', version:'2.3.6' + compile group: 'org.codehaus.groovy', name: 'groovy-templates', version:'2.3.6' + compile group: 'org.thymeleaf', name: 'thymeleaf', version:'2.1.3.RELEASE' + compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-conditionalcomments', version:'2.1.1.RELEASE' + compile group: 'org.slf4j', name: 'slf4j-api', version:'1.7.6' + compile group: 'org.slf4j', name: 'jul-to-slf4j', version:'1.7.6' + compile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.1' + compile group: 'ch.qos.logback', name: 'logback-core', version:'1.1.1' + compile "de.neuland-bfi:jade4j:0.4.2" + compile "org.apache.commons:commons-vfs2:2.0" + testCompile group: 'junit', name: 'junit', version:'4.11' + testCompile group: 'org.assertj', name: 'assertj-core', version:'1.7.0' +} diff --git a/gradle/application.gradle b/gradle/application.gradle new file mode 100644 index 000000000..09307e3a8 --- /dev/null +++ b/gradle/application.gradle @@ -0,0 +1,73 @@ +import org.ajoberstar.grgit.Grgit + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'org.ajoberstar:grgit:1.5.0' + } +} + +apply plugin: 'application' + +mainClassName = "org.jbake.launcher.Main" +applicationName = "jbake" + +ext { + examplesBase = "$project.buildDir/examples" + + exampleRepositories = [ + "example_project_freemarker": "git://github.com/jbake-org/jbake-example-project-freemarker.git", + "example_project_groovy" : "git://github.com/jbake-org/jbake-example-project-groovy.git", + "example_project_thymeleaf" : "git://github.com/jbake-org/jbake-example-project-thymeleaf.git" + ] +} + +task cloneProjectExampleRepositories() { + group = "distribution" + description "Clone jbake example project repositories" + + outputs.dir examplesBase + + doLast { + exampleRepositories.each { name, repository -> + Grgit.clone(dir: "$examplesBase/$name", uri: repository) + } + } +} + +//create Zip Task for each repository +exampleRepositories.each { name, repository -> + + task "zip${name}Repository"(type: Zip, dependsOn: cloneProjectExampleRepositories) { + group "distribution" + description "Zip $name repository" + + baseName = name + archiveName = "${baseName}.zip" + + from "$examplesBase/$baseName" + exclude 'README.md' + exclude 'LICENSE' + exclude '.git' + } + +} + +startScripts { + classpath += files("logging") +} + +distributions { + main { + baseName = "jbake" + contents { + //Include Outputs from zip tasks + exampleRepositories.each { name, repository -> + def task = project.tasks.getByName("zip${name}Repository") + from(task) + } + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..30d399d8d2bf522ff5de94bf434a7cc43a9a74b5 GIT binary patch literal 52271 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 p \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..8a0b282aa --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/logging/logback.xml b/src/dist/lib/logging/logback.xml similarity index 100% rename from src/main/logging/logback.xml rename to src/dist/lib/logging/logback.xml diff --git a/src/test/java/org/jbake/app/AssetTest.java b/src/test/java/org/jbake/app/AssetTest.java index 5b0fe5c82..fe04332b4 100644 --- a/src/test/java/org/jbake/app/AssetTest.java +++ b/src/test/java/org/jbake/app/AssetTest.java @@ -18,11 +18,11 @@ public class AssetTest { - private CompositeConfiguration config; + private CompositeConfiguration config; @Before public void setup() throws Exception { - config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile())); + config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); Assert.assertEquals(".html", config.getString(Keys.OUTPUT_EXTENSION)); } @@ -31,7 +31,7 @@ public void setup() throws Exception { @Test public void copy() throws Exception { - URL assetsUrl = this.getClass().getResource("/assets"); + URL assetsUrl = this.getClass().getResource("/fixture/assets"); File assets = new File(assetsUrl.getFile()); Asset asset = new Asset(assets.getParentFile(), folder.getRoot(), config); asset.copy(assets); @@ -49,7 +49,7 @@ public void copy() throws Exception { @Test public void copyCustomFolder() throws Exception { config.setProperty(ConfigUtil.Keys.ASSET_FOLDER, "media"); - URL assetsUrl = this.getClass().getResource("/media"); + URL assetsUrl = this.getClass().getResource("/fixture/media"); File assets = new File(assetsUrl.getFile()); Asset asset = new Asset(assets.getParentFile(), folder.getRoot(), config); asset.copy(assets); @@ -64,7 +64,7 @@ public void copyCustomFolder() throws Exception { public void copyIgnore() throws Exception { config.setProperty(Keys.ASSET_FOLDER, "ignorables"); config.setProperty(Keys.ASSET_IGNORE_HIDDEN, "true"); - URL assetsUrl = this.getClass().getResource("/ignorables"); + URL assetsUrl = this.getClass().getResource("/fixture/ignorables"); File assets = new File(assetsUrl.getFile()); hideAssets(assets); Asset asset = new Asset(assets.getParentFile(), folder.getRoot(), config); @@ -103,7 +103,7 @@ public boolean accept(File dir, String name) { */ @Test public void testWriteProtected() throws Exception { - URL assetsUrl = this.getClass().getResource("/assets"); + URL assetsUrl = this.getClass().getResource("/fixture/assets"); File assets = new File(assetsUrl.getFile()); final File cssFile = new File(folder.newFolder("css"), "bootstrap.min.css"); FileUtils.touch(cssFile); @@ -122,7 +122,7 @@ public void testWriteProtected() throws Exception { @Test public void testUnlistable() throws Exception { config.setProperty(Keys.ASSET_FOLDER, "non-existent"); - URL assetsUrl = this.getClass().getResource("/"); + URL assetsUrl = this.getClass().getResource("/fixture"); File assets = new File(assetsUrl.getFile() + File.separatorChar + "non-existent"); Asset asset = new Asset(assets.getParentFile(), folder.getRoot(), config); asset.copy(assets); diff --git a/src/test/java/org/jbake/app/ConfigUtilTest.java b/src/test/java/org/jbake/app/ConfigUtilTest.java index 4fcfeca45..5362c0058 100644 --- a/src/test/java/org/jbake/app/ConfigUtilTest.java +++ b/src/test/java/org/jbake/app/ConfigUtilTest.java @@ -10,23 +10,17 @@ public class ConfigUtilTest { - @Test - public void load() throws Exception { - CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile())); - - // check default.properties values exist - assertEquals("output", config.getString(Keys.DESTINATION_FOLDER)); - - // check custom.properties values exist - assertEquals("testing123", config.getString("test.property")); + @Test + public void load() throws Exception { + CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); - assertEquals("http://www.jbake.org", config.getString(Keys.SITE_HOST)); - } + // check default.properties values exist + assertEquals("output", config.getString(Keys.DESTINATION_FOLDER)); - @Test - public void shouldHaveSiteConfiguredWhenServerRunning() throws Exception { - CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile()), true); + // check custom.properties values exist + assertEquals("testing123", config.getString("test.property")); + + assertEquals("http://www.jbake.org", config.getString(Keys.SITE_HOST)); - assertEquals("http://localhost:8820", config.getString(Keys.SITE_HOST)); } } diff --git a/src/test/java/org/jbake/app/CrawlerTest.java b/src/test/java/org/jbake/app/CrawlerTest.java index a5860b4a8..542c12e27 100644 --- a/src/test/java/org/jbake/app/CrawlerTest.java +++ b/src/test/java/org/jbake/app/CrawlerTest.java @@ -24,16 +24,16 @@ public class CrawlerTest { private ContentStore db; private File sourceFolder; - @Before + @Before public void setup() throws Exception { - URL sourceUrl = this.getClass().getResource("/"); + URL sourceUrl = this.getClass().getResource("/fixture"); sourceFolder = new File(sourceUrl.getFile()); if (!sourceFolder.exists()) { throw new Exception("Cannot find sample data structure!"); } - config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile())); + config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); Assert.assertEquals(".html", config.getString(Keys.OUTPUT_EXTENSION)); db = DBUtil.createDataStore("memory", "documents" + System.currentTimeMillis()); } @@ -81,22 +81,23 @@ public void crawl() throws ConfigurationException { @Test public void renderWithPrettyUrls() throws Exception { Map testProperties = new HashMap(); - testProperties.put(Keys.URI_NO_EXTENSION, true); - testProperties.put(Keys.URI_NO_EXTENSION_PREFIX, "/blog"); + testProperties.put(Keys.URI_NO_EXTENSION, "/blog"); CompositeConfiguration config = new CompositeConfiguration(); config.addConfiguration(new MapConfiguration(testProperties)); - config.addConfiguration(ConfigUtil.load(new File(this.getClass().getResource("/").getFile()))); + config.addConfiguration(ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile()))); - Crawler crawler = new Crawler(db, sourceFolder, config); - crawler.crawl(new File(sourceFolder.getPath() + File.separator + config.getString(Keys.CONTENT_FOLDER))); + URL contentUrl = this.getClass().getResource("/fixture"); + File content = new File(contentUrl.getFile()); + Crawler crawler = new Crawler(db, content, config); + crawler.crawl(new File(content.getPath() + File.separator + "content")); - Assert.assertEquals(4, db.getDocumentCount("post")); + Assert.assertEquals(2, db.getDocumentCount("post")); Assert.assertEquals(3, db.getDocumentCount("page")); - DocumentList documents = db.getPublishedPosts(); for (Map model : documents) { + String noExtensionUri = "blog/\\d{4}/" + FilenameUtils.getBaseName((String) model.get("file")) + "/"; Assert.assertThat(model.get("noExtensionUri"), RegexMatcher.matches(noExtensionUri)); diff --git a/src/test/java/org/jbake/app/InitTest.java b/src/test/java/org/jbake/app/InitTest.java index 3bb4be614..51ca5e11e 100644 --- a/src/test/java/org/jbake/app/InitTest.java +++ b/src/test/java/org/jbake/app/InitTest.java @@ -1,11 +1,6 @@ package org.jbake.app; -import java.io.File; -import java.io.IOException; -import java.net.URL; - import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; import org.jbake.app.ConfigUtil.Keys; import org.jbake.launcher.Init; import org.junit.Before; @@ -13,64 +8,69 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; -import static org.assertj.core.api.Assertions.*; +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; public class InitTest { - @Rule - public TemporaryFolder folder = new TemporaryFolder(); - - public CompositeConfiguration config; - private File rootPath; - - @Before - public void setup() throws Exception { - URL sourceUrl = this.getClass().getResource("/"); - rootPath = new File(sourceUrl.getFile()); + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + public CompositeConfiguration config; + private File rootPath; + + @Before + public void setup() throws Exception { + URL sourceUrl = this.getClass().getResource("/fixture"); + rootPath = new File(sourceUrl.getFile()); if (!rootPath.exists()) { throw new Exception("Cannot find base path for test!"); } - config = ConfigUtil.load(rootPath); - // override base template config option - config.setProperty("example.project.freemarker", "test.zip"); - } - - @Test - public void initOK() throws Exception { - Init init = new Init(config); - File initPath = folder.newFolder("init"); - init.run(initPath, rootPath, "freemarker"); - File testFile = new File(initPath, "testfile.txt"); - assertThat(testFile).exists(); - } - - @Test - public void initFailDestinationContainsContent() throws IOException{ - Init init = new Init(config); - File initPath = folder.newFolder("init"); - File contentFolder = new File(initPath.getPath() + File.separatorChar + config.getString(Keys.CONTENT_FOLDER)); - contentFolder.mkdir(); - try { - init.run(initPath, rootPath, "freemarker"); - fail("Shouldn't be able to initialise folder with content folder within it!"); - } catch (Exception e) { - e.printStackTrace(); - } - File testFile = new File(initPath, "testfile.txt"); - assertThat(testFile).doesNotExist(); - } - - @Test - public void initFailInvalidTemplateType() throws IOException{ - Init init = new Init(config); - File initPath = folder.newFolder("init"); - try { - init.run(initPath, rootPath, "invalid"); - fail("Shouldn't be able to initialise folder with invalid template type"); - } catch (Exception e) { - e.printStackTrace(); - } - File testFile = new File(initPath, "testfile.txt"); - assertThat(testFile).doesNotExist(); - } + config = ConfigUtil.load(rootPath); + // override base template config option + config.setProperty("example.project.freemarker", "test.zip"); + } + + @Test + public void initOK() throws Exception { + Init init = new Init(config); + File initPath = folder.newFolder("init"); + init.run(initPath, rootPath, "freemarker"); + File testFile = new File(initPath, "testfile.txt"); + assertThat(testFile).exists(); + } + + @Test + public void initFailDestinationContainsContent() throws IOException { + Init init = new Init(config); + File initPath = folder.newFolder("init"); + File contentFolder = new File(initPath.getPath() + File.separatorChar + config.getString(Keys.CONTENT_FOLDER)); + contentFolder.mkdir(); + try { + init.run(initPath, rootPath, "freemarker"); + fail("Shouldn't be able to initialise folder with content folder within it!"); + } catch (Exception e) { + e.printStackTrace(); + } + File testFile = new File(initPath, "testfile.txt"); + assertThat(testFile).doesNotExist(); + } + + @Test + public void initFailInvalidTemplateType() throws IOException { + Init init = new Init(config); + File initPath = folder.newFolder("init"); + try { + init.run(initPath, rootPath, "invalid"); + fail("Shouldn't be able to initialise folder with invalid template type"); + } catch (Exception e) { + e.printStackTrace(); + } + File testFile = new File(initPath, "testfile.txt"); + assertThat(testFile).doesNotExist(); + } } diff --git a/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java index 52ed8af90..1cad7b53d 100644 --- a/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java @@ -25,6 +25,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FileUtils; +<<<<<<< HEAD import org.jbake.app.ConfigUtil; import org.jbake.app.ContentStore; import org.jbake.app.Crawler; @@ -39,6 +40,20 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +======= +import org.jbake.app.*; +import org.jbake.model.DocumentTypes; +import org.junit.*; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; +>>>>>>> 48e3cb8... added gradle application distribution import java.io.File; import java.net.URL; @@ -53,7 +68,6 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * * @author jdlee */ public abstract class AbstractTemplateEngineRenderingTest { @@ -70,9 +84,12 @@ public abstract class AbstractTemplateEngineRenderingTest { protected final String templateDir; protected final String templateExtension; protected final Map> outputStrings = new HashMap>(); +<<<<<<< HEAD private Crawler crawler; private Parser parser; protected Renderer renderer; +======= +>>>>>>> 48e3cb8... added gradle application distribution protected Locale currentLocale; public AbstractTemplateEngineRenderingTest(String templateDir, String templateExtension) { @@ -81,6 +98,7 @@ public AbstractTemplateEngineRenderingTest(String templateDir, String templateEx } @Before +<<<<<<< HEAD public void setup() throws Exception { currentLocale = Locale.getDefault(); Locale.setDefault(Locale.ENGLISH); @@ -89,6 +107,14 @@ public void setup() throws Exception { DocumentTypes.addListener(listener); URL sourceUrl = this.getClass().getResource("/"); +======= + public void setup() throws Exception, IOException, URISyntaxException { + + currentLocale = Locale.getDefault(); + Locale.setDefault(Locale.ENGLISH); + + URL sourceUrl = this.getClass().getResource("/fixture"); +>>>>>>> 48e3cb8... added gradle application distribution sourceFolder = new File(sourceUrl.getFile()); if (!sourceFolder.exists()) { @@ -102,7 +128,7 @@ public void setup() throws Exception { throw new Exception("Cannot find template folder!"); } - config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile())); + config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); Iterator keys = config.getKeys(); while (keys.hasNext()) { String key = keys.next(); @@ -112,6 +138,7 @@ public void setup() throws Exception { } } Assert.assertEquals(".html", config.getString(ConfigUtil.Keys.OUTPUT_EXTENSION)); +<<<<<<< HEAD db = DBUtil.createDataStore("memory", "documents"+System.currentTimeMillis()); crawler = new Crawler(db, sourceFolder, config); @@ -157,15 +184,21 @@ private void setupExpectedOutputStrings() { outputStrings.put("sitemap", Arrays.asList("blog/2013/second-post.html", "blog/2012/first-post.html", - "papers/published-paper.html")); + "papers/published-fixture.groovyMarkupTemplates.paper.html")); +======= + db = DBUtil.createDataStore("memory", "documents" + System.currentTimeMillis()); +>>>>>>> 48e3cb8... added gradle application distribution } @After public void cleanup() throws InterruptedException { db.drop(); db.close(); +<<<<<<< HEAD db.shutdown(); +======= +>>>>>>> 48e3cb8... added gradle application distribution Locale.setDefault(currentLocale); } @@ -265,7 +298,7 @@ public void renderTags() throws Exception { @Test public void renderSitemap() throws Exception { - DocumentTypes.addDocumentType("paper"); + DocumentTypes.addDocumentType("fixture.groovyMarkupTemplates.paper"); DBUtil.updateSchema(db); renderer.renderSitemap("sitemap.xml"); @@ -277,11 +310,11 @@ public void renderSitemap() throws Exception { for (String string : getOutputStrings("sitemap")) { assertThat(output).contains(string); } - assertThat(output).doesNotContain("draft-paper.html"); + assertThat(output).doesNotContain("draft-fixture.groovyMarkupTemplates.paper.html"); } protected List getOutputStrings(String type) { return outputStrings.get(type); - + } } diff --git a/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java index 923295aa1..c377d5763 100644 --- a/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java @@ -41,8 +41,8 @@ public GroovyMarkupTemplateEngineRenderingTest() { "First Post")); outputStrings.put("sitemap", Arrays.asList("blog/2013/second-post.html", "blog/2012/first-post.html", - "papers/published-paper.html")); - outputStrings.put("paper", Arrays.asList("

Published Paper

", + "papers/published-fixture.groovyMarkupTemplates.paper.html")); + outputStrings.put("fixture.groovyMarkupTemplates.paper", Arrays.asList("

Published Paper

", "

24", "2014

", "Lorem ipsum dolor sit amet", @@ -54,15 +54,15 @@ public GroovyMarkupTemplateEngineRenderingTest() { @Test public void renderCustomTypePaper() throws Exception { // setup - config.setProperty("template.paper.file", "paper." + templateExtension); - DocumentTypes.addDocumentType("paper"); + config.setProperty("template.fixture.groovyMarkupTemplates.paper.file", "fixture.groovyMarkupTemplates.paper." + templateExtension); + DocumentTypes.addDocumentType("fixture.groovyMarkupTemplates.paper"); DBUtil.updateSchema(db); Crawler crawler = new Crawler(db, sourceFolder, config); crawler.crawl(new File(sourceFolder.getPath() + File.separator + "content")); Parser parser = new Parser(config, sourceFolder.getPath()); Renderer renderer = new Renderer(db, destinationFolder, templateFolder, config); - String filename = "published-paper.html"; + String filename = "published-fixture.groovyMarkupTemplates.paper.html"; File sampleFile = new File(sourceFolder.getPath() + File.separator + "content" + File.separator + "papers" + File.separator + filename); Map content = parser.processFile(sampleFile); @@ -73,7 +73,7 @@ public void renderCustomTypePaper() throws Exception { // verify String output = FileUtils.readFileToString(outputFile); - for (String string : getOutputStrings("paper")) { + for (String string : getOutputStrings("fixture.groovyMarkupTemplates.paper")) { assertThat(output).contains(string); } diff --git a/src/test/resources/assets/css/bootstrap.min.css b/src/test/resources/assets/css/bootstrap.min.css deleted file mode 100644 index fd5ed7340..000000000 --- a/src/test/resources/assets/css/bootstrap.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap v2.3.0 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/src/test/resources/assets/css/bootstrap-responsive.min.css b/src/test/resources/fixture/assets/css/bootstrap-responsive.min.css similarity index 100% rename from src/test/resources/assets/css/bootstrap-responsive.min.css rename to src/test/resources/fixture/assets/css/bootstrap-responsive.min.css diff --git a/src/test/resources/fixture/assets/css/bootstrap.min.css b/src/test/resources/fixture/assets/css/bootstrap.min.css new file mode 100644 index 000000000..27adc6a6d --- /dev/null +++ b/src/test/resources/fixture/assets/css/bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v2.3.0 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat} .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")} .icon-glass{background-position:0 0} .icon-music{background-position:-24px 0} .icon-search{background-position:-48px 0} .icon-envelope{background-position:-72px 0} .icon-heart{background-position:-96px 0} .icon-star{background-position:-120px 0} .icon-star-empty{background-position:-144px 0} .icon-user{background-position:-168px 0} .icon-film{background-position:-192px 0} .icon-th-large{background-position:-216px 0} .icon-th{background-position:-240px 0} .icon-th-list{background-position:-264px 0} .icon-ok{background-position:-288px 0} .icon-remove{background-position:-312px 0} .icon-zoom-in{background-position:-336px 0} .icon-zoom-out{background-position:-360px 0} .icon-off{background-position:-384px 0} .icon-signal{background-position:-408px 0} .icon-cog{background-position:-432px 0} .icon-trash{background-position:-456px 0} .icon-home{background-position:0 -24px} .icon-file{background-position:-24px -24px} .icon-time{background-position:-48px -24px} .icon-road{background-position:-72px -24px} .icon-download-alt{background-position:-96px -24px} .icon-download{background-position:-120px -24px} .icon-upload{background-position:-144px -24px} .icon-inbox{background-position:-168px -24px} .icon-play-circle{background-position:-192px -24px} .icon-repeat{background-position:-216px -24px} .icon-refresh{background-position:-240px -24px} .icon-list-alt{background-position:-264px -24px} .icon-lock{background-position:-287px -24px} .icon-flag{background-position:-312px -24px} .icon-headphones{background-position:-336px -24px} .icon-volume-off{background-position:-360px -24px} .icon-volume-down{background-position:-384px -24px} .icon-volume-up{background-position:-408px -24px} .icon-qrcode{background-position:-432px -24px} .icon-barcode{background-position:-456px -24px} .icon-tag{background-position:0 -48px} .icon-tags{background-position:-25px -48px} .icon-book{background-position:-48px -48px} .icon-bookmark{background-position:-72px -48px} .icon-print{background-position:-96px -48px} .icon-camera{background-position:-120px -48px} .icon-font{background-position:-144px -48px} .icon-bold{background-position:-167px -48px} .icon-italic{background-position:-192px -48px} .icon-text-height{background-position:-216px -48px} .icon-text-width{background-position:-240px -48px} .icon-align-left{background-position:-264px -48px} .icon-align-center{background-position:-288px -48px} .icon-align-right{background-position:-312px -48px} .icon-align-justify{background-position:-336px -48px} .icon-list{background-position:-360px -48px} .icon-indent-left{background-position:-384px -48px} .icon-indent-right{background-position:-408px -48px} .icon-facetime-video{background-position:-432px -48px} .icon-picture{background-position:-456px -48px} .icon-pencil{background-position:0 -72px} .icon-map-marker{background-position:-24px -72px} .icon-adjust{background-position:-48px -72px} .icon-tint{background-position:-72px -72px} .icon-edit{background-position:-96px -72px} .icon-share{background-position:-120px -72px} .icon-check{background-position:-144px -72px} .icon-move{background-position:-168px -72px} .icon-step-backward{background-position:-192px -72px} .icon-fast-backward{background-position:-216px -72px} .icon-backward{background-position:-240px -72px} .icon-play{background-position:-264px -72px} .icon-pause{background-position:-288px -72px} .icon-stop{background-position:-312px -72px} .icon-forward{background-position:-336px -72px} .icon-fast-forward{background-position:-360px -72px} .icon-step-forward{background-position:-384px -72px} .icon-eject{background-position:-408px -72px} .icon-chevron-left{background-position:-432px -72px} .icon-chevron-right{background-position:-456px -72px} .icon-plus-sign{background-position:0 -96px} .icon-minus-sign{background-position:-24px -96px} .icon-remove-sign{background-position:-48px -96px} .icon-ok-sign{background-position:-72px -96px} .icon-question-sign{background-position:-96px -96px} .icon-info-sign{background-position:-120px -96px} .icon-screenshot{background-position:-144px -96px} .icon-remove-circle{background-position:-168px -96px} .icon-ok-circle{background-position:-192px -96px} .icon-ban-circle{background-position:-216px -96px} .icon-arrow-left{background-position:-240px -96px} .icon-arrow-right{background-position:-264px -96px} .icon-arrow-up{background-position:-289px -96px} .icon-arrow-down{background-position:-312px -96px} .icon-share-alt{background-position:-336px -96px} .icon-resize-full{background-position:-360px -96px} .icon-resize-small{background-position:-384px -96px} .icon-plus{background-position:-408px -96px} .icon-minus{background-position:-433px -96px} .icon-asterisk{background-position:-456px -96px} .icon-exclamation-sign{background-position:0 -120px} .icon-gift{background-position:-24px -120px} .icon-leaf{background-position:-48px -120px} .icon-fire{background-position:-72px -120px} .icon-eye-open{background-position:-96px -120px} .icon-eye-close{background-position:-120px -120px} .icon-warning-sign{background-position:-144px -120px} .icon-plane{background-position:-168px -120px} .icon-calendar{background-position:-192px -120px} .icon-random{width:16px;background-position:-216px -120px} .icon-comment{background-position:-240px -120px} .icon-magnet{background-position:-264px -120px} .icon-chevron-up{background-position:-288px -120px} .icon-chevron-down{background-position:-313px -119px} .icon-retweet{background-position:-336px -120px} .icon-shopping-cart{background-position:-360px -120px} .icon-folder-close{width:16px;background-position:-384px -120px} .icon-folder-open{width:16px;background-position:-408px -120px} .icon-resize-vertical{background-position:-432px -119px} .icon-resize-horizontal{background-position:-456px -118px} .icon-hdd{background-position:0 -144px} .icon-bullhorn{background-position:-24px -144px} .icon-bell{background-position:-48px -144px} .icon-certificate{background-position:-72px -144px} .icon-thumbs-up{background-position:-96px -144px} .icon-thumbs-down{background-position:-120px -144px} .icon-hand-right{background-position:-144px -144px} .icon-hand-left{background-position:-168px -144px} .icon-hand-up{background-position:-192px -144px} .icon-hand-down{background-position:-216px -144px} .icon-circle-arrow-right{background-position:-240px -144px} .icon-circle-arrow-left{background-position:-264px -144px} .icon-circle-arrow-up{background-position:-288px -144px} .icon-circle-arrow-down{background-position:-312px -144px} .icon-globe{background-position:-336px -144px} .icon-wrench{background-position:-360px -144px} .icon-tasks{background-position:-384px -144px} .icon-filter{background-position:-408px -144px} .icon-briefcase{background-position:-432px -144px} .icon-fullscreen{background-position:-456px -144px} .dropup,.dropdown{position:relative} .dropdown-toggle{*margin-bottom:-3px} .dropdown-toggle:active,.open .dropdown-toggle{outline:0} .caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""} .dropdown .caret{margin-top:8px;margin-left:2px} .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box} .dropdown-menu.pull-right{right:0;left:auto} .dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff} .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap} .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)} .dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)} .dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999} .dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .open{*z-index:1000} .open>.dropdown-menu{display:block} .pull-right>.dropdown-menu{right:0;left:auto} .dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""} .dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px} .dropdown-submenu{position:relative} .dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px} .dropdown-submenu:hover>.dropdown-menu{display:block} .dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0} .dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "} .dropdown-submenu:hover>a:after{border-left-color:#fff} .dropdown-submenu.pull-left{float:none} .dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px} .dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px} .typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)} .well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)} .well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} .well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} .fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear} .fade.in{opacity:1} .collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease} .collapse.in{height:auto} .close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)} .close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)} button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none} .btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)} .btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9} .btn:active,.btn.active{background-color:#ccc \9} .btn:first-child{*margin-left:0} .btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear} .btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} .btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)} .btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none} .btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} .btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px} .btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} .btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0} .btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px} .btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} .btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} .btn-block+.btn-block{margin-top:5px} input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%} .btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)} .btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3} .btn-primary:active,.btn-primary.active{background-color:#039 \9} .btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505} .btn-warning:active,.btn-warning.active{background-color:#c67605 \9} .btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a} .btn-danger:active,.btn-danger.active{background-color:#942a25 \9} .btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249} .btn-success:active,.btn-success.active{background-color:#408140 \9} .btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0} .btn-info:active,.btn-info.active{background-color:#24748c \9} .btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515} .btn-inverse:active,.btn-inverse.active{background-color:#080808 \9} button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px} button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0} button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px} button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px} button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px} .btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none} .btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} .btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent} .btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none} .btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1} .btn-group:first-child{*margin-left:0} .btn-group+.btn-group{margin-left:5px} .btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0} .btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px} .btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} .btn-group>.btn+.btn{margin-left:-1px} .btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px} .btn-group>.btn-mini{font-size:10.5px} .btn-group>.btn-small{font-size:11.9px} .btn-group>.btn-large{font-size:17.5px} .btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px} .btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px} .btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px} .btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px} .btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2} .btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0} .btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)} .btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px} .btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px} .btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px} .btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)} .btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6} .btn-group.open .btn-primary.dropdown-toggle{background-color:#04c} .btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406} .btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f} .btn-group.open .btn-success.dropdown-toggle{background-color:#51a351} .btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4} .btn-group.open .btn-inverse.dropdown-toggle{background-color:#222} .btn .caret{margin-top:8px;margin-left:0} .btn-large .caret{margin-top:6px} .btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px} .btn-mini .caret,.btn-small .caret{margin-top:8px} .dropup .btn-large .caret{border-bottom-width:5px} .btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff} .btn-group-vertical{display:inline-block;*display:inline;*zoom:1} .btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} .btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0} .btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0} .btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px} .btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0} .btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px} .alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} .alert,.alert h4{color:#c09853} .alert h4{margin:0} .alert .close{position:relative;top:-2px;right:-21px;line-height:20px} .alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6} .alert-success h4{color:#468847} .alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7} .alert-danger h4,.alert-error h4{color:#b94a48} .alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1} .alert-info h4{color:#3a87ad} .alert-block{padding-top:14px;padding-bottom:14px} .alert-block>p,.alert-block>ul{margin-bottom:0} .alert-block p+p{margin-top:5px} .nav{margin-bottom:20px;margin-left:0;list-style:none} .nav>li>a{display:block} .nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee} .nav>li>a>img{max-width:none} .nav>.pull-right{float:right} .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase} .nav li+.nav-header{margin-top:9px} .nav-list{padding-right:15px;padding-left:15px;margin-bottom:0} .nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)} .nav-list>li>a{padding:3px 15px} .nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c} .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px} .nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff} .nav-tabs,.nav-pills{*zoom:1} .nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""} .nav-tabs:after,.nav-pills:after{clear:both} .nav-tabs>li,.nav-pills>li{float:left} .nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px} .nav-tabs{border-bottom:1px solid #ddd} .nav-tabs>li{margin-bottom:-1px} .nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0} .nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd} .nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent} .nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px} .nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c} .nav-stacked>li{float:none} .nav-stacked>li>a{margin-right:0} .nav-tabs.nav-stacked{border-bottom:0} .nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} .nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px} .nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px} .nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd} .nav-pills.nav-stacked>li>a{margin-bottom:3px} .nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px} .nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px} .nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} .nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c} .nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580} .nav-tabs .dropdown-toggle .caret{margin-top:8px} .nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff} .nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555} .nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer} .nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999} .nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)} .tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999} .tabbable{*zoom:1} .tabbable:before,.tabbable:after{display:table;line-height:0;content:""} .tabbable:after{clear:both} .tab-content{overflow:auto} .tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0} .tab-content>.tab-pane,.pill-content>.pill-pane{display:none} .tab-content>.active,.pill-content>.active{display:block} .tabs-below>.nav-tabs{border-top:1px solid #ddd} .tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0} .tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px} .tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent} .tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd} .tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none} .tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px} .tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd} .tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px} .tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee} .tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff} .tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd} .tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0} .tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd} .tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff} .nav>.disabled>a{color:#999} .nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent} .navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible} .navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)} .navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""} .navbar-inner:after{clear:both} .navbar .container{width:auto} .nav-collapse.collapse{height:auto;overflow:visible} .navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff} .navbar .brand:hover,.navbar .brand:focus{text-decoration:none} .navbar-text{margin-bottom:0;line-height:40px;color:#777} .navbar-link{color:#777} .navbar-link:hover,.navbar-link:focus{color:#333} .navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2} .navbar .btn,.navbar .btn-group{margin-top:5px} .navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0} .navbar-form{margin-bottom:0;*zoom:1} .navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""} .navbar-form:after{clear:both} .navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px} .navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0} .navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px} .navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap} .navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0} .navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0} .navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px} .navbar-static-top{position:static;margin-bottom:0} .navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} .navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0} .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px} .navbar-fixed-bottom .navbar-inner{border-width:1px 0 0} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} .navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px} .navbar-fixed-top{top:0} .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)} .navbar-fixed-bottom{bottom:0} .navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)} .navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0} .navbar .nav.pull-right{float:right;margin-right:0} .navbar .nav>li{float:left} .navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff} .navbar .nav .dropdown-toggle .caret{margin-top:8px} .navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent} .navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)} .navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)} .navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9} .navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9} .navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)} .btn-navbar .icon-bar+.icon-bar{margin-top:3px} .navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''} .navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''} .navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)} .navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0} .navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333} .navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5} .navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777} .navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555} .navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto} .navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto} .navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto} .navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px} .navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)} .navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)} .navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff} .navbar-inverse .brand{color:#999} .navbar-inverse .navbar-text{color:#999} .navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent} .navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111} .navbar-inverse .navbar-link{color:#999} .navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff} .navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111} .navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111} .navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff} .navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999} .navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff} .navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none} .navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc} .navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc} .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc} .navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)} .navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} .navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000} .navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9} .breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} .breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1} .breadcrumb>li>.divider{padding:0 5px;color:#ccc} .breadcrumb>.active{color:#999} .pagination{margin:20px 0} .pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)} .pagination ul>li{display:inline} .pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0} .pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5} .pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default} .pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent} .pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px} .pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px} .pagination-centered{text-align:center} .pagination-right{text-align:right} .pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px} .pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px} .pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px} .pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px} .pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px} .pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px} .pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px} .pager{margin:20px 0;text-align:center;list-style:none;*zoom:1} .pager:before,.pager:after{display:table;line-height:0;content:""} .pager:after{clear:both} .pager li{display:inline} .pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px} .pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5} .pager .next>a,.pager .next>span{float:right} .pager .previous>a,.pager .previous>span{float:left} .pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff} .modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000} .modal-backdrop.fade{opacity:0} .modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)} .modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box} .modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out} .modal.fade.in{top:10%} .modal-header{padding:9px 15px;border-bottom:1px solid #eee} .modal-header .close{margin-top:2px} .modal-header h3{margin:0;line-height:30px} .modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto} .modal-form{margin-bottom:0} .modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff} .modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""} .modal-footer:after{clear:both} .modal-footer .btn+.btn{margin-bottom:0;margin-left:5px} .modal-footer .btn-group .btn+.btn{margin-left:-1px} .modal-footer .btn-block+.btn-block{margin-left:0} .tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible} .tooltip.in{opacity:.8;filter:alpha(opacity=80)} .tooltip.top{padding:5px 0;margin-top:-3px} .tooltip.right{padding:0 5px;margin-left:3px} .tooltip.bottom{padding:5px 0;margin-top:3px} .tooltip.left{padding:0 5px;margin-left:-3px} .tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid} .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0} .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0} .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px} .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px} .popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box} .popover.top{margin-top:-10px} .popover.right{margin-left:10px} .popover.bottom{margin-top:10px} .popover.left{margin-left:-10px} .popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0} .popover-title:empty{display:none} .popover-content{padding:9px 14px} .popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid} .popover .arrow{border-width:11px} .popover .arrow:after{border-width:10px;content:""} .popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0} .popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0} .popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0} .popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0} .popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0} .popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0} .popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0} .popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0} .thumbnails{margin-left:-20px;list-style:none;*zoom:1} .thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""} .thumbnails:after{clear:both} .row-fluid .thumbnails{margin-left:0} .thumbnails>li{float:left;margin-bottom:20px;margin-left:20px} .thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out} a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)} .thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto} .thumbnail .caption{padding:9px;color:#555} .media,.media-body{overflow:hidden;*overflow:visible;zoom:1} .media,.media .media{margin-top:15px} .media:first-child{margin-top:0} .media-object{display:block} .media-heading{margin:0 0 5px} .media>.pull-left{margin-right:10px} .media>.pull-right{margin-left:10px} .media-list{margin-left:0;list-style:none} .label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999} .label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} .badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px} .label:empty,.badge:empty{display:none} a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer} .label-important,.badge-important{background-color:#b94a48} .label-important[href],.badge-important[href]{background-color:#953b39} .label-warning,.badge-warning{background-color:#f89406} .label-warning[href],.badge-warning[href]{background-color:#c67605} .label-success,.badge-success{background-color:#468847} .label-success[href],.badge-success[href]{background-color:#356635} .label-info,.badge-info{background-color:#3a87ad} .label-info[href],.badge-info[href]{background-color:#2d6987} .label-inverse,.badge-inverse{background-color:#333} .label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a} .btn .label,.btn .badge{position:relative;top:-1px} .btn-mini .label,.btn-mini .badge{top:0} @-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}} @-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}} @-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}} @-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}} @keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}} .progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)} .progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease} .progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)} .progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px} .progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite} .progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)} .progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)} .progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)} .progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)} .progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)} .progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)} .progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)} .progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)} .accordion{margin-bottom:20px} .accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} .accordion-heading{border-bottom:0} .accordion-heading .accordion-toggle{display:block;padding:8px 15px} .accordion-toggle{cursor:pointer} .accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5} .carousel{position:relative;margin-bottom:20px;line-height:1} .carousel-inner{position:relative;width:100%;overflow:hidden} .carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left} .carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1} .carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block} .carousel-inner>.active{left:0} .carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%} .carousel-inner>.next{left:100%} .carousel-inner>.prev{left:-100%} .carousel-inner>.next.left,.carousel-inner>.prev.right{left:0} .carousel-inner>.active.left{left:-100%} .carousel-inner>.active.right{left:100%} .carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)} .carousel-control.right{right:15px;left:auto} .carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)} .carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none} .carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px} .carousel-indicators .active{background-color:#fff} .carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)} .carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff} .carousel-caption h4{margin:0 0 5px} .carousel-caption p{margin-bottom:0} .hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} .hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit} .hero-unit li{line-height:30px} .pull-right{float:right} .pull-left{float:left} .hide{display:none} .show{display:block} .invisible{visibility:hidden} .affix{position:fixed} diff --git a/src/test/resources/assets/img/glyphicons-halflings-white.png b/src/test/resources/fixture/assets/img/glyphicons-halflings-white.png similarity index 100% rename from src/test/resources/assets/img/glyphicons-halflings-white.png rename to src/test/resources/fixture/assets/img/glyphicons-halflings-white.png diff --git a/src/test/resources/assets/img/glyphicons-halflings.png b/src/test/resources/fixture/assets/img/glyphicons-halflings.png similarity index 100% rename from src/test/resources/assets/img/glyphicons-halflings.png rename to src/test/resources/fixture/assets/img/glyphicons-halflings.png diff --git a/src/test/resources/assets/js/bootstrap.min.js b/src/test/resources/fixture/assets/js/bootstrap.min.js similarity index 100% rename from src/test/resources/assets/js/bootstrap.min.js rename to src/test/resources/fixture/assets/js/bootstrap.min.js diff --git a/src/test/resources/assets/js/html5shiv.js b/src/test/resources/fixture/assets/js/html5shiv.js similarity index 100% rename from src/test/resources/assets/js/html5shiv.js rename to src/test/resources/fixture/assets/js/html5shiv.js diff --git a/src/test/resources/assets/js/jquery-1.9.1.min.js b/src/test/resources/fixture/assets/js/jquery-1.9.1.min.js similarity index 100% rename from src/test/resources/assets/js/jquery-1.9.1.min.js rename to src/test/resources/fixture/assets/js/jquery-1.9.1.min.js diff --git a/src/test/resources/content/about.html b/src/test/resources/fixture/content/about.html similarity index 100% rename from src/test/resources/content/about.html rename to src/test/resources/fixture/content/about.html diff --git a/src/test/resources/content/allcontent.html b/src/test/resources/fixture/content/allcontent.html similarity index 100% rename from src/test/resources/content/allcontent.html rename to src/test/resources/fixture/content/allcontent.html diff --git a/src/test/resources/content/blog/2012/first-post.html b/src/test/resources/fixture/content/blog/2012/first-post.html similarity index 100% rename from src/test/resources/content/blog/2012/first-post.html rename to src/test/resources/fixture/content/blog/2012/first-post.html diff --git a/src/test/resources/content/blog/2013/second-post.html b/src/test/resources/fixture/content/blog/2013/second-post.html similarity index 100% rename from src/test/resources/content/blog/2013/second-post.html rename to src/test/resources/fixture/content/blog/2013/second-post.html diff --git a/src/test/resources/content/blog/2016/another-post.html b/src/test/resources/fixture/content/blog/2016/another-post.html similarity index 100% rename from src/test/resources/content/blog/2016/another-post.html rename to src/test/resources/fixture/content/blog/2016/another-post.html diff --git a/src/test/resources/content/blog/2016/draft-post.html b/src/test/resources/fixture/content/blog/2016/draft-post.html similarity index 100% rename from src/test/resources/content/blog/2016/draft-post.html rename to src/test/resources/fixture/content/blog/2016/draft-post.html diff --git a/src/test/resources/content/blog/invalid_header.html b/src/test/resources/fixture/content/blog/invalid_header.html similarity index 100% rename from src/test/resources/content/blog/invalid_header.html rename to src/test/resources/fixture/content/blog/invalid_header.html diff --git a/src/test/resources/content/index2.html b/src/test/resources/fixture/content/index2.html similarity index 100% rename from src/test/resources/content/index2.html rename to src/test/resources/fixture/content/index2.html diff --git a/src/test/resources/content/papers/draft-paper.html b/src/test/resources/fixture/content/papers/draft-paper.html similarity index 95% rename from src/test/resources/content/papers/draft-paper.html rename to src/test/resources/fixture/content/papers/draft-paper.html index ca13dc05c..521a62de1 100644 --- a/src/test/resources/content/papers/draft-paper.html +++ b/src/test/resources/fixture/content/papers/draft-paper.html @@ -1,6 +1,6 @@ title=Draft Paper date=2014-04-22 -type=paper +type=fixture.groovyMarkupTemplates.paper tags=blog status=draft ~~~~~~ diff --git a/src/test/resources/content/papers/published-paper.html b/src/test/resources/fixture/content/papers/published-paper.html similarity index 95% rename from src/test/resources/content/papers/published-paper.html rename to src/test/resources/fixture/content/papers/published-paper.html index 9bf1db3af..bdacf6cd4 100644 --- a/src/test/resources/content/papers/published-paper.html +++ b/src/test/resources/fixture/content/papers/published-paper.html @@ -1,6 +1,6 @@ title=Published Paper date=2014-04-24 -type=paper +type=fixture.groovyMarkupTemplates.paper tags=blog status=published ~~~~~~ diff --git a/src/test/resources/content/projects.html b/src/test/resources/fixture/content/projects.html similarity index 100% rename from src/test/resources/content/projects.html rename to src/test/resources/fixture/content/projects.html diff --git a/src/test/resources/jbake.properties b/src/test/resources/fixture/custom.properties similarity index 100% rename from src/test/resources/jbake.properties rename to src/test/resources/fixture/custom.properties diff --git a/src/test/resources/freemarkerTemplates/allcontent.ftl b/src/test/resources/fixture/freemarkerTemplates/allcontent.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/allcontent.ftl rename to src/test/resources/fixture/freemarkerTemplates/allcontent.ftl diff --git a/src/test/resources/freemarkerTemplates/archive.ftl b/src/test/resources/fixture/freemarkerTemplates/archive.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/archive.ftl rename to src/test/resources/fixture/freemarkerTemplates/archive.ftl diff --git a/src/test/resources/freemarkerTemplates/feed.ftl b/src/test/resources/fixture/freemarkerTemplates/feed.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/feed.ftl rename to src/test/resources/fixture/freemarkerTemplates/feed.ftl diff --git a/src/test/resources/freemarkerTemplates/footer.ftl b/src/test/resources/fixture/freemarkerTemplates/footer.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/footer.ftl rename to src/test/resources/fixture/freemarkerTemplates/footer.ftl diff --git a/src/test/resources/freemarkerTemplates/header.ftl b/src/test/resources/fixture/freemarkerTemplates/header.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/header.ftl rename to src/test/resources/fixture/freemarkerTemplates/header.ftl diff --git a/src/test/resources/freemarkerTemplates/index.ftl b/src/test/resources/fixture/freemarkerTemplates/index.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/index.ftl rename to src/test/resources/fixture/freemarkerTemplates/index.ftl diff --git a/src/test/resources/freemarkerTemplates/menu.ftl b/src/test/resources/fixture/freemarkerTemplates/menu.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/menu.ftl rename to src/test/resources/fixture/freemarkerTemplates/menu.ftl diff --git a/src/test/resources/freemarkerTemplates/page.ftl b/src/test/resources/fixture/freemarkerTemplates/page.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/page.ftl rename to src/test/resources/fixture/freemarkerTemplates/page.ftl diff --git a/src/test/resources/freemarkerTemplates/post.ftl b/src/test/resources/fixture/freemarkerTemplates/post.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/post.ftl rename to src/test/resources/fixture/freemarkerTemplates/post.ftl diff --git a/src/test/resources/freemarkerTemplates/sitemap.ftl b/src/test/resources/fixture/freemarkerTemplates/sitemap.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/sitemap.ftl rename to src/test/resources/fixture/freemarkerTemplates/sitemap.ftl diff --git a/src/test/resources/freemarkerTemplates/tags.ftl b/src/test/resources/fixture/freemarkerTemplates/tags.ftl similarity index 100% rename from src/test/resources/freemarkerTemplates/tags.ftl rename to src/test/resources/fixture/freemarkerTemplates/tags.ftl diff --git a/src/test/resources/groovyMarkupTemplates/allcontent.tpl b/src/test/resources/fixture/groovyMarkupTemplates/allcontent.tpl similarity index 83% rename from src/test/resources/groovyMarkupTemplates/allcontent.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/allcontent.tpl index 907fcaa1a..ac72789c1 100644 --- a/src/test/resources/groovyMarkupTemplates/allcontent.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/allcontent.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + xmlDeclaration() list{ all_content.each { cntnt -> diff --git a/src/test/resources/groovyMarkupTemplates/archive.tpl b/src/test/resources/fixture/groovyMarkupTemplates/archive.tpl similarity index 96% rename from src/test/resources/groovyMarkupTemplates/archive.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/archive.tpl index cf2f4b852..61d37280a 100644 --- a/src/test/resources/groovyMarkupTemplates/archive.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/archive.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + layout 'layout/main.tpl', bodyContents: contents { div(class:"row-fluid marketing"){ diff --git a/src/test/resources/groovyMarkupTemplates/feed.tpl b/src/test/resources/fixture/groovyMarkupTemplates/feed.tpl similarity index 95% rename from src/test/resources/groovyMarkupTemplates/feed.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/feed.tpl index de1494133..2b22310ed 100644 --- a/src/test/resources/groovyMarkupTemplates/feed.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/feed.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + xmlDeclaration() rss(version:"2.0", 'xmlns:atom':'http://www.w3.org/2005/Atom') { channel { diff --git a/src/test/resources/groovyMarkupTemplates/footer.tpl b/src/test/resources/fixture/groovyMarkupTemplates/footer.tpl similarity index 87% rename from src/test/resources/groovyMarkupTemplates/footer.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/footer.tpl index ffd301b38..16c068280 100644 --- a/src/test/resources/groovyMarkupTemplates/footer.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/footer.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + div(class:"footer"){ p{ yieldUnescaped '© Jonathan Bullock 2013 | Mixed with ' diff --git a/src/test/resources/groovyMarkupTemplates/header.tpl b/src/test/resources/fixture/groovyMarkupTemplates/header.tpl similarity index 97% rename from src/test/resources/groovyMarkupTemplates/header.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/header.tpl index 0ce16f508..c398c6e57 100644 --- a/src/test/resources/groovyMarkupTemplates/header.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/header.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + meta(charset:'utf-8') title('Jonathan Bullock') meta(name:"viewport", content:"width=device-width, initial-scale=1.0") diff --git a/src/test/resources/groovyMarkupTemplates/index.tpl b/src/test/resources/fixture/groovyMarkupTemplates/index.tpl similarity index 93% rename from src/test/resources/groovyMarkupTemplates/index.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/index.tpl index 82bc5358e..de530b490 100644 --- a/src/test/resources/groovyMarkupTemplates/index.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/index.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + layout 'layout/main.tpl', bodyContents: contents { diff --git a/src/test/resources/groovyMarkupTemplates/layout/main.tpl b/src/test/resources/fixture/groovyMarkupTemplates/layout/main.tpl similarity index 90% rename from src/test/resources/groovyMarkupTemplates/layout/main.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/layout/main.tpl index 449a699d1..6c38afdab 100644 --- a/src/test/resources/groovyMarkupTemplates/layout/main.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/layout/main.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates.layout + yieldUnescaped '' html(lang:'en'){ diff --git a/src/test/resources/groovyMarkupTemplates/menu.tpl b/src/test/resources/fixture/groovyMarkupTemplates/menu.tpl similarity index 93% rename from src/test/resources/groovyMarkupTemplates/menu.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/menu.tpl index b09a32eb4..dd599dd1e 100644 --- a/src/test/resources/groovyMarkupTemplates/menu.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/menu.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + div(class:"masthead"){ ul(class:"nav nav-pills pull-right"){ li { a(href:"/",'Home') } diff --git a/src/test/resources/groovyMarkupTemplates/page.tpl b/src/test/resources/fixture/groovyMarkupTemplates/page.tpl similarity index 92% rename from src/test/resources/groovyMarkupTemplates/page.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/page.tpl index d01d7f057..e3ccbcba0 100644 --- a/src/test/resources/groovyMarkupTemplates/page.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/page.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + layout 'layout/main.tpl', bodyContents: contents { diff --git a/src/test/resources/groovyMarkupTemplates/paper.tpl b/src/test/resources/fixture/groovyMarkupTemplates/paper.tpl similarity index 93% rename from src/test/resources/groovyMarkupTemplates/paper.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/paper.tpl index 46d4aea73..ce3f5da58 100644 --- a/src/test/resources/groovyMarkupTemplates/paper.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/paper.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + layout 'layout/main.tpl', true, papers: published_papers, bodyContents: contents { diff --git a/src/test/resources/groovyMarkupTemplates/post.tpl b/src/test/resources/fixture/groovyMarkupTemplates/post.tpl similarity index 93% rename from src/test/resources/groovyMarkupTemplates/post.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/post.tpl index fe3755855..dab09b312 100644 --- a/src/test/resources/groovyMarkupTemplates/post.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/post.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + layout 'layout/main.tpl', bodyContents: contents { diff --git a/src/test/resources/groovyMarkupTemplates/sitemap.tpl b/src/test/resources/fixture/groovyMarkupTemplates/sitemap.tpl similarity index 92% rename from src/test/resources/groovyMarkupTemplates/sitemap.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/sitemap.tpl index f44e48531..23442a855 100644 --- a/src/test/resources/groovyMarkupTemplates/sitemap.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/sitemap.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + xmlDeclaration() urlset( xmlns:"http://www.sitemaps.org/schemas/sitemap/0.9", 'xmlns:xsi':"http://www.w3.org/2001/XMLSchema-instance", diff --git a/src/test/resources/groovyMarkupTemplates/tags.tpl b/src/test/resources/fixture/groovyMarkupTemplates/tags.tpl similarity index 97% rename from src/test/resources/groovyMarkupTemplates/tags.tpl rename to src/test/resources/fixture/groovyMarkupTemplates/tags.tpl index 807b6a5db..2c2be4389 100644 --- a/src/test/resources/groovyMarkupTemplates/tags.tpl +++ b/src/test/resources/fixture/groovyMarkupTemplates/tags.tpl @@ -1,3 +1,5 @@ +package fixture.groovyMarkupTemplates + layout 'layout/main.tpl', bodyContents: contents { diff --git a/src/test/resources/groovyTemplates/allcontent.gsp b/src/test/resources/fixture/groovyTemplates/allcontent.gsp similarity index 100% rename from src/test/resources/groovyTemplates/allcontent.gsp rename to src/test/resources/fixture/groovyTemplates/allcontent.gsp diff --git a/src/test/resources/groovyTemplates/archive.gsp b/src/test/resources/fixture/groovyTemplates/archive.gsp similarity index 100% rename from src/test/resources/groovyTemplates/archive.gsp rename to src/test/resources/fixture/groovyTemplates/archive.gsp diff --git a/src/test/resources/groovyTemplates/feed.gsp b/src/test/resources/fixture/groovyTemplates/feed.gsp similarity index 100% rename from src/test/resources/groovyTemplates/feed.gsp rename to src/test/resources/fixture/groovyTemplates/feed.gsp diff --git a/src/test/resources/groovyTemplates/footer.gsp b/src/test/resources/fixture/groovyTemplates/footer.gsp similarity index 100% rename from src/test/resources/groovyTemplates/footer.gsp rename to src/test/resources/fixture/groovyTemplates/footer.gsp diff --git a/src/test/resources/groovyTemplates/header.gsp b/src/test/resources/fixture/groovyTemplates/header.gsp similarity index 100% rename from src/test/resources/groovyTemplates/header.gsp rename to src/test/resources/fixture/groovyTemplates/header.gsp diff --git a/src/test/resources/groovyTemplates/index.gsp b/src/test/resources/fixture/groovyTemplates/index.gsp similarity index 100% rename from src/test/resources/groovyTemplates/index.gsp rename to src/test/resources/fixture/groovyTemplates/index.gsp diff --git a/src/test/resources/groovyTemplates/page.gsp b/src/test/resources/fixture/groovyTemplates/page.gsp similarity index 100% rename from src/test/resources/groovyTemplates/page.gsp rename to src/test/resources/fixture/groovyTemplates/page.gsp diff --git a/src/test/resources/groovyTemplates/post.gsp b/src/test/resources/fixture/groovyTemplates/post.gsp similarity index 100% rename from src/test/resources/groovyTemplates/post.gsp rename to src/test/resources/fixture/groovyTemplates/post.gsp diff --git a/src/test/resources/groovyTemplates/sitemap.gsp b/src/test/resources/fixture/groovyTemplates/sitemap.gsp similarity index 100% rename from src/test/resources/groovyTemplates/sitemap.gsp rename to src/test/resources/fixture/groovyTemplates/sitemap.gsp diff --git a/src/test/resources/groovyTemplates/tags.gsp b/src/test/resources/fixture/groovyTemplates/tags.gsp similarity index 100% rename from src/test/resources/groovyTemplates/tags.gsp rename to src/test/resources/fixture/groovyTemplates/tags.gsp diff --git a/src/test/resources/ignorables/.test.txt b/src/test/resources/fixture/ignorables/.test.txt similarity index 100% rename from src/test/resources/ignorables/.test.txt rename to src/test/resources/fixture/ignorables/.test.txt diff --git a/src/test/resources/ignorables/test.txt b/src/test/resources/fixture/ignorables/test.txt similarity index 100% rename from src/test/resources/ignorables/test.txt rename to src/test/resources/fixture/ignorables/test.txt diff --git a/src/test/resources/jadeTemplates/archive.jade b/src/test/resources/fixture/jadeTemplates/archive.jade similarity index 100% rename from src/test/resources/jadeTemplates/archive.jade rename to src/test/resources/fixture/jadeTemplates/archive.jade diff --git a/src/test/resources/jadeTemplates/feed.jade b/src/test/resources/fixture/jadeTemplates/feed.jade similarity index 100% rename from src/test/resources/jadeTemplates/feed.jade rename to src/test/resources/fixture/jadeTemplates/feed.jade diff --git a/src/test/resources/jadeTemplates/footer.jade b/src/test/resources/fixture/jadeTemplates/footer.jade similarity index 100% rename from src/test/resources/jadeTemplates/footer.jade rename to src/test/resources/fixture/jadeTemplates/footer.jade diff --git a/src/test/resources/jadeTemplates/header.jade b/src/test/resources/fixture/jadeTemplates/header.jade similarity index 100% rename from src/test/resources/jadeTemplates/header.jade rename to src/test/resources/fixture/jadeTemplates/header.jade diff --git a/src/test/resources/jadeTemplates/index.jade b/src/test/resources/fixture/jadeTemplates/index.jade similarity index 100% rename from src/test/resources/jadeTemplates/index.jade rename to src/test/resources/fixture/jadeTemplates/index.jade diff --git a/src/test/resources/jadeTemplates/layout.jade b/src/test/resources/fixture/jadeTemplates/layout.jade similarity index 100% rename from src/test/resources/jadeTemplates/layout.jade rename to src/test/resources/fixture/jadeTemplates/layout.jade diff --git a/src/test/resources/jadeTemplates/page.jade b/src/test/resources/fixture/jadeTemplates/page.jade similarity index 100% rename from src/test/resources/jadeTemplates/page.jade rename to src/test/resources/fixture/jadeTemplates/page.jade diff --git a/src/test/resources/jadeTemplates/post.jade b/src/test/resources/fixture/jadeTemplates/post.jade similarity index 100% rename from src/test/resources/jadeTemplates/post.jade rename to src/test/resources/fixture/jadeTemplates/post.jade diff --git a/src/test/resources/jadeTemplates/sitemap.jade b/src/test/resources/fixture/jadeTemplates/sitemap.jade similarity index 100% rename from src/test/resources/jadeTemplates/sitemap.jade rename to src/test/resources/fixture/jadeTemplates/sitemap.jade diff --git a/src/test/resources/jadeTemplates/tags.jade b/src/test/resources/fixture/jadeTemplates/tags.jade similarity index 100% rename from src/test/resources/jadeTemplates/tags.jade rename to src/test/resources/fixture/jadeTemplates/tags.jade diff --git a/src/test/resources/fixture/jbake.properties b/src/test/resources/fixture/jbake.properties new file mode 100644 index 000000000..ef678557d --- /dev/null +++ b/src/test/resources/fixture/jbake.properties @@ -0,0 +1,18 @@ +template.folder=templates +content.folder=content +asset.folder=assets +render.index=true +index.file=index.html +render.feed=true +feed.file=feed.xml +render.archive=true +render.encoding=UTF-8 +archive.file=archive.html +render.tags=false +tag.path=tags +test.property=testing123 +markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS +site.host=http://www.jbake.org +template.feed.thymeleaf.mode=XML +template.sitemap.thymeleaf.mode=XML +template.allcontent.file=allcontent.ftl \ No newline at end of file diff --git a/src/test/resources/media/favicon.ico b/src/test/resources/fixture/media/favicon.ico similarity index 100% rename from src/test/resources/media/favicon.ico rename to src/test/resources/fixture/media/favicon.ico diff --git a/src/test/resources/test.zip b/src/test/resources/fixture/test.zip similarity index 100% rename from src/test/resources/test.zip rename to src/test/resources/fixture/test.zip diff --git a/src/test/resources/thymeleafTemplates/allcontent.thyme b/src/test/resources/fixture/thymeleafTemplates/allcontent.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/allcontent.thyme rename to src/test/resources/fixture/thymeleafTemplates/allcontent.thyme diff --git a/src/test/resources/thymeleafTemplates/archive.thyme b/src/test/resources/fixture/thymeleafTemplates/archive.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/archive.thyme rename to src/test/resources/fixture/thymeleafTemplates/archive.thyme diff --git a/src/test/resources/thymeleafTemplates/feed.thyme b/src/test/resources/fixture/thymeleafTemplates/feed.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/feed.thyme rename to src/test/resources/fixture/thymeleafTemplates/feed.thyme diff --git a/src/test/resources/thymeleafTemplates/footer.thyme b/src/test/resources/fixture/thymeleafTemplates/footer.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/footer.thyme rename to src/test/resources/fixture/thymeleafTemplates/footer.thyme diff --git a/src/test/resources/thymeleafTemplates/header.thyme b/src/test/resources/fixture/thymeleafTemplates/header.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/header.thyme rename to src/test/resources/fixture/thymeleafTemplates/header.thyme diff --git a/src/test/resources/thymeleafTemplates/index.thyme b/src/test/resources/fixture/thymeleafTemplates/index.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/index.thyme rename to src/test/resources/fixture/thymeleafTemplates/index.thyme diff --git a/src/test/resources/thymeleafTemplates/page.thyme b/src/test/resources/fixture/thymeleafTemplates/page.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/page.thyme rename to src/test/resources/fixture/thymeleafTemplates/page.thyme diff --git a/src/test/resources/thymeleafTemplates/post.thyme b/src/test/resources/fixture/thymeleafTemplates/post.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/post.thyme rename to src/test/resources/fixture/thymeleafTemplates/post.thyme diff --git a/src/test/resources/thymeleafTemplates/sitemap.thyme b/src/test/resources/fixture/thymeleafTemplates/sitemap.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/sitemap.thyme rename to src/test/resources/fixture/thymeleafTemplates/sitemap.thyme diff --git a/src/test/resources/thymeleafTemplates/tags.thyme b/src/test/resources/fixture/thymeleafTemplates/tags.thyme similarity index 100% rename from src/test/resources/thymeleafTemplates/tags.thyme rename to src/test/resources/fixture/thymeleafTemplates/tags.thyme From 4e3f7072bf54c1f48cb228ebd858582b66d495ea Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Tue, 29 Mar 2016 23:52:13 +0200 Subject: [PATCH 11/53] process resources to set version and build timestamp in default.properties --- build.gradle | 50 +++++++++++++-------------- gradle/application.gradle | 14 +++++--- src/main/resources/default.properties | 2 +- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index a982e2b2d..2751e94c4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,42 +1,42 @@ apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'maven' -apply from: 'gradle/application.gradle' group = 'org.jbake' version = '2.5.0-SNAPSHOT' description = """jbake""" +apply from: 'gradle/application.gradle' + sourceCompatibility = 1.6 targetCompatibility = 1.6 - repositories { - jcenter() + jcenter() } dependencies { - compile group: 'commons-io', name: 'commons-io', version:'2.4' - compile group: 'commons-configuration', name: 'commons-configuration', version:'1.9' - compile group: 'com.googlecode.json-simple', name: 'json-simple', version:'1.1.1' - compile group: 'args4j', name: 'args4j', version:'2.0.26' - compile group: 'org.freemarker', name: 'freemarker', version:'2.3.20' - compile group: 'com.orientechnologies', name: 'orient-commons', version:'1.6.4' - compile group: 'com.orientechnologies', name: 'orientdb-core', version:'1.6.4' - compile group: 'org.pegdown', name: 'pegdown', version:'1.4.2' - compile group: 'org.asciidoctor', name: 'asciidoctorj', version:'1.5.2' - compile group: 'org.eclipse.jetty', name: 'jetty-server', version:'8.1.12.v20130726' - compile group: 'org.codehaus.groovy', name: 'groovy', version:'2.3.6' - compile group: 'org.codehaus.groovy', name: 'groovy-templates', version:'2.3.6' - compile group: 'org.thymeleaf', name: 'thymeleaf', version:'2.1.3.RELEASE' - compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-conditionalcomments', version:'2.1.1.RELEASE' - compile group: 'org.slf4j', name: 'slf4j-api', version:'1.7.6' - compile group: 'org.slf4j', name: 'jul-to-slf4j', version:'1.7.6' - compile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.1' - compile group: 'ch.qos.logback', name: 'logback-core', version:'1.1.1' - compile "de.neuland-bfi:jade4j:0.4.2" - compile "org.apache.commons:commons-vfs2:2.0" - testCompile group: 'junit', name: 'junit', version:'4.11' - testCompile group: 'org.assertj', name: 'assertj-core', version:'1.7.0' + compile group: 'commons-io', name: 'commons-io', version: '2.4' + compile group: 'commons-configuration', name: 'commons-configuration', version: '1.9' + compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' + compile group: 'args4j', name: 'args4j', version: '2.0.26' + compile group: 'org.freemarker', name: 'freemarker', version: '2.3.20' + compile group: 'com.orientechnologies', name: 'orient-commons', version: '1.6.4' + compile group: 'com.orientechnologies', name: 'orientdb-core', version: '1.6.4' + compile group: 'org.pegdown', name: 'pegdown', version: '1.4.2' + compile group: 'org.asciidoctor', name: 'asciidoctorj', version: '1.5.2' + compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.1.12.v20130726' + compile group: 'org.codehaus.groovy', name: 'groovy', version: '2.3.6' + compile group: 'org.codehaus.groovy', name: 'groovy-templates', version: '2.3.6' + compile group: 'org.thymeleaf', name: 'thymeleaf', version: '2.1.3.RELEASE' + compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-conditionalcomments', version: '2.1.1.RELEASE' + compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.6' + compile group: 'org.slf4j', name: 'jul-to-slf4j', version: '1.7.6' + compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.1' + compile group: 'ch.qos.logback', name: 'logback-core', version: '1.1.1' + compile group: 'de.neuland-bfi', name: 'jade4j', version: '0.4.2' + compile group: 'org.apache.commons', name: 'commons-vfs2', version: '2.0' + testCompile group: 'junit', name: 'junit', version: '4.11' + testCompile group: 'org.assertj', name: 'assertj-core', version: '1.7.0' } diff --git a/gradle/application.gradle b/gradle/application.gradle index 09307e3a8..a9b1f936b 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -1,5 +1,7 @@ import org.ajoberstar.grgit.Grgit +import java.text.SimpleDateFormat + buildscript { repositories { jcenter() @@ -14,6 +16,14 @@ apply plugin: 'application' mainClassName = "org.jbake.launcher.Main" applicationName = "jbake" +processResources { + from("src/main/resources"){ + include 'default.properties' + expand version: project.version, + timestamp: new SimpleDateFormat("yyyy-MM-dd HH:mm:ssa").format( new Date() ) + } +} + ext { examplesBase = "$project.buildDir/examples" @@ -55,10 +65,6 @@ exampleRepositories.each { name, repository -> } -startScripts { - classpath += files("logging") -} - distributions { main { baseName = "jbake" diff --git a/src/main/resources/default.properties b/src/main/resources/default.properties index 6a2e64391..064dcff30 100644 --- a/src/main/resources/default.properties +++ b/src/main/resources/default.properties @@ -1,5 +1,5 @@ # application version -version=v${project.version} +version=v${version} # build timestamp build.timestamp=${timestamp} # path to destination folder by default From 8f755280f7afa3f472ca806ca04f759241d5cc68 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 30 Mar 2016 01:15:42 +0200 Subject: [PATCH 12/53] determine current running path assuming jar is located in a lib/ directory. --- src/main/java/org/jbake/app/FileUtil.java | 2 +- src/test/java/org/jbake/app/FileUtilTest.java | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/jbake/app/FileUtilTest.java diff --git a/src/main/java/org/jbake/app/FileUtil.java b/src/main/java/org/jbake/app/FileUtil.java index 4c3eae0e7..6d223683c 100644 --- a/src/main/java/org/jbake/app/FileUtil.java +++ b/src/main/java/org/jbake/app/FileUtil.java @@ -52,7 +52,7 @@ public static File getRunningLocation() throws Exception { if (!codeFile.exists()) { throw new Exception("Cannot locate running location of JBake!"); } - File codeFolder = codeFile.getParentFile(); + File codeFolder = codeFile.getParentFile().getParentFile(); if (!codeFolder.exists()) { throw new Exception("Cannot locate running location of JBake!"); } diff --git a/src/test/java/org/jbake/app/FileUtilTest.java b/src/test/java/org/jbake/app/FileUtilTest.java new file mode 100644 index 000000000..23f26272f --- /dev/null +++ b/src/test/java/org/jbake/app/FileUtilTest.java @@ -0,0 +1,20 @@ +package org.jbake.app; + +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.*; + +/** + * Created by frank on 28.03.16. + */ +public class FileUtilTest { + + @Test + public void testGetRunningLocation() throws Exception { + + File path = FileUtil.getRunningLocation(); + assertEquals(new File("build/").getAbsolutePath(), path.getPath()); + } +} \ No newline at end of file From 86a02dc9e7b17ccfa2870a8208d331264d3bdeb9 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 30 Mar 2016 18:57:08 +0200 Subject: [PATCH 13/53] set rootProject name to jbake-core. removed assembly and scripts --- settings.gradle | 1 + .../assembly-example-project-freemarker.xml | 19 ------ .../assembly-example-project-groovy.xml | 19 ------ .../assembly-example-project-jade.xml | 19 ------ .../assembly-example-project-thymeleaf.xml | 19 ------ src/main/assembly/assembly.xml | 65 ------------------- src/main/scripts/jbake | 22 ------- src/main/scripts/jbake.bat | 2 - 8 files changed, 1 insertion(+), 165 deletions(-) create mode 100644 settings.gradle delete mode 100644 src/main/assembly/assembly-example-project-freemarker.xml delete mode 100644 src/main/assembly/assembly-example-project-groovy.xml delete mode 100644 src/main/assembly/assembly-example-project-jade.xml delete mode 100644 src/main/assembly/assembly-example-project-thymeleaf.xml delete mode 100644 src/main/assembly/assembly.xml delete mode 100755 src/main/scripts/jbake delete mode 100644 src/main/scripts/jbake.bat diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..08ebb4dcb --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'jbake-core' diff --git a/src/main/assembly/assembly-example-project-freemarker.xml b/src/main/assembly/assembly-example-project-freemarker.xml deleted file mode 100644 index af6c731be..000000000 --- a/src/main/assembly/assembly-example-project-freemarker.xml +++ /dev/null @@ -1,19 +0,0 @@ - - base - false - - - zip - - - - ${project.build.directory}/example-project-freemarker/ - / - - .git - README.md - LICENSE - - - - \ No newline at end of file diff --git a/src/main/assembly/assembly-example-project-groovy.xml b/src/main/assembly/assembly-example-project-groovy.xml deleted file mode 100644 index 00465a062..000000000 --- a/src/main/assembly/assembly-example-project-groovy.xml +++ /dev/null @@ -1,19 +0,0 @@ - - base - false - - - zip - - - - ${project.build.directory}/example-project-groovy/ - / - - .git - README.md - LICENSE - - - - \ No newline at end of file diff --git a/src/main/assembly/assembly-example-project-jade.xml b/src/main/assembly/assembly-example-project-jade.xml deleted file mode 100644 index 71cc39a23..000000000 --- a/src/main/assembly/assembly-example-project-jade.xml +++ /dev/null @@ -1,19 +0,0 @@ - - base - false - - - zip - - - - ${project.build.directory}/example-project-jade/ - / - - .git - README.md - LICENSE - - - - \ No newline at end of file diff --git a/src/main/assembly/assembly-example-project-thymeleaf.xml b/src/main/assembly/assembly-example-project-thymeleaf.xml deleted file mode 100644 index 8eb93b37b..000000000 --- a/src/main/assembly/assembly-example-project-thymeleaf.xml +++ /dev/null @@ -1,19 +0,0 @@ - - base - false - - - zip - - - - ${project.build.directory}/example-project-thymeleaf/ - / - - .git - README.md - LICENSE - - - - \ No newline at end of file diff --git a/src/main/assembly/assembly.xml b/src/main/assembly/assembly.xml deleted file mode 100644 index 93103e8d3..000000000 --- a/src/main/assembly/assembly.xml +++ /dev/null @@ -1,65 +0,0 @@ - - bin - - - zip - - - - - - - false - lib - false - - - - - - - ${project.build.scriptSourceDirectory} - bin - - jbake* - - - - ${project.basedir}/src/main/logging - lib - - logback.xml - - - - - ${project.build.directory} - - - jbake-core.jar - - - - ${basedir} - - - LICENSE - - - - - ${project.build.directory} - - - example*.zip - - - - diff --git a/src/main/scripts/jbake b/src/main/scripts/jbake deleted file mode 100755 index e75fc3920..000000000 --- a/src/main/scripts/jbake +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -P=$(realpath $0 2>/dev/null) -if [ 0 -ne $? ]; then - P=$0 -fi - -EXEC_LOC="`dirname "$P"`" -EXEC_PARENT="`dirname $EXEC_LOC`" -OPTS="-XX:MaxDirectMemorySize=1024m" - -CYGWIN=false; -case "`uname`" in - CYGWIN*) CYGWIN=true;; -esac - -if $CYGWIN ; -then - java $OPTS -jar $(cygpath -w "${EXEC_PARENT}/jbake-core.jar") $@ -else - java $OPTS -jar "${EXEC_PARENT}/jbake-core.jar" $@ -fi \ No newline at end of file diff --git a/src/main/scripts/jbake.bat b/src/main/scripts/jbake.bat deleted file mode 100644 index 5953c91f1..000000000 --- a/src/main/scripts/jbake.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -java -XX:MaxDirectMemorySize=1024m -jar "%~dp0\..\jbake-core.jar" %* From dd2af052ea422851a6d88ba0cf170c8ab6894bd6 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 30 Mar 2016 22:57:06 +0200 Subject: [PATCH 14/53] local maven publishing with custom pom and signing --- build.gradle | 66 ++++++++++++++++++++---------- gradle/application.gradle | 18 ++++----- gradle/maven-publishing.gradle | 73 ++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 gradle/maven-publishing.gradle diff --git a/build.gradle b/build.gradle index 2751e94c4..d0d16a539 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,7 @@ version = '2.5.0-SNAPSHOT' description = """jbake""" apply from: 'gradle/application.gradle' +apply from: 'gradle/maven-publishing.gradle' sourceCompatibility = 1.6 targetCompatibility = 1.6 @@ -16,27 +17,48 @@ repositories { jcenter() } +ext { + commonsIoVersion = '2.4' + commonsConfigurationVersion = '1.9' + jsonSimpleVersion = '1.1.1' + args4jVersion = '2.0.26' + freemarkerVersion = '2.3.20' + orientDbVersion = '1.6.4' + pegdownVersion = '1.4.2' + asciidoctorjVersion = '1.5.2' + jettyServerVersion = '8.1.12.v20130726' + groovyVersion = '2.4.1' + thymeleafVersion = '2.1.3.RELEASE' + thymeleafExtrasVersion = '2.1.1.RELEASE' + slf4jVersion = '1.7.6' + logbackVersion = '1.1.1' + jade4jVersion = '0.4.2' + commonsVfs2Version = '2.0' + junitVersion = '4.11' + assertjCoreVersion = '1.7.0' +} + dependencies { - compile group: 'commons-io', name: 'commons-io', version: '2.4' - compile group: 'commons-configuration', name: 'commons-configuration', version: '1.9' - compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' - compile group: 'args4j', name: 'args4j', version: '2.0.26' - compile group: 'org.freemarker', name: 'freemarker', version: '2.3.20' - compile group: 'com.orientechnologies', name: 'orient-commons', version: '1.6.4' - compile group: 'com.orientechnologies', name: 'orientdb-core', version: '1.6.4' - compile group: 'org.pegdown', name: 'pegdown', version: '1.4.2' - compile group: 'org.asciidoctor', name: 'asciidoctorj', version: '1.5.2' - compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.1.12.v20130726' - compile group: 'org.codehaus.groovy', name: 'groovy', version: '2.3.6' - compile group: 'org.codehaus.groovy', name: 'groovy-templates', version: '2.3.6' - compile group: 'org.thymeleaf', name: 'thymeleaf', version: '2.1.3.RELEASE' - compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-conditionalcomments', version: '2.1.1.RELEASE' - compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.6' - compile group: 'org.slf4j', name: 'jul-to-slf4j', version: '1.7.6' - compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.1' - compile group: 'ch.qos.logback', name: 'logback-core', version: '1.1.1' - compile group: 'de.neuland-bfi', name: 'jade4j', version: '0.4.2' - compile group: 'org.apache.commons', name: 'commons-vfs2', version: '2.0' - testCompile group: 'junit', name: 'junit', version: '4.11' - testCompile group: 'org.assertj', name: 'assertj-core', version: '1.7.0' + compile group: 'commons-io', name: 'commons-io', version: commonsIoVersion + compile group: 'commons-configuration', name: 'commons-configuration', version: commonsConfigurationVersion + compile group: 'com.googlecode.json-simple', name: 'json-simple', version: jsonSimpleVersion + compile group: 'args4j', name: 'args4j', version: args4jVersion + compile group: 'org.freemarker', name: 'freemarker', version: freemarkerVersion + compile group: 'com.orientechnologies', name: 'orient-commons', version: orientDbVersion + compile group: 'com.orientechnologies', name: 'orientdb-core', version: orientDbVersion + compile group: 'org.pegdown', name: 'pegdown', version: pegdownVersion + compile group: 'org.asciidoctor', name: 'asciidoctorj', version: asciidoctorjVersion + compile group: 'org.eclipse.jetty', name: 'jetty-server', version: jettyServerVersion + compile group: 'org.codehaus.groovy', name: 'groovy', version: groovyVersion + compile group: 'org.codehaus.groovy', name: 'groovy-templates', version: groovyVersion + compile group: 'org.thymeleaf', name: 'thymeleaf', version: thymeleafVersion + compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-conditionalcomments', version: thymeleafExtrasVersion + compile group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion + compile group: 'org.slf4j', name: 'jul-to-slf4j', version: slf4jVersion + compile group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion + compile group: 'ch.qos.logback', name: 'logback-core', version: logbackVersion + compile group: 'de.neuland-bfi', name: 'jade4j', version: jade4jVersion + compile group: 'org.apache.commons', name: 'commons-vfs2', version: commonsVfs2Version + testCompile group: 'junit', name: 'junit', version: junitVersion + testCompile group: 'org.assertj', name: 'assertj-core', version: assertjCoreVersion } diff --git a/gradle/application.gradle b/gradle/application.gradle index a9b1f936b..487b86348 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -16,14 +16,6 @@ apply plugin: 'application' mainClassName = "org.jbake.launcher.Main" applicationName = "jbake" -processResources { - from("src/main/resources"){ - include 'default.properties' - expand version: project.version, - timestamp: new SimpleDateFormat("yyyy-MM-dd HH:mm:ssa").format( new Date() ) - } -} - ext { examplesBase = "$project.buildDir/examples" @@ -34,6 +26,15 @@ ext { ] } +processResources { + from("src/main/resources"){ + include 'default.properties' + expand version: project.version, + timestamp: new SimpleDateFormat("yyyy-MM-dd HH:mm:ssa").format( new Date() ) + } +} + + task cloneProjectExampleRepositories() { group = "distribution" description "Clone jbake example project repositories" @@ -67,7 +68,6 @@ exampleRepositories.each { name, repository -> distributions { main { - baseName = "jbake" contents { //Include Outputs from zip tasks exampleRepositories.each { name, repository -> diff --git a/gradle/maven-publishing.gradle b/gradle/maven-publishing.gradle new file mode 100644 index 000000000..d33ca0551 --- /dev/null +++ b/gradle/maven-publishing.gradle @@ -0,0 +1,73 @@ +apply plugin: 'maven' +apply plugin: 'signing' + +def jbakePom = pom { + project { + description 'JBake is a Java based open source static site/blog generator for developers.' + url 'http://jbake.org' + developers { + developer { + id 'jonbullock' + name 'Jonathan Bullock' + email 'jonbullock@gmail.com' + url 'http://jonathanbullock.com' + timezone '0' + } + } + scm { + url 'https://github.com/jbake-org/jbake/' + connection 'scm:git:git@github.com:jbake-org/jbake.git' + developerConnection 'scm:git:https://github.com/jbake-org/jbake.git' + } + issueManagement { + system 'GitHub Issues' + url 'https://github.com/jbake-org/jbake/issues' + } + mailingLists { + + mailingList { + name 'jbake-dev' + subscribe 'jbake-dev@googlegroups.com' + unsubscribe 'jbake-dev+unsubscribe@googlegroups.com' + archive 'http://groups.google.com/group/jbake-dev' + } + mailingList { + name 'jbake-user' + subscribe 'jbake-user@googlegroups.com' + unsubscribe 'jbake-user+unsubscribe@googlegroups.com' + archive 'http://groups.google.com/group/jbake-user' + } + } + + licenses { + license { + name 'The MIT License (MIT)' + url 'http://opensource.org/licenses/MIT' + } + } + } +} + +task javadocJar(type: Jar) { + classifier = 'javadoc' + from javadoc +} + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} + +artifacts { + archives javadocJar, sourcesJar +} + +signing { + sign configurations.archives +} + +install { + repositories.mavenInstaller { + setPom jbakePom + } +} From fa6911af4d58d7bdb071fce610a49838aa8794d3 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 30 Mar 2016 23:08:19 +0200 Subject: [PATCH 15/53] added jacoco coverage plugin --- build.gradle | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d0d16a539..18b075358 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'java' apply plugin: 'eclipse' -apply plugin: 'maven' +apply plugin: 'idea' +apply plugin: 'jacoco' group = 'org.jbake' version = '2.5.0-SNAPSHOT' @@ -62,3 +63,9 @@ dependencies { testCompile group: 'junit', name: 'junit', version: junitVersion testCompile group: 'org.assertj', name: 'assertj-core', version: assertjCoreVersion } + +jacoco { + toolVersion = '0.7.2.201409121644' +} + +jacocoTestReport.dependsOn test \ No newline at end of file From cab9c72bcf5c9a569d06852c3975f4aa29c75e79 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 30 Mar 2016 23:30:42 +0200 Subject: [PATCH 16/53] added coveralls plugin --- .travis.yml | 4 ++-- build.gradle | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 69247fdb1..9059bcbaa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ jdk: - oraclejdk7 after_success: - - mvn jacoco:report coveralls:jacoco + - ./gradlew jacocoTestReport coveralls notifications: - irc: "irc.freenode.org#jbake" + irc: "irc.freenode.org#anchos" diff --git a/build.gradle b/build.gradle index 18b075358..ab6dc6b13 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,11 @@ +plugins { + id "jacoco" + id "com.github.kt3k.coveralls" version "2.5.0" +} + apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' -apply plugin: 'jacoco' group = 'org.jbake' version = '2.5.0-SNAPSHOT' @@ -68,4 +72,11 @@ jacoco { toolVersion = '0.7.2.201409121644' } +jacocoTestReport { + reports { + xml.enabled = true // coveralls plugin depends on xml format report + html.enabled = true + } +} + jacocoTestReport.dependsOn test \ No newline at end of file From 045ab459f76e7aa929715cce4694a0da83026295 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 30 Mar 2016 23:39:40 +0200 Subject: [PATCH 17/53] gradle wrapper 2.12 --- .travis.yml | 3 +++ gradle/wrapper/gradle-wrapper.jar | Bin 52271 -> 53639 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 10 +++------- gradlew.bat | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9059bcbaa..09fa3109c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,9 @@ jdk: - openjdk7 - oraclejdk7 +script: + - ./gradlew test + after_success: - ./gradlew jacocoTestReport coveralls diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 30d399d8d2bf522ff5de94bf434a7cc43a9a74b5..2c6137b87896c8f70315ae454e00a969ef5f6019 100644 GIT binary patch delta 12685 zcmZX41yr0dvo>zU-QA^7C~l>=ySqbicb4MCVR3hd;_mM5F2&uUNPkNEfA{u&d(NKB zK6z#`N#@PYX6Jh%cu)>FqMRf+1RMwm3=9a9l(kqiA_c}zjQv9YC5<|STBUFFdJI1#bNDI30CR8JW*@OLo{2_M#K-Q2sf1qj%7*r^f z-})m6IwH|vARrG=ARr9DXb4Q83?d!?XeEm#fZYFUd2h~-&(|kAoAiVvHFJXn7D@So zGCYQur(n5lJlRgfiZ<(oqB-e@ivXeyB;(Xp&CJr}9(I;$maB~C6RpR`@o`;{-E-<7 z$;3fDwov>q_)|On{!t$GyGFN;(a*S{<~&9dw^sb;$13a<+Clmic4pqp2>oz?u(Hvc z0{DQnpCJdD@Ogy=hFn%T;;aP>cdaab;DK3dN>?4Jx@wlrk=RqZ$J=J8k=biAEX$RC z6oIa_b)!*gPIpD=HVY9qbsjTSEq5j*Xlo~@NoiKo)eq|AXq{hASY~j`=h>Fh8`mqt z#?#$AE#3NLeyD2i<*c5%Q<{#C=H9oo$dwJ+j6d2dR=QUPRmbPaPfpVoY`-rr zIxa~LD*km_EF#(*V=ACb!sJv!q2x`%c)BsPFcPqTxG@v~ zM0bxCD`JsTLxHASc3Nm#0E)wi3u~{R5J?WPT8U}IqocN6wlfrz=VI^HhinPh(TVMF zj1*v*1-3C>rCbr*RwS5TOix>y5>dJE%sCK^Wl-Wn#16ShXW$CR#6XFtQuwM&h{hbK z!6D*E@vB@UF?k;;8UY370S5{(WrUa*fq3!iDd=4CPhTXWYTy;fRDJiqyb4t^$@5;H zhQN%tW>%ix{rdn^&ml8H{t0VX%*elCorQultPo_Xr( zJU>p0elsHhAZPN8CG=5+lZFFylYPNHf|~aY7T{(w6MjF3K)Og7hotU6Gq#NR2n5#} zP|Quj-5^cJ%;auROFn>u2LBjmI`EVPH-33_3^J}Sy*Ul;h&zsOj>9ACE|JTrxcLB@ z+`SF1HDnB0ylwwb8kMh*Tx_Q`$_mGLe)Ty3YcQ-AGNZH;A=$Fk1DhX$!++JGAXNUdFSR~CrXo-=>Yv*mrG;ExmfjrVNACBx4xis>jQl*P96 zp9m_*lkYiBcjbTpG{$BEwgEK6kN@(l?oV5IBLEIBnJ~7m73S0nv^;~ zPT&7@r8htLU=d0vE^uj)dlAqZe`w z<#>>h4x$;{yJF8A3+4}*fl@5moS`^Ogtpo*r`aR(C{xm0J@78TPk4{L+lG`oDV|d z-&;rvCsB$D-2|oz1bi2Cxf-yhtfj#OKMO|8>0*+U`Eu=+6Z{ET7{Z(hO&uplDs!pI zlBIbEFCWq}%vwEO>7L~r6-uxOrZkQ0*UHqU($I?U;I#2IbLBT(H2h_K;CLwMXA{n8 zpa^vwQ(0TG6TpYkc2Un6S6ouX83rn(iYM7%mFArz0&j?Xpt9#lQ3RrZ_uB0&OxrD= zk3hX+J{Xe|xn44#MDgq`?L^|DxtdeuIVPFD^YzZs7egLIF$V0cb+a20k|K`zSp*U0 zSf*wIB=>F;utO<(6+Iq>Y0D*d89YKzuhk^#36T+PPC)81t$OotG%rEejkbuHse)&9 zjblv>)hv`^vY&bNwKOd z`7Vh`U1UuPyFm|Alxa4N87sG8Q=9~Ljy6+FeyDgp6+%fRR%TUC2ws@bj1(p0KyYdF zOdZUy5df2H-=#v|pB>kIK|ETV4qsMXop`Bqz6VWywdxpl4MqWX-?5&IcMsc1ko5ha zv(r!*M{GsbWb7oGQ4eU_Q+RAfhI0PpH0sqHLH3697_3#|T8+%W`w&qFSwTkw>b2DbpkHFKq_zXFSqX7Y z55N!^PAMxyk2PTxI;L5n2dY?ogc!eg+Lsz~>5e5>K_Jja3a zIn;k*s1j|c>??B(W=86qxPxTi9BP&_E2hSBASPp6FIIZjR^{$&%UZ9XRy=G1hM}{I zb&Zi215tHdRl}^z9^%&Qb<3Be{Hd#JUw}k=mWwi%)HCgKs(02DF>lV4(=|?9d6tE; zyFa1wfk+!+Sih3(Q1*CnO^UVLf&0(Wu4d)7uQo~#lxsQXdq1{K;%qiGm0x()Lrxxg zBu2qY#rM4gb{H=cGKI@yVD{%~osnuhMqz2nYyY{VQghVDX9kqV!PpW*R3C$_?i5{*T|ExSyb zjy*N080u9fb`!|=EH)dWXAJBl1qHqwm`F_*;jc;@dSK=zl|DN-+GqfmZ26(c0r}z(zphSXI^$cS;d`_ zB<>RfM0Z5>FixxJ7+8!7v>Dd28V4t`x&=0;B@HMl**a#NWR%XPo36D3=d7_mj85gO zR+(Dx=Fci?qgG2^3n^7MIlc?e8g*gl*t1yu#(}Bfg-gFm)q-E4oY$$6MhFO6N}ef8 zPV%=y%_hS~i>F9V_c1&0hYDLbo*J%=5aKC5NRAVu=+%)yP-X}*Z|uzvtSVNa6OZp< zPLcYETtDd z{@8Cz@&WjY6UHUZeM;WZx~N4u@w;*Qm_wNEwCzJ4a*DzH?A1E z7e-F-J847wKjtxBqKEi*GYX#+y}=E6Whe?SQ{Xe&d-+9i4mDm1uStG=-mF)C$;;eU zeUj;$${G3?2S6aYvVj0_vxssTK3Dv-a<`TkBS7VEp|f_A&EuaGh5Mzlvwm?y+dl3> zTA%K!`RO6$AUaBPwBGC(dMC`(>Tc&Aey1w7C{J4YG8GV_3PFu;H-s+(P%vK{;PyQr zqujx-E{Ja;EUg8a_cO#$5z&I*Px>*C-ofdC=i+dU$=DqPayISIk*Z1pM82DQEL?E39nYu|tFnNZ zJ?`dM&ZG@k#)C^?7q0qBKqm=%L{n+eU~OkbXd&9BaWNi4 zkq?>OhcDhp%*_G?ibQcJ@_dj75=|kA<$bDzUdeDfuHko|IW3lDQ)5o3B1T+gI#=)x zC~G{8Q$cGKGM9dKMzy-%42Tb8a=@X9Tqqd}pvm55FWQo^LlnLFY4D{Tlh{c( zP!{Hw)(SFFkbD4s1Z4zTvZXbJ1)0vH9dJ-Jfaq&x&DK1uGgEzJAX?l^L< z!j77J8uxO_P>AA0nf15B;cWFt-&9dv&W@8BAl*>lG7C8Us$b8T%coB#%3_BGT-jcJ5j+EW( z)6nMLn)*d|>a-SDN_B)Jnax|+B6QIbw*^5ZB8VR8*@rw5-~&MLOu7k5Vh7YrX;1)P zb78u>gU?#bY)vl|)Ur)vC#joSV?5&IcIF+#pfOs3N4k(~xlB+If7x_(g^#UOseAO{ zFdcMZ{+uR7p{^|!0~9f)HG@{}Lbhs6o!ew(LoGvlaqTG9bqHU}2zBnjiZ$6Xs@WPfMmFf>ACS<(E zd-!f>PkW0tvdeZcB{RhMKd5iecqrx$q0BieJmVqm79Y(%5Y{p%izc}74qt{MBiu!+ zD95%J&S72OOow>osz7De;# z)RI6LA(zhT{TykPJDNl*y}4|?M?_ZP@2@#qc0z5{A&;iKul3Xf`z+cAw$pWe<&njxJe((ta z+;J1cDpqPT1Ty6d#)tLYI*nhUO881}^&E0YKQ$lCk5qnOh{Isj;%Ay8E?c=0?6v5u zfGx!BFt2}zX@tkr@l6n%Xob0WLbea)$@qk5*WnC{k+X_)wEix1HAs37;O)_8Amqic z<;^-*L)PViyf;tMW+NbVCfdUjOzjGD>y2GQ*!_rBajpM^02a{?(&GZsvc4_pxr|_Y zON`qt%h+`|um9-wO$Vx<_hYCIDEjk8e5UFFt7~Jt^Ays4(0P?n-28#)KDTB2^FrWl zkoq_PrZ8l$U;^)25pPKtuz!sU)G5#SLszw_6i;$l=V!%h6ILZl4XSJQd0Jr3EzbJ)@#+I&#pf5aO zPU*_kw3V=_I@aAK_H(2g7CtRiU-dLE@mEfw)jDSa1V3|J{33kWqqCglkCREk2%c=DrB0ZV`1q@1^EDtY^$U@>ts1~V^vgM=!jo9di%oY1tOSs z0D(svx!dp5#xH0)E9=CE0OPM9+3F~gnRB3;J*d>TZLRgAl`fV@dJ0m%jP|BWgMm-i zv6LD@T_M+%03d}A{X&wXy7o|s^E2^tg9uLmCT^!Ci$9^1+ z@wl)NosBiyufUcvIi#n2SV+5t4HIyq=eb%4<@$7KO}N@AT=>qmv}$ki7x@3Vd6Qs# z2l;k+EH+n9KK*)qO@<8uLjCvh7#b+nfe46Gb<@LF#`z^(HE7K??Qb1ZM?*tTVKp@> zJiHoDCa#D(Fl#xLoIN*q`cZx1*ne@65C)E#nl>As6kSNTtX|*%D%d9*vls8|k?*1l z+~)jlREn*7*$M%0oO0KC*LrsE)$j56!vTpOPOla9a+|?>1*JpNkGeC>dj&%X2N3|3 zwPCH^*dJLBY5SeX25F1H)f5?{fiYMD|9V?nKxtbKl5?G*+rx;1yxU{v`q9X>y~2~& z2WjX|usdiivI=+SrxaCuoP8s=NQ$mE1?PH>BVH z8BHKHLN+8Va`;%0`Oy(11BEE!{sQ2Cjvt-&XmqR2&xh5s$bsDfynOZq(S_Lv1@)xy zVT3-918JijmVLOWC2sORIl6ofgqKy`O1Y00d#EE?ht0-X$Dmk$xAl1cHSxBa*xR27 z`U36gqfZ7+;rbLF0nX_OF2Ml-{sJ%8O1+1ft8JmFtC5sI;Tf~l_qpg91vCJG{IFCm zB^!;}lvVCje0-I&*9^RGQV!#090OX$SvRL{10U*DxYQP)OHioD^Uj{vR1f8ziVtPC5uhH&<3&SJHjv^ zo=%UTdl8JNP2f6*O@f^6 zR@Bm(=nsbPE_4=Pcj3hzFC6;TXKEW5rm$IoBbz+#p)z@|KY_QoS)s~(eWcCf^HMkq zEXnJ}7!?JCJq6U1rzW-lg6Tq58tBQsn#9otD2Gc*GHB!1`H4AWmz4b8orSXd@mNT{ zopCMnN)uC0pB3i5FGry@OQtaLHc_AhXXqG6ljxh~jj=ILrt=?JFT_|NDeNW+lF)>5 z^Mes_qiuy~%{bCOL)LB!{~*c{2~F+_vt6jeQM_)9Id6>CYnf*Q5LvA>8Qd0IXK*rQ zev5SoN!2XPZDG?S-rct zv~68EfK{l9?&TF2fSM+@04)EYyNN{G>10Pm4(li>92K?o@hNlDQThQ~{Djl}ej8<; z@bzz9>(yVd)Ol&0w~cB0DkOXJTq{EoHu7i@HzY7_!ZPw6u)b0XsBLL@#Jhd zHHi0S2x}AeN0~?$--p^hDYG55q)dv3CzyR?$=kAt2uo4s0nk|<#(g`W&dK7&eR<#f zYhc+H;+G=Z3k4plu=~g8V>af&hVc07s`EC|j^w^r1k2`*8yk%H`=3N8Pr5t>TW(|M z9eVX4d$p&z*iSznJnb}VLc%KEGmh+)OOfIvOx>D}{9vL}S4PkCPg<1+NmTqQfyaCK z{%m5j=46uj>+ zYoiEzZD0yqID?i0gB6@bk?YHtZ>{vnX0$kOS6gXt-x zm{u~Dwq2o&mWo;u!x0f%zqxS&--6k*(Yr%FC4J7&z&aHQeKghWSj~^h9Z2l%BX@e2 zt1o>Dg@0X|?tbht;~BamthhvP*r3o9G5IqsvqY#&_6w?0azqHPL$qN~Y-s?=ffyE#qQ&iS2%9GSLW zS08=)YWS_8hA+3FN&?H-)(-WP1JC9-SB;eqka>U}d7G{!gK#m*MCd~7-D;N3%+NB3a<9_0l1*O}|3>(cdqDQ4o3$Q^n zHms($NeTe;#pCU%jj?=Uaf}#FRa`JUib^umSJoq?;s$LWoy8m^wZ&2y$ugivzvg{S zrKZHL1q!RxE)(~|(UnyL6e7ydr$n&1c)kFZwdRd>3j8d#<)h%r2 zR2D6$I4!8SE%XhXB`{0UdKJ@pMN;g-tLx^}Evn{|k+Sr2#skT=IwnbNXC6%^FBbsM zj)n-QUA$_0V3in>oYp>(N3$FRwH$u({Ag60^yR63Fk=+8D6I=Z9Bkb^ZVjM&iXv2b zT0S0jBvt!$pgevPE1^3L@Ck~90-sS8*HIud3VGq3FbY=nK zL;W_%k18^E&K?NJ3xZiU>Xsb7c@7+D>doGmrXyP;I2ukW`iKbfJI?w0!DR|gLJhR7 zAXu$GSaEuLBucl-r9xU%HQ)W?P3&nZ;{%{D zy(l)*8FwaM(*~h(nmuJRKV&{;zcv|oh=UDX|xB9U9|5ps01_EU(gb8EH!9Z#!9esrsr5Yur&(_R=L2 zcj3>y(NsKdmBYchF;mk{>U@)%ZH-BjvWwI_N=gA2|{_@1W#Z|G$(EBM@ zSpSS8ZzAZ3mjZLZ9DW1Axm0*cx;(cmR_Rde3j^hWh-_v=Jb5*{y^6tb%VM0{yCUXh z`3ki~3^vQ_*~f^?mNj<3v^#`x8B58jkg)$ltCfiQM16AAr)J++HEDH{mL$TJuFwlM z%8`?m_HI8z!?F0jREF?!24)X5*>@3iH2Mo7M|1e@f~Pk#dhAaA= zYoSFAA}|61H%0;pplacQH;b`4kEd22Qf5mR*#uZ#q6-nSnIxV@DMv0sq;pyMtoN~~HzXj_m?+$6xN3{? zMuYEejb$&r`i%3D?|S@~r#)eZ$deaNlbu?Ri;$;k&z%qtfVe9-3)&FH$S{}`>nn~R zydkrzocjZHUtX;c3&~b6jAoA!e2#6lt+8BG=UvWuPZPFZWQB2WwrCF0kuPdS0F)v%<09u;5L9HYI$2&r z72Hr-7&QvJZZE zzW(avms%q+QdNGH8OP`rxIp7*ti_ly<{>i1HZ97VBgfQwEjDpGpJMNw{bA(1VY1o$ z%GO+ggb<<{fhvPA|0{6MUj?v2>ufEzZ-!|+LGv@v3J|)=HeC5c02fJ>z^s+%Z<4d5 z!RRg@D(^y|H1Ts4zq*atkaJhg+&>e&U=SM>Q_FQ~?z3XXZAOuN8VI zCF?wWW#U-4R=tQRy^=>&NoCsyKoyhfvz$!Gih&cY79lqCqqF-2dn4RD+Ld@Ww}JcD z2mAhy4uD?JyF$Ze5gCDS)TA>^=G|CxAfwQn&K_mAFC6B$lUKm(J5|>fInAA>K$>OD z&ub*q&P2n>kb@QdGa&&+t;1s!`1sE8<+>+kZ?RjrBq~*}eX{8oZL~m%U?A z1j|)l(69etJgRr$&f3mv(1&{JTvexOq<@$A(f}BC*eKxg4#aY@>{KDZtB@D{9;|6w z5+S`%y3Mvyo`b|Vsp>^dz-UpMC?kePIdc;+y^1p;Vyn_m#evnS>-dDR zm(&P8Ca97{Tu0u)wVtp+AznKF5BfTp=A6j^tq0P)DAf~E6VGke;_)by*wk50QjIi1 zYbcK?`+4rD)+Owc(Q791WfV4PHvctSiAm8Hb6Z1F5IeU*Vyk3$kY;7}{yrRw)Wj$wIIH~fB z{Lqya&{gQebbP1!ou_V*??mH*%jAHG({>oMn~}yu1dVqU>R{K;>o)Q3s`c9TxI6Ig zB6>)!3JWVDkOm3)1gFfbY!aFg^p-WP+`5%DbnN5e@3iuEga`HjC*qDXyiG?vq~;bFiSb3yxHP#h z`Np`XpfVYbVrZk=xVquVk%{F6mvo87EbD||I#F%v7ly-2P}8s)FDaj?o$)M_HwM3A zUR-phGL9+&LlU`1alt#Vp=1hOye{6JDuX`h4-x%7<__`77ZkQ zPGQk74xpg1U!sIuG3O&wf1VX6w}0HH--i0u_iIjF#W*V^1+0+aYmO^3b|CJv3IVc- zs`g7m2VP=(nFd7-TPV6ii#K^zT6x9iVy=+c*jBL^LCt||_(q4sR_K9L0GiRL_~ovk z$}LaXudiwM?9Q8X*CiZKO3>>_7Iq0u1b$z@?h3aD3V{nbI-ODOX*_88$J^gC(T-Qe z^8+~?cux%&!x#sXnm@ouHz@4LD@bn=dMk63I&bP2nCrIy^pOIQv-gx6B6V5a5wWp7 zn=`!c@{kbxDDj+-u#U%Ekx=QiBE+`&BtE`903Wt0F!q2naR^kf{q7 zz#7?V-OU8=@6slL@-+sZ6Q{b?GD0)+-G z*N%{$i!DO*7Z$rYu*T1W+&to6FA?g&5)9!_x-IC&{A!C?bkvooOm}?xvkDMf6?vUo zH?}MZx)|o;rN~drcP#1qWP9v!NM^np>F&A@OCy;SL%38Y+t9N9$mKl3dCBzAVr+h3 z$=z{5``%`x#msYk$fS^sia$cJKFInk=ChTa(Wy}ML^P4Q7>E~iQ~6_6Y0B5`0!+3) z;^lwUaQ>b#kW`Bf;LG*uzfzrX4CtR;DN{n2Ka#Z# zA^0CD%AV`5H0Cq~`3KAOc=)T4 zm0b(*r$RN)G zDX*Vw>`fWvBtgN@!T;3R{$GuE|7f%W*PC(wRLwp&4|^4`cHlCe_VY{A-@tLz7hG_DBpQ-lcu zLi~>s4)L4PFL7vKMmy@8TdN&X-+EsCkArgbuPd;{T-OARwgw5MyQDh-V#me>MoQ6Bo=;`3>Xm{P3n6 zV<>@#0|Npgi39>d@{h8&>Kn161qP_60QFz1^Y3B#KbkdP=X76>&JV=@eJK8KlBwS7 z5lQ*>R01`+aQUtD|HQhfy}ps9F{7cS`9ER*+gQ}Vbv)1O&MUs|{D=Rs^%_g5`aoSR zmVaFQt-!2n9GU-0+<$#j|D!-<1eEP310v``19`gP|9BzQjSGfm{Dy~iQ@y$0QYy{- zySm)(bwu8O3}BeO5#{=zfREjze+-cHygo)2uQ)z%!x#%_+w<43&nuo_`NnVWq5i`? zdc_(Y|6_xx7yl0~*NY3b?DB?3_R{{rT3<07k2kybPVhk6!M}D<`f$O{eE!-XdvjRR z)jBcuHO~7{{%@Qg`vSjvQ3IR%{wfc@D))o{_xi-%6qzkm>m*)h3h_GA-)GzZf7N_V z40|0x>5UYSSA%7W3Ifvi8jk-yMIw=}BvRl`|DRJB_}GsNc98{)9Hs{H58(WnhSmTs z*iPKXB?XY~Kyt=G2Z>(|oPDUkyI zSreZ@T(F?;{~4rr@bBInz2fdwuQ)!iF&pW>1`(XZ+&u&b0r7l2PI>+rWU2biSVuV? zFm>qf+LaFBf)O?VH>6-3@}o5CYQO-7qv#5+hwA-5t^m(hMTqC?H)DD*Q+Az2Eb_ z|EzV_IcuNq+k2mV_c`~@xjU)=t|lE0Q(XlP9u)vUMh1|p?#U-%(qsH-`(T?_Bme*a zFiBF2AmiNa%nb(czmR3r@Q;iM#;5j%^RWf9!fZTt8n9s9V4p-0@ZX+9&Ikohq6R`_ zTtwVIeDj)+HWOF?02>hiU2-EF24PnA_F#^0FPz-2 zAq7LjReK26Pqd18< z!LcT&43sdc#8so*$|_{b7H#}(I^C4l?h(uSLEBN2gJ4v>7o*eW=vaV^G3rSEVCQS^ zK_u#hIyINX8vpOl`KYA$KqgJC4-8l=Ax#gz_yoV2;UVSlwv$N_Jg6Xm9!yX)8%gAu zh0}f6&jtt5(x>3^M{I~rJ>q;r?=#Qf-e{=BQ#-!nrAySywygUV|A}aZW0P9a6p;>r z!}P#1PUjSce3I1Ei$v@gor6*4#pR_MPnXQ`fo}twict=>%I+3xdcvTHUe1TPp*v(Z zA|}+aHCfdZPraCmWK6zMP(w9*QZzbgwqen}IL~ zWGSa;sb`cHX#7_s)cUY)2FS@@r6^IQbOxzkQSRW_QBDDv8K}L(sd=#K+2KF3A}0AJ zmXt2$z-THqK>IhDH3BJYzrq6mB+!+>)j)tli|~}MB7_Nl^L3I~8wvAIzUH@x zy&}Q_032z++|*1UlmPsB-v{v{?ut2T6Dh@5A;Lt-mH|gJ5(6SDJSCIx9yCNz$lJo+ zikz#%N_ta9FI?PZ*R5xKVlGPzp4$)xCo){RjFI$9x7o`V;5Db&FVV}zs-Vu3$Y0$V zt8>cw=;sM}YyKB&*Ihq-*3X+xK)3v~OOr&Q_$2}sH|`{$d+A8$6tf!@l6z(G2Vq51 zKdpRc|2N&YDby(t@0~+-l6wY4kP3*X@C34sw2yL!MAB6AeVP@C$Sz zMiGIiKjA7t@PgE2MN;Ko-=kYf>G)>!eU-8+5`gO<=dHm`PpL;m@Fl3xX_emOhkZp- zDDsg-(O;Y<>(|(?=#z*teiBiQ4mG2;hu*`VHWW;>JJ!?p$XL zF{Jf*k0;MOS`#7(DS;Cz#MCJ@zbMYYw;f#se~qLNB*j4Dg|gukam~~rpvVaSe8_t= zqFr{Unfheg>(&A5e6_<^{3J=cz3-YQqTL_U1N{f3*enHwpx?74As;@!(ueWQw*^QU z(w){#3QeiuspO6%wd{04Z3(uo(lTBw>qEqg>3RHuMbdwvxO)Iw(vSD}t7cL)RALz~ zQ&Ch@Kt&!EMe{-f6Ot?0iVQEbMu@3e<@=`yOuj$8_?tR=xcz@ACrqsVS<131N!Zx6Ugs~n{J}9n#r%OKI6dj$o};yyZ@`mW6{D;+f0giw2QQFfFzqS8tW=WYSh;u*{At3bZrnQ5urAI?bR zcA~ncMDFsgY@p|ZM-Q>8o!1bAh}E3tjuteoUF6wrtw}YxKs#l+N-6-coe|15p=mak z#zoS;{XIE8^2TZZjINE)yWqLw@C5pyriSEQux-43^AW%Y?+wp}5(bSqKJh`VrSdOt ztGMvkXf3W=Gl0;{#a^%UrTW^-A73XnSKcs4K}HK5#Eg(}JpzBc7s3=BTS?$>4=@C& z(DIkJn(7Bqhx5UICEeea$IZag^tU@ula%CLt@$(oY0aIc@2jHCgngepDM*6xYbzGx zruURMyum|osT@3*+|I}`5|FVY1lQ-x_I)v8=yYFcIdgQme}=!hnL6BWN7f8=NYT~ znBU)oGEje96YP#&wd{zRGwyO9`DB7dT%~(*Wxt(2lkJw8mw`bLIp1I5#n^RGv zq6b&;IHZ{llb0Pym-`e?C9!0-Umyra*+fy>84G{tgU#)4y7V;AbDlXa( z=Jxh&F6$`W z9IlL*qrGqICtsw{O2(IV8J?sf#**<)(>7aO2dgxIiV7&ma?uV961Xm38SeB^SuuQP z*Ghs?9+ZN0W_oJGl-YM(5fCm8N&pJ)wkYr@EfddQFemKi|0G{Y>T4rf)B&#%MrZj6 zC-WU48<8|yJ)_fiLp4bicgRYH$)pnlGY9OQy>XP6Pei4=D}3(2SWLTo;i5Icl;M7f zg^@GZJPH>8B&Gu15>r_VdulP%H_lR<$`7rRAhAgFaPQ0sogCG&IVu~1^uFR<`lh@* z4`azop0gD%fb7cJ_tMa1Xm`}!VQcPBus}p{RzC;Bi;6yX`e5ht<9MyAen=+NQtzu^ zKOY@SLd-@A+R0aLc|;E~$WDy&Gk)DbI=bRHLJi+IjFc%@Zi#UjR7N1BwFjkr43P;R zz8p`Hf3aJ#>Lw?BKi!1~D1~#H#UQTluu5tE*t_C(@lKj192mG2BI`!$mub}bV^_4jroDy5X%WRE7CZ42hQ#I}x}Y+jfDf|n>e|2Y7|5|hfo1X9%O;}7cYqf)=^ z5S&1|l@V&h zx_e{J0?L*M;p+A+?lE9!p`$?@JJP#@6SH<2E=GtPSXNjgYnmw?Uv_Fh=tVQ>&7#l% z8no0RMX$uXEap|&2fbg@FvivIDZ8j1;}y~U9Tq&+!ZhP;IQ{KF^4<6O`l-RUA5O%F z_Y;|;cnOUXy;O*p6rX)%@sj$EkoNVWLXfsc@j9-=L6q<}om#DkbBbI-4mdVxj=;Z6 z2mj+iBgA$)`?wWt2@eZM|9<8J+ufDYysAo(7_L%IYJrnRzZS@6Ao{6Z~?xFDYbfd6Viq)6Rk&zm;p;6xXQu5@rQ64PW`5oQ=XFH9(rR6pYfO$-TMwvaGq; zMb03=@C-(gNLVoOA*X6XGJEp5{{+eoA+S)0G=fXcmZ_BYZYMt}OIGpoK4`Xj9p4e= zx05c4`4_@+>!1^DjZ459cX83r7b+)8d)p&8E+6X)#ci!Y5=6qj;!4=QRsc^25MARW40~lWy$s<_i z?FuR2liH~aXY|tP(~fSy?GjzcDP%rG7RbvF4)fLR=S#Vs>wYm-tGBk!r^>q2L9E++ zTU!AcZEe;hm-CL%t^(Z z_8~RqI$Yl4kf8;1xjU0!RU%u);)&m?HAiQDKWOKivFG|Bq! zD}b-1ho^qtK;oVGC%LJMVd~kvx3BAy-fqLR`lQnk<<0{mGS_~K}=mC z9Mf2vK?IHkFCkbm9U|112`2Q#MB)c#!XiH}VN?>0^k|LUQ4cXd}r{@5ay`+;F|XsREvQ7Nf+EL(3Q)3zsD zP8>SK0Qmi^@t#d5PrkKF@g-o{e2e-)r81U2HCM0!^F{3UO z8RBvhm{k(d_-A;R;P*FtRY=u1)2q=Qmn3)0dLJ=FJ0vAASV5Szc?cAor=#Dk$%#N9 zR_EK6y=3!S?Mn<7x3#3xgG=`wM$Gv8=VY0Tr}X<)j(Z!d_`hj8?K9U_m$AR+6n7<0 zB~SfK-Yp8)LKfo7rM+D=#|UjlJ-5mZ-!d72=p@k^xoJ8@|FTFfx}a^vUtd|?7?9yD zz89amzlyKvl+5~0acyVV4R_BklPd;VLp{0Jx#;j%qpO3RmT`aK5Gjp}Q%2384L@KP zE{zeIPZ=`(=7hp!D-QfIU_p0}$P~b-S6)1ZjD>aVP{i3s-FLp$(e?u}_O?xVr-V}A z%Pow0GIcALN|d>x;dOhir|kKB@D3+jY(X55Z?ElVT`Z6}nQwI1b%aM1t49UY&8@=S zdK10S(Lf?BB!ks_d(dyRC`|BUYTDNInm5fRNO!~(CEuhes(0)&MPnQDP%u@$HdjQ2>3jY??V^in= z&3!8ICDeuA6WFtV#d!=9ht#0C9z0q;J_qa$bE%Ty+6tX^wnAaKG z457mB*GlAY!kVIjP)S)HNf>{mPm87X^Zy#tPoRICu>UfK`_rK7dbrZzeHq+?^~g#x zf(ka}x?Him_eReQ*8e(3Y6#{XoA&m4W^NZz2Q$nEspuk%Qk4VuDiiyiLgF zNFH+N6zbhv-#A!r1|!3W)LZhZC`#Li!WJ9pscA+v@4sqWAhO62%;DKnG_cWQcT^&p zMxfYtvWdoMl~h@thIC$Ytol!@-UfPG?-v?EPNUY_uh#@X>pm}o4nHAL!n#!BqHcfT zG9u`$C@AfvOQww2&Y5loA>Bs`_6$n{7LGq7*B^l==G;xK_ueXy-1e#iRe-N zt&E{qv6BhNC!HD|TW|FE*^PP6J&ob7V+XOqxmo$JMn2`7U(Ik)#%+ND$m2F>GN|5e znBxS9hAPnB$inBvZD`d8^2I3>EHGK*rQY)LkiQNdK7EyR{*g)=KnejQlbQNqbD44H4TY;?A98BR^Qr|74X>F=Z~Fh@1}-QKvWZ>=+? z>QU@4HlkXoTU)z4PT&Ayw|1VZmwVkCg9`IHOS4lPMWy8$<3uqYGyYO14_J@kOxh`$ zUiJN1X3Kbo(_*BNdhI|{jSbo2Fc-Q1|XcB9Ow@si^7<_i#x$NEg-0BpM+73VQ z!hW$T({f~K8Gk|49-pniGq-1xCHtE*ms@0~MlXFxvkqM#IaV`^I#cB*@0E6es$DS; z=^ur?dsX5>3TZp+AhDWPehC^TsBeknMhM5$U6c<}}%!knOCds^Le+j6B=X>WiuHo$;NW5p3krsY>gO3>*4d~mF9Tg3K7$Ja_}6;X4y4Bn&G zuC&{=URlmDQqr_k!XYf+FKh|i2nnmQ9E;J4g|`*JIFMOvOw~g1)*`W%X+ddU4+nun z@5?f_ZPt2@s`nK)B$T>mZY!l*yC14U&GZ@=wSP%71u;i`Z;}_6OZQB>(sesMh=EJn z7H~T?5VAquOAjwyX0zhOM2EcE@`uH47-vSR!|dJkW_jVdbxnJNbyE-{@o7GeqT)#MmL=M!BPbUUElm?VoCCZ?gp~8{K)G_lslC)6 zJ}OOhbN;zS?5^x-WunXm%Mcu@oX==}0SQSHL&Kn})}ogg?PawlnIGTYxae3fY!8N7 zXI?%x;-Rqq`ph^FdHW=EO#-+=d&7A}^r2=`Mew0)%lO8d_(9{$xU4d8fnW&Caz8A| z6jT10=>p$@ly6&Y{=Lu-i(htuc@@ox^Rs47k%;hCljL4()mp!m5|dm^NDf<-HF0DZX>yMouQeSIow(3@e#=`lPJxsd9O0;G?N4Rn>HwKn= zJtu0>5yuZN&;Rb0vSnFfj{%%hN2aYNq_GTQt7<2sKk}kG;gLtXkMQ40A_#~bh~~_k zQ5sv(@{5_%c)=o8rXt7j&i`#fS@zM7pAfQg&@Ub*mZXxEaV2mFOj(mE?Etdvq{>UF z^Fk-38cTJTf#Z)dWC|@R>7GmkQ(Oi9~+HKbp{WDT(!@IIq~=F z0_a;1ySlT{Q3RexMGvK2g%@nn6RedUX)5=E??l8X?BiWe}^4=}kpEv`!jtbL> zij-33WbthjKbMzIWVE)7D5p$5@udpq)mieWn%|=9yx0bM*DS6Y>>uWQJI*;i9?SuC z@~(7hAFpLhu6>uWF(Pskl~}&&P!%<%%#<4IznsxeUk)&cT`pJ5orPWL-pj^2rdH|@2bdiP;zU3gQaht)=D3DbKD z!xmOCy<#rtqcyh!P+~4_CImdo$0dCEit&KnMD)|%4K7y&QKbVrD9CI1w+cr`; zu@19+vpLBBVN}{0x4*C(yKFZVqhEYBHv)-au9nVr7Zp%xtMT{&kP;wNQ7hPHBAogF z{*;m3E5s{!%~d5_Bdm>B=JqB-aH|yf8Yfq|`$K@z4Boiyrs(_2sjYx-pAe!KKoOt0 z;;jcbwi4e|UFi^sRCp3pT&>x`McEokkZK_rYR@(|3rf=8^3g!yhchsm`^qVH5U8dJD1ap#Yt zW&BHZx*NvLsDG9;H#}zp?GQ;69c1SshN@P>RDhGx(i$}sWJa@TAQZdC4cp=SKK_T% zQ1=)XjWCmYvXFsH!S@;2K8B&DGW>7?cs!u?Fk88GfO(t?-mX*y6jHWbDK!C5~j_4%r=oKX=_q!k~{*8K8*#+bGA-#qYPN#LPzD z2k0ZyHiggSZGT+B(*t28x2E#Ya^VhgAn<+B&m&ZemLd)U2nact(YFy9Kl7`BToF)) za7}D&xCvc`P0pF@z){OW&6ZSZTuA<-eXA~OJ*O)pBHIkj1qRc>x?F`Vsps(@lu=(^ z;g8O%{z~SHu0z2P{<5xlZne-(keO4wV0^$oSeK~9zE-9Fb<0tlC`*MjODrC>3inP| z9O2&&KnfeoXB7!i3;w8kwuC6 zEFf`$Fi*F*rr!FTAtxm8>@wj+d;)+=u~y&s=AUm7b8Z=-*EfIbcg;3=YZOUCTxoL7 zqY*i5l0t)$r8F9AYL(#Q3W?Pc6+7zRCa)rUSvyBUWf}kpD-rcs3bTg))gNP2kfk9f zQApox-^Nl)?Pf@#)0au|&9gz0Qk|^oXJ8groypKrEB25y z&6a&P zWCT*ug9T+r9C&dwqO^1DBu9SDuE>@W#trhQ8koGg$9zfe)?UfMW&0_rBSOO?JFXn1 z+7=Sl0ROy&^ELO@rWoAt9Fs!ke8C{bAV}@iPLpSGU!$PL?3-dX75+mPGRv3{e6(fr z;>yzR4n~vTT5{(~!ztu}0^m%X^{S;XtMM>vOVKEIo}6w^o-fqT3UZZ*F?dMNM19jK zC5O-!*lGh%EwT8kan@5Im+5w&1QUoXJHpe-l&`*_kkp*E;SgDL#LQcCOzvQO>jXu& zz$+i%#aNE{WG$X-ypBn&z!R#ndU@h|+7+i^`0flw{BnbiglZd)ByWqCBySrHtLxnv zLD!Fsb#}U*b5@L>+1|;|3dclrhEm^~S;o#3BpmUTH6oDA!$mqIV=IGjQHNTl z#!;9pWG=+a`$aBYs7^8cvisa(T<7$YZqyqL9OCd;}BrPrTEvaKSb8YE+s#b{5Li__p zdymhzqfY8PnYyOK14&)K_susIAPsS_%CNb*l2;kyrw9v+Nb>P3bY4E9^w}S+A@Nxc z*LV|)?@FxwM=yqi`nN=SKbp0D#<9xJ?6M2J44RiZ|9Ptcu&JDSd&y@Z@5jB@J|XuY zU&(lc!Dp|4qHJ4<{v}=pem<_?88K-Ts~%0f462dLK0$J-37v+(VsOXWOArwHMsWtn z>@~*p_?b-T%eK!5ax%+lhq>eHw! zRq2k@C0SXzaoy$~v1r5a71R zG;70dAvY%hH)>1e42of#H(7*hDLBqMkVO<(Os$(gk-uWR4SXYr>*{rDfMPyiD`4l8 zWIG5kAq}Z}<=4cAX7U_@F|$hYo8$0PoPQlB-GMw7J=|%M4m(db2C z`A+x+u(SxEQbB~;zlQrh;-_`3m)!$`yi2=}%Yu`F(Q8K5bia*uQ|tTxaV+#_qF{eh zR`@@ihH}#=*vB52-(v4cL}Pgmi}`1;qf(V830gc9h5*j1VQg|rKAb| ziIPwW``49}nv=hyZ|V*In%!%V{EK62o%$<#_^9<4r_+%Phx^BzLGrwT0yHb+pcfSY ztUf~nChNif|KwDo`v1tO7d9R)z+@c6^~+d^x-0KcX7q3eT|>Q6@=*W546a3d!G|hxffnh={(}L)f?azFz%{zaVCp{pNAT{Uo_jeI zv<$sy{{ef!KZ0ZW$R2_4WqzxMP^}tJt?d5*O%NV|CxeLKjXvr}F!|Q&ck`;p6vLjlGdK!1``4v@nB zBzTm+93Xy@*+XS-q0i@DLg=1C`RLGpDvi?L4#%-7Ck$gHp@zC@9)to=@YpNO8zYVNIn^)dnEto9r=F;cv9)FWhAiL5dI_hpH1;U zhM;azs6)Yj=JRKdeD-8*e25g5QS(trjV>k_Z5W;UpUo1g;NKhp>4OD^xvBpwga6(f zp<6KVKbCL|z;A{b9zlQP|CN!@GOoYBKN*Q{2%a3KcwCm?lVMU=8ACAlBnkN02*Z<1 zZG;qd(g@6LLkEr@!FyDuDUCu=3e|QE{lg&oU%H@eV@R9vBXE0!@rjK2i4?ZO3@VcV zpNykFlK1E^&K01psz4QR|3fadgaXOILiR-9S7T3L2_l<^VI%+`3c8BK{sD_yKUyLh zWqQ;~ZckV@0oAw+bxGhKpoudS$PB*s!2WL+cFg7&H=$rBsOCTAp8xf03<-66)Jp0@ z3GV*u08^9cM0lcoCNehAHCz zKLj6!EuaZ>3n4`V07U*FIDdeqkkXTTL6fAgOeN6ya{TvAZSJXcPlvi!4!u|Z-c*kA z$6!%R(LM%-5nd6U1R5CYKXduV0!S={1qWv@}Y&- +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -114,6 +109,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` diff --git a/gradlew.bat b/gradlew.bat index 8a0b282aa..5f192121e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -46,7 +46,7 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args From 24b2b6c5bc7abc7b1dceb33fc61a59c0e2b07e15 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 30 Mar 2016 23:43:37 +0200 Subject: [PATCH 18/53] sign only if release version --- gradle/maven-publishing.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gradle/maven-publishing.gradle b/gradle/maven-publishing.gradle index d33ca0551..5cca61caf 100644 --- a/gradle/maven-publishing.gradle +++ b/gradle/maven-publishing.gradle @@ -1,6 +1,8 @@ apply plugin: 'maven' apply plugin: 'signing' +ext.isReleaseVersion = !version.endsWith("SNAPSHOT") + def jbakePom = pom { project { description 'JBake is a Java based open source static site/blog generator for developers.' @@ -62,7 +64,9 @@ artifacts { archives javadocJar, sourcesJar } + signing { + required { isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives") } sign configurations.archives } From ae4a5aa21802663a02186988528fb12230d8e685 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Thu, 31 Mar 2016 00:47:55 +0200 Subject: [PATCH 19/53] apply coveralls plugin only if current java version is jdk 7 compatible --- .travis.yml | 2 +- build.gradle | 15 ++++++++++++--- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 09fa3109c..6aea385da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ script: - ./gradlew test after_success: - - ./gradlew jacocoTestReport coveralls + - ./gradlew jacocoTestReport coveralls || ./gradlew clean notifications: irc: "irc.freenode.org#anchos" diff --git a/build.gradle b/build.gradle index ab6dc6b13..22fa5338c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,20 @@ -plugins { - id "jacoco" - id "com.github.kt3k.coveralls" version "2.5.0" +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3' + } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' +apply plugin: 'jacoco' + +if( JavaVersion.current().java7Compatible ) { + apply plugin: 'com.github.kt3k.coveralls' +} group = 'org.jbake' version = '2.5.0-SNAPSHOT' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 84a778cc6..1acb6bbb1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Mar 30 23:39:26 CEST 2016 +#Thu Mar 31 00:29:42 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip From 8007076a385dfb20125205f043913772917a1d6e Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Thu, 31 Mar 2016 00:53:17 +0200 Subject: [PATCH 20/53] disabled travis-ci install step. not interested in assembling project with jdk6 --- .travis.yml | 2 ++ build.gradle | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6aea385da..a73cd6669 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,8 @@ jdk: - openjdk7 - oraclejdk7 +install: true + script: - ./gradlew test diff --git a/build.gradle b/build.gradle index 22fa5338c..cd9e5132b 100644 --- a/build.gradle +++ b/build.gradle @@ -12,17 +12,17 @@ apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'jacoco' -if( JavaVersion.current().java7Compatible ) { - apply plugin: 'com.github.kt3k.coveralls' -} group = 'org.jbake' version = '2.5.0-SNAPSHOT' description = """jbake""" -apply from: 'gradle/application.gradle' -apply from: 'gradle/maven-publishing.gradle' +if( JavaVersion.current().java7Compatible ) { + apply plugin: 'com.github.kt3k.coveralls' + apply from: 'gradle/application.gradle' + apply from: 'gradle/maven-publishing.gradle' +} sourceCompatibility = 1.6 targetCompatibility = 1.6 From b065c8bac581e0d9d070ab085344766e1d6647ce Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Thu, 31 Mar 2016 01:08:13 +0200 Subject: [PATCH 21/53] replaced ambiguous variable in default.properties which let jdk6 tests fail --- .travis.yml | 5 ++++- gradle/application.gradle | 2 +- src/main/resources/default.properties | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a73cd6669..ad3751863 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,13 @@ jdk: install: true script: - - ./gradlew test + - ./gradlew check after_success: - ./gradlew jacocoTestReport coveralls || ./gradlew clean +after_failure: + - ./gradlew clean check --debug + notifications: irc: "irc.freenode.org#anchos" diff --git a/gradle/application.gradle b/gradle/application.gradle index 487b86348..e372b5552 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -29,7 +29,7 @@ ext { processResources { from("src/main/resources"){ include 'default.properties' - expand version: project.version, + expand jbakeVersion: project.version, timestamp: new SimpleDateFormat("yyyy-MM-dd HH:mm:ssa").format( new Date() ) } } diff --git a/src/main/resources/default.properties b/src/main/resources/default.properties index 064dcff30..97d90b3f2 100644 --- a/src/main/resources/default.properties +++ b/src/main/resources/default.properties @@ -1,5 +1,5 @@ # application version -version=v${version} +version=v${jbakeVersion} # build timestamp build.timestamp=${timestamp} # path to destination folder by default From 0093726d4db3d69380774a8377fe31218c69cb42 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Fri, 1 Apr 2016 16:46:03 +0200 Subject: [PATCH 22/53] renamed example project zip tasks --- .gitignore | 2 ++ gradle/application.gradle | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index dc6be0687..bb7438b2e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,7 @@ /.idea *.iml *~ +*.ipr +*.iws build/ .gradle diff --git a/gradle/application.gradle b/gradle/application.gradle index e372b5552..0480f0c19 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -51,7 +51,7 @@ task cloneProjectExampleRepositories() { //create Zip Task for each repository exampleRepositories.each { name, repository -> - task "zip${name}Repository"(type: Zip, dependsOn: cloneProjectExampleRepositories) { + task "${name}Zip"(type: Zip, dependsOn: cloneProjectExampleRepositories) { group "distribution" description "Zip $name repository" @@ -71,7 +71,7 @@ distributions { contents { //Include Outputs from zip tasks exampleRepositories.each { name, repository -> - def task = project.tasks.getByName("zip${name}Repository") + def task = project.tasks.getByName("${name}Zip") from(task) } } From 52e24bccb0842ba4f7cd57bd8ab45bfdc485c606 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 10:06:26 +0200 Subject: [PATCH 23/53] update gradle wrapper to 3.1 --- gradle/wrapper/gradle-wrapper.jar | Bin 53639 -> 52928 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 51 +++++++++++++---------- gradlew.bat | 12 ++---- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c6137b87896c8f70315ae454e00a969ef5f6019..6ffa237849ef3607e39c3b334a92a65367962071 100644 GIT binary patch delta 13488 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 D6tYUE diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1acb6bbb1..c50fb16b4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Mar 31 00:29:42 CEST 2016 +#Sun Oct 16 10:05:35 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip diff --git a/gradlew b/gradlew index 9d82f7891..9aa616c27 100755 --- a/gradlew +++ b/gradlew @@ -6,12 +6,30 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -157,4 +161,9 @@ function splitJvmOpts() { eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then + cd "$(dirname "$0")" +fi + exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat index 5f192121e..f9553162f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -49,7 +49,6 @@ goto fail @rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line From a772756131b59e74b715953c4bc6c1574ec95474 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 11:43:50 +0200 Subject: [PATCH 24/53] fixed javadoc errors and warnings --- src/main/java/org/jbake/app/Crawler.java | 6 ++-- src/main/java/org/jbake/app/FileUtil.java | 2 +- src/main/java/org/jbake/app/Oven.java | 34 +++++++----------- src/main/java/org/jbake/app/Parser.java | 8 ++--- src/main/java/org/jbake/app/Renderer.java | 35 +++++++++---------- src/main/java/org/jbake/launcher/Main.java | 2 +- .../org/jbake/template/ModelExtractors.java | 2 +- .../jbake/template/TemplateEngineAdapter.java | 34 +++++++++--------- .../org/jbake/template/TemplateEngines.java | 3 +- 9 files changed, 59 insertions(+), 67 deletions(-) diff --git a/src/main/java/org/jbake/app/Crawler.java b/src/main/java/org/jbake/app/Crawler.java index 46a1fbc20..bdf68cb91 100644 --- a/src/main/java/org/jbake/app/Crawler.java +++ b/src/main/java/org/jbake/app/Crawler.java @@ -61,9 +61,9 @@ interface Status { /** * Creates new instance of Crawler. - * @param db Database instance for content - * @param source Base directory where content directory is located - * @param config Project configuration + * @param db Database instance for content + * @param source Base directory where content directory is located + * @param config Project configuration */ public Crawler(ContentStore db, File source, CompositeConfiguration config) { this.db = db; diff --git a/src/main/java/org/jbake/app/FileUtil.java b/src/main/java/org/jbake/app/FileUtil.java index 6d223683c..8781a06f2 100644 --- a/src/main/java/org/jbake/app/FileUtil.java +++ b/src/main/java/org/jbake/app/FileUtil.java @@ -43,7 +43,7 @@ public static boolean isExistingFolder(File f) { * Works out the folder where JBake is running from. * * @return File referencing folder JBake is running from - * @throws Exception when application is not able to work out where is JBake running from + * @throws Exception when application is not able to work out where is JBake running from */ public static File getRunningLocation() throws Exception { String codePath = FileUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath(); diff --git a/src/main/java/org/jbake/app/Oven.java b/src/main/java/org/jbake/app/Oven.java index 4c330df13..6c0752a26 100644 --- a/src/main/java/org/jbake/app/Oven.java +++ b/src/main/java/org/jbake/app/Oven.java @@ -2,6 +2,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.io.FilenameUtils; import org.jbake.app.ConfigUtil.Keys; import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentTypes; @@ -12,22 +13,10 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ServiceLoader; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.orientechnologies.orient.core.Orient; -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import org.apache.commons.io.FilenameUtils; -import org.slf4j.bridge.SLF4JBridgeHandler; - /** * All the baking happens in the Oven! * @@ -51,11 +40,11 @@ public class Oven { /** * Delegate c'tor to prevent API break for the moment. - * - * @param source Project source directory - * @param destination The destination folder - * @param isClearCache Should the cache be cleaned - * @throws ConfigurationException if configuration is not loaded correctly + * + * @param source Project source directory + * @param destination The destination folder + * @param isClearCache Should the cache be cleaned + * @throws ConfigurationException if configuration is not loaded correctly */ public Oven(final File source, final File destination, final boolean isClearCache) throws ConfigurationException { this(source, destination, ConfigUtil.load(source), isClearCache); @@ -64,10 +53,10 @@ public Oven(final File source, final File destination, final boolean isClearCach /** * Creates a new instance of the Oven with references to the source and destination folders. * - * @param source Project source directory - * @param destination The destination folder - * @param config Project configuration - * @param isClearCache Should the cache be cleaned + * @param source Project source directory + * @param destination The destination folder + * @param config Project configuration + * @param isClearCache Should the cache be cleaned */ public Oven(final File source, final File destination, final CompositeConfiguration config, final boolean isClearCache) { this.source = source; @@ -136,6 +125,7 @@ private File setupRequiredFolderFromConfig(final String key) { /** * All the good stuff happens in here... + * */ public void bake() { final ContentStore db = DBUtil.createDataStore(config.getString(Keys.DB_STORE), config.getString(Keys.DB_PATH)); diff --git a/src/main/java/org/jbake/app/Parser.java b/src/main/java/org/jbake/app/Parser.java index fb15146b4..b58f161a6 100644 --- a/src/main/java/org/jbake/app/Parser.java +++ b/src/main/java/org/jbake/app/Parser.java @@ -22,9 +22,9 @@ public class Parser { /** * Creates a new instance of Parser. - * - * @param config Project configuration - * @param contentPath Content location + * + * @param config Project configuration + * @param contentPath Content location */ public Parser(Configuration config, String contentPath) { this.config = config; @@ -35,7 +35,7 @@ public Parser(Configuration config, String contentPath) { * Process the file by parsing the contents. * * @param file File input for parsing - * @return The contents of the file + * @return The contents of the file as a @{@link Map} */ public Map processFile(File file) { ParserEngine engine = Engines.get(FileUtil.fileExt(file)); diff --git a/src/main/java/org/jbake/app/Renderer.java b/src/main/java/org/jbake/app/Renderer.java index eda48836e..633d2c05e 100644 --- a/src/main/java/org/jbake/app/Renderer.java +++ b/src/main/java/org/jbake/app/Renderer.java @@ -138,7 +138,7 @@ public Map getModel() { * @param db The database holding the content * @param destination The destination folder * @param templatesPath The templates folder - * @param config Project configuration + * @param config Project configuration */ public Renderer(ContentStore db, File destination, File templatesPath, CompositeConfiguration config) { this.destination = destination; @@ -150,11 +150,11 @@ public Renderer(ContentStore db, File destination, File templatesPath, Composite /** * Creates a new instance of Renderer with supplied references to folders and the instance of DelegatingTemplateEngine to use. * - * @param db The database holding the content - * @param destination The destination folder - * @param templatesPath The templates folder - * @param config - * @param renderingEngine The instance of DelegatingTemplateEngine to use + * @param db The database holding the content + * @param destination The destination folder + * @param templatesPath The templates folder + * @param config Project configuration + * @param renderingEngine The instance of DelegatingTemplateEngine to use */ public Renderer(ContentStore db, File destination, File templatesPath, CompositeConfiguration config, DelegatingTemplateEngine renderingEngine) { this.destination = destination; @@ -172,8 +172,8 @@ private String findTemplateName(String docType) { /** * Render the supplied content to a file. * - * @param content The content to renderDocument - * @throws Exception if IOException or SecurityException are raised + * @param content The content to renderDocument + * @throws Exception if IOException or SecurityException are raised */ public void render(Map content) throws Exception { String docType = (String) content.get(Crawler.Attributes.TYPE); @@ -296,11 +296,10 @@ public void renderIndexPaging(String indexFile) throws Exception { /** * Render an XML sitemap file using the supplied content. - * - * @param sitemapFile configuration for site map - * @throws Exception if can't create correct default rendering config * - * @throws Exception + * @param sitemapFile configuration for site map + * @throws Exception if can't create correct default rendering config + * * @see About Sitemaps * @see Sitemap protocol */ @@ -311,8 +310,8 @@ public void renderSitemap(String sitemapFile) throws Exception { /** * Render an XML feed file using the supplied content. * - * @param feedFile The name of the output file - * @throws Exception if default rendering configuration is not loaded correctly + * @param feedFile The name of the output file + * @throws Exception if default rendering configuration is not loaded correctly */ public void renderFeed(String feedFile) throws Exception { render(new DefaultRenderingConfig(feedFile, "feed")); @@ -321,8 +320,8 @@ public void renderFeed(String feedFile) throws Exception { /** * Render an archive file using the supplied content. * - * @param archiveFile The name of the output file - * @throws Exception if default rendering configuration is not loaded correctly + * @param archiveFile The name of the output file + * @throws Exception if default rendering configuration is not loaded correctly */ public void renderArchive(String archiveFile) throws Exception { render(new DefaultRenderingConfig(archiveFile, "archive")); @@ -332,8 +331,8 @@ public void renderArchive(String archiveFile) throws Exception { * Render tag files using the supplied content. * * @param tagPath The output path - * @return Number of rendered tags - * @throws Exception if cannot render tags correctly + * @return Number of rendered tags + * @throws Exception if cannot render tags correctly */ public int renderTags(String tagPath) throws Exception { int renderedCount = 0; diff --git a/src/main/java/org/jbake/launcher/Main.java b/src/main/java/org/jbake/launcher/Main.java index 0d6509526..6c1599f13 100644 --- a/src/main/java/org/jbake/launcher/Main.java +++ b/src/main/java/org/jbake/launcher/Main.java @@ -28,7 +28,7 @@ public class Main { /** * Runs the app with the given arguments. - * + * * @param args Application arguments */ public static void main(final String[] args) { diff --git a/src/main/java/org/jbake/template/ModelExtractors.java b/src/main/java/org/jbake/template/ModelExtractors.java index 36ea8e06c..3041349cf 100644 --- a/src/main/java/org/jbake/template/ModelExtractors.java +++ b/src/main/java/org/jbake/template/ModelExtractors.java @@ -135,7 +135,7 @@ public boolean containsKey(Object key) { } /** - * @return Set of keys contained in this object + * @return A @{@link Set} of all known keys a @{@link ModelExtractor} is registered with * @see java.util.Map#keySet() */ public Set keySet() { diff --git a/src/main/java/org/jbake/template/TemplateEngineAdapter.java b/src/main/java/org/jbake/template/TemplateEngineAdapter.java index 03f125b38..c72b4973a 100644 --- a/src/main/java/org/jbake/template/TemplateEngineAdapter.java +++ b/src/main/java/org/jbake/template/TemplateEngineAdapter.java @@ -2,26 +2,28 @@ /** * Adapts model extractor output to used template engine. - * This method typiocally wraps results of model extractions into data types suited to template engine - * @author ndx + * This method typically wraps results of model extractions into data types suited to template engine * + * @author ndx */ public interface TemplateEngineAdapter { - class NoopAdapter implements TemplateEngineAdapter { - @Override - public Object adapt(String key, Object extractedValue) { - return extractedValue; - } - - } + class NoopAdapter implements TemplateEngineAdapter { + + @Override + public Object adapt(String key, Object extractedValue) { + return extractedValue; + } + + } - /** - * Adapt value to expected output - * @param key Template key - * @param extractedValue Value to be used in template model - * @return Value adapted for use in template - */ - Type adapt(String key, Object extractedValue); + /** + * Adapt value to expected output + * + * @param key Template key + * @param extractedValue Value to be used in template model + * @return Value adapted for use in template + */ + Type adapt(String key, Object extractedValue); } diff --git a/src/main/java/org/jbake/template/TemplateEngines.java b/src/main/java/org/jbake/template/TemplateEngines.java index 26be48083..9479db181 100644 --- a/src/main/java/org/jbake/template/TemplateEngines.java +++ b/src/main/java/org/jbake/template/TemplateEngines.java @@ -20,7 +20,8 @@ /** - *

A singleton class giving access to rendering engines. Rendering engines are loaded based on classpath. New + *

+ * A singleton class giving access to rendering engines. Rendering engines are loaded based on classpath. New * rendering may be registered either at runtime (not recommanded) or by putting a descriptor file on classpath * (recommanded).

*

The descriptor file must be found in META-INF directory and named From 64f91305a7422768e1479e193c83687c3d3697c9 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 12:42:06 +0200 Subject: [PATCH 25/53] added pom signing and bintray publishing * skip signing with ./gradlew -PskipSigning=true install * add `bintrayKey` and `bintrayUsername` properties to ~/.gradle/gradle.properties --- build.gradle | 27 ++++++++--------- gradle.properties | 9 ++++++ gradle/maven-publishing.gradle | 15 +++------- gradle/publishing.gradle | 54 ++++++++++++++++++++++++++++++++++ gradle/signing.gradle | 41 ++++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 26 deletions(-) create mode 100644 gradle.properties create mode 100644 gradle/publishing.gradle create mode 100644 gradle/signing.gradle diff --git a/build.gradle b/build.gradle index cd9e5132b..d40f069d0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,27 +1,24 @@ -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3' - } +plugins { + id "java" + id "eclipse" + id "idea" + id "jacoco" + id "com.jfrog.bintray" version "1.7.2" apply false + id "com.github.kt3k.coveralls" version "2.6.3" apply false } -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'jacoco' - - group = 'org.jbake' -version = '2.5.0-SNAPSHOT' +version = '2.6.0-SNAPSHOT' description = """jbake""" if( JavaVersion.current().java7Compatible ) { apply plugin: 'com.github.kt3k.coveralls' + apply plugin: 'com.jfrog.bintray' apply from: 'gradle/application.gradle' + apply from: 'gradle/signing.gradle' apply from: 'gradle/maven-publishing.gradle' + apply from: 'gradle/publishing.gradle' } sourceCompatibility = 1.6 @@ -78,7 +75,7 @@ dependencies { } jacoco { - toolVersion = '0.7.2.201409121644' + toolVersion = '0.7.7.201606060606' } jacocoTestReport { diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..06f4a68bd --- /dev/null +++ b/gradle.properties @@ -0,0 +1,9 @@ +project_description=JBake is a Java based open source static site/blog generator for developers. +website=http://jbake.org +issues=https://github.com/jbake-org/jbake/issues +vcs=https://github.com/jbake-org/jbake/ + +bintrayDryRun=false +bintrayOrg=jbake +bintrayRepo=maven + diff --git a/gradle/maven-publishing.gradle b/gradle/maven-publishing.gradle index 5cca61caf..6060c5801 100644 --- a/gradle/maven-publishing.gradle +++ b/gradle/maven-publishing.gradle @@ -1,12 +1,11 @@ apply plugin: 'maven' -apply plugin: 'signing' ext.isReleaseVersion = !version.endsWith("SNAPSHOT") def jbakePom = pom { project { - description 'JBake is a Java based open source static site/blog generator for developers.' - url 'http://jbake.org' + description project.project_description + url project.website developers { developer { id 'jonbullock' @@ -17,13 +16,13 @@ def jbakePom = pom { } } scm { - url 'https://github.com/jbake-org/jbake/' + url project.vcs connection 'scm:git:git@github.com:jbake-org/jbake.git' developerConnection 'scm:git:https://github.com/jbake-org/jbake.git' } issueManagement { system 'GitHub Issues' - url 'https://github.com/jbake-org/jbake/issues' + url project.issues } mailingLists { @@ -64,12 +63,6 @@ artifacts { archives javadocJar, sourcesJar } - -signing { - required { isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives") } - sign configurations.archives -} - install { repositories.mavenInstaller { setPom jbakePom diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle new file mode 100644 index 000000000..6678844ce --- /dev/null +++ b/gradle/publishing.gradle @@ -0,0 +1,54 @@ +import java.text.SimpleDateFormat + +Date buildTimeAndDate = new Date() +ext { + buildDate = new SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate) + buildTime = new SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate) +} + +jar { + manifest { + attributes( + 'Built-By': System.properties['user.name'], + 'Created-By': "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})".toString(), + 'Build-Date': buildDate, + 'Build-Time': buildTime, + 'Specification-Title': project.name, + 'Specification-Version': project.version, + 'Specification-Vendor': project.name, + 'Implementation-Title': project.name, + 'Implementation-Version': project.version, + 'Implementation-Vendor': project.name + ) + } +} + +bintray { + user = bintrayUsername + key = bintrayKey + configurations = ['archives'] + + if ( !project.hasProperty('skipSigning') ) { + // Copy the signed pom to bintrayDestination + filesSpec { + from signPom + into signPom.bintrayDestination + } + bintrayUpload.dependsOn signPom + } + + dryRun = bintrayDryRun.toBoolean() + pkg { + userOrg = bintrayOrg + repo = bintrayRepo + name = project.name + desc = project.description + licenses = ['MIT'] + labels = ['jbake', 'site-generator'] + websiteUrl = project.website + issueTrackerUrl = project.issues + vcsUrl = project.vcs + publicDownloadNumbers = true + } +} + diff --git a/gradle/signing.gradle b/gradle/signing.gradle new file mode 100644 index 000000000..810aa2852 --- /dev/null +++ b/gradle/signing.gradle @@ -0,0 +1,41 @@ +if ( !project.hasProperty('skipSigning') ) { + apply plugin: 'signing' + + if (!signing.signatory) { + logger.warn "No Signatory configured for project $project.name. Skip signing! See https://docs.gradle.org/current/userguide/signing_plugin.html" + ext.skipSigning = true + } + else { + signing { + sign configurations.archives + } + } + + task signPom(type: Sign) { + group "publishing" + description "Sign the projects pom file" + + ext.pom = file("$buildDir/poms/pom-default.xml") + ext.signedPom = file("$buildDir/poms/${project.name}-${project.version}.pom.asc") + ext.bintrayDestination = "${project.group.replace(".", "/")}/${project.name}/${project.version}" + + inputs.file pom + outputs.file signedPom + + doLast { + + def input = pom.newInputStream() + def output = signedPom.newOutputStream() + try { + signatory.sign(input, output) + } + catch (Exception e) { + logger.error e.message + } + finally { + input.close() + output.close() + } + } + } +} \ No newline at end of file From 79369a709d15700bb32287e8eae78fdeb79183fb Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 12:50:08 +0200 Subject: [PATCH 26/53] downgradle gradle to 2.14.1 as 3.1 dropped java 6 support --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c50fb16b4..baf26ced7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Oct 16 10:05:35 CEST 2016 +#Sun Oct 16 12:48:59 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip From f59af4ecd5d746c06ef9429cf308be12e794ebcf Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 12:57:05 +0200 Subject: [PATCH 27/53] need to use buildscript block to add coveralls and bintray plugin to the classpath --- build.gradle | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d40f069d0..c222fcea2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,19 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.2' + classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3' + } +} + plugins { id "java" id "eclipse" id "idea" id "jacoco" - id "com.jfrog.bintray" version "1.7.2" apply false - id "com.github.kt3k.coveralls" version "2.6.3" apply false } group = 'org.jbake' From 63f15c9b64a68520aa33190588ef3dcc66bfd346 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 13:06:19 +0200 Subject: [PATCH 28/53] set default values to bintrayUsername and bintrayKey if properties do not exist --- gradle/publishing.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index 6678844ce..b764930e3 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -23,6 +23,9 @@ jar { } } +ext.bintrayUsername = project.hasProperty('bintrayUsername')?bintrayUsername:'' +ext.bintrayKey = project.hasProperty('bintrayKey')?bintrayKey:'' + bintray { user = bintrayUsername key = bintrayKey From a2672daa03eda907492d1758ca5e81daf479e432 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 13:19:17 +0200 Subject: [PATCH 29/53] let the signPom depend on maven install task --- gradle/publishing.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index b764930e3..500f6321d 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -37,6 +37,7 @@ bintray { from signPom into signPom.bintrayDestination } + signPom.dependsOn install bintrayUpload.dependsOn signPom } From 6d18c9ea31d04c12fd87daa88e03e41b2bc24bf6 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 15:08:46 +0200 Subject: [PATCH 30/53] added jade and groovy-mte example projects --- gradle/application.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gradle/application.gradle b/gradle/application.gradle index 0480f0c19..7914484c2 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -22,7 +22,9 @@ ext { exampleRepositories = [ "example_project_freemarker": "git://github.com/jbake-org/jbake-example-project-freemarker.git", "example_project_groovy" : "git://github.com/jbake-org/jbake-example-project-groovy.git", - "example_project_thymeleaf" : "git://github.com/jbake-org/jbake-example-project-thymeleaf.git" + "example_project_thymeleaf" : "git://github.com/jbake-org/jbake-example-project-thymeleaf.git", + "example_project_groovy-mte": "git://github.com/jbake-org/jbake-example-project-groovy-mte.git", + "example_project_jade" : "git://github.com/jbake-org/jbake-example-project-jade.git" ] } From 1db29fef9cd15a087df10c6ac75af0c5a393b9a2 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 15:46:24 +0200 Subject: [PATCH 31/53] added sdkman vendor pluging * run `gradlew sdkReleaseVersion` to release and anounce a new candidate * sdk tasks run a distributionAvaialable tasks to check if the archive is available --- build.gradle | 5 +++++ gradle/application.gradle | 4 ++++ gradle/sdkman.gradle | 31 +++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 gradle/sdkman.gradle diff --git a/build.gradle b/build.gradle index c222fcea2..88a12235a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,15 @@ buildscript { repositories { jcenter() + maven { + url "https://plugins.gradle.org/m2/" + } } dependencies { classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.2' classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3' + classpath "gradle.plugin.io.sdkman:gradle-sdkvendor-plugin:1.1.0" } } @@ -28,6 +32,7 @@ if( JavaVersion.current().java7Compatible ) { apply from: 'gradle/signing.gradle' apply from: 'gradle/maven-publishing.gradle' apply from: 'gradle/publishing.gradle' + apply from: 'gradle/sdkman.gradle' } sourceCompatibility = 1.6 diff --git a/gradle/application.gradle b/gradle/application.gradle index 7914484c2..953bd240b 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -79,3 +79,7 @@ distributions { } } } + +distZip { + classifier = "bin" +} diff --git a/gradle/sdkman.gradle b/gradle/sdkman.gradle new file mode 100644 index 000000000..cd9bc44ae --- /dev/null +++ b/gradle/sdkman.gradle @@ -0,0 +1,31 @@ +apply plugin: "io.sdkman.vendors" + +sdkman { + consumerKey = project.sdkman_consumer_key + consumerToken = project.sdkman_consumer_token + candidate = rootProject.name + version = rootProject.version + hashtag = "#JBake" + url = "http://jbake.org/files/${distZip.archiveName}" +} + +task distributionAvailable() { + group = "Verification" + description = "Check if distribution is available on bintray" + + doLast { + String errorMsg = "Distribution is not available at $sdkman.url" + + HttpURLConnection connection = sdkman.url.toURL().openConnection() + connection.setRequestMethod("HEAD") + connection.connect() + + if ( connection.responseCode != 200 ){ + throw new GradleException(errorMsg) + } + } +} + +tasks.findAll{ it.name ==~ /sdk.*(Release|Version)/ }.each { + it.dependsOn distributionAvailable +} \ No newline at end of file From 0f57a80d2656320821c8171d3c9a2df33ff0e18e Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 16 Oct 2016 15:51:50 +0200 Subject: [PATCH 32/53] added versions plugin to check dependency update * run `./gradlew dependencyUpdates` See https://github.com/ben-manes/gradle-versions-plugin --- build.gradle | 1 + gradle/sdkman.gradle | 3 +++ 2 files changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 88a12235a..bbbb8ee14 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,7 @@ plugins { id "eclipse" id "idea" id "jacoco" + id 'com.github.ben-manes.versions' version '0.13.0' } group = 'org.jbake' diff --git a/gradle/sdkman.gradle b/gradle/sdkman.gradle index cd9bc44ae..991444baa 100644 --- a/gradle/sdkman.gradle +++ b/gradle/sdkman.gradle @@ -1,5 +1,8 @@ apply plugin: "io.sdkman.vendors" +ext.sdkman_consumer_key = project.hasProperty('sdkman_consumer_key')?sdkman_consumer_key:'' +ext.sdkman_consumer_token = project.hasProperty('sdkman_consumer_token')?sdkman_consumer_token:'' + sdkman { consumerKey = project.sdkman_consumer_key consumerToken = project.sdkman_consumer_token From e1c51d9880c164bff35d9a87514abc71930f065d Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 17 Oct 2016 23:51:08 +0200 Subject: [PATCH 33/53] enable travis-ci cache for gradle See https://docs.travis-ci.com/user/languages/java/#Caching --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index ad3751863..222d55ea9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,3 +21,13 @@ after_failure: notifications: irc: "irc.freenode.org#anchos" + +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ + From d5e0bd69e392a80aed1ce4dd6951ade56bb366db Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 23 Jan 2017 21:20:57 +0100 Subject: [PATCH 34/53] update gradle wrapper to 3.3 --- gradle/wrapper/gradle-wrapper.jar | Bin 52928 -> 54208 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 19 +++++++++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 6ffa237849ef3607e39c3b334a92a65367962071..bad2fff9e55ff2c14605b68df11a595adf1c914f 100644 GIT binary patch delta 17812 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 delta 16531 zcmZ|01yo#5@-~dSyK5joAh-ku3l=oE2Z!J;gHDj(1Q{T>y99R&?(XjH5-dQzNp|=D z3%l>v=QK>8u6n9&b#>S6zFpt*VZW!sVkpYO!l6JxAt6DXm~l!+V^CuJ)2b~Kjf@u1 z;=6D>cZ7!ehjI-<2?Z%IzyClA9HiPgeq@FHFPi8fYLtJW{pN_iVf?EFE_l5_^iOB^ z%I6t82%bFzOB@QU)P)ZQkRpRr+?||FZ4@2t>`fh=Eliytzku$dF3#qrw$2vDhR$}5 zuZ^t@ot$!2Z0vAEv3v*^f_ld{3Jpr*7G^wDw?pm54M>n9LXg?zi{#~mZ46;QeseRi zi@qqk3bWxlN4(7ruM&x)g2p}V961794gmz3ZZ>ykPoV~YmNXH5$RJdBSS!XQo{BFK zcsweaGbiM@I`vjG7`@+XeLd0o3H8tan7J2#tCk5XST(AgVGaAiy zBHUm$TwVF#$raQRvX@X^(b6ego6cb?yVKB|R_h-Z)gr~tt}(@;%^Xr;Rqk9e;B>ib zVVVxwNUvOdUIaIbse;^CkKld!l9Mk{)rsPD-X5zo=rJT4ClDf_kt$R?`GU4=sbU2L z3ys!n8EA>s-w8!`+@o3LSae6tSLNTYba1H)v&NWh_)L*it@&RiRJ5X*nx zcS=Kz4k%ajlXW{otY5P<=@psp5Ccq*Q;-5X%7217P5U0z-+-V?MpB@}Tt%+j#~g#a zi6-vT0+;X6bQHXqC8Sx+)j~l*L}~KU4^oz{9FjDunpRF)aWUZF02M$H`&NE6U(x=d zUZR6s$+*6mD9EAfs&s-@J1bQ-UJs9;b`jkLH)}Xtv=4f-gx)Eet1XwgQo9Sr&BK zhoNm;qClt`{R>;U5bsH-S0I?5VtwwjU|y89zg)1Y=|d{aUp`odrf|)M00mWp3I)aa zFCVnWp#k+f;i-{5>2YwT%JCzM2V=nPLk+yZlGGJ>iH%M>?u#7q0uBbr)r>+Ktl)OE zPu)e1zvQNyQF37vw=G}H^{LP=S>3&|7aSzE#xEGDR~Y9dZyT+a zRn7oS)Jf*(TnL20(7aOQJXmm@InQ;QsK#fXF?$o=CPtMsWR`pnM?+jE(!P+g-Pe*E z4ZZ&(3AR@Cda2psCNVAdM5QZO*hEQ|Y1hNQP;``ej)QwAF*|!g_Lx7ePFCVD=cwFz zK5cZ+sAAH2NOT|DdIDy&q#s`-S3 zkNQ$5&cb>Aa?$&~J~_dfSD1MW%aLC-g_46@YN7i(%rcRBbWGJcJBO1Y!|V{vbjc&7 z2n_y!UV+Ko)j9hhE!QmR#{W-PUTtz+j)4HAb(|S>v6Ion+G<(BB%aK|4 zfyDVP%~|mp4oU89na2A4N~Lc$Xb-*$TPuk<3qsI{zva@dwO z108q8Tx&$h?x?lcdgKQ42cbVDwz78+@Obfl2lH@w zA`*tBj*Dwf`Vv(+15k*P=b?DNEL#3n<11bAj$4&ve9I0JrN)b7g5(r-(^W<+HOKYK zw;_c`#n(5>Q7_7U#-9?h-^JbZf!I{E(Y{k|sHIhg3YDp;JIu@#(5+qjW?6mpnzy+Z zI|}Un^kW!Vb`&`NmDakhP*3&Eakcd#N~r^1PazMdpaDs~SVdQ`R@Dnw*hA0F27|Q~ zcNH5IS~r5R73z2be{z-u^F->u=(EE>+Gxe&rnllM7#5{chKepl&+k!B@*a9cw z&6I}E;4cH%{C)i;eX4oS+%n0Kmp(U9mq*uebSdTMA&$COeu5+Oi)cu+LbZF`V%*hR z^uo?^|AEP1WqS*~y$au<15<%CEBWm(!$;WCoL(XnJ9M4mDU*tik&}jxQOp#u8uqhK zg3}cCA))}Gt5#b4o>!iVKLn)tOTrwWE|*dHdc+h)jWF}nX5ETECRi@x9;UXaWd~3+ zrRND90oI%mrqiiQdAs#3Ilkq%=$(`Vzbo>qS}U3li3JbDidx;qE7>*6CdX zPw|cSVfBLK^5QS;rTF86<*Bgk^?z}TuB(MG5QfI4Hv~-U>!+)FXq$mZZ8Ict9bv2v zPPW`9$*_`HjY~!N)2P~!@NiTzz-P8Z@4DLLHCRSeT)0a|ji$;t?m=rwir6ItHI|64 zRISlYL*tjQh}0ls~2a!%;FX?N5v+{fPifhN>83#eNnqW+>>hsz++d}~p% z)kf4!ky=WVmEhah0_>Q%OU!jGxQ8j>8%Y{Pjth3mM74gP%hbH2_M4b21k6i3>ig9S z*hnfFN*~%rSM^DS&_m7`Vi_SxnSfZAuF|49|L)P#KGjUh9X$edy!-bBwyoikzGc|` z-cpVM;nR4isI6&cpB{54s2;KOF)H^W;a*RJ^8-EO*O6qsF&zgmoe}77o)Di$pCNQT z$!N$c&K)Ggu>32$V09r@g&P#W{2i1$$Y?zCw zLiNJit`UCOG(XSW`3kFJz)GCPJ&2bC3tc*D4lC-6jq1R}EhhYk_GBbRyi_|(X1Y~T zXI#A`(uhS(NqUT7&eFT~Iq>2@h8&_$jp^D*#v8Ywe8Vt$1`R3 zSIViEzTV@{NvRNXY7kb2(8$-Gmk~4(ApImi7%pgwp8kB23=WF2GdRriehVtu^u+Ai-=x4-$_Z~7i zZ&cRrpp!Z`VRZ*gp^G*h?@FTbl#_}abceZ7SkErsekSY>?}knqmCXSarhn~s0yPAC z#)qepXBd6^af#yojd{%psP<`e`w|9NtO9iT6z@;ibC7Ehm8Zl|f{n8K)4lYHi_y!s zBmKguDt%U3O7_#p=8p+$q_fY>O6xOFrQ7E|D=$WeCsg5qsCH_%G@lnuCTgKdcaNbh z*Te8vurt)x7dyV*-YMVJ%Ox>={sDrjacJtugtFOn6%Kl|zHJcOI%Zyb%_C7f_}HwH zhK)^MWX~)@Uj8EKmhWWeRgN@63fh>0ZER0W2;*lr#wFYg+eFe`J*}~qp?bt?#kZDs z&DtwMEJ6+1>sASV=n+;2JiK;|)tQAZlRbIU$-La9b`8#A%Xu|&pNGF5HeG>|f+-G5 zENXDfN}S*)Z|{N37W?d0VHDD$7gmX0(ZG-S(FRH5Wbd74oawLZy9)ND_m-C>v-0LC zx@16nE4X1@KiDR%>q6ww_Z`+JN_9TC^ygsPL?UfB*rM`mjkIS?hOa2Th~si2wi*gn zB19qX-{Kd{TdbU}S272z!$g5DOSz2mYC`v8CL+fVH@V+5%$e#WH2*j+Z|AC*4<}|R zG;fNY%Q032U}5e@vv_pGo;v5x9&mu=I6u4zv!lU&M~Os-w#-2?l+*28Ta2KS`jTwH z&@~UI(X_|-)c{$3@;OOGNIgxgz=*2rKu(4d(Gjkhr%WsFOBy*`vI}-lXVH9f1+q%0 zV}7;kepvi#D|v}TdMWWAfhnS&%f#F+`)uiJ7ztocgE6u@*klzfuiUePMX)5`EZA_h zh=b%Z7Ambdo3=^w;H|@Lwc=H8InQtq#0rs0QfYrJO{}X9Ecx|MnqF~Kgy`dvEgFJH z!)V@`y_p0{GQ_c!wkElNKGECH8@Q54%c{E~A%s=}l8lxaQJv8RLzM#6yp9XMV2Jvx zTu&plUJHE^t#i(UVRLz5kR&8iG=0r9mN0Lj=~8h|-xZ!uJE2usN)Ok(?e)5mBZA$Jn4QUp&>x zrS+)dB8~SicBsv2Bde2njk?&PK4vkRa|;+Z#>o(6e_)Hr3zN=!iC$bmm{HjkN*XRc zB}Wh67hDoORf{xe0wSQ@b1OFt;3e^xla7{tMfP4xi)x`{whLEjx$+2k1xcA?&$*6P zaF@tMjOKN}tII$*Uu=2icNsm@VS#vP0&^wI^Qw~<2OwNY&hu}GtOe)Ne;d;dKj}#cz3?D>SEZOFAyz_w^6F-o zqjSLJ=im$<@!PO~v4INQfl^E@Mg zG2M9NulUBUZno7X?^r0SYAfrf6?QQ;rmvbU6Z0l6ulztVZJBOr{Bn;>k10Nx6I6oP z6E0W8ao;kn)I0(x)b=G?DZ+bI?FX_(i>i}t756>vOFEj=T7B(Q@90;u&vv&q&Eo9V zb<~~!tD(ntT{6S4CDMD|qT8$&Uo#}W#USm?)VQb>sNg+S4tU=2z`33Tq}an_dx)+t zsJe{S!o-z9s2M9{9I239v74eXeF38t@Z(@O7==zwW`q>H6nA^jph5U)p7_QfwngZ^YY7PvU0WD zcJ)*WP|!lsRB2LTfCEkzEg5b+T~gX7^ZfvX@VTRj!J04PfTI1RxOa5jdJ5=jETI++ z-FbnPMe47ln z)W6=Y*Qq__W^8IaDD+HZ4{*hS&?ztN;6MVLQvAk`<@YuowlX8+IKs`ZY~A1I3Xe;n z{8HauJ^#VfHtI%Gmj=`kxl7)Uj*=R#Ge1Jy4*zI#vwe%UT^U=LD=&YM0t(fDV<2-F zAX5M-Tg>+f`0dluZW7gX)0Yisi5oGkQD4rGQ0eQ+UR(J|7M_&bO5gcoAm+8&Ys1-DBG;Y75(U1j6mRWet zo%6LGO=(bRaKf1X+{w0{N*(0moR4Chqw=E&Nazroq<-Lt zY_KbvA!Mk-F&ic3MhTX38R*GLCaBf>Y2qYv*1uE%_a5jNN9(3*U>ankfQG+oQoODa zKDj)4lQkWinRz82eRWSqmV694%!o67yHg-b*Z*~1fV7{2bRw5&GBMvI2A??P4fKmb zo!5mtb!NYIqdChvMxck!DPAbxk%$2tck3?{6-9|!4h0mj6y&deXihk^9kM8ubIrna z+L?yxB4R0j@NoP9FyxX9XW-z3;(Tp(rM*8IO=`wthMzFruzw-p#$Q(fYNzJ?(pXa1 zU(;S5R)D*1T13iH_=(nm-O>k>qe(Phg)$CXNeF&lrZF_(TaN~XcM{4rFyiLz8>_|l zDKW<{zYGBt+LuW8>8m}@T*w)K=P4ROBJkV(c;>IjcoX#~sD7|Tu$J-3$+&MDUc_mT z=OG7KW2B3DlH84rbjw8KfhLHf3@L{5aGF!4d5v?HGNtRrO2w~}`?{`^-^G1w3(=*x z@=0s`L=nA%1pltxNlijnUN^{0S@sUh1x#SN+Gu;W0%2E8iqiJ2J`^o4o`Ue( zb{BtVZJlnYVe@n5ONBJ?(Oav_ux9t47G`Q}ZRuvOFA3aF-#mRCFlfz3k{RK*fAAmh zN&0}wvRjQFrCtn-zXOFmh^~(RG;cTIr?|quBh+^aP$*+TBDk8=J#FE7T_C4D_Wq+a zI@1KV-Jz{8CEt^W;(mS%byZ1bzj@u;qcC%t8fcQmwT@%1px1eK)v$q$0V6czJ4oYq zczF>fW2RH0^ez+l=0C^WSR|}*T}9dl%kTAw3O~Kh$h|^ujC=rPInR{vjy$33 zWFS&^i!Vs5=D@O9QPb^Hmz?=Y2DD0Gc9s->|FH5^@<~l#9SQ5iCE$aXv1KS6N z&3H9NPvwM@ArB1_YAQ(caQd_oGhN+{fUsy6*-qoG*$|I0zL{|Y*KdlO@0lk4{+mKj zp>XMBRrx1-n-Y)cgTYsb1$i?%bOrkMge(YD1hy=?IdfSW)wS;974mouiK6{eFA^u+S(#`Oc@#v5&XP#;;Daba6dd zpdhx@ul$J#1lQ_6@>w$xiWPq0w9em|N$q>1RD}<}z0Z*3GTQCco968>doB3G37;$f zBp@s6p5^p)2v&+*NfXPTb<1Y;ZQYxuoiSi$@sDcv#Al^t{>){CI|-N@_ECfsdW zKNfx)R;efX_NpXkbFD3K2HMj3Vv%HvxBldzX%FoMAILOnrbAQyGvU=_e%CngO2tXI zR6xWEp)l7bYNoFL0Ug$P9m*zFZafq|*%F_9b*EPQSC}f9DoP!nBIdo$Pm4qKEqrMt z!Wyy+3yeh@Ao*^y-V)4Q+&0H5drSiwfu7%2v9T7U^9L-)U_iPEhQoJPWc=)9%)?dG zu;n26U67AwkCC`H%Z3m4Of_wXC)VyPb*r7I+^JL-AeaG&bnQb_P0{%ixBSZR0UhQ` zFI1NsRP*Yltk)vC{WTRy+k4iIgIU9$?jd>zy@Fg}deC@}Yw;Nx``o~Wc-INcy`Zy7 zlepP^sXYPfw#T`^>maRB5K=+tZvGhQl?v&C1ZdB_Gtf0n*DRNJ#O4-fE?phCkKK6W zF!8gnr6G%L>iv2%BEzcZm=hbR$7i0%?C+!ONeI>Qh?e6178swo?BeLhbX+yJ`#-xU zjrvC^mp3$bd#vnAXB2v6^c&v?ZB;^C_W_7q-b{HG7dW-an<0du%m6ft9hnojhOC>U7LUq24l zr1;n*zj|-`bFyhgV(o=!xmy&!N!y`w)HL1xeC(C=#v-3 zk;p!&KOSON(_&x*`WQZJtOzvLm5c_*9w`+_b}fxxWRrX?-*2D-w%3j@uPJBJt_}XN z7eh3g-1&`x=&jZ@=O68D`Eg~X&)Qiwi8r=Midv=` zID&{@ei0k&N#Ny65;%ZFf7&Ttmob<=;chRjQXPOyeW9|nuw^r5pmn-%7_M7e>V_-a ztT7Fg<$js$PL>3NAFf6-PJ-ux-%tQRaTh4o=1-Z*T_15%3^}J#7_V3@0#P2V7U)sL zV~4q#>OS4-@2^f$EBogU4Sem|QqXpx=gXuy!idEh1L)6z{=fDvkXu-89^ zYhW#o8y!b+eoB7ojrel2MzsIH`l!D!L~1}T&Fzyw{G)s~>J?qS`T0l2JJJ4m`QgX% zs;cCl`=_05PG@gMwhl%BZakEyBTbG=$R%t}Y02z!sn^KiqVCLq%egRqkqcXj<#vez zRQr<3-SJW2MG!)5*G@J;Xj9W_@FqA5Kr7$>|doUS{Ic> zQS1iBIM4_IFN{y@KTq-G)&I!U=9$WisEVJt#?gAE{_4BML_qcMcvH27m`8fG{9*zD zGYN0z%j$ja)mh<*GEO@}3p&U$#-MX<`0tS z6qsws#6Brssnj8kc0fy z(N4sKpY2paU6=4HcWh-sI9*NvP;5{n{5fEhF!2$lOo*cECGhD5W;)8oBmfi`G>UN6 zKqWMa;N{!h#$Zg?+C{IoG5yv3M;uk_z)o8qj6UkxApq3Yck~hVHZZ&e7&7m~@p>~E z?Vg2L!(Oci5Gtw*9`nlKeFKZ|h?+Oz)iwZf9tt(f* z=!G)QuS3xnk(CPMd~`W14`5MKcMq~WbU?--w{oNt9c_q>cLH2%P4dGx9-ruH$8pxA zSXxS50q7>geMKeZK6G64sq2WUSMf^*dfdTWNVdzxmE{dZ%OY&S-tuf`6&6}RTZAVN z^GAW$r<^4f|CSFFDo%r7Fs0ux~bbG2+c`y3~r`hI~iq2+HC z6jH)dbaf^5-nHneCx*W)8)Rdyd_Vl7_$b;^JBiV@FF#3T>tl8h2FKevYP#wb>CAvQ zT#DN|MyU5HdzRJ}#yx0v%>f;|y0B{PJAFo=&03H7V!oO;0vQ|wLXl2xVX-sx({Fdw zBNsp#?~KzFMO6eoWW*?_ya|^+ORu0#W=Kb$Jea+7k9j5V>ZQcR0$p8Y5mqgGYXJJM zCX+sRw+NYF)&513CNbMrZrt$F%u$wQS!OG4KqB=s6usOhT~}a1RLvD}sj4B)#uxc@ z5C;$#6OL>*AG?a9Kq_vA{;DK3dtzRaTcw92Wi1fzy9@kk_l@TIP2us9=??}V>`K8J zgI?Jhkq17YYv+rRTs!8O*aX-$&hl&0EZzeWFW#2O)3S*?J`VD9lKPo({4FwP^3u>& zwTzuYC0q6yH)(dpT0V0gAZs_q89S*IwEl7E(H*`M;R&A8r$1aWQb=0#hzBLH8VQd# z|4b_~A*m-kc%SFXR2g1)Rau+a+Ui;zicfFxs(*}~R%4d8+1%PBikZW`dMjT`%!;(z zeLX)#@vXm~@Wy-S2d#E}KFSFq)U`5{r@%JEGfenjU2QL%F^CMK57(<2xygMrLCH0z zg6WgW_c`BkJ3VG5lXZySGFHsks5tUi74GV0S}=2OiO!x#j?NZlZ4{nPO9D%98@>{5 zX-Xh0WW5kQT@SZ(uY+=%tX7$6O6GFsW>aos)_=4u304)-VxHFg(P;lx$y*Yj#=X-L zP)yDDgJ5u>$*RaimQkVP!A6TC6+|-WRLlS7l-~La`iZ?YjmPdcet-?h$2(jJ@ys-X zm_myP(x1vc6nn;0R`V^TSLljQNLEZCFOR)s$Dtb~+f0M6^pqY=yX~k6iQI|Lz4p7+ zfNV&daqM%G@r!NITkfF&Ea#6jG5fZ{@C5EV(+Djqs+F(okkc0dZB#`|y&#YKGyS*1 z_6OtPoxo28v)F3>$Kq~{d(+}>4SO}>ZcTfh!9p8ZyjaVdS-jL;Er~PKwxdRQf%2Ei z6U#w9F=SLlq%PGkNrY4puQSZJNQziG>Y#p^W4lPe?Z7QjMbxgDy)aij5(9!ied|?3 zJ`;t5W2H!yI)g9K5_vR#cMWRsqsy)t-{NMFU~U;1$kO8{QIs`~Wiv9DXp+@fa)5n! zz0jB=_F^|XwZR-4J)kc9EMC7m)ck?z?f9G;S5IGXSUpyle&@g*{s!JSSEQN|vG(vJ zU)2X3j;Is(}=1jIwHKdLYO zB=TI<6TiAQtrQO5Jp<5uS^c1?u<3eXM*Dcb=o>dDJ-#fV?77EugR?8tc;XG@yf#Ka zw5LGae=vN@7Z6rY$vR&1QhduxysQK1OW3=Sb+}YtO^1gU6&qaznZh2W7F#;9lMN(E ziwq(aLZR9Z^!aePo%kTGk?d60S|#nFY~$DJt))@HKD>{Pf-p~bb0Yk6p=vzw*^7~$ z4mfty%XV}FQkVW+l&t#-p@PBR1K%$0R&3I5nVWlJ3%qAGm@Uved2RIGCFu%00nHUN z;Fwh678|eD|6saN;E^&?(SJx#?iQ=tQYK80-Yay!3PQes8a)O%3vkDdqnp#T(_iEk z=G1<+go0ClKW;=+JBfA~9JtbVio5;-$cJUo3ysFd3)wJkpT zKIt|CF8aHIfg~2^PtXIEi8sUoCq!R;+Ep zZc${Jxbn?UW%F*ZF2k)2x9GQxwag}1l@pG4WI6*hY0b$TYKB01BPq-bAeVrDdV z(2l|6Cb&^znah%Dm+fDGt2%x2Q|M~+ zmzN{OcgY8D;zkF}E;n&6jjkJU02QbsI1|wr+r&7ShR~N-49%DWsOWLW(34vu&Plxy zjHJ_Lf|hNcWpAn&)qazG*40Sl9~onww_uOg+qG7YMrqlJdDhAEfFw+CZjTokd_PX) zScNllndDKTFqsvuY(i@dGOUu z=))OlZ5k|yZy2jXtZ#D!*N3#Id>u z&M`Wh>awPfcuJ1&OiBr6E3&m*y&JopO?LFjVjnuIA8)d_w6{>ErhuzLf0<5^=L_Bq zPzNnBx!Nl3nG=|fG2RE-gn^cM1}h%OQ6gV{<FP1Y+ki5Qdnw&1VC3O@=h(~T)D42ZDKKu5R1l58 zNjxRs*on0Ovx?8??b3Jpp%9F^cz>Qo)c`gt>TEX#GADMNrKO5pC{ zZEgYRvp%PGsgZM|0^pI}&&{PdNagq480-i2-qSNra>@-%e$Z3!BsSy{%==p>ILgBW zY+=)*T|+j5g*;Y;cck=FKfX*Z6Aww+tM|U-BW%}qe!$;NY=9jRQ_rNTees=tHFrJ# zR<3vV_HFNK*Y+poMq@?_uzUo!s%Di5HnOA70GS2ew^n;HzhRHO^<>zsw2t^ZM2Sh3 zR&%@0F_pbvcjZB#GU{@e4RJmS4*Frqg%L`#jm34J0|lNp+ysS1&1+o+rwB}+55dC< zr9GSZ!%P@cG8(>v=u4LPuqm%XoOU(GYh+s+X3u&PiD;9#!vG(7&vJ%!FOU~Zh%Xx~ zhmjM9?x;xV-d!He`f;@=bJz;$_xJc6sntCw&&%qL5vzcVo8%7ghYuX=DICj0R$TX^ z5UofnPhkWMo`NHGb{eg~=o;gG;V9o2q@}Ws-P~z;&qSF%_Mk^6R@7q-+4y^MH}M&?qt{m>~{ zMmZ|B_+kun(uQRIW2hkkT^qGr3+C!^)h^ycqwa$v$u=75moDndf`aldnEez&ViV>z zc3+#&4Hk85+&k5@^&I2kZ*+6FCHi)qgMWF?^~^8MFNP6_&#feA3&X}Wx+Aa@o)8Bp zBikToGhwHR^2M2_idr3@(NK<8!V56yyrB&DLd?|z?XL#gWl>)6ZOFfU4#}oenk=r-N0I>X;uA$ zGaKg<3C#kddFCK^mct4yMy=KKQ~axpC1MYQ!3dt8LVcCslh$ znF98;AhVo6GlE&P^GWT`rP^-=Q1yx?=U%s1;R}g5Th&wdxP(U|IYC3mT1JTj31%Zx z?oad8+PL;t`Zb{Rmv8DVuj~4&t71L` zRm4?HD~GR*m`Cz4j=NQ~++?(Pmi&?$NSzULc>7;E54yIBS1m6FZW8 zz4Eq_viv%Qj~ZWz>$;wig<&(u5Hk=fYges4QlHxcgNVqhDc$ErDO-tisTJ&VgQ&Zu z_eKdnEl|aD$;$(oCa4%{XGxKwV2-luUG5_RhFWXH#-be5ty8oBNnBeQ^z+!3jY<6X z70?)C8B$`%HeVJK3X1w)+k5~i66jx-j6Z9Hfbc#N`OugiKdeyi#aha0Nr13E~RgCT?Q7DwoiM`ah z(pApgy+peS&*{biBw5G3cwSoF8fW$4WlXn8p~JTxP%ES2O@4L-K$un4bCwj)iZMVRkbsaApEMv87%z!{@cvZ$=m4gd{Y4JW-ktvXjo#NVWgQ$FFP4B z`8n4v)vTlFR_S*N^1&Q zCVnYSJ_%17CPk-_K`xfe>+QLgClBexILvC7;8`9hfXf=3;6iGQ9xeu$gEQi_kLBKe#fkn5*rl*|T)!D(SXQH)^E^8||+EA#9;jkclBsuwhrCNe#*+W7!XoAiv zr}aM9x-;{%XQ5P_+LX_>hk4$%WI8V6L?DgJ(P%vS92a?b(AGH5YA!F$6yPq<)N#hg zO?vso5HmjlXK(1i+Q(Mm)1d&MBWmcOBbK_uZeU(rTb$Q&8}wO8dFQou&BeEXT1Nob zo%gF-qKBA%hKsOM7jSkKNH-`)%jma_p&xiyYWkR%%L9dfi9K=TXoig!f_*!V{XoI9oPdZm~ z;4EDUW2c}N{kMQVM}h@Hm;4r)3Vm@g?n3>ZbnXXuyT04vz_xXHbWrah$rClsN&6D0 z1g=p%Dek*9lL8?V&b;HjJf?G8Hc7=vduzoc@t*TScIrsf&7vCj7J9Lwz2h~*KJz9E zy4@xdKBx?q&9JbFq?p;RkwT!BHGkw%C$6!`JQU4{ee_e+&*~16IoO1 z-dCkT@#wKKIRT%nDr!|3)h%^puNJgPLuSgf;y`0E_s#usSz3(RI6NixN-ARu2W906 z?7S*HkM0B)D6ba})|7vd&h){lsYxLp7ICQR@XStOR}n1gkzrc< z*1^LJUM|S!#7;aMgyRs-aXUoX_dc&TrE+~m&@U**|hK8jAer;E%PLVo$ zTn~CzlE`KGPVnfMfYL>>s+M92?c?}J{Z{f&b(ay%Cxlj8hWBPHy#*~=dQssj@wH zfIgWI^S18gb846!_3^&J$vH`@I&-;6lMn;Bt!mveqNJRcEVsMD`dRZj+?WNF!$+9+ zl1Nr#kk^A>ElUUlufIMmZCtrzb*IJl9VHDRBH`QV{f5_0v}-iGV1GuoHE7-pMMup- z?TlgB?Mdqfo$BRimpfaqtMuw14j@yHh`YpMt>9EQw>qWsy$Gh-e_60aR`shZNYrQ2Q%PhrMm=2LIP0yA7F^uuUa9r_302k37V}=785L!M2 z)m&lBY7nObH`)N&3PD107GnS#RL@OAI7VQUR#|$N#ZeI8S{N-N&S>Cm^s(>e z1^pk`wV;}6+GkN$W zuQ6Pbrm5E8i7^tUjLR!f+O>KeK{*RfJsKSj1J!~X@v=9(b83&gzxJbxR*6)#>_^}f zl)}YlsHYEC_eM07RHR)XIUx?tPi}_zu12)3(YUAdGEEH}edAaS_N39PodGMLFL3Ue zVBDK%bc}{us`*7-VY)WGe0N1zjdrx~&aic3Q#&8Nb;D(h8S` zuQB|Bspb|hkW5$+B1kLwsz*uC%qRDjMJ6nA>=Y^q|9(OA`}8lE=dT!GA!D_Fe@U2v zq(QAa2MD-85~hM6l?VzPHAw>E?i0l5U_%pG7t|1a%aeCUTv_g7=!^QIf|iC`emW$-!7)#42&8j%Q-svPTgA7K7z7@T}k6F6Wur0-rK*{-!T8J9ySV zWIX?@Ee!EFIf-ycjHgNf;txc{X}KowH) zepCLt7QpH z{=-o13kCC^d_=7O&PN0)WBL1e|D-WMzO5cHLP1eIqlKk{2q1u*G9rN4`cR)~P~P)f16|HP8m#v`GvM z{A-W;-!8HFc}$-I!a)Y9&u78N2e5rV(|=U^y-+=mOn-}E(SyV(GNyl4hu`GC2_O;T zPl0Tg|6P7h$T>Z5d;kAg>NoAPaPl8g$bX1C>w}})IKiKW{?EC7(}S%Ce-CYpA(+~U z7F;}t_P3tOZ;{ChAd+t&z6E#&=414S{!=k2*58KsgZO&#||9IXXFzk`vU@(?{#3_zY{|!cFMNlye0a}Ep$NLQI zh2tOL1rzwsz!ZmngGsvl0gD`_{Tu9`nD^gvC;$l2jN#d&`>oou5co{Gwhu%A|Nk)P z0BsXu5uu=ZvHx3w#wRc+gXaI?Sij|jiE>+eK}?1U@nimHa#(}G6fS_@Bl`D)a9C^9 z%0R3F2MOSk&*))8|2%k+9o_#9TFW2PRD?q)Xuv;*QU6BN#}t~#h9ELRl;?bgsGI%= zam@_pf1Xxq-0Ua@!juA0<2jRJ7KDir{Bi*MZy`YX4OIik%18o Date: Mon, 23 Jan 2017 21:47:43 +0100 Subject: [PATCH 35/53] update gradle plugins --- build.gradle | 6 +++--- gradle/application.gradle | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index bbbb8ee14..3733ee01b 100644 --- a/build.gradle +++ b/build.gradle @@ -7,9 +7,9 @@ buildscript { } dependencies { - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.2' - classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3' - classpath "gradle.plugin.io.sdkman:gradle-sdkvendor-plugin:1.1.0" + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.7.1' + classpath "gradle.plugin.io.sdkman:gradle-sdkvendor-plugin:1.1.1" } } diff --git a/gradle/application.gradle b/gradle/application.gradle index 953bd240b..311483a2f 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'org.ajoberstar:grgit:1.5.0' + classpath 'org.ajoberstar:grgit:1.6.0' } } From 9ffc0ed9f30c39e416aa40e14ff9921bbcfcc9b5 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 23 Jan 2017 22:11:07 +0100 Subject: [PATCH 36/53] removed openjdk6 from travis build. added oraclejdk8 instead. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 222d55ea9..1e5210075 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,10 @@ addons: hostname: short-hostname jdk: - - openjdk6 - openjdk7 - oraclejdk7 - + - oraclejdk8 + install: true script: From a8361480ac8c13266cbef1e0e34e5f3f5fc9be50 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Tue, 18 Apr 2017 18:16:25 +0200 Subject: [PATCH 37/53] rebase to master --- build.gradle | 40 +++++++------- src/test/java/org/jbake/app/CrawlerTest.java | 31 ++++++----- .../AbstractTemplateEngineRenderingTest.java | 52 +------------------ 3 files changed, 38 insertions(+), 85 deletions(-) diff --git a/build.gradle b/build.gradle index 3733ee01b..547dcd874 100644 --- a/build.gradle +++ b/build.gradle @@ -44,29 +44,32 @@ repositories { } ext { - commonsIoVersion = '2.4' - commonsConfigurationVersion = '1.9' + asciidoctorjVersion = '1.5.4.1' + commonsIoVersion = '2.5' + commonsConfigurationVersion = '1.10' + commonsLangVersion = '3.4' + commonsVfs2Version = '2.1' + args4jVersion = '2.33' + freemarkerVersion = '2.3.25-incubating' + junitVersion = '4.12' + pegdownVersion = '1.6.0' + jettyServerVersion = '8.1.19.v20160209' + orientDbVersion = '1.7.10' + groovyVersion = '2.4.8' + slf4jVersion = '1.7.22' + logbackVersion = '1.1.9' + assertjCoreVersion = '1.7.1' + thymeleafVersion = '3.0.3.RELEASE' jsonSimpleVersion = '1.1.1' - args4jVersion = '2.0.26' - freemarkerVersion = '2.3.20' - orientDbVersion = '1.6.4' - pegdownVersion = '1.4.2' - asciidoctorjVersion = '1.5.2' - jettyServerVersion = '8.1.12.v20130726' - groovyVersion = '2.4.1' - thymeleafVersion = '2.1.3.RELEASE' - thymeleafExtrasVersion = '2.1.1.RELEASE' - slf4jVersion = '1.7.6' - logbackVersion = '1.1.1' - jade4jVersion = '0.4.2' - commonsVfs2Version = '2.0' - junitVersion = '4.11' - assertjCoreVersion = '1.7.0' + jade4jVersion = '1.2.5' + mockitoVersion = '1.10.19' } dependencies { compile group: 'commons-io', name: 'commons-io', version: commonsIoVersion compile group: 'commons-configuration', name: 'commons-configuration', version: commonsConfigurationVersion + compile group: 'org.apache.commons', name: 'commons-vfs2', version: commonsVfs2Version + compile group: 'org.apache.commons', name: 'commons-lang3', version: commonsLangVersion compile group: 'com.googlecode.json-simple', name: 'json-simple', version: jsonSimpleVersion compile group: 'args4j', name: 'args4j', version: args4jVersion compile group: 'org.freemarker', name: 'freemarker', version: freemarkerVersion @@ -78,15 +81,14 @@ dependencies { compile group: 'org.codehaus.groovy', name: 'groovy', version: groovyVersion compile group: 'org.codehaus.groovy', name: 'groovy-templates', version: groovyVersion compile group: 'org.thymeleaf', name: 'thymeleaf', version: thymeleafVersion - compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-conditionalcomments', version: thymeleafExtrasVersion compile group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion compile group: 'org.slf4j', name: 'jul-to-slf4j', version: slf4jVersion compile group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion compile group: 'ch.qos.logback', name: 'logback-core', version: logbackVersion compile group: 'de.neuland-bfi', name: 'jade4j', version: jade4jVersion - compile group: 'org.apache.commons', name: 'commons-vfs2', version: commonsVfs2Version testCompile group: 'junit', name: 'junit', version: junitVersion testCompile group: 'org.assertj', name: 'assertj-core', version: assertjCoreVersion + testCompile group: 'org.mockito', name: 'mockito-core', version: mockitoVersion } jacoco { diff --git a/src/test/java/org/jbake/app/CrawlerTest.java b/src/test/java/org/jbake/app/CrawlerTest.java index 542c12e27..38737dce0 100644 --- a/src/test/java/org/jbake/app/CrawlerTest.java +++ b/src/test/java/org/jbake/app/CrawlerTest.java @@ -1,12 +1,5 @@ package org.jbake.app; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.File; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.MapConfiguration; @@ -19,6 +12,13 @@ import org.junit.Before; import org.junit.Test; +import java.io.File; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + public class CrawlerTest { private CompositeConfiguration config; private ContentStore db; @@ -33,7 +33,7 @@ public void setup() throws Exception { throw new Exception("Cannot find sample data structure!"); } - config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); + config = ConfigUtil.load(sourceFolder); Assert.assertEquals(".html", config.getString(Keys.OUTPUT_EXTENSION)); db = DBUtil.createDataStore("memory", "documents" + System.currentTimeMillis()); } @@ -81,23 +81,22 @@ public void crawl() throws ConfigurationException { @Test public void renderWithPrettyUrls() throws Exception { Map testProperties = new HashMap(); - testProperties.put(Keys.URI_NO_EXTENSION, "/blog"); + testProperties.put(Keys.URI_NO_EXTENSION, true); + testProperties.put(Keys.URI_NO_EXTENSION_PREFIX, "/blog"); CompositeConfiguration config = new CompositeConfiguration(); config.addConfiguration(new MapConfiguration(testProperties)); - config.addConfiguration(ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile()))); + config.addConfiguration(ConfigUtil.load(sourceFolder)); - URL contentUrl = this.getClass().getResource("/fixture"); - File content = new File(contentUrl.getFile()); - Crawler crawler = new Crawler(db, content, config); - crawler.crawl(new File(content.getPath() + File.separator + "content")); + Crawler crawler = new Crawler(db, sourceFolder, config); + crawler.crawl(new File(sourceFolder.getPath() + File.separator + config.getString(Keys.CONTENT_FOLDER))); - Assert.assertEquals(2, db.getDocumentCount("post")); + Assert.assertEquals(4, db.getDocumentCount("post")); Assert.assertEquals(3, db.getDocumentCount("page")); + DocumentList documents = db.getPublishedPosts(); for (Map model : documents) { - String noExtensionUri = "blog/\\d{4}/" + FilenameUtils.getBaseName((String) model.get("file")) + "/"; Assert.assertThat(model.get("noExtensionUri"), RegexMatcher.matches(noExtensionUri)); diff --git a/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java index 1cad7b53d..56d2c7ab3 100644 --- a/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java @@ -25,45 +25,16 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FileUtils; -<<<<<<< HEAD -import org.jbake.app.ConfigUtil; -import org.jbake.app.ContentStore; -import org.jbake.app.Crawler; -import org.jbake.app.DBUtil; -import org.jbake.app.Parser; -import org.jbake.app.Renderer; -import org.jbake.model.DocumentTypes; -import org.jbake.template.ModelExtractorsDocumentTypeListener; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -======= import org.jbake.app.*; import org.jbake.model.DocumentTypes; +import org.jbake.template.ModelExtractorsDocumentTypeListener; import org.junit.*; import org.junit.rules.TemporaryFolder; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.*; - -import static org.assertj.core.api.Assertions.assertThat; ->>>>>>> 48e3cb8... added gradle application distribution - import java.io.File; import java.net.URL; import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import static org.assertj.core.api.Assertions.assertThat; @@ -84,12 +55,9 @@ public abstract class AbstractTemplateEngineRenderingTest { protected final String templateDir; protected final String templateExtension; protected final Map> outputStrings = new HashMap>(); -<<<<<<< HEAD private Crawler crawler; private Parser parser; protected Renderer renderer; -======= ->>>>>>> 48e3cb8... added gradle application distribution protected Locale currentLocale; public AbstractTemplateEngineRenderingTest(String templateDir, String templateExtension) { @@ -98,7 +66,6 @@ public AbstractTemplateEngineRenderingTest(String templateDir, String templateEx } @Before -<<<<<<< HEAD public void setup() throws Exception { currentLocale = Locale.getDefault(); Locale.setDefault(Locale.ENGLISH); @@ -106,15 +73,7 @@ public void setup() throws Exception { ModelExtractorsDocumentTypeListener listener = new ModelExtractorsDocumentTypeListener(); DocumentTypes.addListener(listener); - URL sourceUrl = this.getClass().getResource("/"); -======= - public void setup() throws Exception, IOException, URISyntaxException { - - currentLocale = Locale.getDefault(); - Locale.setDefault(Locale.ENGLISH); - URL sourceUrl = this.getClass().getResource("/fixture"); ->>>>>>> 48e3cb8... added gradle application distribution sourceFolder = new File(sourceUrl.getFile()); if (!sourceFolder.exists()) { @@ -138,7 +97,6 @@ public void setup() throws Exception, IOException, URISyntaxException { } } Assert.assertEquals(".html", config.getString(ConfigUtil.Keys.OUTPUT_EXTENSION)); -<<<<<<< HEAD db = DBUtil.createDataStore("memory", "documents"+System.currentTimeMillis()); crawler = new Crawler(db, sourceFolder, config); @@ -186,19 +144,13 @@ private void setupExpectedOutputStrings() { "blog/2012/first-post.html", "papers/published-fixture.groovyMarkupTemplates.paper.html")); -======= - db = DBUtil.createDataStore("memory", "documents" + System.currentTimeMillis()); ->>>>>>> 48e3cb8... added gradle application distribution } @After public void cleanup() throws InterruptedException { db.drop(); db.close(); -<<<<<<< HEAD db.shutdown(); -======= ->>>>>>> 48e3cb8... added gradle application distribution Locale.setDefault(currentLocale); } From eccba0ef17d2ba1a80bc394154add817e0729981 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 22 Apr 2017 14:14:26 +0200 Subject: [PATCH 38/53] removed javadoc errors and warnings --- gradle/wrapper/gradle-wrapper.jar | Bin 54208 -> 54208 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/org/jbake/launcher/Main.java | 8 ++++---- .../org/jbake/template/ModelExtractors.java | 4 ++-- .../java/org/jbake/app/ConfigUtilTest.java | 6 +++--- ...oovyMarkupTemplateEngineRenderingTest.java | 7 ++++--- .../java/org/jbake/launcher/MainTest.java | 2 +- .../jbake/render/DocumentsRendererTest.java | 4 +--- .../org/jbake/render/TagsRendererTest.java | 4 ++-- 9 files changed, 18 insertions(+), 19 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index bad2fff9e55ff2c14605b68df11a595adf1c914f..c78c0c498f3861383687cf36e76ef7aeba1be5ac 100644 GIT binary patch delta 26 gcmX@GocX|V<_*z@m=8>vv^nmOkRXULx%jd#0INg{i~s-t delta 26 gcmX@GocX|V<_*z@m^)XQZ;m@8BnV...]\n\n"); sw.append("Options:"); System.out.println(sw.toString()); - parser.setUsageWidth(100); + parser.getProperties().withUsageWidth(100); parser.printUsage(System.out); } diff --git a/src/main/java/org/jbake/template/ModelExtractors.java b/src/main/java/org/jbake/template/ModelExtractors.java index 3041349cf..9e4cd8c89 100644 --- a/src/main/java/org/jbake/template/ModelExtractors.java +++ b/src/main/java/org/jbake/template/ModelExtractors.java @@ -126,9 +126,9 @@ public Type extractAndTransform(ContentStore db, String key, Map map, Tem } /** - * @param key Key for lookup - * @return True if the key is contained by this object * @see java.util.Map#containsKey(java.lang.Object) + * @param key A key a {@link ModelExtractor} is registered with + * @return true if key is registered */ public boolean containsKey(Object key) { return extractors.containsKey(key); diff --git a/src/test/java/org/jbake/app/ConfigUtilTest.java b/src/test/java/org/jbake/app/ConfigUtilTest.java index 5362c0058..47ee8ddc0 100644 --- a/src/test/java/org/jbake/app/ConfigUtilTest.java +++ b/src/test/java/org/jbake/app/ConfigUtilTest.java @@ -1,11 +1,11 @@ package org.jbake.app; -import java.io.File; - import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ConfigUtil.Keys; import org.junit.Test; +import java.io.File; + import static org.junit.Assert.assertEquals; public class ConfigUtilTest { @@ -22,5 +22,5 @@ public void load() throws Exception { assertEquals("http://www.jbake.org", config.getString(Keys.SITE_HOST)); - } + } } diff --git a/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java index c377d5763..45c722eac 100644 --- a/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java @@ -10,6 +10,7 @@ import org.junit.Test; import java.io.File; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.Map; @@ -42,7 +43,7 @@ public GroovyMarkupTemplateEngineRenderingTest() { outputStrings.put("sitemap", Arrays.asList("blog/2013/second-post.html", "blog/2012/first-post.html", "papers/published-fixture.groovyMarkupTemplates.paper.html")); - outputStrings.put("fixture.groovyMarkupTemplates.paper", Arrays.asList("

Published Paper

", + outputStrings.put("paper", Arrays.asList("

Published Paper

", "

24", "2014

", "Lorem ipsum dolor sit amet", @@ -72,8 +73,8 @@ public void renderCustomTypePaper() throws Exception { Assert.assertTrue(outputFile.exists()); // verify - String output = FileUtils.readFileToString(outputFile); - for (String string : getOutputStrings("fixture.groovyMarkupTemplates.paper")) { + String output = FileUtils.readFileToString(outputFile, Charset.defaultCharset()); + for (String string : getOutputStrings("paper")) { assertThat(output).contains(string); } diff --git a/src/test/java/org/jbake/launcher/MainTest.java b/src/test/java/org/jbake/launcher/MainTest.java index 84915989b..04134906d 100644 --- a/src/test/java/org/jbake/launcher/MainTest.java +++ b/src/test/java/org/jbake/launcher/MainTest.java @@ -90,7 +90,7 @@ public void launchJettyWithCustomSrcAndDestDir() { @Test public void launchJettyWithCustomDestViaConfig() throws CmdLineException { String[] args = {"-s"}; - Map properties = new HashMap(){{ + Map properties = new HashMap(){{ put("destination.folder", "build/jbake"); }}; main.run(stubOptions(args), stubConfig(properties)); diff --git a/src/test/java/org/jbake/render/DocumentsRendererTest.java b/src/test/java/org/jbake/render/DocumentsRendererTest.java index d60e1b828..2eab6bbc6 100644 --- a/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -17,9 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.anyMap; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class DocumentsRendererTest { diff --git a/src/test/java/org/jbake/render/TagsRendererTest.java b/src/test/java/org/jbake/render/TagsRendererTest.java index 2b6a97ecb..d7414b23e 100644 --- a/src/test/java/org/jbake/render/TagsRendererTest.java +++ b/src/test/java/org/jbake/render/TagsRendererTest.java @@ -53,7 +53,7 @@ public void returnsOneWhenConfigRendersIndices() throws Exception { ContentStore contentStore = mock(ContentStore.class); Renderer mockRenderer = mock(Renderer.class); - Set tags = new HashSet(Arrays.asList("tag1", "tags2")); + Set tags = new HashSet(Arrays.asList("tag1", "tags2")); when(contentStore.getTags()).thenReturn(tags); when(mockRenderer.renderTags("random string")).thenReturn(1); @@ -72,7 +72,7 @@ public void doesRenderWhenConfigDoesNotRenderIndices() throws Exception { ContentStore contentStore = mock(ContentStore.class); Renderer mockRenderer = mock(Renderer.class); - Set tags = new HashSet(Arrays.asList("tag1", "tags2")); + Set tags = new HashSet(Arrays.asList("tag1", "tags2")); when(contentStore.getTags()).thenReturn(tags); int renderResponse = renderer.render(mockRenderer, contentStore, From 50d22e644d40a278cdbbeab2c3d6840394270e0f Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 22 Apr 2017 14:20:50 +0200 Subject: [PATCH 39/53] update gradle wrapper to 3.5 --- .gitignore | 1 + gradle/wrapper/gradle-wrapper.jar | Bin 54208 -> 54783 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index bb7438b2e..82ab65eb3 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ *.iws build/ .gradle +.gradletasknamecache diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c78c0c498f3861383687cf36e76ef7aeba1be5ac..77e62611b2681eb6ee5f660571e5b33fee24fdd4 100644 GIT binary patch delta 6636 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 Date: Sun, 23 Apr 2017 15:23:06 +0200 Subject: [PATCH 40/53] update coveralls and versions gradle plugins --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 547dcd874..212a70e21 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { dependencies { classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' - classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.7.1' + classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.1' classpath "gradle.plugin.io.sdkman:gradle-sdkvendor-plugin:1.1.1" } } @@ -18,7 +18,7 @@ plugins { id "eclipse" id "idea" id "jacoco" - id 'com.github.ben-manes.versions' version '0.13.0' + id 'com.github.ben-manes.versions' version '0.14.0' } group = 'org.jbake' From 5fab71155c1f8e3cf2b9bc7676a56565a2aceb46 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 24 Apr 2017 19:54:32 +0200 Subject: [PATCH 41/53] set source and target compatibility to 1.7. moved some variables to gradle.properties --- build.gradle | 31 +++++++------------------------ gradle.properties | 7 ++++++- gradle/maven-publishing.gradle | 2 +- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/build.gradle b/build.gradle index 212a70e21..8746d9d00 100644 --- a/build.gradle +++ b/build.gradle @@ -1,31 +1,14 @@ -buildscript { - repositories { - jcenter() - maven { - url "https://plugins.gradle.org/m2/" - } - } - - dependencies { - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' - classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.1' - classpath "gradle.plugin.io.sdkman:gradle-sdkvendor-plugin:1.1.1" - } -} - plugins { id "java" id "eclipse" id "idea" id "jacoco" - id 'com.github.ben-manes.versions' version '0.14.0' + id "io.sdkman.vendors" version "1.1.1" apply false + id "com.jfrog.bintray" version "1.7.3" apply false + id "com.github.kt3k.coveralls" version "2.8.1" apply false + id 'com.github.ben-manes.versions' version '0.14.0' } -group = 'org.jbake' -version = '2.6.0-SNAPSHOT' - -description = """jbake""" - if( JavaVersion.current().java7Compatible ) { apply plugin: 'com.github.kt3k.coveralls' apply plugin: 'com.jfrog.bintray' @@ -36,8 +19,8 @@ if( JavaVersion.current().java7Compatible ) { apply from: 'gradle/sdkman.gradle' } -sourceCompatibility = 1.6 -targetCompatibility = 1.6 +sourceCompatibility = 1.7 +targetCompatibility = 1.7 repositories { jcenter() @@ -92,7 +75,7 @@ dependencies { } jacoco { - toolVersion = '0.7.7.201606060606' + toolVersion = jacocoVersion } jacocoTestReport { diff --git a/gradle.properties b/gradle.properties index 06f4a68bd..6c88d0a76 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,13 @@ -project_description=JBake is a Java based open source static site/blog generator for developers. +group=org.jbake +version=2.6.0-SNAPSHOT +description=JBake is a Java based open source static site/blog generator for developers. + website=http://jbake.org issues=https://github.com/jbake-org/jbake/issues vcs=https://github.com/jbake-org/jbake/ +jacocoVersion=0.7.9 + bintrayDryRun=false bintrayOrg=jbake bintrayRepo=maven diff --git a/gradle/maven-publishing.gradle b/gradle/maven-publishing.gradle index 6060c5801..9244eedd6 100644 --- a/gradle/maven-publishing.gradle +++ b/gradle/maven-publishing.gradle @@ -4,7 +4,7 @@ ext.isReleaseVersion = !version.endsWith("SNAPSHOT") def jbakePom = pom { project { - description project.project_description + description project.description url project.website developers { developer { From eba9368facd42da81b52c0106fef071c91bc81cc Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 8 May 2017 20:18:45 +0200 Subject: [PATCH 42/53] make OvenTest green again --- build.gradle | 5 +- pom.xml | 556 ------------------ .../assembly-example-project-groovy-mte.xml | 19 - src/test/java/org/jbake/app/OvenTest.java | 2 +- 4 files changed, 3 insertions(+), 579 deletions(-) delete mode 100644 pom.xml delete mode 100644 src/main/assembly/assembly-example-project-groovy-mte.xml diff --git a/build.gradle b/build.gradle index 8746d9d00..4d6de5416 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ ext { junitVersion = '4.12' pegdownVersion = '1.6.0' jettyServerVersion = '8.1.19.v20160209' - orientDbVersion = '1.7.10' + orientDbVersion = '2.2.15' groovyVersion = '2.4.8' slf4jVersion = '1.7.22' logbackVersion = '1.1.9' @@ -56,8 +56,7 @@ dependencies { compile group: 'com.googlecode.json-simple', name: 'json-simple', version: jsonSimpleVersion compile group: 'args4j', name: 'args4j', version: args4jVersion compile group: 'org.freemarker', name: 'freemarker', version: freemarkerVersion - compile group: 'com.orientechnologies', name: 'orient-commons', version: orientDbVersion - compile group: 'com.orientechnologies', name: 'orientdb-core', version: orientDbVersion + compile group: 'com.orientechnologies', name: 'orientdb-graphdb', version: orientDbVersion compile group: 'org.pegdown', name: 'pegdown', version: pegdownVersion compile group: 'org.asciidoctor', name: 'asciidoctorj', version: asciidoctorjVersion compile group: 'org.eclipse.jetty', name: 'jetty-server', version: jettyServerVersion diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 9f4456b42..000000000 --- a/pom.xml +++ /dev/null @@ -1,556 +0,0 @@ - - - 4.0.0 - - - org.sonatype.oss - oss-parent - 7 - - - org.jbake - jbake-core - 2.5.1 - jar - - jbake - JBake is a Java based open source static site/blog generator for developers. - http://jbake.org - - - jonbullock - Jonathan Bullock - jonbullock@gmail.com - http://jonathanbullock.com - 0 - - - - - https://github.com/jbake-org/jbake/ - scm:git:git@github.com:jbake-org/jbake.git - scm:git:https://github.com/jbake-org/jbake.git - - - - GitHub Issues - https://github.com/jbake-org/jbake/issues - - - - - jbake-dev - jbake-dev@googlegroups.com - jbake-dev+unsubscribe@googlegroups.com - http://groups.google.com/group/jbake-dev - - - jbake-user - jbake-user@googlegroups.com - jbake-user+unsubscribe@googlegroups.com - http://groups.google.com/group/jbake-user - - - - - - The MIT License (MIT) - http://opensource.org/licenses/MIT - - - - - UTF-8 - ${maven.build.timestamp} - yyyy-MM-dd HH:mm:ssa - - 1.5.4.1 - 2.5 - 1.10 - 3.4 - 2.1 - 2.33 - 2.3.25-incubating - 4.12 - 1.6.0 - 8.1.19.v20160209 - 2.2.15 - 2.4.8 - 1.7.22 - 1.1.9 - 1.7.1 - 3.0.3.RELEASE - 1.1.1 - - 1.2.5 - - 1.10.19 - - - - ${project.artifactId} - - - org.apache.maven.plugins - maven-compiler-plugin - 2.5.1 - - 1.6 - 1.6 - - - - org.apache.maven.plugins - maven-eclipse-plugin - 2.10 - - true - - - - maven-source-plugin - - - attach-sources - - jar - - - - - - maven-javadoc-plugin - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-scm-plugin - 1.9.4 - - - checkout-example-project-freemarker - prepare-package - - checkout - - - ${project.build.directory}/example-project-freemarker - scm:git:git://github.com/jbake-org/jbake-example-project-freemarker.git - - - - - checkout-example-project-groovy - prepare-package - - checkout - - - ${project.build.directory}/example-project-groovy - scm:git:git://github.com/jbake-org/jbake-example-project-groovy.git - - - - - checkout-example-project-thymeleaf - prepare-package - - checkout - - - ${project.build.directory}/example-project-thymeleaf - scm:git:git://github.com/jbake-org/jbake-example-project-thymeleaf.git - - - - - checkout-example-project-jade - prepare-package - - checkout - - - ${project.build.directory}/example-project-jade - scm:git:git://github.com/jbake-org/jbake-example-project-jade.git - - - - checkout-example-project-groovy-mte - prepare-package - - checkout - - - ${project.build.directory}/example-project-groovy-mte - scm:git:git://github.com/jbake-org/jbake-example-project-groovy-mte.git - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.6 - - - - true - lib/ - org.jbake.launcher.Main - org.jbake.launcher - - - lib/ - - - - - - org.apache.maven.plugins - maven-clean-plugin - 2.6.1 - - - - dist - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 2.10 - - - copy-dependencies - package - - copy-dependencies - - - ${project.build.directory}/lib - test - compile - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.6 - - - zip-example-project-freemarker - package - - single - - - example_project_freemarker - false - - src/main/assembly/assembly-example-project-freemarker.xml - - false - - - - zip-example-project-groovy - package - - single - - - example_project_groovy - false - - src/main/assembly/assembly-example-project-groovy.xml - - false - - - - zip-example-project-thymeleaf - package - - single - - - example_project_thymeleaf - false - - src/main/assembly/assembly-example-project-thymeleaf.xml - - false - - - - zip-example-project-jade - package - - single - - - example_project_jade - false - - src/main/assembly/assembly-example-project-jade.xml - - false - - - - zip-example-project-groovy-mte - package - - single - - - example_project_groovy-mte - false - - src/main/assembly/assembly-example-project-groovy-mte.xml - - false - - - - make-assembly - package - - single - - - dist - jbake-${project.version} - - src/main/assembly/assembly.xml - - false - - - - - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - prepare-agent - - prepare-agent - - - - - - org.eluder.coveralls - coveralls-maven-plugin - 2.2.0 - - - - - - - - - - - - - - src/main/resources - true - - - - - - commons-io - commons-io - ${commons.io.version} - - - org.apache.commons - commons-lang3 - ${commons.lang3.version} - - - commons-configuration - commons-configuration - ${commons.configuration.version} - - - com.googlecode.json-simple - json-simple - ${json-simple.version} - - - args4j - args4j - ${args4j.version} - - - org.freemarker - freemarker - ${freemarker.version} - true - - - com.orientechnologies - orientdb-graphdb - ${orientdb.version} - - - - junit - junit - ${junit.version} - test - - - - org.assertj - assertj-core - ${assertj.version} - test - - - org.pegdown - pegdown - ${pegdown.version} - true - - - org.asciidoctor - asciidoctorj - ${asciidoctorj.version} - true - - - org.eclipse.jetty - jetty-server - ${jetty.version} - true - - - org.codehaus.groovy - groovy - ${groovy.version} - true - - - org.codehaus.groovy - groovy-templates - ${groovy.version} - true - - - org.thymeleaf - thymeleaf - ${thymeleaf.version} - true - - - de.neuland-bfi - jade4j - ${jade.version} - true - - - - org.slf4j - slf4j-api - ${slf4j.version} - - - - org.slf4j - jul-to-slf4j - ${slf4j.version} - - - - ch.qos.logback - logback-classic - ${logback.version} - true - - - - ch.qos.logback - logback-core - ${logback.version} - true - - - - org.apache.commons - commons-vfs2 - ${commons.vfs2.version} - true - - - - - - org.mockito - mockito-core - ${mockito.version} - test - - - - - - bintray-jbake-maven - jbake-maven - https://api.bintray.com/maven/jbake/maven/jbake-core/;publish=1 - - - diff --git a/src/main/assembly/assembly-example-project-groovy-mte.xml b/src/main/assembly/assembly-example-project-groovy-mte.xml deleted file mode 100644 index 30fa8e31c..000000000 --- a/src/main/assembly/assembly-example-project-groovy-mte.xml +++ /dev/null @@ -1,19 +0,0 @@ - - base - false - - - zip - - - - ${project.build.directory}/example-project-groovy-mte/ - / - - .git - README.md - LICENSE - - - - \ No newline at end of file diff --git a/src/test/java/org/jbake/app/OvenTest.java b/src/test/java/org/jbake/app/OvenTest.java index 097228660..e3da3e542 100644 --- a/src/test/java/org/jbake/app/OvenTest.java +++ b/src/test/java/org/jbake/app/OvenTest.java @@ -29,7 +29,7 @@ public void setup() throws Exception { // reset values to known state otherwise previous test case runs can affect the success of this test case DocumentTypes.resetDocumentTypes(); - URL sourceUrl = this.getClass().getResource("/"); + URL sourceUrl = this.getClass().getResource("/fixture"); rootPath = new File(sourceUrl.getFile()); if (!rootPath.exists()) { throw new Exception("Cannot find base path for test!"); From 6b7a278aca4cfd2b18667922245c3cd7bbfff030 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 10 May 2017 09:19:36 +0200 Subject: [PATCH 43/53] rebased with master. make tests work again. --- .../AbstractTemplateEngineRenderingTest.java | 6 +++--- ...roovyMarkupTemplateEngineRenderingTest.java | 6 +++--- .../fixture/content/papers/draft-paper.html | 2 +- .../content/papers/published-paper.html | 2 +- src/test/resources/fixture/custom.properties | 18 ------------------ 5 files changed, 8 insertions(+), 26 deletions(-) delete mode 100644 src/test/resources/fixture/custom.properties diff --git a/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java index 56d2c7ab3..732d3476a 100644 --- a/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java @@ -142,7 +142,7 @@ private void setupExpectedOutputStrings() { outputStrings.put("sitemap", Arrays.asList("blog/2013/second-post.html", "blog/2012/first-post.html", - "papers/published-fixture.groovyMarkupTemplates.paper.html")); + "papers/published-paper.html")); } @@ -250,7 +250,7 @@ public void renderTags() throws Exception { @Test public void renderSitemap() throws Exception { - DocumentTypes.addDocumentType("fixture.groovyMarkupTemplates.paper"); + DocumentTypes.addDocumentType("paper"); DBUtil.updateSchema(db); renderer.renderSitemap("sitemap.xml"); @@ -262,7 +262,7 @@ public void renderSitemap() throws Exception { for (String string : getOutputStrings("sitemap")) { assertThat(output).contains(string); } - assertThat(output).doesNotContain("draft-fixture.groovyMarkupTemplates.paper.html"); + assertThat(output).doesNotContain("draft-paper.html"); } protected List getOutputStrings(String type) { diff --git a/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java index 45c722eac..782839cb9 100644 --- a/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java @@ -55,15 +55,15 @@ public GroovyMarkupTemplateEngineRenderingTest() { @Test public void renderCustomTypePaper() throws Exception { // setup - config.setProperty("template.fixture.groovyMarkupTemplates.paper.file", "fixture.groovyMarkupTemplates.paper." + templateExtension); - DocumentTypes.addDocumentType("fixture.groovyMarkupTemplates.paper"); + config.setProperty("template.paper.file", "paper." + templateExtension); + DocumentTypes.addDocumentType("paper"); DBUtil.updateSchema(db); Crawler crawler = new Crawler(db, sourceFolder, config); crawler.crawl(new File(sourceFolder.getPath() + File.separator + "content")); Parser parser = new Parser(config, sourceFolder.getPath()); Renderer renderer = new Renderer(db, destinationFolder, templateFolder, config); - String filename = "published-fixture.groovyMarkupTemplates.paper.html"; + String filename = "published-paper.html"; File sampleFile = new File(sourceFolder.getPath() + File.separator + "content" + File.separator + "papers" + File.separator + filename); Map content = parser.processFile(sampleFile); diff --git a/src/test/resources/fixture/content/papers/draft-paper.html b/src/test/resources/fixture/content/papers/draft-paper.html index 521a62de1..ca13dc05c 100644 --- a/src/test/resources/fixture/content/papers/draft-paper.html +++ b/src/test/resources/fixture/content/papers/draft-paper.html @@ -1,6 +1,6 @@ title=Draft Paper date=2014-04-22 -type=fixture.groovyMarkupTemplates.paper +type=paper tags=blog status=draft ~~~~~~ diff --git a/src/test/resources/fixture/content/papers/published-paper.html b/src/test/resources/fixture/content/papers/published-paper.html index bdacf6cd4..9bf1db3af 100644 --- a/src/test/resources/fixture/content/papers/published-paper.html +++ b/src/test/resources/fixture/content/papers/published-paper.html @@ -1,6 +1,6 @@ title=Published Paper date=2014-04-24 -type=fixture.groovyMarkupTemplates.paper +type=paper tags=blog status=published ~~~~~~ diff --git a/src/test/resources/fixture/custom.properties b/src/test/resources/fixture/custom.properties deleted file mode 100644 index ef678557d..000000000 --- a/src/test/resources/fixture/custom.properties +++ /dev/null @@ -1,18 +0,0 @@ -template.folder=templates -content.folder=content -asset.folder=assets -render.index=true -index.file=index.html -render.feed=true -feed.file=feed.xml -render.archive=true -render.encoding=UTF-8 -archive.file=archive.html -render.tags=false -tag.path=tags -test.property=testing123 -markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS -site.host=http://www.jbake.org -template.feed.thymeleaf.mode=XML -template.sitemap.thymeleaf.mode=XML -template.allcontent.file=allcontent.ftl \ No newline at end of file From 877cccac4a26305947c4e10ab58634f10c897c43 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 10 May 2017 22:55:05 +0200 Subject: [PATCH 44/53] fixed logging and PaginationTest. rebased with master --- build.gradle | 4 ++++ gradle/application.gradle | 5 +++++ src/dist/lib/logging/logback.xml | 1 + .../java/org/jbake/app/PaginationTest.java | 10 ++++----- src/test/resources/logback.xml | 22 +++++++++++++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/logback.xml diff --git a/build.gradle b/build.gradle index 4d6de5416..d27ee1203 100644 --- a/build.gradle +++ b/build.gradle @@ -73,6 +73,10 @@ dependencies { testCompile group: 'org.mockito', name: 'mockito-core', version: mockitoVersion } +test { + jvmArgs '-XX:MaxDirectMemorySize=512m', '-Dorientdb.installCustomFormatter=false=false' +} + jacoco { toolVersion = jacocoVersion } diff --git a/gradle/application.gradle b/gradle/application.gradle index 311483a2f..8c8a9e787 100644 --- a/gradle/application.gradle +++ b/gradle/application.gradle @@ -80,6 +80,11 @@ distributions { } } +startScripts { + defaultJvmOpts = ['-XX:MaxDirectMemorySize=512m'] + classpath += files('lib/logging') +} + distZip { classifier = "bin" } diff --git a/src/dist/lib/logging/logback.xml b/src/dist/lib/logging/logback.xml index 31b090593..c5cdc17bc 100644 --- a/src/dist/lib/logging/logback.xml +++ b/src/dist/lib/logging/logback.xml @@ -11,6 +11,7 @@ + diff --git a/src/test/java/org/jbake/app/PaginationTest.java b/src/test/java/org/jbake/app/PaginationTest.java index e8554cc82..45aedab13 100644 --- a/src/test/java/org/jbake/app/PaginationTest.java +++ b/src/test/java/org/jbake/app/PaginationTest.java @@ -23,18 +23,18 @@ */ package org.jbake.app; -import com.orientechnologies.orient.core.record.impl.ODocument; import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.FakeDocumentBuilder; -import org.junit.*; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; import java.io.File; import java.util.Calendar; import java.util.Date; -import java.util.HashMap; import java.util.Iterator; import java.util.Locale; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -48,7 +48,7 @@ public class PaginationTest { @Before public void setup() throws Exception { - config = ConfigUtil.load(new File(this.getClass().getResource("/").getFile())); + config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); Iterator keys = config.getKeys(); while (keys.hasNext()) { String key = keys.next(); diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml new file mode 100644 index 000000000..715728e0a --- /dev/null +++ b/src/test/resources/logback.xml @@ -0,0 +1,22 @@ + + + + + + + %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file From 23b724cca43c926021d375d0a9b7036ac96f5251 Mon Sep 17 00:00:00 2001 From: Jonathan Bullock Date: Thu, 11 May 2017 22:46:20 +0100 Subject: [PATCH 45/53] Updated IRC room. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1e5210075..23844ad51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ after_failure: - ./gradlew clean check --debug notifications: - irc: "irc.freenode.org#anchos" + irc: "irc.freenode.org#jbake" before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock From 13c74860f3338e14b97b3597da6658e09080d56f Mon Sep 17 00:00:00 2001 From: Jonathan Bullock Date: Thu, 11 May 2017 22:51:35 +0100 Subject: [PATCH 46/53] Updated README. --- README.asciidoc | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index 4bcbeca79..4522c56de 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -1,6 +1,6 @@ = JBake Jonathan Bullock -2013-10-20 +2017-05-11 :idprefix: == JBake @@ -54,19 +54,13 @@ Talk to other users of JBake on the forum: == Build System -The project uses Apache Maven as the build system. To build the JBake distribution ZIP file execute the following command from the root of the repo: +The project uses Gradle as the build system. To build the JBake distribution ZIP file execute the following command from the root of the repo: ---- -$ mvn package +$ ./gradlew distZip ---- -This will build a ZIP file in the `/dist` folder. - -Alternatively you can run directly from the source code using the Maven exec plugin: - ----- -$ mvn exec:java -Dexec.mainClass=org.jbake.launcher.Main -Dexec.args="/fromFolder /tmp/toFolder/" ----- +This will build a ZIP file in the `/build/distributions` folder. == Tools & Libraries Used @@ -74,7 +68,6 @@ $ mvn exec:java -Dexec.mainClass=org.jbake.launcher.Main -Dexec.args="/fromFolde * http://maven.apache.org/[Apache Maven] * http://args4j.kohsuke.org/[Args4j] * http://asciidoctor.org/[AsciidoctorJ] -* http://www.eclipse.org/[Eclipse IDE] * http://freemarker.org/[Freemarker] * http://junit.org/[JUnit] * http://pegdown.org/[Pegdown] From 69a8b0711bdb513f8c63c428ac67480342728f24 Mon Sep 17 00:00:00 2001 From: Jonathan Bullock Date: Thu, 11 May 2017 23:04:36 +0100 Subject: [PATCH 47/53] Replaced Maven with Gradle under Tools section. --- README.asciidoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index 4522c56de..339902eba 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -54,7 +54,7 @@ Talk to other users of JBake on the forum: == Build System -The project uses Gradle as the build system. To build the JBake distribution ZIP file execute the following command from the root of the repo: +The project uses http://gradle.org[Gradle] as the build system. To build the JBake distribution ZIP file execute the following command from the root of the repo: ---- $ ./gradlew distZip @@ -65,15 +65,15 @@ This will build a ZIP file in the `/build/distributions` folder. == Tools & Libraries Used * http://commons.apache.org/[Apache Commons IO, Configuration, Lang & Logging] -* http://maven.apache.org/[Apache Maven] * http://args4j.kohsuke.org/[Args4j] * http://asciidoctor.org/[AsciidoctorJ] * http://freemarker.org/[Freemarker] +* http://gradle.org[Gradle] +* http://groovy-lang.org/[Groovy] * http://junit.org/[JUnit] * http://pegdown.org/[Pegdown] * http://www.eclipse.org/jetty/[Jetty Server] * http://www.orientdb.org/[OrientDB] -* http://groovy-lang.org/[Groovy] == Copyright & License From 214e453efe4f8f8cfc0995a2d7ddc58a74fbfc3c Mon Sep 17 00:00:00 2001 From: "manik.magar" Date: Sat, 13 May 2017 23:07:09 -0400 Subject: [PATCH 48/53] Corrected Rootpath for extension less uri and paginated indices. --- src/main/java/org/jbake/app/Crawler.java | 3 +++ src/main/java/org/jbake/app/Renderer.java | 8 +++++++- src/test/java/org/jbake/app/CrawlerTest.java | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jbake/app/Crawler.java b/src/main/java/org/jbake/app/Crawler.java index bdf68cb91..b7959c9c2 100644 --- a/src/main/java/org/jbake/app/Crawler.java +++ b/src/main/java/org/jbake/app/Crawler.java @@ -201,6 +201,9 @@ public String getPathToRoot(File sourceFile) { for (int i = 0; i < parentCount; i++) { sb.append("../"); } + if (config.getBoolean(Keys.URI_NO_EXTENSION)) { + sb.append("../"); + } return sb.toString(); } diff --git a/src/main/java/org/jbake/app/Renderer.java b/src/main/java/org/jbake/app/Renderer.java index 633d2c05e..1faf90019 100644 --- a/src/main/java/org/jbake/app/Renderer.java +++ b/src/main/java/org/jbake/app/Renderer.java @@ -267,7 +267,6 @@ public void renderIndexPaging(String indexFile) throws Exception { Map model = new HashMap(); model.put("renderer", renderingEngine); - model.put("content", buildSimpleModel("masterindex")); model.put("numberOfPages", pagingHelper.getNumberOfPages()); try { @@ -281,6 +280,13 @@ public void renderIndexPaging(String indexFile) throws Exception { model.put("previousFileName", previous); String nextFileName = pagingHelper.getNextFileName(page, fileName); model.put("nextFileName", nextFileName); + + Map contentModel = buildSimpleModel("masterindex"); + + if(page > 1){ + contentModel.put(Attributes.ROOTPATH, "../"); + } + model.put("content", contentModel); // Add page number to file name fileName = pagingHelper.getCurrentFileName(page, fileName); diff --git a/src/test/java/org/jbake/app/CrawlerTest.java b/src/test/java/org/jbake/app/CrawlerTest.java index 38737dce0..ea2e5bad2 100644 --- a/src/test/java/org/jbake/app/CrawlerTest.java +++ b/src/test/java/org/jbake/app/CrawlerTest.java @@ -101,6 +101,8 @@ public void renderWithPrettyUrls() throws Exception { Assert.assertThat(model.get("noExtensionUri"), RegexMatcher.matches(noExtensionUri)); Assert.assertThat(model.get("uri"), RegexMatcher.matches(noExtensionUri + "index\\.html")); + + assertThat(model).containsEntry("rootpath","../../../"); } } From 427a6cdab71b43ff3e661fb4663f93afdc1fdc57 Mon Sep 17 00:00:00 2001 From: "manik.magar" Date: Sat, 13 May 2017 23:46:07 -0400 Subject: [PATCH 49/53] Exclude index.html from previousFileName and nextFileName values. When index is paginated, previousFileName and nextFileName values are added to content model. These values were including index.html in it. For example, nextFileName value on first page was "2/index.html". It is better to have values just as "2/" or "3/" etc. Corresponding test cases have also been updated. --- src/main/java/org/jbake/util/PagingHelper.java | 7 ++++--- .../template/FreemarkerTemplateEngineRenderingTest.java | 4 ++-- src/test/java/org/jbake/util/PagingHelperTest.java | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jbake/util/PagingHelper.java b/src/main/java/org/jbake/util/PagingHelper.java index 3384b5628..b16fc8c62 100644 --- a/src/main/java/org/jbake/util/PagingHelper.java +++ b/src/main/java/org/jbake/util/PagingHelper.java @@ -17,7 +17,7 @@ public int getNumberOfPages() { public String getNextFileName(int currentPageNumber, String fileName) { if (currentPageNumber < getNumberOfPages()) { - return (currentPageNumber + 1) + File.separator + fileName; + return (currentPageNumber + 1) + File.separator; } else { return null; } @@ -29,10 +29,11 @@ public String getPreviousFileName(int currentPageNumber, String fileName) { return null; } else { if ( currentPageNumber == 2 ) { - return fileName; + // Returning to first page, return empty string which when prefixed with content.rootpath should get to root of the site. + return ""; } else { - return (currentPageNumber - 1) + File.separator + fileName; + return (currentPageNumber - 1) + File.separator; } } } diff --git a/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java b/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java index fa4d33b00..08be89bc3 100644 --- a/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java +++ b/src/test/java/org/jbake/app/template/FreemarkerTemplateEngineRenderingTest.java @@ -50,8 +50,8 @@ public void renderPaginatedIndex() throws Exception { config.setProperty(Keys.POSTS_PER_PAGE, 1); outputStrings.put("index", Arrays.asList( - "index.html\">Previous", - "3/index.html\">Next", + "\">Previous", + "3/\">Next", "2 of 3" )); diff --git a/src/test/java/org/jbake/util/PagingHelperTest.java b/src/test/java/org/jbake/util/PagingHelperTest.java index 8d3170b34..579660397 100644 --- a/src/test/java/org/jbake/util/PagingHelperTest.java +++ b/src/test/java/org/jbake/util/PagingHelperTest.java @@ -27,7 +27,7 @@ public void shouldReturnRootIndexPage() throws Exception { String previousFileName = helper.getPreviousFileName(2, "index.html"); - Assert.assertThat("index.html", is( previousFileName) ); + Assert.assertThat("", is( previousFileName) ); } @Test @@ -37,7 +37,7 @@ public void shouldReturnPreviousFileName() throws Exception { String previousFileName = helper.getPreviousFileName(3, "index.html"); - Assert.assertThat("2/index.html", is( previousFileName) ); + Assert.assertThat("2/", is( previousFileName) ); } @@ -66,7 +66,7 @@ public void shouldReturnNextFileName() throws Exception { String nextFileName = helper.getNextFileName(2, "index.html"); - Assert.assertThat("3/index.html", is( nextFileName) ); + Assert.assertThat("3/", is( nextFileName) ); } } \ No newline at end of file From c4d907f37ebb9e85a46dc97b9cd6455f2b15ee52 Mon Sep 17 00:00:00 2001 From: "manik.magar" Date: Mon, 15 May 2017 12:52:54 -0400 Subject: [PATCH 50/53] Add previous and next content links in document model This will allow to have post navigator on individual post/document page. --- src/main/java/org/jbake/app/ContentStore.java | 2 +- .../org/jbake/render/DocumentsRenderer.java | 103 ++++++++++++------ .../jbake/render/DocumentsRendererTest.java | 72 ++++++++++++ 3 files changed, 145 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/jbake/app/ContentStore.java b/src/main/java/org/jbake/app/ContentStore.java index 9ccd9fec5..8dd2f2e73 100644 --- a/src/main/java/org/jbake/app/ContentStore.java +++ b/src/main/java/org/jbake/app/ContentStore.java @@ -183,7 +183,7 @@ public DocumentList getSignaturesForTemplates() { } public DocumentList getUnrenderedContent(String docType) { - return query("select * from " + docType + " where rendered=false"); + return query("select * from " + docType + " where rendered=false order by date desc"); } public void deleteContent(String docType, String uri) { diff --git a/src/main/java/org/jbake/render/DocumentsRenderer.java b/src/main/java/org/jbake/render/DocumentsRenderer.java index 686e828f7..4b76f7cb3 100644 --- a/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -1,43 +1,84 @@ package org.jbake.render; +import java.io.File; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; +import org.jbake.app.Crawler.Attributes; import org.jbake.app.DocumentList; import org.jbake.app.Renderer; import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; -import java.io.File; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - public class DocumentsRenderer implements RenderingTool { - @Override - public int render(Renderer renderer, ContentStore db, File destination, File templatesPath, CompositeConfiguration config) throws RenderingException { - int renderedCount = 0; - final List errors = new LinkedList(); - for (String docType : DocumentTypes.getDocumentTypes()) { - DocumentList documentList = db.getUnrenderedContent(docType); - for (Map page : documentList) { - try { - renderer.render(page); - renderedCount++; - } catch (Exception e) { - errors.add(e.getMessage()); - } - } - } - if (!errors.isEmpty()) { - StringBuilder sb = new StringBuilder(); - sb.append("Failed to render documents. Cause(s):"); - for (String error : errors) { - sb.append("\n").append(error); - } - throw new RenderingException(sb.toString()); - } else { - return renderedCount; - } - } + @Override + public int render(Renderer renderer, ContentStore db, File destination, File templatesPath, + CompositeConfiguration config) throws RenderingException { + int renderedCount = 0; + final List errors = new LinkedList(); + for (String docType : DocumentTypes.getDocumentTypes()) { + DocumentList documentList = db.getUnrenderedContent(docType); + + if(documentList == null) continue; + + int index = 0; + + Map nextDocument = null; + + while (index < documentList.size()) { + try { + Map document = documentList.get(index); + document.put("nextContent", null); + document.put("previousContent", null); + + if (index > 0) { + document.put("nextContent", getContentForNav(nextDocument)); + } + + if (index < documentList.size() - 1) { + Map tempNext = documentList.get(index + 1); + document.put("previousContent", getContentForNav(tempNext)); + } + + renderer.render(document); + renderedCount++; + + nextDocument = document; + + } catch (Exception e) { + errors.add(e.getMessage()); + } + + index++; + } + } + if (!errors.isEmpty()) { + StringBuilder sb = new StringBuilder(); + sb.append("Failed to render documents. Cause(s):"); + for (String error : errors) { + sb.append("\n").append(error); + } + throw new RenderingException(sb.toString()); + } else { + return renderedCount; + } + } + + /** + * Creates a simple content model to use in individual post navigations. + * @param document + * @return + */ + private Map getContentForNav(Map document) { + Map navDocument = new HashMap(); + navDocument.put(Attributes.NO_EXTENSION_URI, document.get(Attributes.NO_EXTENSION_URI)); + navDocument.put(Attributes.URI, document.get(Attributes.URI)); + navDocument.put(Attributes.TITLE, document.get(Attributes.TITLE)); + return navDocument; + } } \ No newline at end of file diff --git a/src/test/java/org/jbake/render/DocumentsRendererTest.java b/src/test/java/org/jbake/render/DocumentsRendererTest.java index 2eab6bbc6..e984edc72 100644 --- a/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -4,15 +4,21 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; import org.jbake.app.Renderer; +import org.jbake.app.Crawler.Attributes; import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.MockitoAnnotations; import java.io.File; import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.anyMap; @@ -30,9 +36,15 @@ public class DocumentsRendererTest { private DocumentList emptyDocumentList; private File destinationFile; private File templatePath; + + @Captor + private ArgumentCaptor> argument; @Before public void setUp() throws Exception { + + MockitoAnnotations.initMocks(this); + documentsRenderer = new DocumentsRenderer(); db = mock(ContentStore.class); @@ -103,8 +115,68 @@ public void shouldThrowAnExceptionWithCollectedErrorMessages() throws Exception // then assertThat(renderResponse).isEqualTo(2); } + + @Test + public void shouldContainPostNavigation() throws Exception{ + DocumentTypes.addDocumentType("customType"); + + String first = "First Document"; + String second = "Second Document"; + String third = "Third Document"; + String fourth = "Fourth Document"; + + DocumentList documents = new DocumentList(); + documents.add(simpleDocument(fourth)); + documents.add(simpleDocument(third)); + documents.add(simpleDocument(second)); + documents.add(simpleDocument(first)); + + when(db.getUnrenderedContent("customType")).thenReturn(documents); + + int renderResponse = documentsRenderer.render(renderer,db,destinationFile,templatePath,configuration); + + Map fourthDoc = simpleDocument(fourth); + fourthDoc.put("previousContent", simpleDocument(third)); + fourthDoc.put("nextContent", null); + + Map thirdDoc = simpleDocument(third); + thirdDoc.put("nextContent", simpleDocument(fourth)); + thirdDoc.put("previousContent", simpleDocument(second)); + + Map secondDoc = simpleDocument(second); + secondDoc.put("nextContent", simpleDocument(third)); + secondDoc.put("previousContent", simpleDocument(first)); + + Map firstDoc = simpleDocument(first); + firstDoc.put("nextContent", simpleDocument(second)); + firstDoc.put("previousContent", null); + + verify(renderer,times(4)).render(argument.capture()); + + List> maps = argument.getAllValues(); + + assertThat(maps).contains(fourthDoc); + + assertThat(maps).contains(thirdDoc); + + assertThat(maps).contains(secondDoc); + + assertThat(maps).contains(firstDoc); + + assertThat(renderResponse).isEqualTo(4); + } private HashMap emptyDocument() { return new HashMap(); } + + private Map simpleDocument(String title) { + Map simpleDoc = new HashMap(); + String uri = title.replace(" ", "_"); + simpleDoc.put(Attributes.NO_EXTENSION_URI, uri); + simpleDoc.put(Attributes.URI, uri); + simpleDoc.put(Attributes.TITLE, title);; + return simpleDoc; + } + } \ No newline at end of file From cff71fd0556b1869a587cb219727f2bd84ceb379 Mon Sep 17 00:00:00 2001 From: "manik.magar" Date: Mon, 15 May 2017 12:52:54 -0400 Subject: [PATCH 51/53] Add previous and next content links in document model This will allow to have post navigator on individual post/document page. --- src/main/java/org/jbake/app/ContentStore.java | 2 +- .../org/jbake/render/DocumentsRenderer.java | 103 ++++++++++++------ .../jbake/render/DocumentsRendererTest.java | 72 ++++++++++++ 3 files changed, 145 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/jbake/app/ContentStore.java b/src/main/java/org/jbake/app/ContentStore.java index 9ccd9fec5..8dd2f2e73 100644 --- a/src/main/java/org/jbake/app/ContentStore.java +++ b/src/main/java/org/jbake/app/ContentStore.java @@ -183,7 +183,7 @@ public DocumentList getSignaturesForTemplates() { } public DocumentList getUnrenderedContent(String docType) { - return query("select * from " + docType + " where rendered=false"); + return query("select * from " + docType + " where rendered=false order by date desc"); } public void deleteContent(String docType, String uri) { diff --git a/src/main/java/org/jbake/render/DocumentsRenderer.java b/src/main/java/org/jbake/render/DocumentsRenderer.java index 686e828f7..8706b3376 100644 --- a/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -1,43 +1,84 @@ package org.jbake.render; +import java.io.File; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; +import org.jbake.app.Crawler.Attributes; import org.jbake.app.DocumentList; import org.jbake.app.Renderer; import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; -import java.io.File; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - public class DocumentsRenderer implements RenderingTool { - @Override - public int render(Renderer renderer, ContentStore db, File destination, File templatesPath, CompositeConfiguration config) throws RenderingException { - int renderedCount = 0; - final List errors = new LinkedList(); - for (String docType : DocumentTypes.getDocumentTypes()) { - DocumentList documentList = db.getUnrenderedContent(docType); - for (Map page : documentList) { - try { - renderer.render(page); - renderedCount++; - } catch (Exception e) { - errors.add(e.getMessage()); - } - } - } - if (!errors.isEmpty()) { - StringBuilder sb = new StringBuilder(); - sb.append("Failed to render documents. Cause(s):"); - for (String error : errors) { - sb.append("\n").append(error); - } - throw new RenderingException(sb.toString()); - } else { - return renderedCount; - } - } + @Override + public int render(Renderer renderer, ContentStore db, File destination, File templatesPath, + CompositeConfiguration config) throws RenderingException { + int renderedCount = 0; + final List errors = new LinkedList(); + for (String docType : DocumentTypes.getDocumentTypes()) { + DocumentList documentList = db.getUnrenderedContent(docType); + + if(documentList == null) continue; + + int index = 0; + + Map nextDocument = null; + + while (index < documentList.size()) { + try { + Map document = documentList.get(index); + document.put("nextContent", null); + document.put("previousContent", null); + + if (index > 0) { + document.put("nextContent", getContentForNav(nextDocument)); + } + + if (index < documentList.size() - 1) { + Map tempNext = documentList.get(index + 1); + document.put("previousContent", getContentForNav(tempNext)); + } + + nextDocument = document; + + renderer.render(document); + renderedCount++; + + } catch (Exception e) { + errors.add(e.getMessage()); + } + + index++; + } + } + if (!errors.isEmpty()) { + StringBuilder sb = new StringBuilder(); + sb.append("Failed to render documents. Cause(s):"); + for (String error : errors) { + sb.append("\n").append(error); + } + throw new RenderingException(sb.toString()); + } else { + return renderedCount; + } + } + + /** + * Creates a simple content model to use in individual post navigations. + * @param document + * @return + */ + private Map getContentForNav(Map document) { + Map navDocument = new HashMap(); + navDocument.put(Attributes.NO_EXTENSION_URI, document.get(Attributes.NO_EXTENSION_URI)); + navDocument.put(Attributes.URI, document.get(Attributes.URI)); + navDocument.put(Attributes.TITLE, document.get(Attributes.TITLE)); + return navDocument; + } } \ No newline at end of file diff --git a/src/test/java/org/jbake/render/DocumentsRendererTest.java b/src/test/java/org/jbake/render/DocumentsRendererTest.java index 2eab6bbc6..e984edc72 100644 --- a/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -4,15 +4,21 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; import org.jbake.app.Renderer; +import org.jbake.app.Crawler.Attributes; import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.MockitoAnnotations; import java.io.File; import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.anyMap; @@ -30,9 +36,15 @@ public class DocumentsRendererTest { private DocumentList emptyDocumentList; private File destinationFile; private File templatePath; + + @Captor + private ArgumentCaptor> argument; @Before public void setUp() throws Exception { + + MockitoAnnotations.initMocks(this); + documentsRenderer = new DocumentsRenderer(); db = mock(ContentStore.class); @@ -103,8 +115,68 @@ public void shouldThrowAnExceptionWithCollectedErrorMessages() throws Exception // then assertThat(renderResponse).isEqualTo(2); } + + @Test + public void shouldContainPostNavigation() throws Exception{ + DocumentTypes.addDocumentType("customType"); + + String first = "First Document"; + String second = "Second Document"; + String third = "Third Document"; + String fourth = "Fourth Document"; + + DocumentList documents = new DocumentList(); + documents.add(simpleDocument(fourth)); + documents.add(simpleDocument(third)); + documents.add(simpleDocument(second)); + documents.add(simpleDocument(first)); + + when(db.getUnrenderedContent("customType")).thenReturn(documents); + + int renderResponse = documentsRenderer.render(renderer,db,destinationFile,templatePath,configuration); + + Map fourthDoc = simpleDocument(fourth); + fourthDoc.put("previousContent", simpleDocument(third)); + fourthDoc.put("nextContent", null); + + Map thirdDoc = simpleDocument(third); + thirdDoc.put("nextContent", simpleDocument(fourth)); + thirdDoc.put("previousContent", simpleDocument(second)); + + Map secondDoc = simpleDocument(second); + secondDoc.put("nextContent", simpleDocument(third)); + secondDoc.put("previousContent", simpleDocument(first)); + + Map firstDoc = simpleDocument(first); + firstDoc.put("nextContent", simpleDocument(second)); + firstDoc.put("previousContent", null); + + verify(renderer,times(4)).render(argument.capture()); + + List> maps = argument.getAllValues(); + + assertThat(maps).contains(fourthDoc); + + assertThat(maps).contains(thirdDoc); + + assertThat(maps).contains(secondDoc); + + assertThat(maps).contains(firstDoc); + + assertThat(renderResponse).isEqualTo(4); + } private HashMap emptyDocument() { return new HashMap(); } + + private Map simpleDocument(String title) { + Map simpleDoc = new HashMap(); + String uri = title.replace(" ", "_"); + simpleDoc.put(Attributes.NO_EXTENSION_URI, uri); + simpleDoc.put(Attributes.URI, uri); + simpleDoc.put(Attributes.TITLE, title);; + return simpleDoc; + } + } \ No newline at end of file From 0f0ee1e88a07ec16222049256fb9c76601507f18 Mon Sep 17 00:00:00 2001 From: "manik.magar" Date: Mon, 15 May 2017 14:22:19 -0400 Subject: [PATCH 52/53] moved nextDocument assignment before redndering --- src/main/java/org/jbake/render/DocumentsRenderer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jbake/render/DocumentsRenderer.java b/src/main/java/org/jbake/render/DocumentsRenderer.java index 4b76f7cb3..8706b3376 100644 --- a/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -44,12 +44,12 @@ public int render(Renderer renderer, ContentStore db, File destination, File tem Map tempNext = documentList.get(index + 1); document.put("previousContent", getContentForNav(tempNext)); } - + + nextDocument = document; + renderer.render(document); renderedCount++; - nextDocument = document; - } catch (Exception e) { errors.add(e.getMessage()); } From d02dc5ff99ded2cf877c57da48cb284c1a87fab0 Mon Sep 17 00:00:00 2001 From: "manik.magar" Date: Wed, 17 May 2017 19:49:09 -0400 Subject: [PATCH 53/53] Prevent image source path from breaking This change prevents image source path from breaking. It prefixes content rootpath the image sources. It excludes the sources that starts with http:// or https:// or /. If image source starts with './' i.e. image is in the same folder as content, then it will replace ./ with content directory path and then adds the rootpath. Once image source is fixed, it should not break, no matter from where content is accessed i.e. index or individual page. --- build.gradle | 2 + src/main/java/org/jbake/app/Crawler.java | 17 +-- src/main/java/org/jbake/app/HtmlUtil.java | 75 ++++++++++++ src/test/java/org/jbake/app/HtmlUtilTest.java | 108 ++++++++++++++++++ 4 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/jbake/app/HtmlUtil.java create mode 100644 src/test/java/org/jbake/app/HtmlUtilTest.java diff --git a/build.gradle b/build.gradle index d27ee1203..4542431e2 100644 --- a/build.gradle +++ b/build.gradle @@ -46,6 +46,7 @@ ext { jsonSimpleVersion = '1.1.1' jade4jVersion = '1.2.5' mockitoVersion = '1.10.19' + jsoupVersion = '1.10.2' } dependencies { @@ -68,6 +69,7 @@ dependencies { compile group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion compile group: 'ch.qos.logback', name: 'logback-core', version: logbackVersion compile group: 'de.neuland-bfi', name: 'jade4j', version: jade4jVersion + compile group: 'org.jsoup', name:'jsoup', version: jsoupVersion testCompile group: 'junit', name: 'junit', version: junitVersion testCompile group: 'org.assertj', name: 'assertj-core', version: assertjCoreVersion testCompile group: 'org.mockito', name: 'mockito-core', version: mockitoVersion diff --git a/src/main/java/org/jbake/app/Crawler.java b/src/main/java/org/jbake/app/Crawler.java index bdf68cb91..8a830016b 100644 --- a/src/main/java/org/jbake/app/Crawler.java +++ b/src/main/java/org/jbake/app/Crawler.java @@ -1,7 +1,11 @@ package org.jbake.app; -import com.orientechnologies.orient.core.record.impl.ODocument; +import java.io.File; +import java.util.Arrays; +import java.util.Date; +import java.util.Map; + import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FilenameUtils; import org.jbake.app.ConfigUtil.Keys; @@ -12,12 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.util.Arrays; -import java.util.Date; -import java.util.Map; - -import static java.io.File.separator; +import com.orientechnologies.orient.core.record.impl.ODocument; /** * Crawls a file system looking for content. @@ -178,6 +177,10 @@ private void crawlSourceFile(final File sourceFile, final String sha1, final Str if (config.getBoolean(Keys.URI_NO_EXTENSION)) { fileContents.put(Attributes.NO_EXTENSION_URI, uri.replace("/index.html", "/")); } + + + // Prevent image source url's from breaking + HtmlUtil.fixImageSourceUrls(fileContents); ODocument doc = new ODocument(documentType); doc.fields(fileContents); diff --git a/src/main/java/org/jbake/app/HtmlUtil.java b/src/main/java/org/jbake/app/HtmlUtil.java new file mode 100644 index 000000000..02d224c71 --- /dev/null +++ b/src/main/java/org/jbake/app/HtmlUtil.java @@ -0,0 +1,75 @@ +package org.jbake.app; + +import java.util.Map; + +import org.jbake.app.Crawler.Attributes; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +/** + * + * @author Manik Magar + * + */ +public class HtmlUtil { + + /** + * Image paths are specified as w.r.t. assets folder. This function prefix rootpath to all img src except + * the ones that starts with http://, https:// or '/'. + * + * If image path starts with "./", i.e. relative to the source file, then it first replace that with output file directory and the add rootpath. + * + * @param fileContents + */ + public static void fixImageSourceUrls(Map fileContents){ + + String htmlContent = fileContents.get(Attributes.BODY).toString(); + + String rootPath = fileContents.get(Attributes.ROOTPATH).toString(); + + String uri = fileContents.get(Attributes.URI).toString(); + + if(fileContents.get(Attributes.NO_EXTENSION_URI) != null){ + uri = fileContents.get(Attributes.NO_EXTENSION_URI).toString(); + + //remove trailing "/" + if(uri.endsWith("/")) { + uri = uri.substring(0, uri.length() - 1); + } + + } + + if(uri.contains("/")){ + //strip that file name, leaving end "/" + uri = uri.substring(0, uri.lastIndexOf("/") + 1); + } + + + + Document document = Jsoup.parseBodyFragment(htmlContent); + + Elements allImgs = document.getElementsByTag("img"); + + for (Element img : allImgs) { + String source = img.attr("src"); + + if(source.startsWith("./")){ + // image relative to current content is specified, + // lets add current url to it. + source = source.replaceFirst("./", uri); + } + + // Now add the root path + if((source.startsWith("http://") + || source.startsWith("https://") || source.startsWith("/")) == false){ + String relativeSource = rootPath + source; + img.attr("src", relativeSource); + } + } + + fileContents.put(Attributes.BODY, document.body().toString()); + } + +} diff --git a/src/test/java/org/jbake/app/HtmlUtilTest.java b/src/test/java/org/jbake/app/HtmlUtilTest.java new file mode 100644 index 000000000..28edb67d0 --- /dev/null +++ b/src/test/java/org/jbake/app/HtmlUtilTest.java @@ -0,0 +1,108 @@ +package org.jbake.app; + +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.Map; + +import org.jbake.app.Crawler.Attributes; +import org.junit.Test; + + + +public class HtmlUtilTest { + + @Test + public void shouldAddRootpath(){ + Map fileContent = new HashMap(); + fileContent.put(Attributes.ROOTPATH, "../../../"); + fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); + fileContent.put(Attributes.BODY, "
Test
"); + + HtmlUtil.fixImageSourceUrls(fileContent); + + assertTrue(fileContent.get(Attributes.BODY).toString().contains("../../../blog/2017/05/first.jpg")); + + } + + @Test + public void shouldAddContentpath(){ + Map fileContent = new HashMap(); + fileContent.put(Attributes.ROOTPATH, "../../../"); + fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); + fileContent.put(Attributes.BODY, "
Test
"); + + HtmlUtil.fixImageSourceUrls(fileContent); + + assertTrue(fileContent.get(Attributes.BODY).toString().contains("../../../blog/2017/05/first.jpg")); + + } + + @Test + public void shouldNotAddRootPath(){ + Map fileContent = new HashMap(); + fileContent.put(Attributes.ROOTPATH, "../../../"); + fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); + fileContent.put(Attributes.BODY, "
Test
"); + + HtmlUtil.fixImageSourceUrls(fileContent); + + assertFalse(fileContent.get(Attributes.BODY).toString().contains("../../../blog/2017/05/first.jpg")); + assertTrue(fileContent.get(Attributes.BODY).toString().contains("/blog/2017/05/first.jpg")); + + } + + @Test + public void shouldAddRootPathForNoExtension(){ + Map fileContent = new HashMap(); + fileContent.put(Attributes.ROOTPATH, "../../../"); + fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); + fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); + fileContent.put(Attributes.BODY, "
Test
"); + + HtmlUtil.fixImageSourceUrls(fileContent); + + assertTrue(fileContent.get(Attributes.BODY).toString().contains("../../../blog/2017/05/first.jpg")); + + } + + @Test + public void shouldAddContentPathForNoExtension(){ + Map fileContent = new HashMap(); + fileContent.put(Attributes.ROOTPATH, "../../../"); + fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); + fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); + fileContent.put(Attributes.BODY, "
Test
"); + + HtmlUtil.fixImageSourceUrls(fileContent); + + assertTrue(fileContent.get(Attributes.BODY).toString().contains("../../../blog/2017/05/first.jpg")); + + } + + @Test + public void shouldNotChangeForHTTP(){ + Map fileContent = new HashMap(); + fileContent.put(Attributes.ROOTPATH, "../../../"); + fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); + fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); + fileContent.put(Attributes.BODY, "
Test
"); + + HtmlUtil.fixImageSourceUrls(fileContent); + assertTrue(fileContent.get(Attributes.BODY).toString().contains("http://example.com/first.jpg")); + + } + + @Test + public void shouldNotChangeForHTTPS(){ + Map fileContent = new HashMap(); + fileContent.put(Attributes.ROOTPATH, "../../../"); + fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); + fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); + fileContent.put(Attributes.BODY, "
Test
"); + + HtmlUtil.fixImageSourceUrls(fileContent); + assertTrue(fileContent.get(Attributes.BODY).toString().contains("https://example.com/first.jpg")); + + } +}