diff --git a/01.html b/01.html new file mode 100644 index 0000000..66aa4c7 --- /dev/null +++ b/01.html @@ -0,0 +1,309 @@ + + + + +Try Unfiltered · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Try Unfiltered

+

It’s not hard to write a request handler in the Scala console using Unfiltered. The tricky part is getting everything on the classpath.

+

Play Project

+

The approach recommended here uses giter8, a tool for setting up projects based on templates stored in github. Assuming you don’t have giter8 installed and you are on a network-connected Linux or Mac, it’s easy to fix that.

+
curl https://raw.githubusercontent.com/foundweekends/conscript/master/setup.sh | sh
+
+

That is conscript. Its setup.sh places a permanent (assuming you don’t delete it) executable script in ~/bin/cs. At some point you may want to add ~/bin to your executable search path, but these instructions will not assume it is.

+
~/bin/cs foundweekends/giter8
+
+

That installs a g8. Now you have a script to run giter8. The next step creates a sbt project under the current working directory.

+
~/bin/g8 unfiltered/unfiltered --name=justplayin
+
+

Okay, finally we can use this project with sbt to get a console for Unfiltered. You do have sbt setup, don’t you?

+
cd justplayin
+sbt console
+
+

Consoled

+

Now that you have a scala> prompt with the unfiltered-filter and unfiltered-jetty modules on the classpath, let’s have some fun.

+
import unfiltered.request._
+import unfiltered.response._
+
+val echo = unfiltered.filter.Planify {
+  case Path(Seg(p :: Nil)) => ResponseString(p)
+}
+

This filter echo would work with any servlet container. We can use it in a Jetty server right now.

+
unfiltered.jetty.Server.anylocal.plan(echo).run()
+

The startup message tells you which open port was selected, and by default it is only listening to requests from 127.0.0.1. So on the same machine, you can make requests to your server. e.g.

+
curl http://127.0.0.1:<the right port>/hello+world
+
+

Fancy desktop web browsers will work too. Notice that exactly one path segment is required for the filter to respond to the request. If you ask for the root path or a deeper path, the echo filter will not handle the request and Jetty responds with a 404 page.

+

If we want to handle any request, we could broaden the pattern matching expression. (Press enter to stop the running server.)

+
val echoNice = unfiltered.filter.Planify {
+  case Path(Seg(p :: Nil)) => ResponseString(p)
+  case _ => ResponseString(
+    "I can echo exactly one path element."
+  )
+}
+unfiltered.jetty.Server.anylocal.plan(echoNice).run()
+

Or we could define another filter chain it to the first.

+
val nice = unfiltered.filter.Planify {
+  case _ => ResponseString(
+    "I can echo exactly one path element."
+  )
+}
+unfiltered.jetty.Server.anylocal.plan(echo).plan(nice).run()
+

Happy now?

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/02.html b/02.html new file mode 100644 index 0000000..9f3e909 --- /dev/null +++ b/02.html @@ -0,0 +1,306 @@ + + + + +Plans and Intents · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Plans and Intents

+

Unfiltered conditionally handles incoming requests using partial functions. From the application’s perspective, requests are mapped to code paths by pattern matching. The library uses a particular vocabulary to refer to the agents of this process without ambiguity.

+
    +
  • An intent is a partial function for matching requests.
  • +
  • A plan binds an intent to a particular server interface.
  • +
+

For example, the unfiltered.filter.Plan trait extends the javax.servlet.Filter interface. It declares an abstract intent method for clients to define the intent partial function.

+

Making Plans of Intents

+

Looking back at the example on the previous page, you might wonder where the plan ends and the intent begins.

+
import unfiltered.request._
+import unfiltered.response._
+val echo = unfiltered.filter.Planify {
+  case Path(Seg(p :: Nil)) => ResponseString(p)
+}
+

In this case a plan is constructed directly from an anonymous partial function—that function is the intent. We can define the same plan in more explicit parts, as is usually necessary in a larger application.

+
object Echo extends unfiltered.filter.Plan {
+  def intent = {
+    case Path(Seg(p :: Nil)) => ResponseString(p)
+  }
+}
+

Since this kind of plan is an implementation of the servlet filter interface, we can pass it directly to a servlet container.

+
unfiltered.jetty.Server.anylocal.plan(Echo).run()
+

Passing on That

+

Since an intent is a partial function, it may be undefined for a request. In this case the request may be handled by some other intent or it could produce a 404 error from the server.

+

Unfiltered also supports an explicit mechanism to specify that a matched request should not be handled by an intent: the Pass object.

+
object Public extends unfiltered.filter.Plan {
+  def intent = {
+    case Path(Seg("admin" :: _)) => Pass
+    case Path(Seg(path :: Nil)) => myRenderer(path)
+  }
+}
+

This intent avoids handling anything under /admin by matching that condition and passing on it. There are other ways to achieve the same ends, but an explicit Pass is often the most straightforward.

+

Keep in mind that Scala’s partial functions are unaware of Unfiltered’s Pass mechanism, so the intent above is in fact defined for the excluded paths. But when attached to a plan, requests that evaluate to Pass are treated the same as those that are undefined.

+

Chaining Intents

+

When you want to combine intents within a single plan, use onPass:

+
object MyPlan extends unfiltered.filter.Plan {
+  def intent = publicIntent.onPass(privateIntent)
+
+  val publicIntent = unfiltered.filter.Intent { ??? }
+  val privateIntent = unfiltered.filter.Intent { ??? }
+}
+

The onPass method is defined implicitly for PartialFunction with the import of the unfiltered.response._ package. It works like orElse but is aware of the Pass object and it’s optimized to avoid unnecessary reevaluation of pattern guards.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/03.html b/03.html new file mode 100644 index 0000000..169355a --- /dev/null +++ b/03.html @@ -0,0 +1,308 @@ + + + + +Bindings and Servers · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Bindings and Servers

+

The core module unfiltered-library does not depend on or reference any particular server backend. It defines internal abstractions for requests and responses, with higher level abstractions on top.

+

An application or library that depends only on the core library could be used with any backend that Unfiltered supports, but in most cases it will depend on a binding module.

+

Binding Modules

+

These bind Unfiltered’s generic request and response interfaces to a given implementation, as well as intent types and plan traits.

+

Servlet Filters (unfiltered-filter)

+

The Java Servlet API enables you to write applications that run on servlet containers, anything from Tomcat to Google App Engine. Its plan trait is a servlet filter.

+

Asynchronous Servlet Filters (unfiltered-filter-async)

+

Asynchronous Servlet Filters are using jetty-continuation under the hood which should provide a general purpose API that will work asynchronously on any servlet-3.0 container, as well as on Jetty 6, 7 or 8 (Continuations will also work in blocking mode with any servlet 2.5 container.)

+
import unfiltered.request.{Path => UFPath, _}
+import unfiltered.response._
+
+object AsyncPlan extends unfiltered.filter.async.Plan  {
+  def intent = {
+    case GET(UFPath("/pass")) => Pass
+    case req@GET(UFPath("/async")) =>
+      //"respond" is usually called from an asynchronous callback handler
+      req.respond(ResponseString("test") ~> Ok)
+  }
+}
+//then you can register this plan with jetty as usual
+unfiltered.jetty.Server.http(8080).plan(AsyncPlan).run()
Note
+

Alternately, local(8080) binds to the loopback network interface only.

+

Netty Channel Handlers (unfiltered-netty)

+

Netty defines channels for network I/O and implements them using Java’s Native I/O (NIO) interface. Its plan traits are upstream channel handlers, and the module defines intents and plans in separate cycle and async subpackages, the former for traditional request-response cycles and the latter for open-ended interaction.

+

Server Modules

+

Server modules define runnable servers to execute your plans. They are entirely optional. Applications can instead use Unfiltered’s binding modules with external containers, or they can interface directly with server libraries.

+

unfiltered-jetty

+

Includes builders for Jetty servers that implement the HTTP and HTTPS protocols. With this server it is particularly easy to serve a web browser interface for a local process. Unfiltered even gives you a shortcut to open a browser window, if the user is on a 1.6+ JVM that supports it.

+
import unfiltered.response._
+val hello = unfiltered.filter.Planify {
+  case _ => ResponseString("hello world")
+}
+unfiltered.jetty.Server.anylocal.plan(hello).run { s =>
+  unfiltered.util.Browser.open(
+    s.portBindings.head.url
+  )
+}
+

unfiltered-netty-server

+

Bootstraps and binds a server for your channel handlers.

+
import unfiltered.response._
+val hello = unfiltered.netty.cycle.Planify {
+  case _ => ResponseString("hello world")
+}
+unfiltered.netty.Server.http(8080).plan(hello).run()
+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/04.html b/04.html new file mode 100644 index 0000000..ef8414d --- /dev/null +++ b/04.html @@ -0,0 +1,313 @@ + + + + +Project Setup · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Project Setup

+

Modules and Artifacts

+

Unfiltered’s core, binding, server, and other modules are published with references to their underlying dependencies, so that applications need only explicitly depend on Unfiltered and other top-level dependencies. Keep in mind that server modules and binding modules are not generally co-dependent, so that if you are using for example unfiltered-jetty, you will also need to specify unfiltered-filter.

+

Each module is cross-built against several versions of Scala and published to the sonatype repository with the organization-id “ws.unfiltered”. The modules have the Scala version they are built against appended. For Scala 2.12+, the full artifact names are as follows:

+
    +
  • unfiltered_2.12
  • +
  • unfiltered-filter_2.12
  • +
  • unfiltered-filter-async_2.12
  • +
  • unfiltered-netty_2.12
  • +
  • unfiltered-netty-websockets_2.12
  • +
  • unfiltered-jetty_2.12
  • +
  • unfiltered-netty-server_2.12
  • +
  • unfiltered-uploads_2.12
  • +
  • unfiltered-util_2.12
  • +
  • unfiltered-specs2_2.12
  • +
  • unfiltered-scalatest_2.12
  • +
  • unfiltered-json4s_2.12
  • +
  • unfiltered-oauth_2.12
  • +
+

Build Tools

+

Configuring sbt projects

+

When using sbt with binary dependencies it’s best to have the Scala version automatically appended so it will always match your project’s. In an sbt project:

+
libraryDependencies += "ws.unfiltered" %% "unfiltered-filter" % "0.9.1"
+
+

Maven

+

For Maven, specify the full artifact name:

+
<dependency>
+  <groupId>ws.unfiltered</groupId>
+  <artifactId>unfiltered-filter_2.12</artifactId>
+  <version>0.9.1</version>
+</dependency>
+
+

To use source dependencies with Maven, your best bet is to check out the project as a submodule.

+

Template Projects

+

For a new project the easiest the easiest option to apply a giter8 template for the Unfiltered backend of your choice.

+ +

So for example:

+
g8 unfiltered/unfiltered-netty --name=justplayin
+cd justplayin
+sbt # *or whatever your 0.11.x command is
+> run
+
+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/05.html b/05.html new file mode 100644 index 0000000..f9d1492 --- /dev/null +++ b/05.html @@ -0,0 +1,251 @@ + + + + +Community · Unfiltered + + + + + + + + + + + + + + +
+
+ + + + +
+
+ + + + + + + + + + + + diff --git a/06/00.html b/06/00.html new file mode 100644 index 0000000..d98df68 --- /dev/null +++ b/06/00.html @@ -0,0 +1,251 @@ + + + + +Matching and Responding · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Matching and Responding

+

A typical request/response cycle can be handily directed with a few lines of code. This section applies pattern matching and combinator functions to expose a simple key-value store.

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/06/a.html b/06/a.html new file mode 100644 index 0000000..da4aa56 --- /dev/null +++ b/06/a.html @@ -0,0 +1,287 @@ + + + + +Request Matchers · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Request Matchers

+

Methods and Paths

+

Unfiltered supplies a wide range of request matchers–extractor objects that work against requests–from path segments to HTTP methods and headers. Applications use request matchers to define whether and how they will respond to a request.

+
case GET(Path("/record/1")) => ???
+

This case will match GET requests to the path /record/1. To match against path segments, we can nest one additional extractor:

+
case GET(Path(Seg("record" :: id :: Nil))) => ???
+

This matches any id string that is directly under the record path. The Seg extractor object matches against the String type and it is typically nested under a Path matcher. Seg extracts a lists of strings from the supplied string, separated into path segments by forward-slashes.

+

Reading Requests and Delayed Matching

+

The above case clause matches a request to get a record. What about putting them?

+
case req @ PUT(Path(Seg("record" :: id :: Nil))) =>
+  val bytes = Body.bytes(req)
+

Access to the request body generally has side effects, such as the consumption of a stream that can only be read once. For this reason the body is not accessed from a request matcher, which could be evaluated more than one time, but from utility functions that operate on the request object.

+

In this case, we assigned a reference to the request using req @ and then read its body into a byte array–on the assumption that its body will fit into available memory. That aside, a minor annoyance is that this code introduces some repetition in the matching expression.

+
case GET(Path(Seg("record" :: id :: Nil))) => ???
+case req @ PUT(Path(Seg("record" :: id :: Nil))) => ???
+

An alternative is to match first on the path, then on the method:

+
case req @ Path(Seg("record" :: id :: Nil)) => req match {
+  case GET(_) => ???
+  case PUT(_) => ???
+  case _ => ???
+}
+

This approach eliminates the duplicated code, but it’s important to recognize that it behaves differently as well. The original intent partial function was simply not defined for request to that path that were not a GET or a PUT. The latest one matches any request to that path, and therefore it must return a value for all methods with its match expression.

+

Importantly, delaying the match on request method simplified the intent partial function. What used to be two cases is now one, and we could add support for other methods like DELETE without adding any complexity to its pattern matching. This is worth noting because ifDefined is called on every intent at least once prior to its evaluation. By making the intent more broadly defined, we’ve reduced the complexity of that and potentially improved runtime performance.

+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/06/b.html b/06/b.html new file mode 100644 index 0000000..54933e2 --- /dev/null +++ b/06/b.html @@ -0,0 +1,316 @@ + + + + +Within the Parameters · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Within the Parameters

+

Extracting Params

+

Requests are commonly accompanied by named parameters, either in the query string of the URL or in the body of a POST. Unfiltered supports access to these parameters with the Params extractor.

+
import unfiltered.request._
+import unfiltered.response._
+val pEcho = unfiltered.filter.Planify {
+  case Params(params) =>
+    ResponseString(params("test").toString)
+}
+

The type of params extracted is Map[String, Seq[String]], with a default value of Seq.empty. With this interface, it is always safe to apply the map. But keep in mind that parameters may be specified with no value, and may occur multiple times. The Params extractor returns empty strings for named parameters with no value, as many times in the sequence as they occurred in the request.

+

For example, the query string ?test&test=3&test produces the sequence of strings "", "3", "". You can check this yourself by querying the plan defined above:

+
unfiltered.jetty.Server.anylocal.plan(pEcho).run()
+

Routing by Parameter

+

While the Params extractor is useful for accessing parameters, it doesn’t provide any control flow to an intent partial function.

+

If you want to route requests based on the parameters present, you’ll need to nest a custom extractor inside Params. For this Unfiltered provides a Params.Extract base class:

+
object Test extends Params.Extract("test", Params.first)
+

The above extractor will match on the first parameter named “test” in a request. If no parameters are named test, the pattern does not match. However, a named parameter with no value would match. We can exclude this possibility with a richer definition.

+
object NonEmptyTest extends Params.Extract(
+  "test",
+  Params.first ~> Params.nonempty
+)
+

The second parameter of the Params.Extract constructor is a function Seq[String] => Option[B], with B being the type extracted. The values first and nonempty are functions defined in the Params object that may be chained together with ~> (as with response functions).

+

Typically the chain begins with first, to require at least one parameter of the given name and discard the rest. Subsequent functions may require a nonempty value as above, or produce a trimmed string, or an int value from the string.

+

When a parameter transformation function fails, None is produced and the extractor does not match for the request. Knowing this, you can write your own transformation functions using map and filter.

+
object NotShortTest extends Params.Extract(
+  "test",
+  Params.first ~> { p: Option[String] =>
+    p.filter { _.length > 4 }
+  }
+)
+

There’s also a convenience function to simplify the definition of transformation predicates.

+
object NotShortTest2 extends Params.Extract(
+  "test",
+  Params.first ~> Params.pred { _.length > 4 }
+)
+

Try it all out in this server, which returns 404 unless provided with a “pos” parameter that is a positive integer, and “neg” that is negative.

+
object Pos extends Params.Extract(
+  "pos",
+  Params.first ~> Params.int ~>
+    Params.pred { _ > 0 }
+)
+object Neg extends Params.Extract(
+  "neg",
+  Params.first ~> Params.int ~>
+    Params.pred { _ < 0 }
+)
+val intEcho = unfiltered.filter.Planify {
+  case Params(Pos(pos) & Neg(neg)) =>
+    ResponseString("%d %d".format(pos,neg))
+}
+unfiltered.jetty.Server.anylocal.plan(intEcho).run()
Note
+

The & extractor matches when the extractor to its left and right match, in this case to require multiple parameters.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/06/c.html b/06/c.html new file mode 100644 index 0000000..40636b4 --- /dev/null +++ b/06/c.html @@ -0,0 +1,285 @@ + + + + +Response Functions · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Response Functions

+

Response Function and Combinators

+

With a typical request-response cycle intent, the partial function’s return value is of Unfiltered’s type ResponseFunction. A response function takes a response object, presumably mutates it, and returns the same response object.

+

Unfiltered includes a number of response functions for common response types. Continuing the “record” example, in some cases we may want to respond with a particular string:

+
case PUT(_) =>
+  // ...
+  ResponseString("Record created")
+

We should also set a status code for this response. Fortunately there is a predefined function for this too, and response functions are easily composed. Unfiltered even supplies a chaining combinator ~> to make it pretty:

+
case PUT(_) =>
+  // ...
+  Created ~> ResponseString("Record created")
+

If we had some bytes, they would be as easy to serve as strings:

+
case GET(_) =>
+  // ...
+  ResponseBytes(bytes)
+

Passing or Handling Errors

+

And finally, for the case of unexpected methods we have a few choices. One option is to pass on the request:

+
case _ => Pass
+

The Pass response function is a signal for the plan act as if the request was not defined for this intent. If no other plan responds to the request, the server may respond with a 404 eror. But we can improve on that by ensuring that any request to this path that is not an expected method receives an appropriate response:

+
case _ => MethodNotAllowed ~>
+            ResponseString("Must be GET or PUT")
+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/06/d.html b/06/d.html new file mode 100644 index 0000000..254ea87 --- /dev/null +++ b/06/d.html @@ -0,0 +1,309 @@ + + + + +Silly Store · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Silly Store

+

Opening the Store

+

Using the request matchers and response functions outlined over the last couple of pages, we have everything we need to build a naive key-value store.

+
import unfiltered.request._
+import unfiltered.response._
+
+object SillyStore extends unfiltered.filter.Plan {
+  @volatile private var store = Map.empty[String, Array[Byte]]
+  def intent = {
+    case req @ Path(Seg("record" :: id :: Nil)) => req match {
+      case GET(_) =>
+        store.get(id).map(ResponseBytes).getOrElse {
+          NotFound ~> ResponseString("No record: " + id)
+        }
+      case PUT(_) =>
+        SillyStore.synchronized {
+          store = store + (id -> Body.bytes(req))
+        }
+        Created ~> ResponseString("Created record: " + id)
+      case _ =>
+        MethodNotAllowed ~> ResponseString("Must be GET or PUT")
+    }
+  }
+}
+

Go ahead and paste that into a console. Then, execute the plan with a server, adjusting the port if your system does not have 8080 available.

+
unfiltered.jetty.Server.local(8080).plan(SillyStore).run()
+

The method local, like anylocal, binds only to the loopback interface, for safety. SillyStore is not quite “web-scale”.

+

Curling the Store

+

The command line utility cURL is great for testing HTTP servers. First, we’ll try to retrieve a record.

+
curl -i http://127.0.0.1:8080/record/my+file
+
+

The -i tells it to print out the response headers. Curl does a GET by default; since there is no record by that or any other name it prints out the 404 response with our error message. We have to PUT something into storage.

+
echo "Ta daa" | curl -i http://127.0.0.1:8080/record/my+file -T -
+
+

Curl’s option -T is for uploading files with a PUT, and the hyphen tells it to read the data piped in from echo. Now, we should have better luck with a GET request:

+
curl -i http://127.0.0.1:8080/record/my+file
+
+

That worked, right? We should also be able to replace items:

+
echo "Ta daa 2" | curl -i http://127.0.0.1:8080/record/my+file -T -
+curl -i http://127.0.0.1:8080/record/my+file
+
+

And lastly, test the method error message:

+
curl -i http://127.0.0.1:8080/record/my+file -X DELETE
+
+

405 Method Not Allowed. But it’s a shame, really. DELETE support would be easy to add. Why don’t you give it a try?

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/00.html b/07/00.html new file mode 100644 index 0000000..75a73f4 --- /dev/null +++ b/07/00.html @@ -0,0 +1,253 @@ + + + + +Directives and Validation · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Directives and Validation

+

Pattern matching is an easy and reliable way to handle requests that conform to expected criteria, but what about the requests that don’t? Typically, they fall through to a 404 handler. While this behavior is logical enough from the perspective of a service’s programming, clients of the service might reasonably assume that they’ve supplied the wrong path instead of, as in a previous example, an invalid parameter.

+

With enough fallback cases and nested match expressions, you could program whatever logic you want — including descriptive error handling. But that approach sacrifices the simplicity and readability that made pattern matching attractive in the first place.

+

Fortunately, there is another way. With directives you can express request criteria concisely, and scrupulously handle errors too.

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/a.html b/07/a.html new file mode 100644 index 0000000..9014b3a --- /dev/null +++ b/07/a.html @@ -0,0 +1,307 @@ + + + + +Directive Intent · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Directive Intent

+

Within an Unfiltered plan, an intent function maps from request objects to response functions. With directives, you define a partial function mapping from requests to a Result. We compose this function with another, which produces the standard intent function understood by Unfiltered.

Note
+

Directives are an example of an Unfiltered kit, set of tools providing a higher level of abstraction over the core library.

+

Selective enforcement

+

You can define a directive function using familiar request extractors. Let’s start with a raw intent function.

+
import unfiltered.request._
+import unfiltered.response._
+import unfiltered.jetty.SocketPortBinding
+
+val binding = SocketPortBinding(host = "localhost", port = 8080)
+
+val Simple = unfiltered.filter.Planify {
+  case Path("/") & Accepts.Json(_) =>
+    JsonContent ~> ResponseString("""{ "response": "Ok" }""")
+}
+unfiltered.jetty.Server.portBinding(binding).plan(Simple).run()
+

You can use curl to inspect the different responses:

+
curl -v http://localhost:8080/ -H "Accept: application/json"
+curl -v http://localhost:8080/
+
+

The 404 response page to the second request is not so great. With directives, we’ll do better than that by default.

+
import unfiltered.directives._, Directives._
+
+val Smart = unfiltered.filter.Planify { Directive.Intent {
+  case Path("/") =>
+    for {
+      _ <- Accepts.Json
+    } yield JsonContent ~> ResponseString("""{ "response": "Ok" }""")
+} }
+unfiltered.jetty.Server.portBinding(binding).plan(Smart).run()
+

And with that you’ll see a 406 Not Acceptable response when appropriate.

+

Directives results are typically, but not necessarily, defined in a single for expression. In the expression above we discard the result value of the Accepts.Json directive, as we did previously with the extractor, and map it to our dummy response function.

+

The 406 error response is produced by the directive itself, encapsulating behavior that can be used everywhere. What if you want different error behavior? Make your own directive! (Seriously, you’ll see how on the next page.)

+

One true path

+

You may have noticed that directives transfer (and enrich) routing logic from extractors. If your extractors are reduced to the task of matching against paths alone, you can even eliminate those.

+
val Sweet = unfiltered.filter.Planify { Directive.Intent.Path {
+  case "/" =>
+    for {
+      _ <- Accepts.Json
+    } yield JsonContent ~> ResponseString("""{ "response": "Ok" }""")
+} }
+unfiltered.jetty.Server.portBinding(binding).plan(Sweet).run()
+

It looks pretty different, but remember that here still composes to a standard Unfiltered intent function.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/b.html b/07/b.html new file mode 100644 index 0000000..9654b2c --- /dev/null +++ b/07/b.html @@ -0,0 +1,313 @@ + + + + +Parameters as Directives · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Parameters as Directives

+

Any part of a request can be used to route and accept or reject the request. Request parameters, encoded in a query string or a POST request body, are an open field for richer requests – and user error. We can handle these with directives as well.

+

Parameters Values

+

In HTTP, a parameter key can be specified multiple times with different values. Unfiltered’s base model for parameters is therefore a string key to a sequence of string values in the order they were supplied. This is easy to obtain in a directive.

+
import unfiltered.request._
+import unfiltered.response._
+import unfiltered.directives._, Directives._
+import unfiltered.jetty.SocketPortBinding
+
+val binding = SocketPortBinding(host = "localhost", port = 8080)
+
+unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        in <- parameterValues("in")
+      } yield ResponseString(in.toString)
+  } }
+).run()
+

You can try this service with multiple, one, or no parameters.

+
curl -v http://127.0.0.1:8080/ -d in=one -d in=two
+
+

Even with no parameters, the directive succeeds with an empty sequence. Since it’s not establishing control flow, we could have accessed it just as easily through the Params map. But typically, we do have requirements on our input.

+

I’m thinking of a Number

+

Things get more interesting when require parameters to be in a particular format. From here on out, we’ll be working with interpreters in the unfiltered.directives.data package. Interpreters define abstract operations on data; we can produce directives for a particular request parameter with named.

+
unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        in <- data.as.Int named "in"
+      } yield ResponseString(in.toString)
+  } }
+).run()
+

By testing this service you’ll find that all requests to the root path are accepted, and that the in value is bound to an Option[Int]. If an in request parameter is not present or not a valid int, the value is None. This is a directive, but it’s still one that always produceses a Success result.

Note
+

What about repeated parameters? The object data.as.Int is an interpreter from String to Int, but in HTTP we model parameter values as a sequence of strings. This gap is bridged by another interpreter data.as.String, which chooses the first in the sequence. It’s applied implicitly when needed.

+

We can transform an interpreter that ignores failed interpretation into one that produces a failure response by passing an error handler to its fail method.

+
unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        in <- data.as.Int.fail { (k,v) =>
+          BadRequest ~> ResponseString(
+            s"'$v' is not a valid int for $k"
+          )
+        } named "in"
+      } yield ResponseString(in.toString)
+  } }
+).run()
+

The error handling function receives both the parameter name and given value as parameters. This way, a directive used for more than one parameter can have a specific error message for each.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/c.html b/07/c.html new file mode 100644 index 0000000..64a3704 --- /dev/null +++ b/07/c.html @@ -0,0 +1,312 @@ + + + + +Interpreter Reuse and Implicits · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Interpreter Reuse and Implicits

+

Explicit Interpreters

+

In a non-trival application you are likely to have more than one parameter of one method that expects an integer. Instead of defining interpreters inline, as in previous examples, you can define a general interpreter once and use it many places.

+
import unfiltered.request._
+import unfiltered.response._
+import unfiltered.directives._, Directives._
+
+val intValue = data.as.Int.fail { (k,v) =>
+  BadRequest ~> ResponseString(
+    s"'$v' is not a valid int for $k"
+  )
+}
+
+unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        a <- intValue named "a"
+        b <- intValue named "b"
+      } yield ResponseString(
+        (a ++ b).sum + "n"
+      )
+  } }
+).run()
+

In the example above we explicitly reference and apply a single interpreter to parameters “a” and “b”, responding with their sum.

Note
+

Unclear on the summing step? Values a and b are both of the iterable type Option[Int]. We join these with ++ forming a sequence of integers that could be as long as 2 or as short as 0, depending on the input. The sum method on this sequence does what you’d expect, and finally we join with a string.

+

Implicit Interpreters

+

Referencing an interpreter was fairly tidy operation, but as we’ll be using interpreters often and in different applications, naming and recalling names for various types could become tedious. Let’s try it with an implicit.

+
implicit val implyIntValue =
+  data.as.String ~> data.as.Int.fail { (k,v) =>
+    BadRequest ~> ResponseString(
+      s"'$v' is not a valid int for $k"
+    )
+  }
+
+unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        a <- data.as.Option[Int] named "a"
+        b <- data.as.Option[Int] named "b"
+      } yield ResponseString(
+        (a ++ b).sum + "\n"
+      )
+  } }
+).run()
+

The first thing you may notice is that implyIntValue is a bit wordier than its predecessor. An implicit interpreter used for request parameters must interpret from Seq[String]. Think of it as a full interpretation from the input format to the output type. You may define these for any output types you want, and import them into scope wherever you want to use them. Interpreters like response functions can be chained with ~>, and so data.as.String is typically used at the beginning of an interpreter to be used implicit.

+

If it seems like extra work to define implicit interpreters, keep reading. The payoff comes with required parameters.

+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/d.html b/07/d.html new file mode 100644 index 0000000..30d34b2 --- /dev/null +++ b/07/d.html @@ -0,0 +1,332 @@ + + + + +Required Parameters · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Required Parameters

+

So far we’ve learned know how to define implicit interpreters from a sequence of string to any type T and use them with data.as.Option[T]. Now we’ll see how to use the same interpreters for required parameters.

+

Your “required” Function

+

The failure to supply a required parameter must produce an application defined error response. We’ll define a very simple one.

+
import unfiltered.request._
+import unfiltered.response._
+import unfiltered.directives._, Directives._
+
+implicit def required[T] = data.Requiring[T].fail(name =>
+  BadRequest ~> ResponseString(name + " is missing\n")
+)
+

The name of the function is not important when used implicitly, but call it required is a good convention since you may also want to use it explicitly when defining interpreters inline.

+

Using “required” Implicitly

+

With a required function in scope we can use it with any implicit interpreters also in scope. The data.as.String interpreter is imported from the Directives object, so we can use it immediately.

+
unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        opt <- data.as.Option[String] named "opt"
+        req <- data.as.Required[String] named "req"
+      } yield ResponseString(
+        s"opt: $opt req: $req"
+      )
+  } }
+).run()
+

Let’s examine the output from this one with curl:

+
$ curl -v http://127.0.0.1:8080/ -d opt=hello -d req=world
+opt: Some(hello) req: world
+
+

Since req is required to produce a success response, it’s not wrapped in Option or anything else; the type of the bound value is whatever its interpreter produces.

+

Using “required” Explicitly

+

Most interpreters work with an option of the data so that they can be chained together in support of both optional and required parameters. Required is itself an interpreter which unboxes from the Option, so it generally must be the last interpreter in a chain.

+
unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        in <- data.as.BigInt ~> required named "in"
+      } yield ResponseString(
+        in % 10 + "\n"
+      )
+  } }
+).run()
+

This service returns the last digit of the required provided integer. Since we didn’t provide a fail handler for data.as.BigInt, it falls to required to produce a failure response.

+
$ curl http://127.0.0.1:8080/ -d in=1334534
+4
+$ curl http://127.0.0.1:8080/ -d in=1334534a
+in is missing
+
+

To be more specific, we can supply a failure to the integer interpreter.

+
unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        in <- data.as.BigInt.fail((k,v) =>
+          BadRequest ~> ResponseString(s"'$v' is not a valid int for $k\n")
+        ) ~> required named "in"
+      } yield ResponseString(
+        in % 10 + "\n"
+      )
+  } }
+).run()
+

Now each failure condition produces a distinct error.

+
$ curl http://127.0.0.1:8080/ -d in=1334534a
+'1334534a' is not a valid int for in
+$ curl http://127.0.0.1:8080/
+in is missing
+
+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/e.html b/07/e.html new file mode 100644 index 0000000..2311316 --- /dev/null +++ b/07/e.html @@ -0,0 +1,320 @@ + + + + +Independent Failure · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Independent Failure

+

A request that is mapped through a directive can produce either a failure or success response. Usually, this works the way you want. When a PUT request is received for an endpoint that only supports POST, the service can respond with a 405 MethodNotAllowed status without inspecting any request parameters.

+

But among the request parameters themselves, it may be desirable to respond with multiple error messages when there are multiple parameters in error. This can be accomplished by combining directives into a single directive which knows how to bundle the error responses.

+

Normalizing Error Responses

+

Even if you don’t intend to bundle errors right away, it’s a good idea to generate error responses in a consistent way. This allows you to factor out the status code generation and to put error messages in context. One way to do this is with a case class.

+
import unfiltered.request._
+import unfiltered.response._
+import unfiltered.directives._, Directives._
+
+case class OneBadParam(msg: String) extends Responder[Any] {
+  def respond(res: HttpResponse[Any]): Unit =
+    (BadRequest ~> ResponseString(msg + "\n"))(res)
+}
+

We could use this class with a “required” function.

+
implicit def required[T] = data.Requiring[T].fail(name =>
+  OneBadParam(name + " is missing")
+)
+

This cuts out a bit of boiler plate, but things get more interesting when we define a smarter case class.

+

Joinable Responses

+

If we want Unfiltered to combine error responses from multiple directives, we need to specify exactly how that should work. This can be done with a simple variation of the case class defined above.

+
case class BadParam(msg: String) extends ResponseJoiner(msg)(
+  msgs =>
+    BadRequest ~> ResponseString(msgs.mkString("","\n","\n"))
+)
+

Instances of this class are still defined for a single error message msg, but they know how to format a response for multiple messages of the same type. This allows the toolkit to combine many BadParam instances into a single error response, using the response function defined on any one of the instances.

Note
+

The type system guarantees that error messages are of the same type and that any instance can produce a response from them, but it is not guaranteed which instance’s error handler will be used to produce the error response. You should use the same case class, or the same error handling function, for all of your response error instances.

+

We can redefine “required” with this improved error responder.

+
implicit def required[T] = data.Requiring[T].fail(name =>
+  BadParam(name + " is missing")
+)
+

Joining and Splitting Directives

+

Now that we have joinable error responses issued from our required interpreter, we can use the & method of Directive to join them, as well as an unapply method of unfiltered.request.& to split them.

+
import unfiltered.jetty.SocketPortBinding
+
+val binding = SocketPortBinding(host = "localhost", port = 8080)
+
+unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        (a & b & c) <-
+          (data.as.Required[String] named "a") &
+          (data.as.Required[String] named "b") &
+          (data.as.Required[String] named "c")
+      } yield ResponseString(
+        s"a: $a b: $b c: $c"
+      )
+  } }
+).run()
+

In a failure case, the errors objects are combined and returned on separate lines. On success, the combined directive produces nested tuples of the success cases which & extracts in the order produced.

+
$ curl http://127.0.0.1:8080/
+a is missing
+b is missing
+c is missing
+
+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/f.html b/07/f.html new file mode 100644 index 0000000..64864cd --- /dev/null +++ b/07/f.html @@ -0,0 +1,331 @@ + + + + +Interpreters of Your Own Design · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Interpreters of Your Own Design

+

Unfiltered comes with a small number of interpreters for standard Scala types. We may have left out the one you want (send a pull request), or perhaps you’d like to define interpreters for a type specific to your own application. This is in fact a very good idea!

+

Conditional Interpreters

+

A simple way to augment an interpreter is to require a condition for which it is valid. For example, in your application valid identifiers might be non-negative, non-zero integers up to a certain size. Another application might permit a certain set of characters as identifiers.

+

Rather than attempting to anticipate all the ways you might like to constrain input parameters, Unfiltered leaves it to you to define interpreters using the Scala language. Here, we’ll define a simple one that accepts only even integers.

+
import unfiltered.request._
+import unfiltered.response._
+import unfiltered.directives._, Directives._
+
+def badParam(msg: String) =
+  BadRequest ~> ResponseString(msg)
+
+val evenInt = data.Conditional[Int](_ % 2 == 0).fail(
+  (k, v) => badParam("not even: " + v)
+)
+

As a conditional interpreter of integer, evenInt inputs and outputs an integer, failing with an error if it doesn’t satisfy the condition. To make it work seamlessly with request parameters we may define an implicit integer interpreter.

+
implicit val intValue =
+  data.as.String ~> data.as.Int.fail(
+    (k, v) => badParam("not an int: " + v)
+  )
+

Then it’s just a matter of using evenInt like any other interpreter.

+
import unfiltered.jetty.SocketPortBinding
+
+val binding = SocketPortBinding(host = "localhost", port = 8080)
+
+unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        even <- evenInt named "even"
+      } yield ResponseString(
+        even + "\n"
+      )
+  } }
+).run()
+

Fallible Interpreters

+

Conditional interpreters are great for adding application-specific constraints to existing interpreters, but often you’ll need to create interpreters for your own types. These are known as fallible interpreters, under the assumption that any conversion may fail.

+

You can make a fallible interpreter to any type. We’ll demonstrate with a simple typed data store.

+
case class Tool(name: String)
+val toolStore = Map(
+  1 -> Tool("Rock"),
+  2 -> Tool("Paper"),
+  3 -> Tool("Scissors")
+)
+
+val asTool = data.Fallible[Int,Tool](toolStore.get)
+
+implicit def implyTool =
+  data.as.String ~> data.as.Int ~> asTool.fail(
+    (k, v) => badParam(s"'$v' is not a valid tool identifier")
+  )
+

The data.Fallible case class takes a function from its input type to an option of its output type; Map#get fits the bill perfectly. Then we defined a complete, error-capable interpreter so that it’s easy and clean to turn input parameters into tools.

+
unfiltered.jetty.Server.portBinding(binding).plan(
+  unfiltered.filter.Planify { Directive.Intent {
+    case Path("/") =>
+      for {
+        tool <- data.as.Option[Tool] named "id"
+      } yield ResponseString(
+        tool + "\n"
+      )
+  } }
+).run()
+

Let’s see how it works:

+
curl http://127.0.0.1:8080/  -d id=3
+Some(Tool(Scissors))
+
+

With a parameter directive you can interpret the input into any type you like. We used an in-memory map, but it could just as easily be an entity loaded from external storage.

+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/07/g.html b/07/g.html new file mode 100644 index 0000000..791c065 --- /dev/null +++ b/07/g.html @@ -0,0 +1,306 @@ + + + + +Lets wrap this up, Ada · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Let’s wrap this up, Ada

+

We’ve seen how to use directives in general, and how to use interpreters to make our own parameter directives, and even how to make our own interpreters. Our closing example will be one that you’ve had with you all along: the default Unfiltered giter8 template.

+

Setting up the Template

+

If you don’t have the template project already, skip back to the beginning and follow the directions up until the Consoled section.

+

Instead of entering a Scala console this time, we want to examine and use the Scala sources included in the project. Go ahead and compile and run them:

+
sbt run
+
+

The main class in the project will start an HTTP server on some available port, and it will attempt to open the root document on that server in your default browser. If you see a big ugly form, you’re all set.

+

Understanding the Source

+

Take a look at the source for the server, located here:

+
src/main/scala/Example.scala
+
+

You should be able to understand most of what’s happening, but there are a few things worth mentioning. Unlike previous examples in this chapter, this is a web server intended for browser clients. Our output is HTML and our input for the POST is a form serialized by the browser.

+

A simple view function is defined for displaying the page in both its initial, error, and success states. The function takes a map of parameters so that it can serve back the form inputs exactly as they were submitted, without being affected by any interpreters. We can get this separately from our parameter directives, using the trusty old Params extractor.

Note
+

Since we’re just calling out snippets of the code, you won’t be able to copy and paste these into a console as you can with most sections of this documentation. Feel free to play around with the template project source though, that’s what it’s there for.

+
case POST(Params(params)) =>
+  case class BadParam(msg: String)
+  extends ResponseJoiner(msg)( messages =>
+    view(params)(<ul>{
+      for (message <- messages)
+      yield <li>{message}</li>
+    }</ul>)
+  )
+

Also worth noting is that we defined our BadParam case class inside the match expression, since it needs a reference to params to build its error response. Another option would have been to take the params as a constructor parameter for the class.

+

Finally, since we’re dealing with user input via a serialized form rather than a programmatic web service, our expectations for errors are different. An “empty” field in the form is still submitted as a parameter – an empty string. Since this will be a common user error, we should handle it much like we would if the parameter were not submitted at all.

+
val inputString = data.as.String ~>
+  data.as.String.trimmed ~>
+  data.as.String.nonEmpty.fail(
+    (key, _) => BadParam(s"$key is empty")
+  )
+

But of course, we still need to define a required function since it is possible that some client will fail to submit a parameter.

+
implicit def required[T] = data.Requiring[T].fail(name =>
+  BadParam(name + " is missing")
+)
+

Finally, in this case the code keeps the logic of the conditional interpreter separate from the implementation, which is inline.

+
(inputString ~> data.Conditional(palindrome).fail(
+  (_, value) => BadParam(s"'$value' is not a palindrome")
+) ~> required named "palindrome")
+
+def palindrome(s: String) =
+  s.toLowerCase.reverse == s.toLowerCase
+

This is just to show the variety of what’s possible, it’s up to you to decide how to organize and apply your own interpreters. Good luck, and don’t be shy about contributing back interpreters of standard library types back into the Unfiltered directives source!

+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/08/00.html b/08/00.html new file mode 100644 index 0000000..80785f6 --- /dev/null +++ b/08/00.html @@ -0,0 +1,253 @@ + + + + +Application Structure · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Application Structure

+

The previous section showed how to respond to requests using a simple intent function. The building blocks of Unfiltered are easy to grasp, but how do you build a much larger application with them?

+

The short answer is, by using Scala. Unfiltered does not impose idioms on your application structure, it’s just an HTTP translation layer to be applied as you see fit.

+

That said, partial functions are not the most common entry point for web applications and their heavy use in this context may disorient the beginner. This section explores some logical structures to put you on the path to determining your own application design.

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/08/a.html b/08/a.html new file mode 100644 index 0000000..671fba8 --- /dev/null +++ b/08/a.html @@ -0,0 +1,281 @@ + + + + +Planning for Any-thing · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Planning for Any-thing

+

Thanks to one of the darker corners of the Scala type system (*variance*), it’s a cinch to define intents that work with all plans.

+

Agnostic Intents

+
object Hello {
+  val intent = unfiltered.Cycle.Intent[Any, Any] {
+    case _ => ResponseString("Hello")
+  }
+}
+

The object Hello defines an intent with underlying request and response types of Any. As a result, the intent can not statically expect a particular underlying request or response binding. This makes sense, as we want to make an intent that works with any of them.

+

Specific Plans

+

The next step is to supply the same generic intent to different kinds of plans.

+
val helloFilter =
+  unfiltered.filter.Planify(Hello.intent)
+
+val helloHandler =
+  unfiltered.netty.cycle.Planify(Hello.intent)
+

As usual the plans are actual servlet filters or Netty handlers, so you could use them with a server you have configured separately or with a server configured by Unfiltered.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/08/b.html b/08/b.html new file mode 100644 index 0000000..ea6f493 --- /dev/null +++ b/08/b.html @@ -0,0 +1,288 @@ + + + + +Just Kitting · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Just Kitting

+

Unfiltered gives you many extractors to facilitate pattern matching, and it might be helpful to create some extractors specific to an application, but often you want to factor-out broader functionality. That’s where kits come in.

+

The GZip Kit

+

We first had the idea for kits when considering how best to support GZip response encodings. An extractor to match an Accept-Encoding header for gzip would help, and a ResponseFunction to compress the response stream, but these would have to be repeated for every case expression.

+

The GZip kit is a higher level abstraction that can be applied at once to full intent function. The kit will examine the request first, and if appropriate, prepends a compressing function to the response function chain provided by the intent.

+

GZip Kit Definition

+

This part is already done for you in unfiltered-libary, but in case you are curious this is how the GZip kit is defined.

+
object GZip extends unfiltered.kit.Prepend {
+  def intent = unfiltered.Cycle.Intent[Any,Any] {
+    case Decodes.GZip(req) =>
+      ContentEncoding.GZip ~> ResponseFilter.GZip
+  }
+}
+

Unlike a plan’s intent function, this one defines the conditions for which its response function is prepended another intent’s. It sets a header and a FilterOutputStream for the response.

+

GZip Usage

+

This is a very simple plan that will compress its responses if the user-agent supports it:

+
object EchoPlan extends unfiltered.filter.Plan {
+  def intent = unfiltered.kit.GZip {
+    case Path(path) => ResponseString(path)
+  }
+}
+

Do Kit Yourself

+

The higher level abstraction provided by kits can be applied to problems specific to an application just as well as for general problems. Don’t be afraid to experiment, and if you happen to make something that does solve a general problem, please share it!

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/09/00.html b/09/00.html new file mode 100644 index 0000000..952031f --- /dev/null +++ b/09/00.html @@ -0,0 +1,251 @@ + + + + +Identification and Cookies · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Identification and Cookies

+

When remote users are humans interacting with web browsers, applications are often concerned with their identity and preferences. This section covers relevant interfaces defined for HTTP.

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/09/a.html b/09/a.html new file mode 100644 index 0000000..28bb8f7 --- /dev/null +++ b/09/a.html @@ -0,0 +1,278 @@ + + + + +Whos Who · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Who’s Who

+

Out of the box HTTP provides you with basic authentication, a simple way to specify a name and password for a request. These credentials are transferred as an unencrypted request header, so applications should secure both credentials and message bodies by requiring HTTPS for any protected resources.

+

Below, we define a kit that extracts a username and password via basic HTTP authentication and verifies those credentials before letting anyone through the gate. It presumes a Users service that would validate the user’s credentials.

+
trait Users {
+  def auth(u: String, p: String): Boolean
+}
+
+import unfiltered.request._
+import unfiltered.response._
+import unfiltered.Cycle
+
+case class Auth(users: Users) {
+  def apply[A,B](intent: Cycle.Intent[A,B]) =
+    Cycle.Intent[A,B] {
+      case req@BasicAuth(user, pass) if(users.auth(user, pass)) =>
+        Cycle.Intent.complete(intent)(req)
+      case _ =>
+        Unauthorized ~> WWWAuthenticate("""Basic realm="/"""")
+    }
+}
+

By applying this kit we can layer basic authentication around any intent in a client application.

+
case class App(users: Users) extends
+unfiltered.filter.Plan {
+  def intent = Auth(users) {
+    case _ => ResponseString("Shhhh!")
+  }
+}
+

Also, don’t give the password to any newspaper reporters.

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/09/b.html b/09/b.html new file mode 100644 index 0000000..5874608 --- /dev/null +++ b/09/b.html @@ -0,0 +1,290 @@ + + + + +Remembrance of Things Past · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Remembrance of Things Past

+

Basic authentication is a lightweight solution to general authentication, but what if we need to remember a little more information about a user’s session? That’s where cookies come in.

+

Let’s build on our authenticated application and add support for simple cookie handling.

+
import unfiltered.Cookie
+
+case class App(users: Users) extends
+unfiltered.filter.Plan {
+  def intent = Auth(users) {
+    case Path("/") & Cookies(cookies) =>
+      ResponseString(cookies("pref") match {
+        case Some(c: Cookie) =>
+          "you pref %s, don't you?" format c.value
+        case _ => "no preference?"
+      })
+    case Path("/prefer") & Params(p) =>
+      // let's store it on the client
+      SetCookies(Cookie("pref", p("pref")(0))) ~>
+        Redirect("/")
+    case Path("/forget") =>
+      SetCookies(Cookie("pref", "")) ~>
+        Redirect("/")
+  }
+}
+

Now that we have a slightly more sophisitcated basic application let’s mount it with a user named jim and a password of j@m.

+
object JimsAuth extends Users {
+  def auth(u: String, p: String) =
+    u == "jim" && p == "j@m"
+}
+
+val binding = SocketPortBinding(host = "localhost", port = 8080)
+
+unfiltered.jetty.Server.portBinding(binding).plan(
+  App(JimsAuth)
+).run
+

In your browser, open the url http://localhost:8080/ and you should be greeted with its native authentication dialog. Enter jim and j@m, if you are feeling authentic.

+

Once authenticated you should see simple text questioning your preferences. Why is this? Well, you have yet to tell the server what you prefer. In your url bar, enter the address

+
http://localhost:8080/prefer?pref=kittens
+
+

or whatever else you have a preference for. Now, every time you request http://localhost:8080/ the server has remembered your preference for you. This is a cookie at work!

+

If you change your mind you can always hit the prefer path with a new pref or just tell the server to forget it by entering the address http://localhost:8080/forget.

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/10/00.html b/10/00.html new file mode 100644 index 0000000..77c665d --- /dev/null +++ b/10/00.html @@ -0,0 +1,251 @@ + + + + +Netty Plans · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Netty Plans

+

Unfiltered’s interfaces to Netty reflect the lower-level nature of Netty as compared to Servlet Filters. This gives greater flexibility and power to the application, necessarily requiring greater responsibility and attention to detail by the programmer. If you’re up for the challenge or just want to play with something new, then give it a whirl.

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/10/a.html b/10/a.html new file mode 100644 index 0000000..c515b03 --- /dev/null +++ b/10/a.html @@ -0,0 +1,278 @@ + + + + +Trying Netty · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Trying Netty

+

As with the Jetty server used for earlier console hacking, for Netty we also need a starter project. If you don’t have the g8 command line tool installed, please go back to that page until you do.

+

Enter the Console

+

This step will fetch a number of dependencies and sometimes certain repositories are a little wonky, so cross your fingers.

+
g8 unfiltered/unfiltered-netty --name=nettyplayin
+cd nettyplayin
+sbt console
+
+

Once you do get to a console, this should just work:

+
import unfiltered.response._
+val hello = unfiltered.netty.cycle.Planify {
+  case _ => ResponseString("hello world")
+}
+unfiltered.netty.Server.http(8080).plan(hello).run()
+

Direct a web browser to http://127.0.0.1:8080/ and you’ll be in hello world business.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/10/b.html b/10/b.html new file mode 100644 index 0000000..fcc4708 --- /dev/null +++ b/10/b.html @@ -0,0 +1,301 @@ + + + + +Execution and Exceptions · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Execution and Exceptions

+

That’s pretty nifty how we started up a Netty server in a few lines of code, just like with Jetty, right? But while Planify is really handy for experimenting in the console, it makes a lot of assumptions that are unlikely to hold for a live server.

+

A Less Simple Plan

+

Let’s see what the plan looks like with those defaults made explicit.

+
import unfiltered.netty._
+
+trait MyPlan extends cycle.Plan with
+cycle.ThreadPool with ServerErrorResponse
+
+object Hello extends MyPlan {
+  def intent = {
+    case _ => ResponseString("hello world")
+  }
+}
+
+

The traits define methods needed by cycle.Plan. But what for?

+

Deferred Execution

+

Netty handlers are invoked on an I/O worker thread. In some scenarios (including this one, actually) it would be just fine to prepare a response on this thread. If the work is CPU-bound (does not perform blocking operations), you can mix in the cycle.SynchronousExecution trait instead, for no-overhead execution.

+

But a typical web application does need to access a database or something, and the typical way to do this is with a blocking call. That’s why Planify uses the cycle.ThreadPool trait, which defers application of the intent partial function to a cached thread pool.

+

Deference has its Memory Limits

+

Unfortunately, that’s not the end of the story with deferred execution. Applications also need to worry about running out of memory. If you defer request handling jobs to an executor queue as fast as Netty can accept requests, any heap limit can be exceeded with a severe enough usage spike.

+

To avoid that kind of failure, you should equip your plans with an executor that consumes a limited amount of memory and blocks on incoming requests when that limit is reached. If you’ve defined a simple local base plan (like the MyPlan above), you can customize it later (ideally, before your server throws an out of memory exception) with a memory-aware thread pool executor.

+
trait MyPlan extends cycle.Plan with
+cycle.DeferralExecutor with cycle.DeferredIntent with
+ServerErrorResponse {
+  def underlying = MyExecutor.underlying
+}
+object MyExecutor {
+  import org.jboss.netty.handler.execution._
+  lazy val underlying = new MemoryAwareThreadPoolExecutor(
+    16, 65536, 1048576)
+}
+
+

Expecting Exceptions

+

The ServerErrorResponse trait also implements behavior that your application will likely need to customize, sooner or later. Instead of mixing in that trait, you can implement onException directly in your base plan. For a starting point see the source for the provided exception handler, which logs the stack trace to stdout and serves a very terse error response. Normally an application will hook into its own logger and serve a custom error page or redirect.

+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/10/c.html b/10/c.html new file mode 100644 index 0000000..5223d83 --- /dev/null +++ b/10/c.html @@ -0,0 +1,272 @@ + + + + +Chunked Requests · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Chunked Requests

+

If you’re handling HTTP POSTs, it’s very possible that your browser or non-browser clients will send requests using chunked transfer encoding. This part of HTTP 1.1 is great for keeping messages short, but not so great for short and simple NIO servers.

+

An Inconvenient Party Line

+

The challenge for your server, as it is handling many concurrent requests, is to maintain the state of a message that is split into many chunks. For example if the request body contains url-encoded parameters, you must assemble all the chunks together to have uniform access to any parameter.

+

Netty provides a simple solution for cases like this: its HttpChunkAggregator assembles chunks into a single message. The caveat is that the full message is necessarily loaded into memory, and it could be arbitrarily large. The interface therefore requires you to chose a limit for the aggregated message size; any chunked request that exceeds this limit will raise a TooLongFrameException. (For general file upload support, see the netty-uploads module.)

+

Unfiltered’s Netty server-builder provides a convenient chunked interface for adding aggregating handlers to your pipeline:

+
unfiltered.netty.Server(8080).chunked(1048576).plan(hello).run()
+
+

If you want quick, easy, and limited support for chunked requests, don’t forget to call this method on your server builder.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/10/d.html b/10/d.html new file mode 100644 index 0000000..89b5d0f --- /dev/null +++ b/10/d.html @@ -0,0 +1,302 @@ + + + + +Going Asynchronous · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Going Asynchronous

+

While the cycle.Plan gives us the means to implement a traditional request-response cycle, with unfiltered-netty you also have the option to respond asynchronously to the request. When used with other asynchronous libraries, this can result in more efficient use of threads and support for more simultaneous connections.

+

Other Asynchronous Libraries

+

Luckily, the “nettyplayin” project created in the last few pages already depends on a second asynchronous library, dispatch-nio, which acts as client for HTTP requests to other services. Using an async.Plan with dispatch.nio.Http, we can query other HTTP services to satisfy a request without hoarding a thread for the many milliseconds it could take to perform that request.

+

Always Sunny in…

+

Google has a secret weather API. Let’s use that until they take it offline.

+
import dispatch._
+val h = new nio.Http
+def weather(loc: String) =
+  :/("www.google.com") / "ig/api" <<? Map(
+    "weather" -> loc)
+
+

Paste that into a console, then you can print the response like this:

+
h(weather("San+Francisco") >- { x => println(x) })
+
+

You may notice that the prompt for the next command appears before the response is printed. It’s working!

+

Taking the Temperature

+

Now all we have to do is consume this service from a server.

+
import unfiltered.response._
+import unfiltered.netty._
+
+val temp = async.Planify {
+  case req =>
+    h(weather("San+Francisco") <> { reply =>
+      val tempC = (reply \\\\ "temp_c").headOption.flatMap {
+        _.attribute("data")
+      }.getOrElse("unknown")
+      req.respond(PlainTextContent ~>
+                  ResponseString(tempC + "°C"))
+    })
+}
+
+Http(8080).plan(temp).run()
+
+

Pasting all that into a console should start up a server that always gives you the temperature in San Francisco (the closest city by that name to Google’s headquarters, anyway). When you are done with this hardcoded showpiece, shut down the Dispatch executor it was using so we can move on real deal.

+
h.shutdown()
+
+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/10/e.html b/10/e.html new file mode 100644 index 0000000..6211f9a --- /dev/null +++ b/10/e.html @@ -0,0 +1,297 @@ + + + + +Asyncrazy Temperature Server · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Asyncrazy Temperature Server

+

Putting this all together, we can build a server that would very efficiently get your IP address banned by Google if you actually put it on the web. But it’s totally cool to run it locally. We think.

+
import dispatch._
+import unfiltered.request._
+import unfiltered.response._
+import unfiltered.netty._
+
+object Location extends
+Params.Extract("location", Params.first ~> Params.nonempty)
+
+object Temperature extends async.Plan with ServerErrorResponse {
+  val http = new nio.Http
+  def intent = {
+    case req @ GET(_) =>
+      req.respond(view("", None))
+    case req @ POST(Params(Location(loc))) =>
+      http(:/("www.google.com") / "ig/api" <<? Map(
+        "weather" -> loc) <> { reply =>
+          val tempC = for {
+            elem <- reply \\\\ "temp_c"
+            attr <- elem.attribute("data")
+          } yield attr.toString
+          req.respond(view(loc, tempC.headOption))
+        }
+      )
+  }
+  def view(loc: String, temp: Option[String]) = Html(
+    <html>
+      <body>
+        <form method="POST">
+          Location:
+          <input value={loc} name="location" />
+          <input type="submit" />
+        </form>
+        { temp.map { t => <p>It's {t}°C in {loc}!</p> }.toSeq }
+      </body>
+    </html>
+  )
+}
+
+

Put all that into a console, then start it:

+
Http(8080).chunked(1048576).plan(Temperature).run()
+
+

You can lookup the current temperature for almost anywhere; just type in a place name or postal code and Google will probably figure it out.

+

When you are done checking the temperature of exciting places around the world, shutdown the handler’s Dispatch executor.

+
Temperature.http.shutdown()
+
+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/11.html b/11.html new file mode 100644 index 0000000..65682e5 --- /dev/null +++ b/11.html @@ -0,0 +1,278 @@ + + + + +Jetty Extras · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Jetty Extras

+

Serving Resources from a relative path

+

Sometimes you may want to serve resources from a relative path, for example a sibling directory located at ../client. But paths containing .. are considered aliased and Jetty disallows these by default, as described in this policy.

+

If you’ve evaluated the security risks described in the link above and wish to enable aliases in paths, you can do so with allowAliases(true), eg:

+
import unfiltered.jetty.ContextAdder
+
+unfiltered.jetty.Server.http(8080).
+  context("/client"){ ctx: ContextAdder =>
+    ctx.resources(new java.net.URL(
+      """file:../client"""
+    )).allowAliases(true)
+  }.plan(myPlan).run()
+

Enabling Request Logs

+

Jetty can be configured to log all requests in Common or Extended formats with requestLogging. This is a global, not per-context, setting. At minimum you need to specify where to log to:

+
unfiltered.jetty.Server.http(8080).plan(myPlan).requestLogging("/tmp/access.log").run()
+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/12.html b/12.html new file mode 100644 index 0000000..ac6fe0b --- /dev/null +++ b/12.html @@ -0,0 +1,301 @@ + + + + +ScalaTest · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

ScalaTest

+

Helps creating feature tests for Unfiltered apps with scalatest.

+

Usage

+

Here is a test written using this support.

+
class ExampleFeature extends FeatureSpec with unfiltered.scalatest.jetty.Served
+                                              with unfiltered.scalatest.Hosted
+                                              with GivenWhenThen with Matchers {
+
+  def setup = {
+    _.plan(new App)
+  }
+
+  feature("rest app") {
+    scenario("should validate integers") {
+      Given("an invalid int and a valid palindrome as parameters")
+        val params = Map("int" -> "x", "palindrome" -> "twistsiwt")
+      When("parameters are posted")
+        val response = httpx(req(host <<? params))
+      Then("status is BAD Request")
+        response.code should be(400)
+      And("""body includes "x is not an integer" """)
+        response.as_string should include("x is not an integer")
+    }
+
+    scenario("should validate palindrome") {
+      Given("a valid int and an invalid palindrome as parameters")
+        val params = Map("int" -> "1", "palindrome" -> "sweets")
+      When("parameters are posted")
+        val response = httpx(req(host <<? params))
+      Then("status is BAD Request")
+        response.code should be(400)
+      And("""body includes "sweets is not a palindrome" """)
+        response.as_string should include("sweets is not a palindrome")
+    }
+  }
+}
+

Limitations

+

Only Feature type scalatests are supported.

+ +
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/99.html b/99.html new file mode 100644 index 0000000..644220a --- /dev/null +++ b/99.html @@ -0,0 +1,299 @@ + + + + +Whos Using Unfiltered? · Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Who’s Using Unfiltered?

+

These are some projects and companies that have used Unfiltered. Are you using Unfiltered? Fork this page on github.

+

Meetup

+

Unfiltered, Netty, and RabbitMQ run Meetup’s real-time APIs.

+

Novus

+

Entire web layer of the Novus real-time financial analytics platform has been built by maxaf using Unfiltered. We have a myriad custom request unapplies and use Scalate extensively. There’s no better way to express web application concerns than using Scala idioms. High engineer productivity and type safety have contributed a lot to our product’s bottom line.

+

Remember The Milk

+

Remember The Milk uses Unfiltered for all web services, including the web app, public API, real time updates and syncing endpoints for Android, iOS and Outlook.

+

Trust Metrics

+

Trust Metrics uses Unfiltered everywhere. We use it in our API, our client facing app, our intranet, and even our web crawler. We use it because it’s simple and nonintrusive–it lets us decide how to add web to our app, unlike other frameworks (Grails/Rails/Django), which do all of the deciding for you.

+

EAT.PRAY.MOVE

+

EAT.PRAY.MOVE organizes, facilitates, and instructs yoga retreats in Italy and other Mediterranean areas. This is a simple crud website hosted on Google App Engine using Scalate for templating and highchair for persisting scala objects to the Google data store. Unfiltered runs the show.

+

lssn.me

+

lssn.me is a simple URL shortening service hosted on Google App Engine. Unfiltered services the requests and highchair handles persistence.

+

nescala.org

+

The event site for the North East Scala Symposium is written using Unfiltered’s filter plans and hosted on Heroku. https://github.com/nescalas/northeast-scala-symposium

+

pamflet

+

The documentation preview server in pamflet is Unfiltered.

+

picture show

+

Self-contained slide-show presentations authored in basic markdown, served in html and css served by Unfiltered.

+

scalaxb

+

scalaxb-appengine is an Unfiltered API to run scalaxb over the web on appengine.

+

unplanned

+

A super simple run anywhere adhoc HTTP server using conscript and the Unfiltered jetty module.

+

penger.no

+

penger.no is a Norwegian web based service whose aim is to help consumers compare the prices and terms of bank and insurance providers to find the best offer.

+

REA Group

+

REA Group is a digital advertising company that operates Australia’s leading property websites and real estate websites in Europe, Asia and the US. Unfiltered is our default choice when building the Scala-based HTTP microservices that power sites like https://www.realestate.com.au.

+
+ +
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..8614467 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +unfiltered.ws diff --git a/css/fonts/icons.eot b/css/fonts/icons.eot new file mode 100644 index 0000000..a5203e8 Binary files /dev/null and b/css/fonts/icons.eot differ diff --git a/css/fonts/icons.svg b/css/fonts/icons.svg new file mode 100644 index 0000000..58c7488 --- /dev/null +++ b/css/fonts/icons.svg @@ -0,0 +1,12 @@ + + + +Generated by Fontastic.me + + + + + + + + diff --git a/css/fonts/icons.ttf b/css/fonts/icons.ttf new file mode 100644 index 0000000..6da4b13 Binary files /dev/null and b/css/fonts/icons.ttf differ diff --git a/css/fonts/icons.woff b/css/fonts/icons.woff new file mode 100644 index 0000000..2c7e917 Binary files /dev/null and b/css/fonts/icons.woff differ diff --git a/css/page.css b/css/page.css new file mode 100644 index 0000000..86b3638 --- /dev/null +++ b/css/page.css @@ -0,0 +1,929 @@ +@charset "UTF-8"; + +/* fonts */ + +@font-face { + font-family: "icons"; + src:url("fonts/icons.eot"); + src:url("fonts/icons.eot?#iefix") format("embedded-opentype"), + url("fonts/icons.woff") format("woff"), + url("fonts/icons.ttf") format("truetype"), + url("fonts/icons.svg#icons") format("svg"); + font-weight: normal; + font-style: normal; +} + +/* body */ + +body { + background: #fff; + padding: 0; + margin: 0; + font-weight: 400; + font-style: normal; + line-height: 1.4em; + position: relative; + cursor: default; + font: 1em "Roboto", "Helvetica Neue", "Helvetica", Arial, sans-serif; + color: #333333; + font-smoothing: antialiased; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-font-size-adjust: none; + text-rendering: optimizeLegibility; +} + +/* headers */ + +h1 { + font-family: inherit; + font-size: 2.6em; + font-weight: 300; + color: #333333; + margin-bottom: 0.4em; + margin-top: 1.1em; +} + +h1:first-child { + margin-top: 0; +} + +h2 { + font-family: inherit; + font-size: 1.8em; + font-weight: 400; + color: #333333; + margin-bottom: 0.2em; + margin-top: 1.3em; +} + +h2:first-child { + margin-top: 0; +} + +h3 { + font-family: inherit; + font-size: 1.125em; + font-weight: 700; + color: #333333; + margin-top: 1.3em; +} + +h3:first-child { + margin-top: 0; +} + +h4 { + font-family: inherit; + font-size: 1em; + font-weight: 700; + color: #333333; + margin-top: 1.3em; +} + +h4:first-child { + margin-top: 0; +} + +h5 { + font-family: inherit; + font-size: 1em; + color: #333333; + margin-top: 1.3em; +} + +h5:first-child { + margin-top: 0; +} + +h6 { + font-family: inherit; + font-size: 1em; + color: #333333; + margin-top: 1.3em; +} + +h6:first-child { + margin-top: 0; +} + +/* text */ + +p { + font-family: inherit; + font-size: 1em; + color: #333333; + line-height: 1.45em; + margin: 1em 0em; +} + +/* links */ + +a { + font-family: inherit; + color: #4078c0; + text-decoration: none; + cursor: pointer; +} + +a:link { + color: #4078c0; +} + +a:visited { + color: #4078c0; +} + +a:hover { + color: #4078c0; + text-decoration: underline; +} + +a:active { + color: #4078c0; +} + +/* header anchors */ + +a.anchor .anchor-link:before { + content: "§"; + font-size: 18px; + font-family: "icons" !important; + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1.2; + vertical-align: middle; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { + visibility: hidden; + position: absolute; + display: block; + width: 30px; + margin-left: -30px; + padding-right: 3px; + text-align: right; + text-decoration: none; +} + +h1:hover > a.anchor, h2:hover > a.anchor, h3:hover > a.anchor, h4:hover > a.anchor, h5:hover > a.anchor, h6:hover > a.anchor { + visibility: visible; + color: inherit; + text-decoration: none; +} + + +/* table */ + +table th { + background: #ffffff; + border: solid 1px #dddddd; +} + +table td { + background: #ffffff; + border: solid 1px #dddddd; +} + +/* code */ + +pre { + padding: 1rem !important; + border: 1px solid #dddddd !important; + margin: 0 0 1rem 0 !important; + white-space: pre; + overflow: auto; + line-height: 0.9em !important; +} + +code { + line-height: 1.45em !important; + font-family: Consolas, "Liberation Mono", Courier, monospace; + font-size: 0.85em !important; + font-weight: normal !important; + padding: 0 !important; +} + +pre > code { + background: none; + border: none; +} + +p code { + border: none; + color: #0c323b; + padding: 0 0.2em !important; +} + +li code { + border: none; + color: #0c323b; + padding: 0 0.2em !important; +} + +/* Github-like */ + +pre.prettyprint span.str { + color: #183691; +} +pre.prettyprint span.kwd { + color: #000000; + font-weight: bold; +} +pre.prettyprint span.com { + color: #999988; + font-style: italic; +} +pre.prettyprint span.typ { + color: #445588; + font-weight: bold; +} +pre.prettyprint span.lit { + color: #009999 +} +pre.prettyprint span.pun { + color: #000000; + font-weight: bold; +} +pre.prettyprint span.pln { + color: #000000 +} +pre.prettyprint span.tag { + color: navy +} +pre.prettyprint span.atn { + color: teal +} +pre.prettyprint span.atv { + color: #dd1144 +} +pre.prettyprint span.dec { + color: #990000 +} +pre.prettyprint span.var { + color: #000000 +} +pre.prettyprint span.fun { + color: #990000 +} + +/* tabbed code snippets */ + +dl.tabbed { + position: relative; +} + +dl.tabbed dt { + float: left; + display: inline-block; + position: relative; + left: 1px; + margin-left: -1px; +} + +dl.tabbed dt.current { + z-index: 2; +} + +dl.tabbed dt a { + display: block; + border: 1px solid #f7f7f7; + padding: 0 20px; + height: 30px; + line-height: 2; + color: #4078c0; + text-decoration: none; +} + +dl.tabbed dt a:hover { + background: #f7f7f7; +} + +dl.tabbed dt.first a { + border-top-left-radius: 5px; +} + +dl.tabbed dt.last a { + border-top-right-radius: 5px; +} + +dl.tabbed dt.current a { + background-color: #f7f7f7; + border-color: #dddddd; + border-bottom: 0; + padding-bottom: 1px; +} + +dl.tabbed dt.current a { + color: #0c323b; + outline: none; +} + +dl.tabbed dd { + position: absolute; + width: 100%; + left: 0; + top: 29px; +} + +dl.tabbed dd.current { + z-index: 1; +} + +dl.tabbed dd pre { + border-top-left-radius: 0 !important; +} + +dl.tabbed dd.has-note pre { + border-bottom: 0 !important; + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; + margin-bottom: 0 !important; +} + +dl.tabbed dd.has-note blockquote { + color: #0c323b; + border: solid #dddddd; + border-width: 1px 1px 1px 10px; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + margin-top: 0; + font-style: italic; +} + +/* blockquotes */ + +blockquote { + border-left: 4px solid rgb(221, 221, 221); + margin: 1.5em 0; + padding: 1em 20px; + color: rgb(119, 119, 119); + line-height: 1.4em; +} + +blockquote p { + margin: 0; + line-height: 1.4em; +} + +blockquote p ~ p { + margin-top: 1em; +} + +blockquote p code { + background: #fff; + padding-right: 0.4em !important; +} + +/* callout */ + +.callout { + border: none; + border-left: 10px solid #4078c0; + background-color: rgba(64, 120, 192, 0.1); +} + +.callout.warning { + border-color: #DB504A; + background-color: #fff3d9; +} + +.callout .callout-title { + font-weight: bold; + margin-bottom: 0.33em; +} + +.callout div ~ p { + margin-top: 0; +} + +.callout p ~ p { + margin-top: 1em; + margin-bottom: 0; +} + +.callout p code { + background: #fff; + padding-right: 0.4em !important; +} + +/* footnotes */ + +small { + display: block; +} + +/* logo links */ + +.logo .svg-icon-logo { + height: 24px; + width: 112px; +} + +.logo:hover { + text-decoration: none; +} + +.svg-icon-logo .svg-icon-logo-text { + fill: #ffffff; +} + +.logo:hover .svg-icon-logo .svg-icon-logo-text { + fill: #4078C0; +} + +/* site header */ + +.site-header { + background: #fcfcfc; + border-bottom: solid 1px #cccccc; +} + +.site-header .title { + display: inline-block; + float: left; + height: 70px; + line-height: 70px; + font-weight: 400; + font-size: 1.4em; +} + +.site-header .title a:link, .site-header .title a:visited { + color: #515151; +} + +.site-header .title a:hover { + color: #515151; + text-decoration: none; +} + +.site-header .off-canvas-toggle { + float: left; +} + +.site-header .off-canvas-toggle .svg-icon-menu { + height: 40px; + width: 40px; + margin-top: 1rem; + margin-right: 1rem; +} + +.site-header .off-canvas-toggle .svg-icon-menu .svg-icon-menu-path { + fill: #000; +} + +.site-header .off-canvas-toggle .svg-icon-menu:hover .svg-icon-menu-path { + fill: #4183C4; +} + +.site-header .logo { + float: right; + margin-top: 1rem; + text-align: right; + color: #000; +} + +/* page header */ + +.page-header { + background: #ffffff; + margin-top: 1rem; +} + +.page-header .nav-breadcrumbs { + border-bottom: 1px solid #c2d2dc; +} + +.page-header .nav-breadcrumbs ul { + display: block; + overflow: hidden; + margin: 0; + padding: 15px; + list-style: none; + font-size: 0.9em; +} + +.page-header .nav-breadcrumbs li { + float: left; + margin: 0; +} + +.page-header .nav-breadcrumbs li:before { + content: "/"; + margin: 0 5px; + color: #c2d2dc; +} + +.page-header .nav-breadcrumbs li:first-child:before { + content: ""; + margin: 0; +} + +.page-header .nav-breadcrumbs li a { + color: #4078c0; + font-weight: normal; +} + +/* content */ + +.site-content .row { + max-width: 90rem; +} + +.page-content { + background: #ffffff; + min-height: 600px; + padding: 2.5rem 0; +} + +/* sidebar */ + +.sidebar { + background: #ffffff; + width: 100%; + padding: 0; +} + +.sidebar .nav-toc { + padding-top: 1rem; +} + +/* navigation */ + +.nav-home { + background: #f7f7f7; + line-height: 2rem; +} + +.nav-home a { + display: block; + color: #4078c0; + font-weight: bold; + font-size: 1rem; + padding-left: 1rem; +} + +.nav-home a.active { + background: #e7e7e7; +} + +.nav-home a:hover { + background: #e7e7e7; + text-decoration: none; +} + +.nav-home a .home-icon { + font-size: 18px; + font-family: "icons" !important; + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1.2; + vertical-align: middle; + padding-right: 5px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.nav-home .version-number { + padding-left: 1.4rem; + font-size: 0.9rem; +} + +.nav-toc { +} + +.nav-toc ul { + margin: 0; + padding: 0; + line-height: 2rem; +} + +.nav-toc ul > li { + list-style-type: none; + padding-left: 0; +} + +.nav-toc ul > li a { + display: block; + color: #4078c0; + font-weight: bold; + font-size: 0.9rem; + padding-left: 1rem; +} + +.nav-toc ul > li a.active { + background: #e7e7e7; +} + +.nav-toc ul > li a:hover { + background: #e7e7e7; + text-decoration: none; +} + +.nav-toc ul > li > ul li { + margin-top: 0; + border-top: 0; + padding-top: 0; + padding-bottom: 0; +} + +.nav-toc ul > li > ul li a { + font-size: 0.9rem; + font-weight: normal; + text-transform: none; + margin-top: 0; + padding-left: 1.2rem; +} + +.nav-toc ul > li > ul > li > ul li a { + font-size: 0.8rem; + padding-left: 2rem; +} + + +/* site navigation */ + +.site-nav { + margin-top: 1rem; + margin-bottom: 1rem; + border: solid 1px #cccccc; +} + +/* off-canvas navigation colours */ + +.off-canvas { +} + +.off-canvas-nav { + padding: 0; +} + +.off-canvas-nav .nav-home { + background: #ffffff; +} + +.off-canvas-nav .nav-toc { + background: #ffffff; +} + +.off-canvas-nav .nav-toc ul > li { +} + +.off-canvas-nav .nav-toc ul > li a { +} + +.off-canvas-nav .nav-toc ul > li a.active { +} + +.off-canvas-nav .nav-toc ul > li a:hover { +} + +.off-canvas-nav .nav-toc ul > li a.active:hover { +} + +.off-canvas-nav .nav-toc ul > li > ul li { + border-top: 0; +} + +/* page navigation */ + +.page-nav { + background: #ffffff; +} + +.page-nav .nav-title { + display: block; + color: #9eb1b7; + font-weight: bold; + font-size: 0.8rem; + padding-left: 1rem; +} + +.page-nav .nav-toc { + background: #ffffff; +} + +.page-nav .nav-toc ul > li { + border-top: 0; +} + +.page-nav .nav-toc ul > li a.active { + background: #4078c0; + color: #ffffff; +} + +.page-nav .nav-toc ul > li a.active:hover { + background: #4078c0; +} + +/* navigation next */ + +.nav-next { + background: #F7F7F7; + border-left: 10px solid #4078c0; + margin-top: 40px; + padding: 1em 20px; +} + +.nav-next p { + display: inline; + color: #0c323b; + font-style: italic; +} + +.nav-next a { + color: #4078c0; + font-weight: normal; +} + +/* table of contents -- ordered */ + +.toc a { + color: #4078c0; + font-weight: normal; +} + +.toc ol li { + color: #778a99; +} + +.toc > ol > li > ol { + list-style-type: lower-alpha; +} + +.toc > ol > li > ol > li > ol { + list-style-type: lower-roman; +} + +.toc.main > ol > li { + margin-top: 0.5em; + font-size: 1.2em; +} + +.toc.main > ol > li { + counter-increment: root; +} + +.toc.main > ol > li > ol { + counter-reset: subsection; + list-style-type: none; + margin-left: 2rem; +} + +.toc.main > ol > li > ol > li { + counter-increment: subsection; +} + +.toc.main > ol > li > ol > li:before { + content: counter(root) "." counter(subsection) ". "; + margin-left: -2rem; + padding-right: 0.25rem; +} + +.toc.main > ol > li > ol > li > ol { + list-style-type: lower-alpha; +} + +.toc.main > ol > li > ol > li > ol > li > ol { + list-style-type: lower-roman; +} + +/* table of contents -- unordered */ + +.toc ul li { + color: #778a99; +} + +.toc.main > ul { + margin-left: 0; + padding-bottom: 2rem; + border-bottom: 1px solid #f3f6f6; +} + +.toc.main > ul > li { + margin-top: 2rem; + border-top: 1px solid #f3f6f6; + padding-top: 2rem; + list-style-type: none; +} + +.toc.main > ul > li > a { + font-weight: bold; +} + +.toc.main > ul > li > ul { + margin-top: 1rem; +} + +.toc.main > ul > li > ul > li { + list-style-type: disc; +} + +.toc.main > ul > li > ul > li > a { + font-weight: normal; + text-transform: none; +} + +.toc.main > ul > li > ul > li > ul > li { + list-style-type: circle; +} + +/* site footer */ + +.site-footer { + margin-top: 3rem; + border-top: solid 1px #cccccc; +} + +.site-footer-content.row { + max-width: 90rem; +} + +.site-footer-nav { + padding: 2rem 0; +} + +.site-footer-nav .with-left-divider { + border-top: 0; + border-left: 1px solid rgba(255, 255, 255, 0.2); +} + +@media screen and (max-width: 40em) { + .site-footer-nav .with-left-divider { + margin-top: 2rem; + border-top: 1px solid rgba(255, 255, 255, 0.2); + padding-top: 2rem; + border-left: 0; + } +} + +@media screen and (min-width: 40em) { + .site-footer-nav .nav-links { + height: 8rem; + } +} + +.nav-links ul { + margin: 0; + padding: 0; + line-height: 2rem; +} + +.nav-links ul > li { + list-style-type: none; + padding-left: 0; +} + +.nav-links ul > li a { + color: #c5d0d4; + font-weight: bold; + font-size: 0.9rem; +} + +.nav-links ul > li a:hover { + color: #4078C0; + text-decoration: none; +} + +.nav-links ul > li > ul li a { + font-weight: normal; + text-transform: none; +} + +.site-footer-base { + padding: 1rem 0; +} + +.site-footer-base h3, .site-footer-base a { +} + +.site-footer-base .copyright { + margin-top: 20px; +} + +.site-footer-base .copyright .text { + display: inline-block; + line-height: 24px; + padding-right: 10px; + vertical-align: top; +} + +.site-footer-base .svg-icon-logo-text { +} + +.site-footer-base .svg-icon-logo-image { +} + +.site-footer-base .logo:hover .svg-icon-logo-text { +} + +.site-footer-base .logo:hover .svg-icon-logo-image { +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..d751d27 --- /dev/null +++ b/index.html @@ -0,0 +1,247 @@ + + + + +Unfiltered + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+
+

Unfiltered

+

Unfiltered is a toolkit for servicing HTTP requests in Scala. It provides a consistent vocabulary for handing requests on various server backends, without impeding direct access to their native interfaces.

+

This documentation walks through basic functionality of the library. You may also want to refer to Unfiltered’s

+

scaladocs

+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + diff --git a/js/magellan.js b/js/magellan.js new file mode 100644 index 0000000..52d231e --- /dev/null +++ b/js/magellan.js @@ -0,0 +1,25 @@ +$(function() { + + // add magellan targets to anchor headers, up to depth 3 + $("a.anchor").each(function() { + var anchor = $(this); + var name = anchor.attr("name"); + var header = anchor.parent(); + if (header.is("h1") || header.is("h2") || header.is("h3")) { + header.attr("id", name).attr("data-magellan-target", name); + } + }); + + // enable magellan plugin on the page navigation + $(".page-nav").each(function() { + var nav = $(this); + + // strip page navigation links down to just the hash fragment + nav.find("a").attr('href', function(_, current){ + return this.hash ? this.hash : current; + }); + + new Foundation.Magellan(nav); + }); + +}); diff --git a/js/page.js b/js/page.js new file mode 100644 index 0000000..4b4daf4 --- /dev/null +++ b/js/page.js @@ -0,0 +1,37 @@ +$(function() { + + // Tabbed code samples + + $("dl").has("dd > pre").each(function() { + var dl = $(this); + dl.addClass("tabbed"); + var dts = dl.find("dt"); + dts.each(function(i) { + var dt = $(this); + dt.html("" + dt.text() + ""); + }); + var dds = dl.find("dd"); + dds.each(function(i) { + var dd = $(this); + dd.hide(); + if (dd.find("blockquote").length) { + dd.addClass("has-note"); + } + }); + var current = dts.first().addClass("first").addClass("current"); + var currentContent = current.next("dd").addClass("current").show(); + dts.last().addClass("last"); + dl.css("height", current.height() + currentContent.height()); + }); + + $("dl.tabbed dt a").click(function(e){ + e.preventDefault(); + var current = $(this).parent("dt"); + var dl = current.parent("dl"); + dl.find(".current").removeClass("current").next("dd").removeClass("current").hide(); + current.addClass("current"); + var currentContent = current.next("dd").addClass("current").show(); + dl.css("height", current.height() + currentContent.height()); + }); + +}); diff --git a/lib/foundation/dist/foundation.min.css b/lib/foundation/dist/foundation.min.css new file mode 100644 index 0000000..81418ac --- /dev/null +++ b/lib/foundation/dist/foundation.min.css @@ -0,0 +1,2 @@ +@charset "UTF-8"; +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:not-allowed}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.foundation-mq{font-family:"small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"}html{font-size:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{padding:0;margin:0;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:1.5;color:#0a0a0a;background:#fefefe;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{max-width:100%;height:auto;-ms-interpolation-mode:bicubic;display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px;border-radius:0}select{width:100%;border-radius:0}#map_canvas embed,#map_canvas img,#map_canvas object,.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}button{-webkit-appearance:none;-moz-appearance:none;background:transparent;padding:0;border:0;border-radius:0;line-height:1}[data-whatinput=mouse] button{outline:0}.is-visible{display:block!important}.is-hidden{display:none!important}.row{max-width:75rem;margin-left:auto;margin-right:auto}.row:after,.row:before{content:' ';display:table}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row .row{max-width:none;margin-left:-.625rem;margin-right:-.625rem}@media screen and (min-width:40em){.row .row{margin-left:-.9375rem;margin-right:-.9375rem}}.row .row.collapse{margin-left:0;margin-right:0}.row.expanded{max-width:none}.row.expanded .row{margin-left:auto;margin-right:auto}.column,.columns{width:100%;float:left;padding-left:.625rem;padding-right:.625rem}@media screen and (min-width:40em){.column,.columns{padding-left:.9375rem;padding-right:.9375rem}}.column:last-child:not(:first-child),.columns:last-child:not(:first-child){float:right}.column.end:last-child:last-child,.end.columns:last-child:last-child{float:left}.column.row.row,.row.row.columns{float:none}.row .column.row.row,.row .row.row.columns{padding-left:0;padding-right:0;margin-left:0;margin-right:0}.small-1{width:8.33333%}.small-push-1{position:relative;left:8.33333%}.small-pull-1{position:relative;left:-8.33333%}.small-offset-0{margin-left:0}.small-2{width:16.66667%}.small-push-2{position:relative;left:16.66667%}.small-pull-2{position:relative;left:-16.66667%}.small-offset-1{margin-left:8.33333%}.small-3{width:25%}.small-push-3{position:relative;left:25%}.small-pull-3{position:relative;left:-25%}.small-offset-2{margin-left:16.66667%}.small-4{width:33.33333%}.small-push-4{position:relative;left:33.33333%}.small-pull-4{position:relative;left:-33.33333%}.small-offset-3{margin-left:25%}.small-5{width:41.66667%}.small-push-5{position:relative;left:41.66667%}.small-pull-5{position:relative;left:-41.66667%}.small-offset-4{margin-left:33.33333%}.small-6{width:50%}.small-push-6{position:relative;left:50%}.small-pull-6{position:relative;left:-50%}.small-offset-5{margin-left:41.66667%}.small-7{width:58.33333%}.small-push-7{position:relative;left:58.33333%}.small-pull-7{position:relative;left:-58.33333%}.small-offset-6{margin-left:50%}.small-8{width:66.66667%}.small-push-8{position:relative;left:66.66667%}.small-pull-8{position:relative;left:-66.66667%}.small-offset-7{margin-left:58.33333%}.small-9{width:75%}.small-push-9{position:relative;left:75%}.small-pull-9{position:relative;left:-75%}.small-offset-8{margin-left:66.66667%}.small-10{width:83.33333%}.small-push-10{position:relative;left:83.33333%}.small-pull-10{position:relative;left:-83.33333%}.small-offset-9{margin-left:75%}.small-11{width:91.66667%}.small-push-11{position:relative;left:91.66667%}.small-pull-11{position:relative;left:-91.66667%}.small-offset-10{margin-left:83.33333%}.small-12{width:100%}.small-offset-11{margin-left:91.66667%}.small-up-1>.column,.small-up-1>.columns{width:100%;float:left}.small-up-1>.column:nth-of-type(1n),.small-up-1>.columns:nth-of-type(1n){clear:none}.small-up-1>.column:nth-of-type(1n+1),.small-up-1>.columns:nth-of-type(1n+1){clear:both}.small-up-1>.column:last-child,.small-up-1>.columns:last-child{float:left}.small-up-2>.column,.small-up-2>.columns{width:50%;float:left}.small-up-2>.column:nth-of-type(1n),.small-up-2>.columns:nth-of-type(1n){clear:none}.small-up-2>.column:nth-of-type(2n+1),.small-up-2>.columns:nth-of-type(2n+1){clear:both}.small-up-2>.column:last-child,.small-up-2>.columns:last-child{float:left}.small-up-3>.column,.small-up-3>.columns{width:33.33333%;float:left}.small-up-3>.column:nth-of-type(1n),.small-up-3>.columns:nth-of-type(1n){clear:none}.small-up-3>.column:nth-of-type(3n+1),.small-up-3>.columns:nth-of-type(3n+1){clear:both}.small-up-3>.column:last-child,.small-up-3>.columns:last-child{float:left}.small-up-4>.column,.small-up-4>.columns{width:25%;float:left}.small-up-4>.column:nth-of-type(1n),.small-up-4>.columns:nth-of-type(1n){clear:none}.small-up-4>.column:nth-of-type(4n+1),.small-up-4>.columns:nth-of-type(4n+1){clear:both}.small-up-4>.column:last-child,.small-up-4>.columns:last-child{float:left}.small-up-5>.column,.small-up-5>.columns{width:20%;float:left}.small-up-5>.column:nth-of-type(1n),.small-up-5>.columns:nth-of-type(1n){clear:none}.small-up-5>.column:nth-of-type(5n+1),.small-up-5>.columns:nth-of-type(5n+1){clear:both}.small-up-5>.column:last-child,.small-up-5>.columns:last-child{float:left}.small-up-6>.column,.small-up-6>.columns{width:16.66667%;float:left}.small-up-6>.column:nth-of-type(1n),.small-up-6>.columns:nth-of-type(1n){clear:none}.small-up-6>.column:nth-of-type(6n+1),.small-up-6>.columns:nth-of-type(6n+1){clear:both}.small-up-6>.column:last-child,.small-up-6>.columns:last-child{float:left}.small-up-7>.column,.small-up-7>.columns{width:14.28571%;float:left}.small-up-7>.column:nth-of-type(1n),.small-up-7>.columns:nth-of-type(1n){clear:none}.small-up-7>.column:nth-of-type(7n+1),.small-up-7>.columns:nth-of-type(7n+1){clear:both}.small-up-7>.column:last-child,.small-up-7>.columns:last-child{float:left}.small-up-8>.column,.small-up-8>.columns{width:12.5%;float:left}.small-up-8>.column:nth-of-type(1n),.small-up-8>.columns:nth-of-type(1n){clear:none}.small-up-8>.column:nth-of-type(8n+1),.small-up-8>.columns:nth-of-type(8n+1){clear:both}.small-up-8>.column:last-child,.small-up-8>.columns:last-child{float:left}.small-collapse>.column,.small-collapse>.columns{padding-left:0;padding-right:0}.expanded.row .small-collapse.row,.small-collapse .row{margin-left:0;margin-right:0}.small-uncollapse>.column,.small-uncollapse>.columns{padding-left:.625rem;padding-right:.625rem}.small-centered{float:none;margin-left:auto;margin-right:auto}.small-pull-0,.small-push-0,.small-uncentered{position:static;margin-left:0;margin-right:0;float:left}@media screen and (min-width:40em){.medium-1{width:8.33333%}.medium-push-1{position:relative;left:8.33333%}.medium-pull-1{position:relative;left:-8.33333%}.medium-offset-0{margin-left:0}.medium-2{width:16.66667%}.medium-push-2{position:relative;left:16.66667%}.medium-pull-2{position:relative;left:-16.66667%}.medium-offset-1{margin-left:8.33333%}.medium-3{width:25%}.medium-push-3{position:relative;left:25%}.medium-pull-3{position:relative;left:-25%}.medium-offset-2{margin-left:16.66667%}.medium-4{width:33.33333%}.medium-push-4{position:relative;left:33.33333%}.medium-pull-4{position:relative;left:-33.33333%}.medium-offset-3{margin-left:25%}.medium-5{width:41.66667%}.medium-push-5{position:relative;left:41.66667%}.medium-pull-5{position:relative;left:-41.66667%}.medium-offset-4{margin-left:33.33333%}.medium-6{width:50%}.medium-push-6{position:relative;left:50%}.medium-pull-6{position:relative;left:-50%}.medium-offset-5{margin-left:41.66667%}.medium-7{width:58.33333%}.medium-push-7{position:relative;left:58.33333%}.medium-pull-7{position:relative;left:-58.33333%}.medium-offset-6{margin-left:50%}.medium-8{width:66.66667%}.medium-push-8{position:relative;left:66.66667%}.medium-pull-8{position:relative;left:-66.66667%}.medium-offset-7{margin-left:58.33333%}.medium-9{width:75%}.medium-push-9{position:relative;left:75%}.medium-pull-9{position:relative;left:-75%}.medium-offset-8{margin-left:66.66667%}.medium-10{width:83.33333%}.medium-push-10{position:relative;left:83.33333%}.medium-pull-10{position:relative;left:-83.33333%}.medium-offset-9{margin-left:75%}.medium-11{width:91.66667%}.medium-push-11{position:relative;left:91.66667%}.medium-pull-11{position:relative;left:-91.66667%}.medium-offset-10{margin-left:83.33333%}.medium-12{width:100%}.medium-offset-11{margin-left:91.66667%}.medium-up-1>.column,.medium-up-1>.columns{width:100%;float:left}.medium-up-1>.column:nth-of-type(1n),.medium-up-1>.columns:nth-of-type(1n){clear:none}.medium-up-1>.column:nth-of-type(1n+1),.medium-up-1>.columns:nth-of-type(1n+1){clear:both}.medium-up-1>.column:last-child,.medium-up-1>.columns:last-child{float:left}.medium-up-2>.column,.medium-up-2>.columns{width:50%;float:left}.medium-up-2>.column:nth-of-type(1n),.medium-up-2>.columns:nth-of-type(1n){clear:none}.medium-up-2>.column:nth-of-type(2n+1),.medium-up-2>.columns:nth-of-type(2n+1){clear:both}.medium-up-2>.column:last-child,.medium-up-2>.columns:last-child{float:left}.medium-up-3>.column,.medium-up-3>.columns{width:33.33333%;float:left}.medium-up-3>.column:nth-of-type(1n),.medium-up-3>.columns:nth-of-type(1n){clear:none}.medium-up-3>.column:nth-of-type(3n+1),.medium-up-3>.columns:nth-of-type(3n+1){clear:both}.medium-up-3>.column:last-child,.medium-up-3>.columns:last-child{float:left}.medium-up-4>.column,.medium-up-4>.columns{width:25%;float:left}.medium-up-4>.column:nth-of-type(1n),.medium-up-4>.columns:nth-of-type(1n){clear:none}.medium-up-4>.column:nth-of-type(4n+1),.medium-up-4>.columns:nth-of-type(4n+1){clear:both}.medium-up-4>.column:last-child,.medium-up-4>.columns:last-child{float:left}.medium-up-5>.column,.medium-up-5>.columns{width:20%;float:left}.medium-up-5>.column:nth-of-type(1n),.medium-up-5>.columns:nth-of-type(1n){clear:none}.medium-up-5>.column:nth-of-type(5n+1),.medium-up-5>.columns:nth-of-type(5n+1){clear:both}.medium-up-5>.column:last-child,.medium-up-5>.columns:last-child{float:left}.medium-up-6>.column,.medium-up-6>.columns{width:16.66667%;float:left}.medium-up-6>.column:nth-of-type(1n),.medium-up-6>.columns:nth-of-type(1n){clear:none}.medium-up-6>.column:nth-of-type(6n+1),.medium-up-6>.columns:nth-of-type(6n+1){clear:both}.medium-up-6>.column:last-child,.medium-up-6>.columns:last-child{float:left}.medium-up-7>.column,.medium-up-7>.columns{width:14.28571%;float:left}.medium-up-7>.column:nth-of-type(1n),.medium-up-7>.columns:nth-of-type(1n){clear:none}.medium-up-7>.column:nth-of-type(7n+1),.medium-up-7>.columns:nth-of-type(7n+1){clear:both}.medium-up-7>.column:last-child,.medium-up-7>.columns:last-child{float:left}.medium-up-8>.column,.medium-up-8>.columns{width:12.5%;float:left}.medium-up-8>.column:nth-of-type(1n),.medium-up-8>.columns:nth-of-type(1n){clear:none}.medium-up-8>.column:nth-of-type(8n+1),.medium-up-8>.columns:nth-of-type(8n+1){clear:both}.medium-up-8>.column:last-child,.medium-up-8>.columns:last-child{float:left}.medium-collapse>.column,.medium-collapse>.columns{padding-left:0;padding-right:0}.expanded.row .medium-collapse.row,.medium-collapse .row{margin-left:0;margin-right:0}.medium-uncollapse>.column,.medium-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem}.medium-centered{float:none;margin-left:auto;margin-right:auto}.medium-pull-0,.medium-push-0,.medium-uncentered{position:static;margin-left:0;margin-right:0;float:left}}@media screen and (min-width:64em){.large-1{width:8.33333%}.large-push-1{position:relative;left:8.33333%}.large-pull-1{position:relative;left:-8.33333%}.large-offset-0{margin-left:0}.large-2{width:16.66667%}.large-push-2{position:relative;left:16.66667%}.large-pull-2{position:relative;left:-16.66667%}.large-offset-1{margin-left:8.33333%}.large-3{width:25%}.large-push-3{position:relative;left:25%}.large-pull-3{position:relative;left:-25%}.large-offset-2{margin-left:16.66667%}.large-4{width:33.33333%}.large-push-4{position:relative;left:33.33333%}.large-pull-4{position:relative;left:-33.33333%}.large-offset-3{margin-left:25%}.large-5{width:41.66667%}.large-push-5{position:relative;left:41.66667%}.large-pull-5{position:relative;left:-41.66667%}.large-offset-4{margin-left:33.33333%}.large-6{width:50%}.large-push-6{position:relative;left:50%}.large-pull-6{position:relative;left:-50%}.large-offset-5{margin-left:41.66667%}.large-7{width:58.33333%}.large-push-7{position:relative;left:58.33333%}.large-pull-7{position:relative;left:-58.33333%}.large-offset-6{margin-left:50%}.large-8{width:66.66667%}.large-push-8{position:relative;left:66.66667%}.large-pull-8{position:relative;left:-66.66667%}.large-offset-7{margin-left:58.33333%}.large-9{width:75%}.large-push-9{position:relative;left:75%}.large-pull-9{position:relative;left:-75%}.large-offset-8{margin-left:66.66667%}.large-10{width:83.33333%}.large-push-10{position:relative;left:83.33333%}.large-pull-10{position:relative;left:-83.33333%}.large-offset-9{margin-left:75%}.large-11{width:91.66667%}.large-push-11{position:relative;left:91.66667%}.large-pull-11{position:relative;left:-91.66667%}.large-offset-10{margin-left:83.33333%}.large-12{width:100%}.large-offset-11{margin-left:91.66667%}.large-up-1>.column,.large-up-1>.columns{width:100%;float:left}.large-up-1>.column:nth-of-type(1n),.large-up-1>.columns:nth-of-type(1n){clear:none}.large-up-1>.column:nth-of-type(1n+1),.large-up-1>.columns:nth-of-type(1n+1){clear:both}.large-up-1>.column:last-child,.large-up-1>.columns:last-child{float:left}.large-up-2>.column,.large-up-2>.columns{width:50%;float:left}.large-up-2>.column:nth-of-type(1n),.large-up-2>.columns:nth-of-type(1n){clear:none}.large-up-2>.column:nth-of-type(2n+1),.large-up-2>.columns:nth-of-type(2n+1){clear:both}.large-up-2>.column:last-child,.large-up-2>.columns:last-child{float:left}.large-up-3>.column,.large-up-3>.columns{width:33.33333%;float:left}.large-up-3>.column:nth-of-type(1n),.large-up-3>.columns:nth-of-type(1n){clear:none}.large-up-3>.column:nth-of-type(3n+1),.large-up-3>.columns:nth-of-type(3n+1){clear:both}.large-up-3>.column:last-child,.large-up-3>.columns:last-child{float:left}.large-up-4>.column,.large-up-4>.columns{width:25%;float:left}.large-up-4>.column:nth-of-type(1n),.large-up-4>.columns:nth-of-type(1n){clear:none}.large-up-4>.column:nth-of-type(4n+1),.large-up-4>.columns:nth-of-type(4n+1){clear:both}.large-up-4>.column:last-child,.large-up-4>.columns:last-child{float:left}.large-up-5>.column,.large-up-5>.columns{width:20%;float:left}.large-up-5>.column:nth-of-type(1n),.large-up-5>.columns:nth-of-type(1n){clear:none}.large-up-5>.column:nth-of-type(5n+1),.large-up-5>.columns:nth-of-type(5n+1){clear:both}.large-up-5>.column:last-child,.large-up-5>.columns:last-child{float:left}.large-up-6>.column,.large-up-6>.columns{width:16.66667%;float:left}.large-up-6>.column:nth-of-type(1n),.large-up-6>.columns:nth-of-type(1n){clear:none}.large-up-6>.column:nth-of-type(6n+1),.large-up-6>.columns:nth-of-type(6n+1){clear:both}.large-up-6>.column:last-child,.large-up-6>.columns:last-child{float:left}.large-up-7>.column,.large-up-7>.columns{width:14.28571%;float:left}.large-up-7>.column:nth-of-type(1n),.large-up-7>.columns:nth-of-type(1n){clear:none}.large-up-7>.column:nth-of-type(7n+1),.large-up-7>.columns:nth-of-type(7n+1){clear:both}.large-up-7>.column:last-child,.large-up-7>.columns:last-child{float:left}.large-up-8>.column,.large-up-8>.columns{width:12.5%;float:left}.large-up-8>.column:nth-of-type(1n),.large-up-8>.columns:nth-of-type(1n){clear:none}.large-up-8>.column:nth-of-type(8n+1),.large-up-8>.columns:nth-of-type(8n+1){clear:both}.large-up-8>.column:last-child,.large-up-8>.columns:last-child{float:left}.large-collapse>.column,.large-collapse>.columns{padding-left:0;padding-right:0}.expanded.row .large-collapse.row,.large-collapse .row{margin-left:0;margin-right:0}.large-uncollapse>.column,.large-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem}.large-centered{float:none;margin-left:auto;margin-right:auto}.large-pull-0,.large-push-0,.large-uncentered{position:static;margin-left:0;margin-right:0;float:left}}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}p{font-size:inherit;line-height:1.6;margin-bottom:1rem;text-rendering:optimizeLegibility}em,i{font-style:italic}b,em,i,strong{line-height:inherit}b,strong{font-weight:700}small{font-size:80%;line-height:inherit}h1,h2,h3,h4,h5,h6{font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;font-style:normal;color:inherit;text-rendering:optimizeLegibility;margin-top:0;margin-bottom:.5rem;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#cacaca;line-height:0}h1{font-size:1.5rem}h2{font-size:1.25rem}h3{font-size:1.1875rem}h4{font-size:1.125rem}h5{font-size:1.0625rem}h6{font-size:1rem}@media screen and (min-width:40em){h1{font-size:3rem}h2{font-size:2.5rem}h3{font-size:1.9375rem}h4{font-size:1.5625rem}h5{font-size:1.25rem}h6{font-size:1rem}}a{color:#2199e8;text-decoration:none;line-height:inherit;cursor:pointer}a:focus,a:hover{color:#1585cf}a img{border:0}hr{max-width:75rem;height:0;border-right:0;border-top:0;border-bottom:1px solid #cacaca;border-left:0;margin:1.25rem auto;clear:both}dl,ol,ul{line-height:1.6;margin-bottom:1rem;list-style-position:outside}li{font-size:inherit}ul{list-style-type:disc}ol,ul{margin-left:1.25rem}ol ol,ol ul,ul ol,ul ul{margin-left:1.25rem;margin-bottom:0}dl{margin-bottom:1rem}dl dt{margin-bottom:.3rem;font-weight:700}blockquote{margin:0 0 1rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #cacaca}blockquote,blockquote p{line-height:1.6;color:#8a8a8a}cite{display:block;font-size:.8125rem;color:#8a8a8a}cite:before{content:'\2014 \0020'}abbr{color:#0a0a0a;cursor:help;border-bottom:1px dotted #0a0a0a}code{font-weight:400;border:1px solid #cacaca;padding:.125rem .3125rem .0625rem}code,kbd{font-family:Consolas,Liberation Mono,Courier,monospace;color:#0a0a0a;background-color:#e6e6e6}kbd{padding:.125rem .25rem 0;margin:0}.subheader{margin-top:.2rem;margin-bottom:.5rem;font-weight:400;line-height:1.4;color:#8a8a8a}.lead{font-size:125%;line-height:1.6}.stat{font-size:2.5rem;line-height:1}p+.stat{margin-top:-1rem}.no-bullet{margin-left:0;list-style:none}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}@media screen and (min-width:40em){.medium-text-left{text-align:left}.medium-text-right{text-align:right}.medium-text-center{text-align:center}.medium-text-justify{text-align:justify}}@media screen and (min-width:64em){.large-text-left{text-align:left}.large-text-right{text-align:right}.large-text-center{text-align:center}.large-text-justify{text-align:justify}}.show-for-print{display:none!important}@media print{*{background:transparent!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}.show-for-print{display:block!important}.hide-for-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}.ir a:after,a[href^='#']:after,a[href^='javascript:']:after{content:''}abbr[title]:after{content:" (" attr(title) ")"}blockquote,pre{border:1px solid #8a8a8a;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}}[type=color],[type=date],[type=datetime-local],[type=datetime],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],textarea{display:block;box-sizing:border-box;width:100%;height:2.4375rem;padding:.5rem;border:1px solid #cacaca;margin:0 0 1rem;font-family:inherit;font-size:1rem;color:#0a0a0a;background-color:#fefefe;box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);border-radius:0;-webkit-transition:-webkit-box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out;-webkit-appearance:none;-moz-appearance:none}[type=color]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=datetime]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,textarea:focus{border:1px solid #8a8a8a;background-color:#fefefe;outline:none;box-shadow:0 0 5px #cacaca;-webkit-transition:-webkit-box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out}textarea{max-width:100%}textarea[rows]{height:auto}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#cacaca}input::-moz-placeholder,textarea::-moz-placeholder{color:#cacaca}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#cacaca}input::placeholder,textarea::placeholder{color:#cacaca}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#e6e6e6;cursor:not-allowed}[type=button],[type=submit]{border-radius:0;-webkit-appearance:none;-moz-appearance:none}input[type=search]{box-sizing:border-box}[type=checkbox],[type=file],[type=radio]{margin:0 0 1rem}[type=checkbox]+label,[type=radio]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}[type=checkbox]+label[for],[type=radio]+label[for]{cursor:pointer}label>[type=checkbox],label>[type=radio]{margin-right:.5rem}[type=file]{width:100%}label{display:block;margin:0;font-size:.875rem;font-weight:400;line-height:1.8;color:#0a0a0a}label.middle{margin:0 0 1rem;padding:.5625rem 0}.help-text{margin-top:-.5rem;font-size:.8125rem;font-style:italic;color:#0a0a0a}.input-group{display:table;width:100%;margin-bottom:1rem}.input-group>:first-child,.input-group>:last-child>*{border-radius:0 0 0 0}.input-group-button,.input-group-field,.input-group-label{margin:0;white-space:nowrap;display:table-cell;vertical-align:middle}.input-group-label{text-align:center;padding:0 1rem;background:#e6e6e6;color:#0a0a0a;border:1px solid #cacaca;white-space:nowrap;width:1%;height:100%}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{border-radius:0;height:2.5rem}.input-group-button{padding-top:0;padding-bottom:0;text-align:center;height:100%;width:1%}.input-group-button a,.input-group-button button,.input-group-button input{margin:0}.input-group .input-group-button{display:table-cell}fieldset{border:0;padding:0;margin:0}legend{margin-bottom:.5rem;max-width:100%}.fieldset{border:1px solid #cacaca;padding:1.25rem;margin:1.125rem 0}.fieldset legend{background:#fefefe;padding:0 .1875rem;margin:0;margin-left:-.1875rem}select{height:2.4375rem;padding:.5rem;border:1px solid #cacaca;margin:0 0 1rem;font-size:1rem;font-family:inherit;line-height:normal;color:#0a0a0a;background-color:#fefefe;border-radius:0;-webkit-appearance:none;-moz-appearance:none;background-image:url("data:image/svg+xml;utf8,");background-size:9px 6px;background-position:right -1rem center;background-origin:content-box;background-repeat:no-repeat;padding-right:1.5rem}@media screen and (min-width:0\0){select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==")}}select:disabled{background-color:#e6e6e6;cursor:not-allowed}select::-ms-expand{display:none}select[multiple]{height:auto;background-image:none}.is-invalid-input:not(:focus){background-color:rgba(236,88,64,.1);border-color:#ec5840}.form-error,.is-invalid-label{color:#ec5840}.form-error{display:none;margin-top:-.5rem;margin-bottom:1rem;font-size:.75rem;font-weight:700}.form-error.is-visible{display:block}.button{display:inline-block;text-align:center;line-height:1;cursor:pointer;-webkit-appearance:none;-webkit-transition:background-color .25s ease-out,color .25s ease-out;transition:background-color .25s ease-out,color .25s ease-out;vertical-align:middle;border:1px solid transparent;border-radius:0;padding:.85em 1em;margin:0 0 1rem;font-size:.9rem;background-color:#2199e8;color:#fefefe}[data-whatinput=mouse] .button{outline:0}.button:focus,.button:hover{background-color:#1583cc;color:#fefefe}.button.tiny{font-size:.6rem}.button.small{font-size:.75rem}.button.large{font-size:1.25rem}.button.expanded{display:block;width:100%;margin-left:0;margin-right:0}.button.primary{background-color:#2199e8;color:#fefefe}.button.primary:focus,.button.primary:hover{background-color:#147cc0;color:#fefefe}.button.secondary{background-color:#777;color:#fefefe}.button.secondary:focus,.button.secondary:hover{background-color:#5f5f5f;color:#fefefe}.button.success{background-color:#3adb76;color:#fefefe}.button.success:focus,.button.success:hover{background-color:#22bb5b;color:#fefefe}.button.warning{background-color:#ffae00;color:#fefefe}.button.warning:focus,.button.warning:hover{background-color:#cc8b00;color:#fefefe}.button.alert{background-color:#ec5840;color:#fefefe}.button.alert:focus,.button.alert:hover{background-color:#da3116;color:#fefefe}.button.hollow{border:1px solid #2199e8;color:#2199e8}.button.hollow,.button.hollow:focus,.button.hollow:hover{background-color:transparent}.button.hollow:focus,.button.hollow:hover{border-color:#0c4d78;color:#0c4d78}.button.hollow.primary{border:1px solid #2199e8;color:#2199e8}.button.hollow.primary:focus,.button.hollow.primary:hover{border-color:#0c4d78;color:#0c4d78}.button.hollow.secondary{border:1px solid #777;color:#777}.button.hollow.secondary:focus,.button.hollow.secondary:hover{border-color:#3c3c3c;color:#3c3c3c}.button.hollow.success{border:1px solid #3adb76;color:#3adb76}.button.hollow.success:focus,.button.hollow.success:hover{border-color:#157539;color:#157539}.button.hollow.warning{border:1px solid #ffae00;color:#ffae00}.button.hollow.warning:focus,.button.hollow.warning:hover{border-color:#805700;color:#805700}.button.hollow.alert{border:1px solid #ec5840;color:#ec5840}.button.hollow.alert:focus,.button.hollow.alert:hover{border-color:#881f0e;color:#881f0e}.button.disabled,.button[disabled]{opacity:.25;cursor:not-allowed}.button.disabled:focus,.button.disabled:hover,.button[disabled]:focus,.button[disabled]:hover{background-color:#2199e8;color:#fefefe}.button.dropdown:after{content:'';display:block;width:0;height:0;border:.4em inset;border-color:#fefefe transparent transparent;border-top-style:solid;border-bottom-width:0;position:relative;top:.4em;float:right;margin-left:1em;display:inline-block}.button.arrow-only:after{margin-left:0;float:none;top:-.1em}.accordion{list-style-type:none;background:#fefefe;margin-left:0}.accordion-item:first-child>:first-child,.accordion-item:last-child>:last-child{border-radius:0 0 0 0}.accordion-title{display:block;padding:1.25rem 1rem;line-height:1;font-size:.75rem;color:#2199e8;position:relative;border:1px solid #e6e6e6;border-bottom:0}:last-child:not(.is-active)>.accordion-title{border-radius:0 0 0 0;border-bottom:1px solid #e6e6e6}.accordion-title:focus,.accordion-title:hover{background-color:#e6e6e6}.accordion-title:before{content:'+';position:absolute;right:1rem;top:50%;margin-top:-.5rem}.is-active>.accordion-title:before{content:'–'}.accordion-content{padding:1rem;display:none;border:1px solid #e6e6e6;border-bottom:0;background-color:#fefefe;color:#0a0a0a}:last-child>.accordion-content:last-child{border-bottom:1px solid #e6e6e6}.is-accordion-submenu-parent>a{position:relative}.is-accordion-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:6px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;position:absolute;top:50%;margin-top:-4px;right:1rem}.is-accordion-submenu-parent[aria-expanded=true]>a:after{-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:scaleY(-1);transform:scaleY(-1)}.badge{display:inline-block;padding:.3em;min-width:2.1em;font-size:.6rem;text-align:center;border-radius:50%;background:#2199e8;color:#fefefe}.badge.secondary{background:#777;color:#fefefe}.badge.success{background:#3adb76;color:#fefefe}.badge.warning{background:#ffae00;color:#fefefe}.badge.alert{background:#ec5840;color:#fefefe}.breadcrumbs{list-style:none;margin:0 0 1rem}.breadcrumbs:after,.breadcrumbs:before{content:' ';display:table}.breadcrumbs:after{clear:both}.breadcrumbs li{float:left;color:#0a0a0a;font-size:.6875rem;cursor:default;text-transform:uppercase}.breadcrumbs li:not(:last-child):after{color:#cacaca;content:"/";margin:0 .75rem;position:relative;top:1px;opacity:1}.breadcrumbs a{color:#2199e8}.breadcrumbs a:hover{text-decoration:underline}.breadcrumbs .disabled{color:#cacaca;cursor:not-allowed}.button-group{margin-bottom:1rem;font-size:0}.button-group:after,.button-group:before{content:' ';display:table}.button-group:after{clear:both}.button-group .button{margin:0;margin-right:1px;margin-bottom:1px;font-size:.9rem}.button-group .button:last-child{margin-right:0}.button-group.tiny .button{font-size:.6rem}.button-group.small .button{font-size:.75rem}.button-group.large .button{font-size:1.25rem}.button-group.expanded{margin-right:-1px}.button-group.expanded:after,.button-group.expanded:before{display:none}.button-group.expanded .button:first-child:nth-last-child(2),.button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2)~.button{display:inline-block;width:calc(50% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(2):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(3),.button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3)~.button{display:inline-block;width:calc(33.33333% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(3):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(4),.button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4)~.button{display:inline-block;width:calc(25% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(4):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(5),.button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5)~.button{display:inline-block;width:calc(20% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(5):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(6),.button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6)~.button{display:inline-block;width:calc(16.66667% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(6):last-child{margin-right:-6px}.button-group.primary .button{background-color:#2199e8;color:#fefefe}.button-group.primary .button:focus,.button-group.primary .button:hover{background-color:#147cc0;color:#fefefe}.button-group.secondary .button{background-color:#777;color:#fefefe}.button-group.secondary .button:focus,.button-group.secondary .button:hover{background-color:#5f5f5f;color:#fefefe}.button-group.success .button{background-color:#3adb76;color:#fefefe}.button-group.success .button:focus,.button-group.success .button:hover{background-color:#22bb5b;color:#fefefe}.button-group.warning .button{background-color:#ffae00;color:#fefefe}.button-group.warning .button:focus,.button-group.warning .button:hover{background-color:#cc8b00;color:#fefefe}.button-group.alert .button{background-color:#ec5840;color:#fefefe}.button-group.alert .button:focus,.button-group.alert .button:hover{background-color:#da3116;color:#fefefe}.button-group.stacked-for-medium .button,.button-group.stacked-for-small .button,.button-group.stacked .button{width:100%}.button-group.stacked-for-medium .button:last-child,.button-group.stacked-for-small .button:last-child,.button-group.stacked .button:last-child{margin-bottom:0}@media screen and (min-width:40em){.button-group.stacked-for-small .button{width:auto;margin-bottom:0}}@media screen and (min-width:64em){.button-group.stacked-for-medium .button{width:auto;margin-bottom:0}}@media screen and (max-width:39.9375em){.button-group.stacked-for-small.expanded{display:block}.button-group.stacked-for-small.expanded .button{display:block;margin-right:0}}.callout{margin:0 0 1rem;padding:1rem;border:1px solid hsla(0,0%,4%,.25);border-radius:0;position:relative;color:#0a0a0a;background-color:#fff}.callout>:first-child{margin-top:0}.callout>:last-child{margin-bottom:0}.callout.primary{background-color:#def0fc}.callout.secondary{background-color:#ebebeb}.callout.success{background-color:#e1faea}.callout.warning{background-color:#fff3d9}.callout.alert{background-color:#fce6e2}.callout.small{padding:.5rem}.callout.large{padding:3rem}.close-button{position:absolute;color:#8a8a8a;right:1rem;top:.5rem;font-size:2em;line-height:1;cursor:pointer}[data-whatinput=mouse] .close-button{outline:0}.close-button:focus,.close-button:hover{color:#0a0a0a}.menu{margin:0;list-style-type:none}.menu>li{display:table-cell;vertical-align:middle}[data-whatinput=mouse] .menu>li{outline:0}.menu>li>a{display:block;padding:.7rem 1rem;line-height:1}.menu a,.menu button,.menu input{margin-bottom:0}.menu>li>a i,.menu>li>a i+span,.menu>li>a img,.menu>li>a img+span,.menu>li>a svg,.menu>li>a svg+span{vertical-align:middle}.menu>li>a i,.menu>li>a img,.menu>li>a svg{margin-right:.25rem;display:inline-block}.menu>li{display:table-cell}.menu.vertical>li{display:block}@media screen and (min-width:40em){.menu.medium-horizontal>li{display:table-cell}.menu.medium-vertical>li{display:block}}@media screen and (min-width:64em){.menu.large-horizontal>li{display:table-cell}.menu.large-vertical>li{display:block}}.menu.simple li{line-height:1;display:inline-block;margin-right:1rem}.menu.simple a{padding:0}.menu.align-right:after,.menu.align-right:before{content:' ';display:table}.menu.align-right:after{clear:both}.menu.align-right>li{float:right}.menu.expanded{width:100%;display:table;table-layout:fixed}.menu.expanded>li:first-child:last-child{width:100%}.menu.icon-top>li>a{text-align:center}.menu.icon-top>li>a i,.menu.icon-top>li>a img,.menu.icon-top>li>a svg{display:block;margin:0 auto .25rem}.menu.nested{margin-left:1rem}.menu .active>a{color:#fefefe;background:#2199e8}.menu-text{font-weight:700;color:inherit;line-height:1;padding-top:0;padding-bottom:0;padding:.7rem 1rem}.menu-centered{text-align:center}.menu-centered>.menu{display:inline-block}.no-js [data-responsive-menu] ul{display:none}.menu-icon{position:relative;display:inline-block;vertical-align:middle;cursor:pointer;width:20px;height:16px}.menu-icon:after{content:'';position:absolute;display:block;width:100%;height:2px;background:#fefefe;top:0;left:0;box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe}.menu-icon:hover:after{background:#cacaca;box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca}.is-drilldown{position:relative;overflow:hidden}.is-drilldown li{display:block!important}.is-drilldown-submenu{position:absolute;top:0;left:100%;z-index:-1;height:100%;width:100%;background:#fefefe;-webkit-transition:-webkit-transform .15s linear;transition:transform .15s linear}.is-drilldown-submenu.is-active{z-index:1;display:block;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.is-drilldown-submenu.is-closing{-webkit-transform:translateX(100%);transform:translateX(100%)}.is-drilldown-submenu-parent>a{position:relative}.is-drilldown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:6px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0;position:absolute;top:50%;margin-top:-6px;right:1rem}.js-drilldown-back>a:before{content:'';display:block;width:0;height:0;border:6px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0;display:inline-block;vertical-align:middle;margin-right:.75rem}.dropdown-pane{background-color:#fefefe;border:1px solid #cacaca;border-radius:0;display:block;font-size:1rem;padding:1rem;position:absolute;visibility:hidden;width:300px;z-index:10}.dropdown-pane.is-open{visibility:visible}.dropdown-pane.tiny{width:100px}.dropdown-pane.small{width:200px}.dropdown-pane.large{width:400px}.dropdown.menu>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu>li.opens-right>.is-dropdown-submenu{right:auto;left:0;top:100%}.dropdown.menu>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu>li.is-dropdown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;right:5px;margin-top:-2px}[data-whatinput=mouse] .dropdown.menu a{outline:0}.no-js .dropdown.menu ul{display:none}.dropdown.menu.vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%}.dropdown.menu.vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.vertical>li>a:after{right:14px;margin-top:-3px}.dropdown.menu.vertical>li.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.dropdown.menu.vertical>li.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}@media screen and (min-width:40em){.dropdown.menu.medium-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.medium-horizontal>li.opens-right>.is-dropdown-submenu{right:auto;left:0;top:100%}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;right:5px;margin-top:-2px}.dropdown.menu.medium-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.medium-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%}.dropdown.menu.medium-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.medium-vertical>li>a:after{right:14px;margin-top:-3px}.dropdown.menu.medium-vertical>li.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.dropdown.menu.medium-vertical>li.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}}@media screen and (min-width:64em){.dropdown.menu.large-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.large-horizontal>li.opens-right>.is-dropdown-submenu{right:auto;left:0;top:100%}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;right:5px;margin-top:-2px}.dropdown.menu.large-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.large-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%}.dropdown.menu.large-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.large-vertical>li>a:after{right:14px;margin-top:-3px}.dropdown.menu.large-vertical>li.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.dropdown.menu.large-vertical>li.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}}.dropdown.menu.align-right .is-dropdown-submenu.first-sub{top:100%;left:auto;right:0}.is-dropdown-menu.vertical{width:100px}.is-dropdown-menu.vertical.align-right{float:right}.is-dropdown-submenu-parent{position:relative}.is-dropdown-submenu-parent a:after{position:absolute;top:50%;right:5px;margin-top:-2px}.is-dropdown-submenu-parent.opens-inner>.is-dropdown-submenu{top:100%;left:auto}.is-dropdown-submenu-parent.opens-left>.is-dropdown-submenu{left:auto;right:100%}.is-dropdown-submenu-parent.opens-right>.is-dropdown-submenu{right:auto;left:100%}.is-dropdown-submenu{display:none;position:absolute;top:0;left:100%;min-width:200px;z-index:1;background:#fefefe;border:1px solid #cacaca}.is-dropdown-submenu .is-dropdown-submenu-parent>a:after{right:14px;margin-top:-3px}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}.is-dropdown-submenu .is-dropdown-submenu{margin-top:-1px}.is-dropdown-submenu>li{width:100%}.is-dropdown-submenu.js-dropdown-active{display:block}.flex-video{position:relative;height:0;padding-bottom:75%;margin-bottom:1rem;overflow:hidden}.flex-video embed,.flex-video iframe,.flex-video object,.flex-video video{position:absolute;top:0;left:0;width:100%;height:100%}.flex-video.widescreen{padding-bottom:56.25%}.flex-video.vimeo{padding-top:0}.label{display:inline-block;padding:.33333rem .5rem;font-size:.8rem;line-height:1;white-space:nowrap;cursor:default;border-radius:0;background:#2199e8;color:#fefefe}.label.secondary{background:#777;color:#fefefe}.label.success{background:#3adb76;color:#fefefe}.label.warning{background:#ffae00;color:#fefefe}.label.alert{background:#ec5840;color:#fefefe}.media-object{margin-bottom:1rem;display:block}.media-object img{max-width:none}@media screen and (max-width:39.9375em){.media-object.stack-for-small .media-object-section{padding:0;padding-bottom:1rem;display:block}.media-object.stack-for-small .media-object-section img{width:100%}}.media-object-section{display:table-cell;vertical-align:top}.media-object-section:first-child{padding-right:1rem}.media-object-section:last-child:not(:nth-child(2)){padding-left:1rem}.media-object-section>:last-child{margin-bottom:0}.media-object-section.middle{vertical-align:middle}.media-object-section.bottom{vertical-align:bottom}body,html{height:100%}.off-canvas-wrapper{width:100%;overflow-x:hidden;position:relative;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:auto}.off-canvas-wrapper-inner{position:relative;width:100%;-webkit-transition:-webkit-transform .5s ease;transition:transform .5s ease}.off-canvas-wrapper-inner:after,.off-canvas-wrapper-inner:before{content:' ';display:table}.off-canvas-wrapper-inner:after{clear:both}.off-canvas-content{min-height:100%;background:#fefefe;-webkit-transition:-webkit-transform .5s ease;transition:transform .5s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;padding-bottom:.1px;box-shadow:0 0 10px hsla(0,0%,4%,.5)}.js-off-canvas-exit{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:hsla(0,0%,100%,.25);cursor:pointer;-webkit-transition:background .5s ease;transition:background .5s ease}.off-canvas{position:absolute;background:#e6e6e6;z-index:-1;max-height:100%;overflow-y:auto;-webkit-transform:translateX(0);transform:translateX(0)}[data-whatinput=mouse] .off-canvas{outline:0}.off-canvas.position-left{left:-250px;top:0;width:250px}.is-open-left{-webkit-transform:translateX(250px);transform:translateX(250px)}.off-canvas.position-right{right:-250px;top:0;width:250px}.is-open-right{-webkit-transform:translateX(-250px);transform:translateX(-250px)}@media screen and (min-width:40em){.position-left.reveal-for-medium{left:0;z-index:auto;position:fixed}.position-left.reveal-for-medium~.off-canvas-content{margin-left:250px}.position-right.reveal-for-medium{right:0;z-index:auto;position:fixed}.position-right.reveal-for-medium~.off-canvas-content{margin-right:250px}}@media screen and (min-width:64em){.position-left.reveal-for-large{left:0;z-index:auto;position:fixed}.position-left.reveal-for-large~.off-canvas-content{margin-left:250px}.position-right.reveal-for-large{right:0;z-index:auto;position:fixed}.position-right.reveal-for-large~.off-canvas-content{margin-right:250px}}.orbit,.orbit-container{position:relative}.orbit-container{margin:0;overflow:hidden;list-style:none}.orbit-slide{width:100%;max-height:100%}.orbit-slide.no-motionui.is-active{top:0;left:0}.orbit-figure{margin:0}.orbit-image{margin:0;width:100%;max-width:100%}.orbit-caption{bottom:0;width:100%;margin-bottom:0;background-color:hsla(0,0%,4%,.5)}.orbit-caption,.orbit-next,.orbit-previous{position:absolute;padding:1rem;color:#fefefe}.orbit-next,.orbit-previous{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);z-index:10}[data-whatinput=mouse] .orbit-next,[data-whatinput=mouse] .orbit-previous{outline:0}.orbit-next:active,.orbit-next:focus,.orbit-next:hover,.orbit-previous:active,.orbit-previous:focus,.orbit-previous:hover{background-color:hsla(0,0%,4%,.5)}.orbit-previous{left:0}.orbit-next{left:auto;right:0}.orbit-bullets{position:relative;margin-top:.8rem;margin-bottom:.8rem;text-align:center}[data-whatinput=mouse] .orbit-bullets{outline:0}.orbit-bullets button{width:1.2rem;height:1.2rem;margin:.1rem;background-color:#cacaca;border-radius:50%}.orbit-bullets button.is-active,.orbit-bullets button:hover{background-color:#8a8a8a}.pagination{margin-left:0;margin-bottom:1rem}.pagination:after,.pagination:before{content:' ';display:table}.pagination:after{clear:both}.pagination li{font-size:.875rem;margin-right:.0625rem;border-radius:0;display:none}.pagination li:first-child,.pagination li:last-child{display:inline-block}@media screen and (min-width:40em){.pagination li{display:inline-block}}.pagination a,.pagination button{color:#0a0a0a;display:block;padding:.1875rem .625rem;border-radius:0}.pagination a:hover,.pagination button:hover{background:#e6e6e6}.pagination .current{padding:.1875rem .625rem;background:#2199e8;color:#fefefe;cursor:default}.pagination .disabled{padding:.1875rem .625rem;color:#cacaca;cursor:not-allowed}.pagination .disabled:hover{background:transparent}.pagination .ellipsis:after{content:'\2026';padding:.1875rem .625rem;color:#0a0a0a}.pagination-previous.disabled:before,.pagination-previous a:before{content:'\00ab';display:inline-block;margin-right:.5rem}.pagination-next.disabled:after,.pagination-next a:after{content:'\00bb';display:inline-block;margin-left:.5rem}.progress{background-color:#cacaca;height:1rem;margin-bottom:1rem;border-radius:0}.progress.primary .progress-meter{background-color:#2199e8}.progress.secondary .progress-meter{background-color:#777}.progress.success .progress-meter{background-color:#3adb76}.progress.warning .progress-meter{background-color:#ffae00}.progress.alert .progress-meter{background-color:#ec5840}.progress-meter{position:relative;display:block;width:0;height:100%;background-color:#2199e8}.progress-meter-text{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;margin:0;font-size:.75rem;font-weight:700;color:#fefefe;white-space:nowrap}.slider{position:relative;height:.5rem;margin-top:1.25rem;margin-bottom:2.25rem;background-color:#e6e6e6;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:none;touch-action:none}.slider-fill{position:absolute;top:0;left:0;display:inline-block;max-width:100%;height:.5rem;background-color:#cacaca;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.slider-fill.is-dragging{-webkit-transition:all 0s linear;transition:all 0s linear}.slider-handle{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);position:absolute;left:0;z-index:1;display:inline-block;width:1.4rem;height:1.4rem;background-color:#2199e8;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;-ms-touch-action:manipulation;touch-action:manipulation;border-radius:0}[data-whatinput=mouse] .slider-handle{outline:0}.slider-handle:hover{background-color:#1583cc}.slider-handle.is-dragging{-webkit-transition:all 0s linear;transition:all 0s linear}.slider.disabled,.slider[disabled]{opacity:.25;cursor:not-allowed}.slider.vertical{display:inline-block;width:.5rem;height:12.5rem;margin:0 1.25rem;-webkit-transform:scaleY(-1);transform:scaleY(-1)}.slider.vertical .slider-fill{top:0;width:.5rem;max-height:100%}.slider.vertical .slider-handle{position:absolute;top:0;left:50%;width:1.4rem;height:1.4rem;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.sticky-container{position:relative}.sticky{position:absolute;z-index:0;-webkit-transform:translateZ(0);transform:translateZ(0)}.sticky.is-stuck{position:fixed;z-index:5}.sticky.is-stuck.is-at-top{top:0}.sticky.is-stuck.is-at-bottom{bottom:0}.sticky.is-anchored{position:absolute;left:auto;right:auto}.sticky.is-anchored.is-at-bottom{bottom:0}body.is-reveal-open{overflow:hidden}html.is-reveal-open,html.is-reveal-open body{height:100%;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.reveal-overlay{display:none;position:fixed;top:0;bottom:0;left:0;right:0;z-index:1005;background-color:hsla(0,0%,4%,.45);overflow-y:scroll}.reveal{display:none;z-index:1006;padding:1rem;border:1px solid #cacaca;background-color:#fefefe;border-radius:0;position:relative;top:100px;margin-left:auto;margin-right:auto;overflow-y:auto}[data-whatinput=mouse] .reveal{outline:0}@media screen and (min-width:40em){.reveal{min-height:0}}.reveal .column,.reveal .columns{min-width:0}.reveal>:last-child{margin-bottom:0}@media screen and (min-width:40em){.reveal{width:600px;max-width:75rem}}@media screen and (min-width:40em){.reveal .reveal{left:auto;right:auto;margin:0 auto}}.reveal.collapse{padding:0}@media screen and (min-width:40em){.reveal.tiny{width:30%;max-width:75rem}}@media screen and (min-width:40em){.reveal.small{width:50%;max-width:75rem}}@media screen and (min-width:40em){.reveal.large{width:90%;max-width:75rem}}.reveal.full{top:0;left:0;width:100%;height:100%;height:100vh;min-height:100vh;max-width:none;margin-left:0;border:0;border-radius:0}@media screen and (max-width:39.9375em){.reveal{top:0;left:0;width:100%;height:100%;height:100vh;min-height:100vh;max-width:none;margin-left:0;border:0;border-radius:0}}.reveal.without-overlay{position:fixed}.switch{margin-bottom:1rem;outline:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#fefefe;font-weight:700;font-size:.875rem}.switch-input{opacity:0;position:absolute}.switch-paddle{background:#cacaca;cursor:pointer;display:block;position:relative;width:4rem;height:2rem;-webkit-transition:all .25s ease-out;transition:all .25s ease-out;border-radius:0;color:inherit;font-weight:inherit}input+.switch-paddle{margin:0}.switch-paddle:after{background:#fefefe;content:'';display:block;position:absolute;height:1.5rem;left:.25rem;top:.25rem;width:1.5rem;-webkit-transition:all .25s ease-out;transition:all .25s ease-out;-webkit-transform:translateZ(0);transform:translateZ(0);border-radius:0}input:checked~.switch-paddle{background:#2199e8}input:checked~.switch-paddle:after{left:2.25rem}[data-whatinput=mouse] input:focus~.switch-paddle{outline:0}.switch-active,.switch-inactive{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.switch-active{left:8%;display:none}input:checked+label>.switch-active{display:block}.switch-inactive{right:15%}input:checked+label>.switch-inactive{display:none}.switch.tiny .switch-paddle{width:3rem;height:1.5rem;font-size:.625rem}.switch.tiny .switch-paddle:after{width:1rem;height:1rem}.switch.tiny input:checked~.switch-paddle:after{left:1.75rem}.switch.small .switch-paddle{width:3.5rem;height:1.75rem;font-size:.75rem}.switch.small .switch-paddle:after{width:1.25rem;height:1.25rem}.switch.small input:checked~.switch-paddle:after{left:2rem}.switch.large .switch-paddle{width:5rem;height:2.5rem;font-size:1rem}.switch.large .switch-paddle:after{width:2rem;height:2rem}.switch.large input:checked~.switch-paddle:after{left:2.75rem}table{width:100%;margin-bottom:1rem;border-radius:0}table tbody,table tfoot,table thead{border:1px solid #f1f1f1;background-color:#fefefe}table caption{font-weight:700;padding:.5rem .625rem .625rem}table tfoot,table thead{background:#f8f8f8;color:#0a0a0a}table tfoot tr,table thead tr{background:transparent}table tfoot td,table tfoot th,table thead td,table thead th{padding:.5rem .625rem .625rem;font-weight:700;text-align:left}table tbody tr:nth-child(even){background-color:#f1f1f1}table tbody td,table tbody th{padding:.5rem .625rem .625rem}@media screen and (max-width:63.9375em){table.stack tfoot,table.stack thead{display:none}table.stack td,table.stack th,table.stack tr{display:block}table.stack td{border-top:0}}table.scroll{display:block;width:100%;overflow-x:auto}table.hover tr:hover{background-color:#f9f9f9}table.hover tr:nth-of-type(even):hover{background-color:#ececec}.table-scroll{overflow-x:auto}.table-scroll table{width:auto}.tabs{margin:0;list-style-type:none;background:#fefefe;border:1px solid #e6e6e6}.tabs:after,.tabs:before{content:' ';display:table}.tabs:after{clear:both}.tabs.vertical>li{width:auto;float:none;display:block}.tabs.simple>li>a{padding:0}.tabs.simple>li>a:hover{background:transparent}.tabs.primary{background:#2199e8}.tabs.primary>li>a{color:#fefefe}.tabs.primary>li>a:focus,.tabs.primary>li>a:hover{background:#1893e4}.tabs-title{float:left}.tabs-title>a{display:block;padding:1.25rem 1.5rem;line-height:1;font-size:.75rem}.tabs-title>a:hover{background:#fefefe}.tabs-title>a:focus,.tabs-title>a[aria-selected=true]{background:#e6e6e6}.tabs-content{background:#fefefe;-webkit-transition:all .5s ease;transition:all .5s ease;border:1px solid #e6e6e6;border-top:0}.tabs-content.vertical{border:1px solid #e6e6e6;border-left:0}.tabs-panel{display:none;padding:1rem}.tabs-panel.is-active{display:block}.thumbnail{border:4px solid #fefefe;box-shadow:0 0 0 1px hsla(0,0%,4%,.2);display:inline-block;line-height:0;max-width:100%;-webkit-transition:-webkit-box-shadow .2s ease-out;transition:box-shadow .2s ease-out;border-radius:0;margin-bottom:1rem}.thumbnail:focus,.thumbnail:hover{box-shadow:0 0 6px 1px rgba(33,153,232,.5)}.title-bar{background:#0a0a0a;color:#fefefe;padding:.5rem}.title-bar:after,.title-bar:before{content:' ';display:table}.title-bar:after{clear:both}.title-bar .menu-icon{margin-left:.25rem;margin-right:.25rem}.title-bar-left{float:left}.title-bar-right{float:right;text-align:right}.title-bar-title{font-weight:700}.menu-icon.dark,.title-bar-title{vertical-align:middle;display:inline-block}.menu-icon.dark{position:relative;cursor:pointer;width:20px;height:16px}.menu-icon.dark:after{content:'';position:absolute;display:block;width:100%;height:2px;background:#0a0a0a;top:0;left:0;box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a}.menu-icon.dark:hover:after{background:#8a8a8a;box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a}.has-tip{border-bottom:1px dotted #8a8a8a;font-weight:700;position:relative;display:inline-block;cursor:help}.tooltip{background-color:#0a0a0a;color:#fefefe;font-size:80%;padding:.75rem;position:absolute;z-index:10;top:calc(100% + .6495rem);max-width:10rem!important;border-radius:0}.tooltip:before{border-color:transparent transparent #0a0a0a;border-bottom-style:solid;border-top-width:0;bottom:100%;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.tooltip.top:before,.tooltip:before{content:'';display:block;width:0;height:0;border:.75rem inset}.tooltip.top:before{border-color:#0a0a0a transparent transparent;border-top-style:solid;border-bottom-width:0;top:100%;bottom:auto}.tooltip.left:before{border-color:transparent transparent transparent #0a0a0a;border-left-style:solid;border-right-width:0;left:100%}.tooltip.left:before,.tooltip.right:before{content:'';display:block;width:0;height:0;border:.75rem inset;bottom:auto;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.tooltip.right:before{border-color:transparent #0a0a0a transparent transparent;border-right-style:solid;border-left-width:0;left:auto;right:100%}.top-bar{padding:.5rem}.top-bar:after,.top-bar:before{content:' ';display:table}.top-bar:after{clear:both}.top-bar,.top-bar ul{background-color:#e6e6e6}.top-bar input{max-width:200px;margin-right:1rem}.top-bar .input-group-field{width:100%;margin-right:0}.top-bar input.button{width:auto}.top-bar .top-bar-left,.top-bar .top-bar-right{width:100%}@media screen and (min-width:40em){.top-bar .top-bar-left,.top-bar .top-bar-right{width:auto}}@media screen and (max-width:63.9375em){.top-bar.stacked-for-medium .top-bar-left,.top-bar.stacked-for-medium .top-bar-right{width:100%}}@media screen and (max-width:74.9375em){.top-bar.stacked-for-large .top-bar-left,.top-bar.stacked-for-large .top-bar-right{width:100%}}.top-bar-title{float:left;margin-right:1rem}.top-bar-left{float:left}.top-bar-right{float:right}.hide{display:none!important}.invisible{visibility:hidden}@media screen and (max-width:39.9375em){.hide-for-small-only{display:none!important}}@media screen and (max-width:0em),screen and (min-width:40em){.show-for-small-only{display:none!important}}@media screen and (min-width:40em){.hide-for-medium{display:none!important}}@media screen and (max-width:39.9375em){.show-for-medium{display:none!important}}@media screen and (min-width:40em) and (max-width:63.9375em){.hide-for-medium-only{display:none!important}}@media screen and (max-width:39.9375em),screen and (min-width:64em){.show-for-medium-only{display:none!important}}@media screen and (min-width:64em){.hide-for-large{display:none!important}}@media screen and (max-width:63.9375em){.show-for-large{display:none!important}}@media screen and (min-width:64em) and (max-width:74.9375em){.hide-for-large-only{display:none!important}}@media screen and (max-width:63.9375em),screen and (min-width:75em){.show-for-large-only{display:none!important}}.show-for-sr,.show-on-focus{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.show-on-focus:active,.show-on-focus:focus{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hide-for-portrait,.show-for-landscape{display:block!important}@media screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:block!important}}@media screen and (orientation:portrait){.hide-for-portrait,.show-for-landscape{display:none!important}}.hide-for-landscape,.show-for-portrait{display:none!important}@media screen and (orientation:landscape){.hide-for-landscape,.show-for-portrait{display:none!important}}@media screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:block!important}}.float-left{float:left!important}.float-right{float:right!important}.float-center{display:block;margin-left:auto;margin-right:auto}.clearfix:after,.clearfix:before{content:' ';display:table}.clearfix:after{clear:both} \ No newline at end of file diff --git a/lib/foundation/dist/foundation.min.js b/lib/foundation/dist/foundation.min.js new file mode 100644 index 0000000..02b9150 --- /dev/null +++ b/lib/foundation/dist/foundation.min.js @@ -0,0 +1,4 @@ +function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}!function(t){"use strict";function e(t){if(void 0===Function.prototype.name){var e=/function\s([^(]{1,})\(/,i=e.exec(t.toString());return i&&i.length>1?i[1].trim():""}return void 0===t.prototype?t.constructor.name:t.prototype.constructor.name}function i(t){return/true/.test(t)?!0:/false/.test(t)?!1:isNaN(1*t)?t:parseFloat(t)}function n(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}var s="6.2.3",o={version:s,_plugins:{},_uuids:[],rtl:function(){return"rtl"===t("html").attr("dir")},plugin:function(t,i){var s=i||e(t),o=n(s);this._plugins[o]=this[s]=t},registerPlugin:function(t,i){var s=i?n(i):e(t.constructor).toLowerCase();t.uuid=this.GetYoDigits(6,s),t.$element.attr("data-"+s)||t.$element.attr("data-"+s,t.uuid),t.$element.data("zfPlugin")||t.$element.data("zfPlugin",t),t.$element.trigger("init.zf."+s),this._uuids.push(t.uuid)},unregisterPlugin:function(t){var i=n(e(t.$element.data("zfPlugin").constructor));this._uuids.splice(this._uuids.indexOf(t.uuid),1),t.$element.removeAttr("data-"+i).removeData("zfPlugin").trigger("destroyed.zf."+i);for(var s in t)t[s]=null},reInit:function(e){var i=e instanceof t;try{if(i)e.each(function(){t(this).data("zfPlugin")._init()});else{var s=typeof e,o=this,a={object:function(e){e.forEach(function(e){e=n(e),t("[data-"+e+"]").foundation("_init")})},string:function(){e=n(e),t("[data-"+e+"]").foundation("_init")},undefined:function(){this.object(Object.keys(o._plugins))}};a[s](e)}}catch(r){console.error(r)}finally{return e}},GetYoDigits:function(t,e){return t=t||6,Math.round(Math.pow(36,t+1)-Math.random()*Math.pow(36,t)).toString(36).slice(1)+(e?"-"+e:"")},reflow:function(e,n){"undefined"==typeof n?n=Object.keys(this._plugins):"string"==typeof n&&(n=[n]);var s=this;t.each(n,function(n,o){var a=s._plugins[o],r=t(e).find("[data-"+o+"]").addBack("[data-"+o+"]");r.each(function(){var e=t(this),n={};if(e.data("zfPlugin"))return void console.warn("Tried to initialize "+o+" on an element that already has a Foundation plugin.");if(e.attr("data-options")){e.attr("data-options").split(";").forEach(function(t,e){var s=t.split(":").map(function(t){return t.trim()});s[0]&&(n[s[0]]=i(s[1]))})}try{e.data("zfPlugin",new a(t(this),n))}catch(s){console.error(s)}finally{return}})})},getFnName:e,transitionend:function(t){var e,i={transition:"transitionend",WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend"},n=document.createElement("div");for(var s in i)"undefined"!=typeof n.style[s]&&(e=i[s]);return e?e:(e=setTimeout(function(){t.triggerHandler("transitionend",[t])},1),"transitionend")}};o.util={throttle:function(t,e){var i=null;return function(){var n=this,s=arguments;null===i&&(i=setTimeout(function(){t.apply(n,s),i=null},e))}}};var a=function(i){var n=typeof i,s=t("meta.foundation-mq"),a=t(".no-js");if(s.length||t('').appendTo(document.head),a.length&&a.removeClass("no-js"),"undefined"===n)o.MediaQuery._init(),o.reflow(this);else{if("string"!==n)throw new TypeError("We're sorry, "+n+" is not a valid parameter. You must use a string representing the method you wish to invoke.");var r=Array.prototype.slice.call(arguments,1),l=this.data("zfPlugin");if(void 0===l||void 0===l[i])throw new ReferenceError("We're sorry, '"+i+"' is not an available method for "+(l?e(l):"this element")+".");1===this.length?l[i].apply(l,r):this.each(function(e,n){l[i].apply(t(n).data("zfPlugin"),r)})}return this};window.Foundation=o,t.fn.foundation=a,function(){Date.now&&window.Date.now||(window.Date.now=Date.now=function(){return(new Date).getTime()});for(var t=["webkit","moz"],e=0;e=d.offset.top,r=u.offset.left>=d.offset.left,l=u.offset.left+u.width<=d.width+d.offset.left}else a=u.offset.top+u.height<=u.windowDims.height+u.windowDims.offset.top,o=u.offset.top>=u.windowDims.offset.top,r=u.offset.left>=u.windowDims.offset.left,l=u.offset.left+u.width<=u.windowDims.width;var h=[a,o,r,l];return n?r===l==!0:s?o===a==!0:-1===h.indexOf(!1)}function i(t,e){if(t=t.length?t[0]:t,t===window||t===document)throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");var i=t.getBoundingClientRect(),n=t.parentNode.getBoundingClientRect(),s=document.body.getBoundingClientRect(),o=window.pageYOffset,a=window.pageXOffset;return{width:i.width,height:i.height,offset:{top:i.top+o,left:i.left+a},parentDims:{width:n.width,height:n.height,offset:{top:n.top+o,left:n.left+a}},windowDims:{width:s.width,height:s.height,offset:{top:o,left:a}}}}function n(t,e,n,s,o,a){var r=i(t),l=e?i(e):null;switch(n){case"top":return{left:Foundation.rtl()?l.offset.left-r.width+l.width:l.offset.left,top:l.offset.top-(r.height+s)};case"left":return{left:l.offset.left-(r.width+o),top:l.offset.top};case"right":return{left:l.offset.left+l.width+o,top:l.offset.top};case"center top":return{left:l.offset.left+l.width/2-r.width/2,top:l.offset.top-(r.height+s)};case"center bottom":return{left:a?o:l.offset.left+l.width/2-r.width/2,top:l.offset.top+l.height+s};case"center left":return{left:l.offset.left-(r.width+o),top:l.offset.top+l.height/2-r.height/2};case"center right":return{left:l.offset.left+l.width+o+1,top:l.offset.top+l.height/2-r.height/2};case"center":return{left:r.windowDims.offset.left+r.windowDims.width/2-r.width/2,top:r.windowDims.offset.top+r.windowDims.height/2-r.height/2};case"reveal":return{left:(r.windowDims.width-r.width)/2,top:r.windowDims.offset.top+s};case"reveal full":return{left:r.windowDims.offset.left,top:r.windowDims.offset.top};case"left bottom":return{left:l.offset.left-(r.width+o),top:l.offset.top+l.height};case"right bottom":return{left:l.offset.left+l.width+o-r.width,top:l.offset.top+l.height};default:return{left:Foundation.rtl()?l.offset.left-r.width+l.width:l.offset.left,top:l.offset.top+l.height+s}}}Foundation.Box={ImNotTouchingYou:e,GetDimensions:i,GetOffsets:n}}(jQuery),!function(t){function e(t){var e={};for(var i in t)e[t[i]]=t[i];return e}var i={9:"TAB",13:"ENTER",27:"ESCAPE",32:"SPACE",37:"ARROW_LEFT",38:"ARROW_UP",39:"ARROW_RIGHT",40:"ARROW_DOWN"},n={},s={keys:e(i),parseKey:function(t){var e=i[t.which||t.keyCode]||String.fromCharCode(t.which).toUpperCase();return t.shiftKey&&(e="SHIFT_"+e),t.ctrlKey&&(e="CTRL_"+e),t.altKey&&(e="ALT_"+e),e},handleKey:function(e,i,s){var o,a,r,l=n[i],u=this.parseKey(e);if(!l)return console.warn("Component not defined!");if(o="undefined"==typeof l.ltr?l:Foundation.rtl()?t.extend({},l.ltr,l.rtl):t.extend({},l.rtl,l.ltr),a=o[u],r=s[a],r&&"function"==typeof r){var d=r.apply();(s.handled||"function"==typeof s.handled)&&s.handled(d)}else(s.unhandled||"function"==typeof s.unhandled)&&s.unhandled()},findFocusable:function(e){return e.find("a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]").filter(function(){return t(this).is(":visible")&&!(t(this).attr("tabindex")<0)})},register:function(t,e){n[t]=e}};Foundation.Keyboard=s}(jQuery),!function(t){function e(t){var e={};return"string"!=typeof t?e:(t=t.trim().slice(1,-1))?e=t.split("&").reduce(function(t,e){var i=e.replace(/\+/g," ").split("="),n=i[0],s=i[1];return n=decodeURIComponent(n),s=void 0===s?null:decodeURIComponent(s),t.hasOwnProperty(n)?Array.isArray(t[n])?t[n].push(s):t[n]=[t[n],s]:t[n]=s,t},{}):e}var i={queries:[],current:"",_init:function(){var i,n=this,s=t(".foundation-mq").css("font-family");i=e(s);for(var o in i)i.hasOwnProperty(o)&&n.queries.push({name:o,value:"only screen and (min-width: "+i[o]+")"});this.current=this._getCurrentSize(),this._watcher()},atLeast:function(t){var e=this.get(t);return e?window.matchMedia(e).matches:!1},get:function(t){for(var e in this.queries)if(this.queries.hasOwnProperty(e)){var i=this.queries[e];if(t===i.name)return i.value}return null},_getCurrentSize:function(){for(var t,e=0;eo?s=window.requestAnimationFrame(n,e):(window.cancelAnimationFrame(s),e.trigger("finished.zf.animate",[e]).triggerHandler("finished.zf.animate",[e]))}var s,o,a=null;s=window.requestAnimationFrame(n)}function i(e,i,o,a){function r(){e||i.hide(),l(),a&&a.apply(i)}function l(){i[0].style.transitionDuration=0,i.removeClass(u+" "+d+" "+o)}if(i=t(i).eq(0),i.length){var u=e?n[0]:n[1],d=e?s[0]:s[1];l(),i.addClass(o).css("transition","none"),requestAnimationFrame(function(){i.addClass(u),e&&i.show()}),requestAnimationFrame(function(){i[0].offsetWidth,i.css("transition","").addClass(d)}),i.one(Foundation.transitionend(i),r)}}var n=["mui-enter","mui-leave"],s=["mui-enter-active","mui-leave-active"],o={animateIn:function(t,e,n){i(!0,t,e,n)},animateOut:function(t,e,n){i(!1,t,e,n)}};Foundation.Move=e,Foundation.Motion=o}(jQuery),!function(t){var e={Feather:function(e){var i=arguments.length<=1||void 0===arguments[1]?"zf":arguments[1];e.attr("role","menubar");var n=e.find("li").attr({role:"menuitem"}),s="is-"+i+"-submenu",o=s+"-item",a="is-"+i+"-submenu-parent";e.find("a:first").attr("tabindex",0),n.each(function(){var e=t(this),i=e.children("ul");i.length&&(e.addClass(a).attr({"aria-haspopup":!0,"aria-expanded":!1,"aria-label":e.children("a:first").text()}),i.addClass("submenu "+s).attr({"data-submenu":"","aria-hidden":!0,role:"menu"})),e.parent("[data-submenu]").length&&e.addClass("is-submenu-item "+o)})},Burn:function(t,e){var i=(t.find("li").removeAttr("tabindex"),"is-"+e+"-submenu"),n=i+"-item",s="is-"+e+"-submenu-parent";t.find("*").removeClass(i+" "+n+" "+s+" is-submenu-item submenu is-active").removeAttr("data-submenu").css("display","")}};Foundation.Nest=e}(jQuery),!function(t){function e(t,e,i){var n,s,o=this,a=e.duration,r=Object.keys(t.data())[0]||"timer",l=-1;this.isPaused=!1,this.restart=function(){l=-1,clearTimeout(s),this.start()},this.start=function(){this.isPaused=!1,clearTimeout(s),l=0>=l?a:l,t.data("paused",!1),n=Date.now(),s=setTimeout(function(){e.infinite&&o.restart(),i()},l),t.trigger("timerstart.zf."+r)},this.pause=function(){this.isPaused=!0,clearTimeout(s),t.data("paused",!0);var e=Date.now();l-=e-n,t.trigger("timerpaused.zf."+r)}}function i(e,i){function n(){s--,0===s&&i()}var s=e.length;0===s&&i(),e.each(function(){this.complete?n():"undefined"!=typeof this.naturalWidth&&this.naturalWidth>0?n():t(this).one("load",function(){n()})})}Foundation.Timer=e,Foundation.onImagesLoaded=i}(jQuery),function(t){function e(){this.removeEventListener("touchmove",i),this.removeEventListener("touchend",e),u=!1}function i(i){if(t.spotSwipe.preventDefault&&i.preventDefault(),u){var n,s=i.touches[0].pageX,a=(i.touches[0].pageY,o-s);l=(new Date).getTime()-r,Math.abs(a)>=t.spotSwipe.moveThreshold&&l<=t.spotSwipe.timeThreshold&&(n=a>0?"left":"right"),n&&(i.preventDefault(),e.call(this),t(this).trigger("swipe",n).trigger("swipe"+n))}}function n(t){1==t.touches.length&&(o=t.touches[0].pageX,a=t.touches[0].pageY,u=!0,r=(new Date).getTime(),this.addEventListener("touchmove",i,!1),this.addEventListener("touchend",e,!1))}function s(){this.addEventListener&&this.addEventListener("touchstart",n,!1)}t.spotSwipe={version:"1.0.0",enabled:"ontouchstart"in document.documentElement,preventDefault:!1,moveThreshold:75,timeThreshold:200};var o,a,r,l,u=!1;t.event.special.swipe={setup:s},t.each(["left","up","down","right"],function(){t.event.special["swipe"+this]={setup:function(){t(this).on("swipe",t.noop)}}})}(jQuery),!function(t){t.fn.addTouch=function(){this.each(function(i,n){t(n).bind("touchstart touchmove touchend touchcancel",function(){e(event)})});var e=function(t){var e,i=t.changedTouches,n=i[0],s={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup"},o=s[t.type];"MouseEvent"in window&&"function"==typeof window.MouseEvent?e=new window.MouseEvent(o,{bubbles:!0,cancelable:!0,screenX:n.screenX,screenY:n.screenY,clientX:n.clientX,clientY:n.clientY}):(e=document.createEvent("MouseEvent"),e.initMouseEvent(o,!0,!0,window,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null)),n.target.dispatchEvent(e)}}}(jQuery),!function(t){function e(){o(),n(),s(),i()}function i(e){var i=t("[data-yeti-box]"),n=["dropdown","tooltip","reveal"];if(e&&("string"==typeof e?n.push(e):"object"==typeof e&&"string"==typeof e[0]?n.concat(e):console.error("Plugin names must be strings")),i.length){var s=n.map(function(t){return"closeme.zf."+t}).join(" ");t(window).off(s).on(s,function(e,i){var n=e.namespace.split(".")[0],s=t("[data-"+n+"]").not('[data-yeti-box="'+i+'"]');s.each(function(){var e=t(this);e.triggerHandler("close.zf.trigger",[e])})})}}function n(e){var i=void 0,n=t("[data-resize]");n.length&&t(window).off("resize.zf.trigger").on("resize.zf.trigger",function(s){i&&clearTimeout(i),i=setTimeout(function(){a||n.each(function(){t(this).triggerHandler("resizeme.zf.trigger")}),n.attr("data-events","resize")},e||10)})}function s(e){var i=void 0,n=t("[data-scroll]");n.length&&t(window).off("scroll.zf.trigger").on("scroll.zf.trigger",function(s){i&&clearTimeout(i),i=setTimeout(function(){a||n.each(function(){t(this).triggerHandler("scrollme.zf.trigger")}),n.attr("data-events","scroll")},e||10)})}function o(){if(!a)return!1;var e=document.querySelectorAll("[data-resize], [data-scroll], [data-mutate]"),i=function(e){var i=t(e[0].target);switch(i.attr("data-events")){case"resize":i.triggerHandler("resizeme.zf.trigger",[i]);break;case"scroll":i.triggerHandler("scrollme.zf.trigger",[i,window.pageYOffset]);break;default:return!1}};if(e.length)for(var n=0;n<=e.length-1;n++){var s=new a(i);s.observe(e[n],{attributes:!0,childList:!1,characterData:!1,subtree:!1,attributeFilter:["data-events"]})}}var a=function(){for(var t=["WebKit","Moz","O","Ms",""],e=0;e'),i.data("savedHref",i.attr("href")).removeAttr("href"),i.children("[data-submenu]").attr({"aria-hidden":!0,tabindex:0,role:"menu"}),e._events(i)}),this.$submenus.each(function(){var i=t(this),n=i.find(".js-drilldown-back");n.length||i.prepend(e.options.backButton),e._back(i)}),this.$element.parent().hasClass("is-drilldown")||(this.$wrapper=t(this.options.wrapper).addClass("is-drilldown"),this.$wrapper=this.$element.wrap(this.$wrapper).parent().css(this._getMaxDims()))}},{key:"_events",value:function(e){var i=this;e.off("click.zf.drilldown").on("click.zf.drilldown",function(n){if(t(n.target).parentsUntil("ul","li").hasClass("is-drilldown-submenu-parent")&&(n.stopImmediatePropagation(),n.preventDefault()),i._show(e.parent("li")),i.options.closeOnClick){var s=t("body");s.off(".zf.drilldown").on("click.zf.drilldown",function(e){e.target===i.$element[0]||t.contains(i.$element[0],e.target)||(e.preventDefault(),i._hideAll(),s.off(".zf.drilldown"))})}})}},{key:"_keyboardEvents",value:function(){var e=this;this.$menuItems.add(this.$element.find(".js-drilldown-back > a")).on("keydown.zf.drilldown",function(i){var n,s,o=t(this),a=o.parent("li").parent("ul").children("li").children("a");a.each(function(e){return t(this).is(o)?(n=a.eq(Math.max(0,e-1)),void(s=a.eq(Math.min(e+1,a.length-1)))):void 0}),Foundation.Keyboard.handleKey(i,"Drilldown",{next:function(){return o.is(e.$submenuAnchors)?(e._show(o.parent("li")),o.parent("li").one(Foundation.transitionend(o),function(){o.parent("li").find("ul li a").filter(e.$menuItems).first().focus()}),!0):void 0},previous:function(){return e._hide(o.parent("li").parent("ul")),o.parent("li").parent("ul").one(Foundation.transitionend(o),function(){setTimeout(function(){o.parent("li").parent("ul").parent("li").children("a").first().focus()},1)}),!0},up:function(){return n.focus(),!0},down:function(){return s.focus(),!0},close:function(){e._back()},open:function(){return o.is(e.$menuItems)?o.is(e.$submenuAnchors)&&(e._show(o.parent("li")),o.parent("li").one(Foundation.transitionend(o),function(){o.parent("li").find("ul li a").filter(e.$menuItems).first().focus()})):(e._hide(o.parent("li").parent("ul")),o.parent("li").parent("ul").one(Foundation.transitionend(o),function(){setTimeout(function(){o.parent("li").parent("ul").parent("li").children("a").first().focus()},1)})),!0},handled:function(t){t&&i.preventDefault(),i.stopImmediatePropagation()}})})}},{key:"_hideAll",value:function(){var t=this.$element.find(".is-drilldown-submenu.is-active").addClass("is-closing");t.one(Foundation.transitionend(t),function(e){t.removeClass("is-active is-closing")}),this.$element.trigger("closed.zf.drilldown")}},{key:"_back",value:function(t){var e=this;t.off("click.zf.drilldown"),t.children(".js-drilldown-back").on("click.zf.drilldown",function(i){i.stopImmediatePropagation(),e._hide(t)})}},{key:"_menuLinkEvents",value:function(){var t=this;this.$menuItems.not(".is-drilldown-submenu-parent").off("click.zf.drilldown").on("click.zf.drilldown",function(e){setTimeout(function(){t._hideAll()},0)})}},{key:"_show",value:function(t){t.children("[data-submenu]").addClass("is-active"),this.$element.trigger("open.zf.drilldown",[t])}},{key:"_hide",value:function(t){t.addClass("is-closing").one(Foundation.transitionend(t),function(){t.removeClass("is-active is-closing"),t.blur()}),t.trigger("hide.zf.drilldown",[t])}},{key:"_getMaxDims",value:function(){var e=0,i={};return this.$submenus.add(this.$element).each(function(){var i=t(this).children("li").length;e=i>e?i:e}),i["min-height"]=e*this.$menuItems[0].getBoundingClientRect().height+"px",i["max-width"]=this.$element[0].getBoundingClientRect().width+"px",i}},{key:"destroy",value:function(){this._hideAll(),Foundation.Nest.Burn(this.$element,"drilldown"),this.$element.unwrap().find(".js-drilldown-back, .is-submenu-parent-item").remove().end().find(".is-active, .is-closing, .is-drilldown-submenu").removeClass("is-active is-closing is-drilldown-submenu").end().find("[data-submenu]").removeAttr("aria-hidden tabindex role"),this.$submenuAnchors.each(function(){t(this).off(".zf.drilldown")}),this.$element.find("a").each(function(){var e=t(this);e.data("savedHref")&&e.attr("href",e.data("savedHref")).removeData("savedHref")}),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={backButton:'
  • Back
  • ',wrapper:"
    ",parentLink:!1,closeOnClick:!1},Foundation.plugin(e,"Drilldown")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i-1&&this.usedPositions.indexOf("left")<0?this.$element.addClass("left"):"top"===t&&this.usedPositions.indexOf("bottom")>-1&&this.usedPositions.indexOf("left")<0?this.$element.removeClass(t).addClass("left"):"left"===t&&this.usedPositions.indexOf("right")>-1&&this.usedPositions.indexOf("bottom")<0?this.$element.removeClass(t):"right"===t&&this.usedPositions.indexOf("left")>-1&&this.usedPositions.indexOf("bottom")<0?this.$element.removeClass(t):this.$element.removeClass(t),this.classChanged=!0,this.counter--}},{key:"_setPosition",value:function(){if("false"===this.$anchor.attr("aria-expanded"))return!1;var t=this.getPositionClass(),e=Foundation.Box.GetDimensions(this.$element),i=(Foundation.Box.GetDimensions(this.$anchor),"left"===t?"left":"right"===t?"left":"top"),n="top"===i?"height":"width";"height"===n?this.options.vOffset:this.options.hOffset;if(e.width>=e.windowDims.width||!this.counter&&!Foundation.Box.ImNotTouchingYou(this.$element))return this.$element.offset(Foundation.Box.GetOffsets(this.$element,this.$anchor,"center bottom",this.options.vOffset,this.options.hOffset,!0)).css({width:e.windowDims.width-2*this.options.hOffset,height:"auto"}),this.classChanged=!0,!1;for(this.$element.offset(Foundation.Box.GetOffsets(this.$element,this.$anchor,t,this.options.vOffset,this.options.hOffset));!Foundation.Box.ImNotTouchingYou(this.$element,!1,!0)&&this.counter;)this._reposition(t),this._setPosition()}},{key:"_events",value:function(){var e=this;this.$element.on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":this.close.bind(this),"toggle.zf.trigger":this.toggle.bind(this),"resizeme.zf.trigger":this._setPosition.bind(this)}),this.options.hover&&(this.$anchor.off("mouseenter.zf.dropdown mouseleave.zf.dropdown").on("mouseenter.zf.dropdown",function(){clearTimeout(e.timeout),e.timeout=setTimeout(function(){e.open(),e.$anchor.data("hover",!0)},e.options.hoverDelay)}).on("mouseleave.zf.dropdown",function(){clearTimeout(e.timeout),e.timeout=setTimeout(function(){e.close(),e.$anchor.data("hover",!1)},e.options.hoverDelay)}),this.options.hoverPane&&this.$element.off("mouseenter.zf.dropdown mouseleave.zf.dropdown").on("mouseenter.zf.dropdown",function(){clearTimeout(e.timeout)}).on("mouseleave.zf.dropdown",function(){clearTimeout(e.timeout),e.timeout=setTimeout(function(){e.close(),e.$anchor.data("hover",!1)},e.options.hoverDelay)})),this.$anchor.add(this.$element).on("keydown.zf.dropdown",function(i){var n=t(this),s=Foundation.Keyboard.findFocusable(e.$element);Foundation.Keyboard.handleKey(i,"Dropdown",{tab_forward:function(){e.$element.find(":focus").is(s.eq(-1))&&(e.options.trapFocus?(s.eq(0).focus(),i.preventDefault()):e.close())},tab_backward:function(){(e.$element.find(":focus").is(s.eq(0))||e.$element.is(":focus"))&&(e.options.trapFocus?(s.eq(-1).focus(),i.preventDefault()):e.close())},open:function(){n.is(e.$anchor)&&(e.open(),e.$element.attr("tabindex",-1).focus(),i.preventDefault())},close:function(){e.close(),e.$anchor.focus()}})})}},{key:"_addBodyHandler",value:function(){var e=t(document.body).not(this.$element),i=this;e.off("click.zf.dropdown").on("click.zf.dropdown",function(t){i.$anchor.is(t.target)||i.$anchor.find(t.target).length||i.$element.find(t.target).length||(i.close(),e.off("click.zf.dropdown"))})}},{key:"open",value:function(){if(this.$element.trigger("closeme.zf.dropdown",this.$element.attr("id")),this.$anchor.addClass("hover").attr({"aria-expanded":!0}),this._setPosition(),this.$element.addClass("is-open").attr({"aria-hidden":!1}),this.options.autoFocus){var t=Foundation.Keyboard.findFocusable(this.$element);t.length&&t.eq(0).focus()}this.options.closeOnClick&&this._addBodyHandler(),this.$element.trigger("show.zf.dropdown",[this.$element])}},{key:"close",value:function(){if(!this.$element.hasClass("is-open"))return!1;if(this.$element.removeClass("is-open").attr({"aria-hidden":!0}),this.$anchor.removeClass("hover").attr("aria-expanded",!1),this.classChanged){var t=this.getPositionClass();t&&this.$element.removeClass(t),this.$element.addClass(this.options.positionClass).css({height:"",width:""}),this.classChanged=!1,this.counter=4,this.usedPositions.length=0}this.$element.trigger("hide.zf.dropdown",[this.$element])}},{key:"toggle",value:function(){if(this.$element.hasClass("is-open")){if(this.$anchor.data("hover"))return;this.close()}else this.open()}},{key:"destroy",value:function(){this.$element.off(".zf.trigger").hide(),this.$anchor.off(".zf.dropdown"),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={hoverDelay:250,hover:!1,hoverPane:!1,vOffset:1,hOffset:1,positionClass:"",trapFocus:!1,autoFocus:!1,closeOnClick:!1},Foundation.plugin(e,"Dropdown")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i-1,r=a?e.$tabs:o.siblings("li").add(o);r.each(function(e){return t(this).is(o)?(n=r.eq(e-1),void(s=r.eq(e+1))):void 0});var l=function(){o.is(":last-child")||(s.children("a:first").focus(),i.preventDefault())},u=function(){n.children("a:first").focus(),i.preventDefault()},d=function(){var t=o.children("ul.is-dropdown-submenu");t.length&&(e._show(t),o.find("li > a:first").focus(),i.preventDefault())},h=function(){var t=o.parent("ul").parent("li");t.children("a:first").focus(),e._hide(t),i.preventDefault()},c={open:d,close:function(){e._hide(e.$element),e.$menuItems.find("a:first").focus(),i.preventDefault()},handled:function(){i.stopImmediatePropagation()}};a?e.$element.hasClass(e.options.verticalClass)?"left"===e.options.alignment?t.extend(c,{down:l,up:u,next:d,previous:h}):t.extend(c,{down:l,up:u,next:h,previous:d}):t.extend(c,{next:l,previous:u,down:d,up:h}):"left"===e.options.alignment?t.extend(c,{next:d,previous:h,down:l,up:u}):t.extend(c,{next:h,previous:d,down:l,up:u}),Foundation.Keyboard.handleKey(i,"DropdownMenu",c)})}},{key:"_addBodyHandler",value:function(){var e=t(document.body),i=this;e.off("mouseup.zf.dropdownmenu touchend.zf.dropdownmenu").on("mouseup.zf.dropdownmenu touchend.zf.dropdownmenu",function(t){var n=i.$element.find(t.target);n.length||(i._hide(),e.off("mouseup.zf.dropdownmenu touchend.zf.dropdownmenu"))})}},{key:"_show",value:function(e){var i=this.$tabs.index(this.$tabs.filter(function(i,n){return t(n).find(e).length>0})),n=e.parent("li.is-dropdown-submenu-parent").siblings("li.is-dropdown-submenu-parent");this._hide(n,i),e.css("visibility","hidden").addClass("js-dropdown-active").attr({"aria-hidden":!1}).parent("li.is-dropdown-submenu-parent").addClass("is-active").attr({"aria-expanded":!0});var s=Foundation.Box.ImNotTouchingYou(e,null,!0);if(!s){var o="left"===this.options.alignment?"-right":"-left",a=e.parent(".is-dropdown-submenu-parent");a.removeClass("opens"+o).addClass("opens-"+this.options.alignment),s=Foundation.Box.ImNotTouchingYou(e,null,!0),s||a.removeClass("opens-"+this.options.alignment).addClass("opens-inner"),this.changed=!0}e.css("visibility",""),this.options.closeOnClick&&this._addBodyHandler(),this.$element.trigger("show.zf.dropdownmenu",[e])}},{key:"_hide",value:function(t,e){var i;i=t&&t.length?t:void 0!==e?this.$tabs.not(function(t,i){return t===e}):this.$element;var n=i.hasClass("is-active")||i.find(".is-active").length>0;if(n){if(i.find("li.is-active").add(i).attr({"aria-expanded":!1,"data-is-click":!1}).removeClass("is-active"),i.find("ul.js-dropdown-active").attr({"aria-hidden":!0}).removeClass("js-dropdown-active"),this.changed||i.find("opens-inner").length){var s="left"===this.options.alignment?"right":"left";i.find("li.is-dropdown-submenu-parent").add(i).removeClass("opens-inner opens-"+this.options.alignment).addClass("opens-"+s),this.changed=!1}this.$element.trigger("hide.zf.dropdownmenu",[i])}}},{key:"destroy",value:function(){this.$menuItems.off(".zf.dropdownmenu").removeAttr("data-is-click").removeClass("is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner"),t(document.body).off(".zf.dropdownmenu"),Foundation.Nest.Burn(this.$element,"dropdown"),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={disableHover:!1,autoclose:!0,hoverDelay:50,clickOpen:!1,closingTime:500,alignment:"left",closeOnClick:!0,verticalClass:"vertical",rightClass:"align-right",forceFollow:!0},Foundation.plugin(e,"DropdownMenu")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i0,this.isNested=this.$element.parentsUntil(document.body,"[data-equalizer]").length>0,this.isOn=!1,this._bindHandler={onResizeMeBound:this._onResizeMe.bind(this),onPostEqualizedBound:this._onPostEqualized.bind(this)};var n,s=this.$element.find("img");this.options.equalizeOn?(n=this._checkMQ(),t(window).on("changed.zf.mediaquery",this._checkMQ.bind(this))):this._events(),(void 0!==n&&n===!1||void 0===n)&&(s.length?Foundation.onImagesLoaded(s,this._reflow.bind(this)):this._reflow())}},{key:"_pauseEvents",value:function(){this.isOn=!1,this.$element.off({".zf.equalizer":this._bindHandler.onPostEqualizedBound,"resizeme.zf.trigger":this._bindHandler.onResizeMeBound})}},{key:"_onResizeMe",value:function(t){this._reflow()}},{key:"_onPostEqualized",value:function(t){t.target!==this.$element[0]&&this._reflow()}},{key:"_events",value:function(){this._pauseEvents(),this.hasNested?this.$element.on("postequalized.zf.equalizer",this._bindHandler.onPostEqualizedBound):this.$element.on("resizeme.zf.trigger",this._bindHandler.onResizeMeBound),this.isOn=!0}},{key:"_checkMQ",value:function(){var t=!Foundation.MediaQuery.atLeast(this.options.equalizeOn);return t?this.isOn&&(this._pauseEvents(),this.$watched.css("height","auto")):this.isOn||this._events(),t}},{key:"_killswitch",value:function(){}},{key:"_reflow",value:function(){return!this.options.equalizeOnStack&&this._isStacked()?(this.$watched.css("height","auto"),!1):void(this.options.equalizeByRow?this.getHeightsByRow(this.applyHeightByRow.bind(this)):this.getHeights(this.applyHeight.bind(this)))}},{key:"_isStacked",value:function(){return this.$watched[0].getBoundingClientRect().top!==this.$watched[1].getBoundingClientRect().top}},{key:"getHeights",value:function(t){for(var e=[],i=0,n=this.$watched.length;n>i;i++)this.$watched[i].style.height="auto",e.push(this.$watched[i].offsetHeight);t(e)}},{key:"getHeightsByRow",value:function(e){var i=this.$watched.length?this.$watched.first().offset().top:0,n=[],s=0;n[s]=[];for(var o=0,a=this.$watched.length;a>o;o++){this.$watched[o].style.height="auto";var r=t(this.$watched[o]).offset().top;r!=i&&(s++,n[s]=[],i=r),n[s].push([this.$watched[o],this.$watched[o].offsetHeight])}for(var l=0,u=n.length;u>l;l++){var d=t(n[l]).map(function(){return this[1]}).get(),h=Math.max.apply(null,d);n[l].push(h)}e(n)}},{key:"applyHeight",value:function(t){var e=Math.max.apply(null,t);this.$element.trigger("preequalized.zf.equalizer"),this.$watched.css("height",e),this.$element.trigger("postequalized.zf.equalizer")}},{key:"applyHeightByRow",value:function(e){this.$element.trigger("preequalized.zf.equalizer");for(var i=0,n=e.length;n>i;i++){var s=e[i].length,o=e[i][s-1];if(2>=s)t(e[i][0][0]).css({height:"auto"});else{this.$element.trigger("preequalizedrow.zf.equalizer");for(var a=0,r=s-1;r>a;a++)t(e[i][a][0]).css({height:o});this.$element.trigger("postequalizedrow.zf.equalizer")}}this.$element.trigger("postequalized.zf.equalizer")}},{key:"destroy",value:function(){this._pauseEvents(),this.$watched.css("height","auto"),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={equalizeOnStack:!0,equalizeByRow:!1,equalizeOn:""},Foundation.plugin(e,"Equalizer")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i1&&this.geoSync(),this.options.accessible&&this.$wrapper.attr("tabindex",0)}},{key:"_loadBullets",value:function(){this.$bullets=this.$element.find("."+this.options.boxOfBullets).find("button")}},{key:"geoSync",value:function(){var t=this;this.timer=new Foundation.Timer(this.$element,{duration:this.options.timerDelay,infinite:!1},function(){t.changeSlide(!0)}),this.timer.start()}},{key:"_prepareForOrbit",value:function(){var t=this;this._setWrapperHeight(function(e){t._setSlideHeight(e)})}},{key:"_setWrapperHeight",value:function(e){var i,n=0,s=0;this.$slides.each(function(){i=this.getBoundingClientRect().height,t(this).attr("data-slide",s),s&&t(this).css({position:"relative",display:"none"}),n=i>n?i:n,s++}),s===this.$slides.length&&(this.$wrapper.css({height:n}),e(n))}},{key:"_setSlideHeight",value:function(e){this.$slides.each(function(){t(this).css("max-height",e)})}},{key:"_events",value:function(){var e=this;if(this.$slides.length>1){if(this.options.swipe&&this.$slides.off("swipeleft.zf.orbit swiperight.zf.orbit").on("swipeleft.zf.orbit",function(t){t.preventDefault(),e.changeSlide(!0)}).on("swiperight.zf.orbit",function(t){t.preventDefault(),e.changeSlide(!1)}),this.options.autoPlay&&(this.$slides.on("click.zf.orbit",function(){e.$element.data("clickedOn",!e.$element.data("clickedOn")),e.timer[e.$element.data("clickedOn")?"pause":"start"]()}),this.options.pauseOnHover&&this.$element.on("mouseenter.zf.orbit",function(){e.timer.pause()}).on("mouseleave.zf.orbit",function(){e.$element.data("clickedOn")||e.timer.start()})),this.options.navButtons){var i=this.$element.find("."+this.options.nextClass+", ."+this.options.prevClass);i.attr("tabindex",0).on("click.zf.orbit touchend.zf.orbit",function(i){i.preventDefault(),e.changeSlide(t(this).hasClass(e.options.nextClass))})}this.options.bullets&&this.$bullets.on("click.zf.orbit touchend.zf.orbit",function(){if(/is-active/g.test(this.className))return!1;var i=t(this).data("slide"),n=i>e.$slides.filter(".is-active").data("slide"),s=e.$slides.eq(i);e.changeSlide(n,s,i)}),this.$wrapper.add(this.$bullets).on("keydown.zf.orbit",function(i){Foundation.Keyboard.handleKey(i,"Orbit",{next:function(){e.changeSlide(!0)},previous:function(){e.changeSlide(!1)},handled:function(){t(i.target).is(e.$bullets)&&e.$bullets.filter(".is-active").focus()}})})}}},{key:"changeSlide",value:function(t,e,i){var n=this.$slides.filter(".is-active").eq(0);if(/mui/g.test(n[0].className))return!1;var s,o=this.$slides.first(),a=this.$slides.last(),r=t?"Right":"Left",l=t?"Left":"Right",u=this;s=e?e:t?this.options.infiniteWrap?n.next("."+this.options.slideClass).length?n.next("."+this.options.slideClass):o:n.next("."+this.options.slideClass):this.options.infiniteWrap?n.prev("."+this.options.slideClass).length?n.prev("."+this.options.slideClass):a:n.prev("."+this.options.slideClass),s.length&&(this.options.bullets&&(i=i||this.$slides.index(s),this._updateBullets(i)),this.options.useMUI?(Foundation.Motion.animateIn(s.addClass("is-active").css({position:"absolute",top:0}),this.options["animInFrom"+r],function(){s.css({position:"relative",display:"block"}).attr("aria-live","polite")}),Foundation.Motion.animateOut(n.removeClass("is-active"),this.options["animOutTo"+l],function(){n.removeAttr("aria-live"),u.options.autoPlay&&!u.timer.isPaused&&u.timer.restart()})):(n.removeClass("is-active is-in").removeAttr("aria-live").hide(),s.addClass("is-active is-in").attr("aria-live","polite").show(),this.options.autoPlay&&!this.timer.isPaused&&this.timer.restart()),this.$element.trigger("slidechange.zf.orbit",[s]))}},{key:"_updateBullets",value:function(t){var e=this.$element.find("."+this.options.boxOfBullets).find(".is-active").removeClass("is-active").blur(),i=e.find("span:last").detach();this.$bullets.eq(t).addClass("is-active").append(i)}},{key:"destroy",value:function(){this.$element.off(".zf.orbit").find("*").off(".zf.orbit").end().hide(),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={bullets:!0,navButtons:!0,animInFromRight:"slide-in-right",animOutToRight:"slide-out-right",animInFromLeft:"slide-in-left",animOutToLeft:"slide-out-left",autoPlay:!0,timerDelay:5e3,infiniteWrap:!0,swipe:!0,pauseOnHover:!0,accessible:!0,containerClass:"orbit-container",slideClass:"orbit-slide",boxOfBullets:"orbit-bullets",nextClass:"orbit-next",prevClass:"orbit-previous",useMUI:!0},Foundation.plugin(e,"Orbit")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i1?o[0]:"small",r=o.length>1?o[1]:o[0];null!==i[r]&&(e[a]=i[r])}this.rules=e}t.isEmptyObject(this.rules)||this._checkMediaQueries()}},{key:"_events",value:function(){var e=this;t(window).on("changed.zf.mediaquery",function(){e._checkMediaQueries()})}},{key:"_checkMediaQueries",value:function(){var e,n=this;t.each(this.rules,function(t){Foundation.MediaQuery.atLeast(t)&&(e=t)}),e&&(this.currentPlugin instanceof this.rules[e].plugin||(t.each(i,function(t,e){n.$element.removeClass(e.cssClass)}),this.$element.addClass(this.rules[e].cssClass),this.currentPlugin&&this.currentPlugin.destroy(),this.currentPlugin=new this.rules[e].plugin(this.$element,{})))}},{key:"destroy",value:function(){this.currentPlugin.destroy(),t(window).off(".zf.ResponsiveMenu"),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={};var i={dropdown:{cssClass:"dropdown",plugin:Foundation._plugins["dropdown-menu"]||null},drilldown:{cssClass:"drilldown",plugin:Foundation._plugins.drilldown||null},accordion:{cssClass:"accordion-menu",plugin:Foundation._plugins["accordion-menu"]||null}};Foundation.plugin(e,"ResponsiveMenu")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i").addClass("reveal-overlay").appendTo("body");return i}},{key:"_updatePosition",value:function(){var e,i,n=this.$element.outerWidth(),s=t(window).width(),o=this.$element.outerHeight(),a=t(window).height();e="auto"===this.options.hOffset?parseInt((s-n)/2,10):parseInt(this.options.hOffset,10),i="auto"===this.options.vOffset?o>a?parseInt(Math.min(100,a/10),10):parseInt((a-o)/4,10):parseInt(this.options.vOffset,10),this.$element.css({top:i+"px"}),this.$overlay&&"auto"===this.options.hOffset||(this.$element.css({left:e+"px"}),this.$element.css({margin:"0px"}))}},{key:"_events",value:function(){var e=this,i=this;this.$element.on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":function(n,s){return n.target===i.$element[0]||t(n.target).parents("[data-closable]")[0]===s?e.close.apply(e):void 0},"toggle.zf.trigger":this.toggle.bind(this),"resizeme.zf.trigger":function(){i._updatePosition()}}),this.$anchor.length&&this.$anchor.on("keydown.zf.reveal",function(t){13!==t.which&&32!==t.which||(t.stopPropagation(),t.preventDefault(),i.open())}),this.options.closeOnClick&&this.options.overlay&&this.$overlay.off(".zf.reveal").on("click.zf.reveal",function(e){e.target===i.$element[0]||t.contains(i.$element[0],e.target)||i.close()}),this.options.deepLink&&t(window).on("popstate.zf.reveal:"+this.id,this._handleState.bind(this))}},{key:"_handleState",value:function(t){window.location.hash!=="#"+this.id||this.isActive?this.close():this.open()}},{key:"open",value:function(){var e=this;if(this.options.deepLink){var i="#"+this.id;window.history.pushState?window.history.pushState(null,null,i):window.location.hash=i}if(this.isActive=!0,this.$element.css({visibility:"hidden"}).show().scrollTop(0),this.options.overlay&&this.$overlay.css({visibility:"hidden"}).show(),this._updatePosition(),this.$element.hide().css({visibility:""}),this.$overlay&&(this.$overlay.css({visibility:""}).hide(),this.$element.hasClass("fast")?this.$overlay.addClass("fast"):this.$element.hasClass("slow")&&this.$overlay.addClass("slow")),this.options.multipleOpened||this.$element.trigger("closeme.zf.reveal",this.id),this.options.animationIn){var n;!function(){var t=function(){n.$element.attr({"aria-hidden":!1,tabindex:-1}).focus(),console.log("focus")};n=e,e.options.overlay&&Foundation.Motion.animateIn(e.$overlay,"fade-in"),Foundation.Motion.animateIn(e.$element,e.options.animationIn,function(){e.focusableElements=Foundation.Keyboard.findFocusable(e.$element),t()})}()}else this.options.overlay&&this.$overlay.show(0),this.$element.show(this.options.showDelay);this.$element.attr({"aria-hidden":!1,tabindex:-1}).focus(),this.$element.trigger("open.zf.reveal"),this.isMobile?(this.originalScrollPos=window.pageYOffset,t("html, body").addClass("is-reveal-open")):t("body").addClass("is-reveal-open"),setTimeout(function(){e._extraHandlers()},0)}},{key:"_extraHandlers",value:function(){var e=this;this.focusableElements=Foundation.Keyboard.findFocusable(this.$element),this.options.overlay||!this.options.closeOnClick||this.options.fullScreen||t("body").on("click.zf.reveal",function(i){i.target===e.$element[0]||t.contains(e.$element[0],i.target)||e.close()}),this.options.closeOnEsc&&t(window).on("keydown.zf.reveal",function(t){Foundation.Keyboard.handleKey(t,"Reveal",{close:function(){e.options.closeOnEsc&&(e.close(),e.$anchor.focus())}})}),this.$element.on("keydown.zf.reveal",function(i){var n=t(this);Foundation.Keyboard.handleKey(i,"Reveal",{tab_forward:function(){return e.$element.find(":focus").is(e.focusableElements.eq(-1))?(e.focusableElements.eq(0).focus(),!0):0===e.focusableElements.length?!0:void 0},tab_backward:function(){return e.$element.find(":focus").is(e.focusableElements.eq(0))||e.$element.is(":focus")?(e.focusableElements.eq(-1).focus(),!0):0===e.focusableElements.length?!0:void 0},open:function(){e.$element.find(":focus").is(e.$element.find("[data-close]"))?setTimeout(function(){e.$anchor.focus()},1):n.is(e.focusableElements)&&e.open()},close:function(){e.options.closeOnEsc&&(e.close(),e.$anchor.focus())},handled:function(t){t&&i.preventDefault()}})})}},{key:"close",value:function(){function e(){i.isMobile?(t("html, body").removeClass("is-reveal-open"),i.originalScrollPos&&(t("body").scrollTop(i.originalScrollPos),i.originalScrollPos=null)):t("body").removeClass("is-reveal-open"),i.$element.attr("aria-hidden",!0),i.$element.trigger("closed.zf.reveal")}if(!this.isActive||!this.$element.is(":visible"))return!1;var i=this;this.options.animationOut?(this.options.overlay?Foundation.Motion.animateOut(this.$overlay,"fade-out",e):e(),Foundation.Motion.animateOut(this.$element,this.options.animationOut)):(this.options.overlay?this.$overlay.hide(0,e):e(),this.$element.hide(this.options.hideDelay)),this.options.closeOnEsc&&t(window).off("keydown.zf.reveal"),!this.options.overlay&&this.options.closeOnClick&&t("body").off("click.zf.reveal"),this.$element.off("keydown.zf.reveal"),this.options.resetOnClose&&this.$element.html(this.$element.html()),this.isActive=!1,i.options.deepLink&&(window.history.replaceState?window.history.replaceState("",document.title,window.location.pathname):window.location.hash="")}},{key:"toggle",value:function(){this.isActive?this.close():this.open()}},{key:"destroy",value:function(){this.options.overlay&&(this.$element.appendTo(t("body")),this.$overlay.hide().off().remove()),this.$element.hide().off(),this.$anchor.off(".zf"),t(window).off(".zf.reveal:"+this.id),Foundation.unregisterPlugin(this)}}]),e}();s.defaults={animationIn:"",animationOut:"",showDelay:0,hideDelay:0,closeOnClick:!0,closeOnEsc:!0,multipleOpened:!1,vOffset:"auto",hOffset:"auto",fullScreen:!1,btmOffsetPct:10,overlay:!0,resetOnClose:!1,deepLink:!1},Foundation.plugin(s,"Reveal")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i1?this.inputs.eq(1):t("#"+this.$handle2.attr("aria-controls")),this.inputs[1]||(this.inputs=this.inputs.add(this.$input2)),e=!0,this._setHandlePos(this.$handle,this.options.initialStart,!0,function(){i._setHandlePos(i.$handle2,i.options.initialEnd,!0)}),this._setInitAttr(1),this._events(this.$handle2)),e||this._setHandlePos(this.$handle,this.options.initialStart,!0)}},{key:"_setHandlePos",value:function(t,i,n,s){if(!this.$element.hasClass(this.options.disabledClass)){i=parseFloat(i),ithis.options.end&&(i=this.options.end);var o=this.options.doubleSided;if(o)if(0===this.handles.index(t)){var a=parseFloat(this.$handle2.attr("aria-valuenow"));i=i>=a?a-this.options.step:i}else{var r=parseFloat(this.$handle.attr("aria-valuenow"));i=r>=i?r+this.options.step:i}this.options.vertical&&!n&&(i=this.options.end-i);var l=this,u=this.options.vertical,d=u?"height":"width",h=u?"top":"left",c=t[0].getBoundingClientRect()[d],f=this.$element[0].getBoundingClientRect()[d],p=e(i-this.options.start,this.options.end-this.options.start).toFixed(2),m=(f-c)*p,v=(100*e(m,f)).toFixed(this.options.decimal);i=parseFloat(i.toFixed(this.options.decimal));var g={};if(this._setValues(t,i),o){var w,y=0===this.handles.index(t),b=~~(100*e(c,f));if(y)g[h]=v+"%",w=parseFloat(this.$handle2[0].style[h])-v+b,s&&"function"==typeof s&&s();else{var $=parseFloat(this.$handle[0].style[h]);w=v-(isNaN($)?this.options.initialStart/((this.options.end-this.options.start)/100):$)+b}g["min-"+d]=w+"%"}this.$element.one("finished.zf.animate",function(){l.$element.trigger("moved.zf.slider",[t])});var C=this.$element.data("dragging")?1e3/60:this.options.moveTime;Foundation.Move(C,t,function(){t.css(h,v+"%"),l.options.doubleSided?l.$fill.css(g):l.$fill.css(d,100*p+"%")}),clearTimeout(l.timeout),l.timeout=setTimeout(function(){l.$element.trigger("changed.zf.slider",[t])},l.options.changedDelay)}}},{key:"_setInitAttr",value:function(t){var e=this.inputs.eq(t).attr("id")||Foundation.GetYoDigits(6,"slider");this.inputs.eq(t).attr({id:e,max:this.options.end,min:this.options.start,step:this.options.step}),this.handles.eq(t).attr({role:"slider","aria-controls":e,"aria-valuemax":this.options.end,"aria-valuemin":this.options.start,"aria-valuenow":0===t?this.options.initialStart:this.options.initialEnd,"aria-orientation":this.options.vertical?"vertical":"horizontal",tabindex:0})}},{key:"_setValues",value:function(t,e){var i=this.options.doubleSided?this.handles.index(t):0;this.inputs.eq(i).val(e),t.attr("aria-valuenow",e)}},{key:"_handleEvent",value:function(n,s,o){var a,r;if(o)a=this._adjustValue(null,o),r=!0;else{n.preventDefault();var l=this,u=this.options.vertical,d=u?"height":"width",h=u?"top":"left",c=u?n.pageY:n.pageX,f=(this.$handle[0].getBoundingClientRect()[d]/2,this.$element[0].getBoundingClientRect()[d]),p=u?t(window).scrollTop():t(window).scrollLeft(),m=this.$element.offset()[h];n.clientY===n.pageY&&(c+=p);var v,g=c-m;if(v=0>g?0:g>f?f:g,offsetPct=e(v,f),a=(this.options.end-this.options.start)*offsetPct+this.options.start,Foundation.rtl()&&!this.options.vertical&&(a=this.options.end-a),a=l._adjustValue(null,a),r=!1,!s){var w=i(this.$handle,h,v,d),y=i(this.$handle2,h,v,d);s=y>=w?this.$handle:this.$handle2}}this._setHandlePos(s,a,r)}},{key:"_adjustValue",value:function(t,e){var i,n,s,o,a=this.options.step,r=parseFloat(a/2);return i=t?parseFloat(t.attr("aria-valuenow")):e,n=i%a,s=i-n,o=s+a,0===n?i:i=i>=s+r?o:s}},{key:"_events",value:function(e){var i,n=this;if(this.inputs.off("change.zf.slider").on("change.zf.slider",function(e){var i=n.inputs.index(t(this));n._handleEvent(e,n.handles.eq(i),t(this).val())}),this.options.clickSelect&&this.$element.off("click.zf.slider").on("click.zf.slider",function(e){return n.$element.data("dragging")?!1:void(t(e.target).is("[data-slider-handle]")||(n.options.doubleSided?n._handleEvent(e):n._handleEvent(e,n.$handle)))}),this.options.draggable){this.handles.addTouch();var s=t("body");e.off("mousedown.zf.slider").on("mousedown.zf.slider",function(o){e.addClass("is-dragging"),n.$fill.addClass("is-dragging"),n.$element.data("dragging",!0),i=t(o.currentTarget),s.on("mousemove.zf.slider",function(t){t.preventDefault(),n._handleEvent(t,i)}).on("mouseup.zf.slider",function(t){n._handleEvent(t,i),e.removeClass("is-dragging"),n.$fill.removeClass("is-dragging"),n.$element.data("dragging",!1),s.off("mousemove.zf.slider mouseup.zf.slider")})}).on("selectstart.zf.slider touchmove.zf.slider",function(t){t.preventDefault()})}e.off("keydown.zf.slider").on("keydown.zf.slider",function(e){var i,s=t(this),o=n.options.doubleSided?n.handles.index(s):0,a=parseFloat(n.inputs.eq(o).val());Foundation.Keyboard.handleKey(e,"Slider",{decrease:function(){i=a-n.options.step},increase:function(){i=a+n.options.step},decrease_fast:function(){i=a-10*n.options.step},increase_fast:function(){i=a+10*n.options.step},handled:function(){e.preventDefault(),n._setHandlePos(s,i,!0)}})})}},{key:"destroy",value:function(){this.handles.off(".zf.slider"),this.inputs.off(".zf.slider"),this.$element.off(".zf.slider"),Foundation.unregisterPlugin(this)}}]),n}();n.defaults={start:0,end:100,step:1,initialStart:0,initialEnd:100,binding:!1,clickSelect:!0,vertical:!1,draggable:!0,disabled:!1,doubleSided:!1,decimal:2,moveTime:200,disabledClass:"disabled",invertVertical:!1,changedDelay:500},Foundation.plugin(n,"Slider")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;io&&n[o];o++){var r;if("number"==typeof n[o])r=n[o];else{var l=n[o].split(":"),u=t("#"+l[0]);r=u.offset().top,l[1]&&"bottom"===l[1].toLowerCase()&&(r+=u[0].getBoundingClientRect().height)}s[o]=r}this.points=s}},{key:"_events",value:function(e){var i=this,n=this.scrollListener="scroll.zf."+e;this.isOn||(this.canStick&&(this.isOn=!0,t(window).off(n).on(n,function(t){0===i.scrollCount?(i.scrollCount=i.options.checkEvery,i._setSizes(function(){i._calc(!1,window.pageYOffset)})):(i.scrollCount--,i._calc(!1,window.pageYOffset))})),this.$element.off("resizeme.zf.trigger").on("resizeme.zf.trigger",function(t,s){i._setSizes(function(){i._calc(!1),i.canStick?i.isOn||i._events(e):i.isOn&&i._pauseListeners(n)})}))}},{key:"_pauseListeners",value:function(e){this.isOn=!1,t(window).off(e),this.$element.trigger("pause.zf.sticky")}},{key:"_calc",value:function(t,e){return t&&this._setSizes(),this.canStick?(e||(e=window.pageYOffset),void(e>=this.topPoint?e<=this.bottomPoint?this.isStuck||this._setSticky():this.isStuck&&this._removeSticky(!1):this.isStuck&&this._removeSticky(!0))):(this.isStuck&&this._removeSticky(!0),!1)}},{key:"_setSticky",value:function(){var t=this,e=this.options.stickTo,i="top"===e?"marginTop":"marginBottom",n="top"===e?"bottom":"top",s={};s[i]=this.options[i]+"em",s[e]=0,s[n]="auto",s.left=this.$container.offset().left+parseInt(window.getComputedStyle(this.$container[0])["padding-left"],10),this.isStuck=!0,this.$element.removeClass("is-anchored is-at-"+n).addClass("is-stuck is-at-"+e).css(s).trigger("sticky.zf.stuckto:"+e),this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd",function(){t._setSizes()})}},{key:"_removeSticky",value:function(t){var e=this.options.stickTo,i="top"===e,n={},s=(this.points?this.points[1]-this.points[0]:this.anchorHeight)-this.elemHeight,o=i?"marginTop":"marginBottom",a=t?"top":"bottom";n[o]=0,n.bottom="auto",t?n.top=0:n.top=s,n.left="",this.isStuck=!1,this.$element.removeClass("is-stuck is-at-"+e).addClass("is-anchored is-at-"+a).css(n).trigger("sticky.zf.unstuckfrom:"+a)}},{key:"_setSizes",value:function(t){this.canStick=Foundation.MediaQuery.atLeast(this.options.stickyOn),this.canStick||t();var e=this.$container[0].getBoundingClientRect().width,i=window.getComputedStyle(this.$container[0]),n=parseInt(i["padding-right"],10);this.$anchor&&this.$anchor.length?this.anchorHeight=this.$anchor[0].getBoundingClientRect().height:this._parsePoints(),this.$element.css({"max-width":e-n+"px"});var s=this.$element[0].getBoundingClientRect().height||this.containerHeight;"none"==this.$element.css("display")&&(s=0),this.containerHeight=s,this.$container.css({height:s}),this.elemHeight=s,this.isStuck&&this.$element.css({left:this.$container.offset().left+parseInt(i["padding-left"],10)}),this._setBreakPoints(s,function(){t&&t()})}},{key:"_setBreakPoints",value:function(t,i){if(!this.canStick){if(!i)return!1;i()}var n=e(this.options.marginTop),s=e(this.options.marginBottom),o=this.points?this.points[0]:this.$anchor.offset().top,a=this.points?this.points[1]:o+this.anchorHeight,r=window.innerHeight;"top"===this.options.stickTo?(o-=n,a-=t+n):"bottom"===this.options.stickTo&&(o-=r-(t+s),a-=r-s),this.topPoint=o,this.bottomPoint=a,i&&i()}},{key:"destroy",value:function(){this._removeSticky(!0),this.$element.removeClass(this.options.stickyClass+" is-anchored is-at-top").css({height:"",top:"",bottom:"","max-width":""}).off("resizeme.zf.trigger"),this.$anchor&&this.$anchor.length&&this.$anchor.off("change.zf.sticky"),t(window).off(this.scrollListener),this.wasWrapped?this.$element.unwrap():this.$container.removeClass(this.options.containerClass).css({height:""}),Foundation.unregisterPlugin(this)}}]),i}();i.defaults={container:"
    ",stickTo:"top",anchor:"",topAnchor:"",btmAnchor:"",marginTop:1,marginBottom:1,stickyOn:"medium",stickyClass:"sticky",containerClass:"sticky-container",checkEvery:-1},Foundation.plugin(i,"Sticky")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;ie?s:e}).css("height",e+"px")}},{key:"destroy",value:function(){this.$element.find("."+this.options.linkClass).off(".zf.tabs").hide().end().find("."+this.options.panelClass).hide(),this.options.matchHeight&&null!=this._setHeightMqHandler&&t(window).off("changed.zf.mediaquery",this._setHeightMqHandler),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={autoFocus:!1,wrapOnKeys:!0,matchHeight:!1,linkClass:"tabs-title",panelClass:"tabs-panel"},Foundation.plugin(e,"Tabs")}(jQuery);var _createClass=function(){function t(t,e){for(var i=0;i").addClass(i).attr({role:"tooltip","aria-hidden":!0,"data-is-active":!1,"data-is-focus":!1,id:e});return n}},{key:"_reposition",value:function(t){this.usedPositions.push(t?t:"bottom"),!t&&this.usedPositions.indexOf("top")<0?this.template.addClass("top"):"top"===t&&this.usedPositions.indexOf("bottom")<0?this.template.removeClass(t):"left"===t&&this.usedPositions.indexOf("right")<0?this.template.removeClass(t).addClass("right"):"right"===t&&this.usedPositions.indexOf("left")<0?this.template.removeClass(t).addClass("left"):!t&&this.usedPositions.indexOf("top")>-1&&this.usedPositions.indexOf("left")<0?this.template.addClass("left"):"top"===t&&this.usedPositions.indexOf("bottom")>-1&&this.usedPositions.indexOf("left")<0?this.template.removeClass(t).addClass("left"):"left"===t&&this.usedPositions.indexOf("right")>-1&&this.usedPositions.indexOf("bottom")<0?this.template.removeClass(t):"right"===t&&this.usedPositions.indexOf("left")>-1&&this.usedPositions.indexOf("bottom")<0?this.template.removeClass(t):this.template.removeClass(t),this.classChanged=!0,this.counter--}},{key:"_setPosition",value:function(){var t=this._getPositionClass(this.template),e=Foundation.Box.GetDimensions(this.template),i=Foundation.Box.GetDimensions(this.$element),n="left"===t?"left":"right"===t?"left":"top",s="top"===n?"height":"width";"height"===s?this.options.vOffset:this.options.hOffset;if(e.width>=e.windowDims.width||!this.counter&&!Foundation.Box.ImNotTouchingYou(this.template))return this.template.offset(Foundation.Box.GetOffsets(this.template,this.$element,"center bottom",this.options.vOffset,this.options.hOffset,!0)).css({width:i.windowDims.width-2*this.options.hOffset,height:"auto"}),!1;for(this.template.offset(Foundation.Box.GetOffsets(this.template,this.$element,"center "+(t||"bottom"),this.options.vOffset,this.options.hOffset));!Foundation.Box.ImNotTouchingYou(this.template)&&this.counter;)this._reposition(t),this._setPosition()}},{key:"show",value:function(){if("all"!==this.options.showOn&&!Foundation.MediaQuery.atLeast(this.options.showOn))return!1;var t=this;this.template.css("visibility","hidden").show(),this._setPosition(),this.$element.trigger("closeme.zf.tooltip",this.template.attr("id")),this.template.attr({"data-is-active":!0,"aria-hidden":!1}),t.isActive=!0,this.template.stop().hide().css("visibility","").fadeIn(this.options.fadeInDuration,function(){}),this.$element.trigger("show.zf.tooltip")}},{key:"hide",value:function(){var t=this;this.template.stop().attr({"aria-hidden":!0,"data-is-active":!1}).fadeOut(this.options.fadeOutDuration,function(){t.isActive=!1,t.isClick=!1,t.classChanged&&(t.template.removeClass(t._getPositionClass(t.template)).addClass(t.options.positionClass),t.usedPositions=[],t.counter=4,t.classChanged=!1)}),this.$element.trigger("hide.zf.tooltip")}},{key:"_events",value:function(){var t=this,e=(this.template,!1);this.options.disableHover||this.$element.on("mouseenter.zf.tooltip",function(e){t.isActive||(t.timeout=setTimeout(function(){t.show()},t.options.hoverDelay))}).on("mouseleave.zf.tooltip",function(i){clearTimeout(t.timeout),(!e||t.isClick&&!t.options.clickOpen)&&t.hide()}),this.options.clickOpen?this.$element.on("mousedown.zf.tooltip",function(e){e.stopImmediatePropagation(),t.isClick||(t.isClick=!0,!t.options.disableHover&&t.$element.attr("tabindex")||t.isActive||t.show())}):this.$element.on("mousedown.zf.tooltip",function(e){e.stopImmediatePropagation(),t.isClick=!0}),this.options.disableForTouch||this.$element.on("tap.zf.tooltip touchend.zf.tooltip",function(e){t.isActive?t.hide():t.show()}),this.$element.on({"close.zf.trigger":this.hide.bind(this)}),this.$element.on("focus.zf.tooltip",function(i){return e=!0,t.isClick?(t.options.clickOpen||(e=!1),!1):void t.show()}).on("focusout.zf.tooltip",function(i){e=!1,t.isClick=!1,t.hide()}).on("resizeme.zf.trigger",function(){t.isActive&&t._setPosition()})}},{key:"toggle",value:function(){this.isActive?this.hide():this.show()}},{key:"destroy",value:function(){this.$element.attr("title",this.template.text()).off(".zf.trigger .zf.tootip").removeAttr("aria-describedby").removeAttr("data-yeti-box").removeAttr("data-toggle").removeAttr("data-resize"),this.template.remove(),Foundation.unregisterPlugin(this)}}]),e}();e.defaults={disableForTouch:!1,hoverDelay:200,fadeInDuration:150,fadeOutDuration:150,disableHover:!1,templateClasses:"",tooltipClass:"tooltip",triggerClass:"has-tip",showOn:"small",template:"",tipText:"",touchCloseText:"Tap to close.",clickOpen:!0,positionClass:"",vOffset:10,hOffset:12},Foundation.plugin(e,"Tooltip")}(jQuery); diff --git a/lib/jquery/jquery.min.js b/lib/jquery/jquery.min.js new file mode 100644 index 0000000..c4643af --- /dev/null +++ b/lib/jquery/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
    ",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) +},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("