[
  {
    "path": ".gitattributes",
    "content": "web/client/resources/js/lib/* linguist-vendored\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nThumbs.db\nexamples/output.json\nweb/client/reports/\n/.idea\n/goconvey\n"
  },
  {
    "path": ".travis.yml",
    "content": "arch:\n  - amd64\n  - ppc64le\n\nlanguage: go\n\ngo:\n  - 1.13.x\n  - 1.14.x\n  - 1.15.x\n  - 1.16.x\n  - master\n\ninstall:\n  - go get -t ./...\n\nbefore_script: ./check_third_party.sh\nscript: go test -short -v ./...\n\nsudo: false\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Subject: GoConvey maintainers wanted\n\nWe'd like to open the project up to additional maintainers who want to move the project forward in a meaningful way.\n\nWe've spent significant time at SmartyStreets building GoConvey and it has perfectly met (and exceeded) all of our initial design specifications. We've used it to great effect. Being so well-matched to our development workflows at SmartyStreets, we haven't had a need to hack on it lately. This had been frustrating to many in the community who have ideas for the project and would like to see new features released (and some old bugs fixed). The release of Go 1.5 and the new vendoring experiment has been a source of confusion and hassle for those who have already upgraded and find that GoConvey needs to be brought up to speed.\n\nGoConvey is a popular 2-pronged, open-source github project (1,600+ stargazers, 100+ forks):\n\n- A package you import in your test code that allows you to write BDD-style tests.\n- An executable that runs a local web server which displays auto-updating test results in a web browser.\n\n----\n\n- https://github.com/smartystreets/goconvey\n- https://github.com/smartystreets/goconvey/wiki\n\n_I should mention that the [assertions package](https://github.com/smartystreets/assertions) imported by the convey package is used by other projects at SmartyStreets and so we will be continuing to maintain that project internally._\n\nWe hope to hear from you soon. Thanks!\n\n---\n\n# Contributing\n\nIn general, the code posted to the [SmartyStreets github organization](https://github.com/smartystreets) is created to solve specific problems at SmartyStreets that are ancillary to our core products in the address verification industry and may or may not be useful to other organizations or developers. Our reason for posting said code isn't necessarily to solicit feedback or contributions from the community but more as a showcase of some of the approaches to solving problems we have adopted.\n\nHaving stated that, we do consider issues raised by other githubbers as well as contributions submitted via pull requests. When submitting such a pull request, please follow these guidelines:\n\n- _Look before you leap:_ If the changes you plan to make are significant, it's in everyone's best interest for you to discuss them with a SmartyStreets team member prior to opening a pull request.\n- _License and ownership:_ If modifying the `LICENSE.md` file, limit your changes to fixing typographical mistakes. Do NOT modify the actual terms in the license or the copyright by **SmartyStreets, LLC**. Code submitted to SmartyStreets projects becomes property of SmartyStreets and must be compatible with the associated license.\n- _Testing:_ If the code you are submitting resides in packages/modules covered by automated tests, be sure to add passing tests that cover your changes and assert expected behavior and state. Submit the additional test cases as part of your change set.\n- _Style:_ Match your approach to **naming** and **formatting** with the surrounding code. Basically, the code you submit shouldn't stand out.\n  - \"Naming\" refers to such constructs as variables, methods, functions, classes, structs, interfaces, packages, modules, directories, files, etc...\n  - \"Formatting\" refers to such constructs as whitespace, horizontal line length, vertical function length, vertical file length, indentation, curly braces, etc...\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2022 Smarty\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nNOTE: Various optional and subordinate components carry their own licensing\nrequirements and restrictions.  Use of those components is subject to the terms\nand conditions outlined the respective license of each component.\n"
  },
  {
    "path": "README.md",
    "content": "# SMARTY DISCLAIMER: Subject to the terms of the associated license agreement, this software is freely available for your use. This software is FREE, AS IN PUPPIES, and is a gift. Enjoy your new responsibility. This means that while we may consider enhancement requests, we may or may not choose to entertain requests at our sole and absolute discretion.\n\nGoConvey is awesome Go testing\n==============================\n\n[![Build Status](https://app.travis-ci.com/smartystreets/goconvey.svg?branch=master)](https://app.travis-ci.com/smartystreets/goconvey)\n[![GoDoc](https://godoc.org/github.com/smartystreets/goconvey?status.svg)](http://godoc.org/github.com/smartystreets/goconvey)\n\n\nWelcome to GoConvey, a yummy Go testing tool for gophers. Works with `go test`. Use it in the terminal or browser according to your viewing pleasure.\n\nGoConvey supports the current versions of Go (see the official Go\n[release policy](https://golang.org/doc/devel/release#policy)). Currently\nthis means Go 1.16 and Go 1.17 are supported.\n\n**Features:**\n\n- Directly integrates with `go test`\n- Fully-automatic web UI (works with native Go tests, too)\n- Huge suite of regression tests\n- Shows test coverage\n- Readable, colorized console output (understandable by any manager, IT or not)\n- Test code generator\n- Desktop notifications (optional)\n- Immediately open problem lines in [Sublime Text](http://www.sublimetext.com) ([some assembly required](https://github.com/asuth/subl-handler))\n\n\nYou can ask questions about how to use GoConvey on [StackOverflow](http://stackoverflow.com/questions/ask?tags=goconvey,go&title=GoConvey%3A%20). Use the tags `go` and `goconvey`.\n\n**Menu:**\n\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [Documentation](#documentation)\n- [Screenshots](#screenshots)\n- [Contributors](#contributors)\n\n\n\n\nInstallation\n------------\n\n\t$ go install github.com/smartystreets/goconvey\n\n[Quick start](https://github.com/smartystreets/goconvey/wiki#get-going-in-25-seconds)\n-----------\n\nMake a test, for example:\n\n```go\npackage package_name\n\nimport (\n    \"testing\"\n    . \"github.com/smartystreets/goconvey/convey\"\n)\n\nfunc TestSpec(t *testing.T) {\n\n\t// Only pass t into top-level Convey calls\n\tConvey(\"Given some integer with a starting value\", t, func() {\n\t\tx := 1\n\n\t\tConvey(\"When the integer is incremented\", func() {\n\t\t\tx++\n\n\t\t\tConvey(\"The value should be greater by one\", func() {\n\t\t\t\tSo(x, ShouldEqual, 2)\n\t\t\t})\n\t\t})\n\t})\n}\n```\n\n\n#### [In the browser](https://github.com/smartystreets/goconvey/wiki/Web-UI)\n\nStart up the GoConvey web server at your project's path:\n\n\t$ $GOPATH/bin/goconvey\n\nThen watch the test results display in your browser at:\n\n\thttp://localhost:8080\n\n\nIf the browser doesn't open automatically, please click [http://localhost:8080](http://localhost:8080) to open manually.\n\nThere you have it.\n![](http://d79i1fxsrar4t.cloudfront.net/goconvey.co/gc-1-dark.png)\nAs long as GoConvey is running, test results will automatically update in your browser window.\n\n![](http://d79i1fxsrar4t.cloudfront.net/goconvey.co/gc-5-dark.png)\nThe design is responsive, so you can squish the browser real tight if you need to put it beside your code.\n\n\nThe [web UI](https://github.com/smartystreets/goconvey/wiki/Web-UI) supports traditional Go tests, so use it even if you're not using GoConvey tests.\n\n\n\n#### [In the terminal](https://github.com/smartystreets/goconvey/wiki/Execution)\n\nJust do what you do best:\n\n    $ go test\n\nOr if you want the output to include the story:\n\n    $ go test -v\n\n\n[Documentation](https://github.com/smartystreets/goconvey/wiki)\n-----------\n\nCheck out the\n\n- [GoConvey wiki](https://github.com/smartystreets/goconvey/wiki),\n- [![GoDoc](https://godoc.org/github.com/smartystreets/goconvey?status.png)](http://godoc.org/github.com/smartystreets/goconvey)\n- and the *_test.go files scattered throughout this project.\n\nContributors\n----------------------\n\nGoConvey is brought to you by [SmartyStreets](https://github.com/smartystreets) and [several contributors](https://github.com/smartystreets/goconvey/graphs/contributors) (Thanks!).\n"
  },
  {
    "path": "check_third_party.sh",
    "content": "#!/usr/bin/env bash\n\ncd \"$(dirname $(realpath $0))\"\n\nbash ./web/client/resources/js/lib/update.sh\n\nif ! (git diff-files --quiet web/client/resources/js/lib); then\n  echo \"Third party libraries don't match their .url files.\"\n  echo \"Re-run ./web/client/resources/js/lib/update.sh\"\n  exit 1\nfi\n"
  },
  {
    "path": "convey/assertions.go",
    "content": "package convey\n\n// DO NOT EDIT: generated by update_assertions.sh\n\n//go:generate ./update_assertions.sh\n\nimport \"github.com/smarty/assertions\"\n\n// These assertions are forwarded from github.com/smarty/assertions\n// in order to make convey self-contained.\nvar (\n\tShouldAlmostEqual            = assertions.ShouldAlmostEqual\n\tShouldBeBetween              = assertions.ShouldBeBetween\n\tShouldBeBetweenOrEqual       = assertions.ShouldBeBetweenOrEqual\n\tShouldBeBlank                = assertions.ShouldBeBlank\n\tShouldBeChronological        = assertions.ShouldBeChronological\n\tShouldBeEmpty                = assertions.ShouldBeEmpty\n\tShouldBeError                = assertions.ShouldBeError\n\tShouldBeFalse                = assertions.ShouldBeFalse\n\tShouldBeGreaterThan          = assertions.ShouldBeGreaterThan\n\tShouldBeGreaterThanOrEqualTo = assertions.ShouldBeGreaterThanOrEqualTo\n\tShouldBeIn                   = assertions.ShouldBeIn\n\tShouldBeLessThan             = assertions.ShouldBeLessThan\n\tShouldBeLessThanOrEqualTo    = assertions.ShouldBeLessThanOrEqualTo\n\tShouldBeNil                  = assertions.ShouldBeNil\n\tShouldBeTrue                 = assertions.ShouldBeTrue\n\tShouldBeZeroValue            = assertions.ShouldBeZeroValue\n\tShouldContain                = assertions.ShouldContain\n\tShouldContainKey             = assertions.ShouldContainKey\n\tShouldContainSubstring       = assertions.ShouldContainSubstring\n\tShouldEndWith                = assertions.ShouldEndWith\n\tShouldEqual                  = assertions.ShouldEqual\n\tShouldEqualJSON              = assertions.ShouldEqualJSON\n\tShouldEqualTrimSpace         = assertions.ShouldEqualTrimSpace\n\tShouldEqualWithout           = assertions.ShouldEqualWithout\n\tShouldHappenAfter            = assertions.ShouldHappenAfter\n\tShouldHappenBefore           = assertions.ShouldHappenBefore\n\tShouldHappenBetween          = assertions.ShouldHappenBetween\n\tShouldHappenOnOrAfter        = assertions.ShouldHappenOnOrAfter\n\tShouldHappenOnOrBefore       = assertions.ShouldHappenOnOrBefore\n\tShouldHappenOnOrBetween      = assertions.ShouldHappenOnOrBetween\n\tShouldHappenWithin           = assertions.ShouldHappenWithin\n\tShouldHaveLength             = assertions.ShouldHaveLength\n\tShouldHaveSameTypeAs         = assertions.ShouldHaveSameTypeAs\n\tShouldImplement              = assertions.ShouldImplement\n\tShouldNotAlmostEqual         = assertions.ShouldNotAlmostEqual\n\tShouldNotBeBetween           = assertions.ShouldNotBeBetween\n\tShouldNotBeBetweenOrEqual    = assertions.ShouldNotBeBetweenOrEqual\n\tShouldNotBeBlank             = assertions.ShouldNotBeBlank\n\tShouldNotBeChronological     = assertions.ShouldNotBeChronological\n\tShouldNotBeEmpty             = assertions.ShouldNotBeEmpty\n\tShouldNotBeIn                = assertions.ShouldNotBeIn\n\tShouldNotBeNil               = assertions.ShouldNotBeNil\n\tShouldNotBeZeroValue         = assertions.ShouldNotBeZeroValue\n\tShouldNotContain             = assertions.ShouldNotContain\n\tShouldNotContainKey          = assertions.ShouldNotContainKey\n\tShouldNotContainSubstring    = assertions.ShouldNotContainSubstring\n\tShouldNotEndWith             = assertions.ShouldNotEndWith\n\tShouldNotEqual               = assertions.ShouldNotEqual\n\tShouldNotHappenOnOrBetween   = assertions.ShouldNotHappenOnOrBetween\n\tShouldNotHappenWithin        = assertions.ShouldNotHappenWithin\n\tShouldNotHaveSameTypeAs      = assertions.ShouldNotHaveSameTypeAs\n\tShouldNotImplement           = assertions.ShouldNotImplement\n\tShouldNotPanic               = assertions.ShouldNotPanic\n\tShouldNotPanicWith           = assertions.ShouldNotPanicWith\n\tShouldNotPointTo             = assertions.ShouldNotPointTo\n\tShouldNotResemble            = assertions.ShouldNotResemble\n\tShouldNotStartWith           = assertions.ShouldNotStartWith\n\tShouldPanic                  = assertions.ShouldPanic\n\tShouldPanicWith              = assertions.ShouldPanicWith\n\tShouldPointTo                = assertions.ShouldPointTo\n\tShouldResemble               = assertions.ShouldResemble\n\tShouldStartWith              = assertions.ShouldStartWith\n\tShouldWrap                   = assertions.ShouldWrap\n)\n"
  },
  {
    "path": "convey/context.go",
    "content": "package convey\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/jtolds/gls\"\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n)\n\ntype conveyErr struct {\n\tfmt    string\n\tparams []any\n}\n\nfunc (e *conveyErr) Error() string {\n\treturn fmt.Sprintf(e.fmt, e.params...)\n}\n\nfunc conveyPanic(fmt string, params ...any) {\n\tpanic(&conveyErr{fmt, params})\n}\n\nconst (\n\tmissingGoTest = `Top-level calls to Convey(...) need a reference to the *testing.T.\n\t\tHint: Convey(\"description here\", t, func() { /* notice that the second argument was the *testing.T (t)! */ }) `\n\textraGoTest    = `Only the top-level call to Convey(...) needs a reference to the *testing.T.`\n\tnoStackContext = \"Convey operation made without context on goroutine stack.\\n\" +\n\t\t\"Hint: Perhaps you meant to use `Convey(..., func(c C){...})` ?\"\n\tdifferentConveySituations = \"Different set of Convey statements on subsequent pass!\\nDid not expect %#v.\"\n\tmultipleIdenticalConvey   = \"Multiple convey suites with identical names: %#v\"\n)\n\nconst (\n\tfailureHalt = \"___FAILURE_HALT___\"\n\n\tnodeKey = \"node\"\n)\n\n///////////////////////////////// Stack Context /////////////////////////////////\n\nfunc getCurrentContext() *context {\n\tctx, ok := ctxMgr.GetValue(nodeKey)\n\tif ok {\n\t\treturn ctx.(*context)\n\t}\n\treturn nil\n}\n\nfunc mustGetCurrentContext() *context {\n\tctx := getCurrentContext()\n\tif ctx == nil {\n\t\tconveyPanic(noStackContext)\n\t}\n\treturn ctx\n}\n\n//////////////////////////////////// Context ////////////////////////////////////\n\n// context magically handles all coordination of Convey's and So assertions.\n//\n// It is tracked on the stack as goroutine-local-storage with the gls package,\n// or explicitly if the user decides to call convey like:\n//\n//   Convey(..., func(c C) {\n//     c.So(...)\n//   })\n//\n// This implements the `C` interface.\ntype context struct {\n\treporter reporting.Reporter\n\n\tchildren map[string]*context\n\n\tresets []func()\n\n\texecutedOnce   bool\n\texpectChildRun *bool\n\tcomplete       bool\n\n\tfocus       bool\n\tfailureMode FailureMode\n\tstackMode   StackMode\n}\n\n// rootConvey is the main entry point to a test suite. This is called when\n// there's no context in the stack already, and items must contain a `t` object,\n// or this panics.\nfunc rootConvey(items ...any) {\n\tentry := discover(items)\n\n\tif entry.Test == nil {\n\t\tconveyPanic(missingGoTest)\n\t}\n\n\texpectChildRun := true\n\tctx := &context{\n\t\treporter: buildReporter(),\n\n\t\tchildren: make(map[string]*context),\n\n\t\texpectChildRun: &expectChildRun,\n\n\t\tfocus:       entry.Focus,\n\t\tfailureMode: defaultFailureMode.combine(entry.FailMode),\n\t\tstackMode:   defaultStackMode.combine(entry.StackMode),\n\t}\n\tctxMgr.SetValues(gls.Values{nodeKey: ctx}, func() {\n\t\tctx.reporter.BeginStory(reporting.NewStoryReport(entry.Test))\n\t\tdefer ctx.reporter.EndStory()\n\n\t\tfor ctx.shouldVisit() {\n\t\t\tctx.conveyInner(entry.Situation, entry.Func)\n\t\t\texpectChildRun = true\n\t\t}\n\t})\n}\n\n//////////////////////////////////// Methods ////////////////////////////////////\n\nfunc (ctx *context) SkipConvey(items ...any) {\n\tctx.Convey(items, skipConvey)\n}\n\nfunc (ctx *context) FocusConvey(items ...any) {\n\tctx.Convey(items, focusConvey)\n}\n\nfunc (ctx *context) Convey(items ...any) {\n\tentry := discover(items)\n\n\t// we're a branch, or leaf (on the wind)\n\tif entry.Test != nil {\n\t\tconveyPanic(extraGoTest)\n\t}\n\tif ctx.focus && !entry.Focus {\n\t\treturn\n\t}\n\n\tvar inner_ctx *context\n\tif ctx.executedOnce {\n\t\tvar ok bool\n\t\tinner_ctx, ok = ctx.children[entry.Situation]\n\t\tif !ok {\n\t\t\tconveyPanic(differentConveySituations, entry.Situation)\n\t\t}\n\t} else {\n\t\tif _, ok := ctx.children[entry.Situation]; ok {\n\t\t\tconveyPanic(multipleIdenticalConvey, entry.Situation)\n\t\t}\n\t\tinner_ctx = &context{\n\t\t\treporter: ctx.reporter,\n\n\t\t\tchildren: make(map[string]*context),\n\n\t\t\texpectChildRun: ctx.expectChildRun,\n\n\t\t\tfocus:       entry.Focus,\n\t\t\tfailureMode: ctx.failureMode.combine(entry.FailMode),\n\t\t\tstackMode:   ctx.stackMode.combine(entry.StackMode),\n\t\t}\n\t\tctx.children[entry.Situation] = inner_ctx\n\t}\n\n\tif inner_ctx.shouldVisit() {\n\t\tctxMgr.SetValues(gls.Values{nodeKey: inner_ctx}, func() {\n\t\t\tinner_ctx.conveyInner(entry.Situation, entry.Func)\n\t\t})\n\t}\n}\n\nfunc (ctx *context) SkipSo(stuff ...any) {\n\tctx.assertionReport(reporting.NewSkipReport())\n}\n\nfunc (ctx *context) So(actual any, assert Assertion, expected ...any) {\n\tif result := assert(actual, expected...); result == assertionSuccess {\n\t\tctx.assertionReport(reporting.NewSuccessReport())\n\t} else {\n\t\tctx.assertionReport(reporting.NewFailureReport(result, ctx.shouldShowStack()))\n\t}\n}\n\nfunc (ctx *context) SoMsg(msg string, actual any, assert Assertion, expected ...any) {\n\tif result := assert(actual, expected...); result == assertionSuccess {\n\t\tctx.assertionReport(reporting.NewSuccessReport())\n\t\treturn\n\t} else {\n\t\tctx.reporter.Enter(reporting.NewScopeReport(msg))\n\t\tdefer ctx.reporter.Exit()\n\t\tctx.assertionReport(reporting.NewFailureReport(result, ctx.shouldShowStack()))\n\t}\n}\n\nfunc (ctx *context) Reset(action func()) {\n\t/* TODO: Failure mode configuration */\n\tctx.resets = append(ctx.resets, action)\n}\n\nfunc (ctx *context) Print(items ...any) (int, error) {\n\tfmt.Fprint(ctx.reporter, items...)\n\treturn fmt.Print(items...)\n}\n\nfunc (ctx *context) Println(items ...any) (int, error) {\n\tfmt.Fprintln(ctx.reporter, items...)\n\treturn fmt.Println(items...)\n}\n\nfunc (ctx *context) Printf(format string, items ...any) (int, error) {\n\tfmt.Fprintf(ctx.reporter, format, items...)\n\treturn fmt.Printf(format, items...)\n}\n\n//////////////////////////////////// Private ////////////////////////////////////\n\n// shouldVisit returns true iff we should traverse down into a Convey. Note\n// that just because we don't traverse a Convey this time, doesn't mean that\n// we may not traverse it on a subsequent pass.\nfunc (c *context) shouldVisit() bool {\n\treturn !c.complete && *c.expectChildRun\n}\n\nfunc (c *context) shouldShowStack() bool {\n\treturn c.stackMode == StackFail\n}\n\n// conveyInner is the function which actually executes the user's anonymous test\n// function body. At this point, Convey or RootConvey has decided that this\n// function should actually run.\nfunc (ctx *context) conveyInner(situation string, f func(C)) {\n\t// Record/Reset state for next time.\n\tdefer func() {\n\t\tctx.executedOnce = true\n\n\t\t// This is only needed at the leaves, but there's no harm in also setting it\n\t\t// when returning from branch Convey's\n\t\t*ctx.expectChildRun = false\n\t}()\n\n\t// Set up+tear down our scope for the reporter\n\tctx.reporter.Enter(reporting.NewScopeReport(situation))\n\tdefer ctx.reporter.Exit()\n\n\t// Recover from any panics in f, and assign the `complete` status for this\n\t// node of the tree.\n\tdefer func() {\n\t\tctx.complete = true\n\t\tif problem := recover(); problem != nil {\n\t\t\tif problem, ok := problem.(*conveyErr); ok {\n\t\t\t\tpanic(problem)\n\t\t\t}\n\t\t\tif problem != failureHalt {\n\t\t\t\tctx.reporter.Report(reporting.NewErrorReport(problem))\n\t\t\t}\n\t\t} else {\n\t\t\tfor _, child := range ctx.children {\n\t\t\t\tif !child.complete {\n\t\t\t\t\tctx.complete = false\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Resets are registered as the `f` function executes, so nil them here.\n\t// All resets are run in registration order (FIFO).\n\tctx.resets = []func(){}\n\tdefer func() {\n\t\tfor _, r := range ctx.resets {\n\t\t\t// panics handled by the previous defer\n\t\t\tr()\n\t\t}\n\t}()\n\n\tif f == nil {\n\t\t// if f is nil, this was either a Convey(..., nil), or a SkipConvey\n\t\tctx.reporter.Report(reporting.NewSkipReport())\n\t} else {\n\t\tf(ctx)\n\t}\n}\n\n// assertionReport is a helper for So and SkipSo which makes the report and\n// then possibly panics, depending on the current context's failureMode.\nfunc (ctx *context) assertionReport(r *reporting.AssertionResult) {\n\tctx.reporter.Report(r)\n\tif r.Failure != \"\" && ctx.failureMode == FailureHalts {\n\t\tpanic(failureHalt)\n\t}\n}\n"
  },
  {
    "path": "convey/convey.goconvey",
    "content": "#ignore\n-timeout=1s\n#-covermode=count\n#-coverpkg=github.com/smartystreets/goconvey/convey,github.com/smartystreets/goconvey/convey/gotest,github.com/smartystreets/goconvey/convey/reporting"
  },
  {
    "path": "convey/discovery.go",
    "content": "package convey\n\ntype actionSpecifier uint8\n\nconst (\n\tnoSpecifier actionSpecifier = iota\n\tskipConvey\n\tfocusConvey\n)\n\ntype suite struct {\n\tSituation string\n\tTest      t\n\tFocus     bool\n\tFunc      func(C) // nil means skipped\n\tFailMode  FailureMode\n\tStackMode StackMode\n}\n\nfunc newSuite(situation string, failureMode FailureMode, stackMode StackMode, f func(C), test t, specifier actionSpecifier) *suite {\n\tret := &suite{\n\t\tSituation: situation,\n\t\tTest:      test,\n\t\tFunc:      f,\n\t\tFailMode:  failureMode,\n\t\tStackMode: stackMode,\n\t}\n\tswitch specifier {\n\tcase skipConvey:\n\t\tret.Func = nil\n\tcase focusConvey:\n\t\tret.Focus = true\n\t}\n\treturn ret\n}\n\nfunc discover(items []any) *suite {\n\tname, items := parseName(items)\n\ttest, items := parseGoTest(items)\n\tfailure, items := parseFailureMode(items)\n\tstack, items := parseStackMode(items)\n\taction, items := parseAction(items)\n\tspecifier, items := parseSpecifier(items)\n\n\tif len(items) != 0 {\n\t\tconveyPanic(parseError)\n\t}\n\n\treturn newSuite(name, failure, stack, action, test, specifier)\n}\nfunc item(items []any) any {\n\tif len(items) == 0 {\n\t\tconveyPanic(parseError)\n\t}\n\treturn items[0]\n}\nfunc parseName(items []any) (string, []any) {\n\tif name, parsed := item(items).(string); parsed {\n\t\treturn name, items[1:]\n\t}\n\tconveyPanic(parseError)\n\tpanic(\"never get here\")\n}\nfunc parseGoTest(items []any) (t, []any) {\n\tif test, parsed := item(items).(t); parsed {\n\t\treturn test, items[1:]\n\t}\n\treturn nil, items\n}\nfunc parseFailureMode(items []any) (FailureMode, []any) {\n\tif mode, parsed := item(items).(FailureMode); parsed {\n\t\treturn mode, items[1:]\n\t}\n\treturn FailureInherits, items\n}\nfunc parseStackMode(items []any) (StackMode, []any) {\n\tif mode, parsed := item(items).(StackMode); parsed {\n\t\treturn mode, items[1:]\n\t}\n\treturn StackInherits, items\n}\nfunc parseAction(items []any) (func(C), []any) {\n\tswitch x := item(items).(type) {\n\tcase nil:\n\t\treturn nil, items[1:]\n\tcase func(C):\n\t\treturn x, items[1:]\n\tcase func():\n\t\treturn func(C) { x() }, items[1:]\n\t}\n\tconveyPanic(parseError)\n\tpanic(\"never get here\")\n}\nfunc parseSpecifier(items []any) (actionSpecifier, []any) {\n\tif len(items) == 0 {\n\t\treturn noSpecifier, items\n\t}\n\tif spec, ok := items[0].(actionSpecifier); ok {\n\t\treturn spec, items[1:]\n\t}\n\tconveyPanic(parseError)\n\tpanic(\"never get here\")\n}\n\n// This interface allows us to pass the *testing.T struct\n// throughout the internals of this package without ever\n// having to import the \"testing\" package.\ntype t interface {\n\tFail()\n}\n\nconst parseError = \"You must provide a name (string), then a *testing.T (if in outermost scope), an optional FailureMode and / or StackMode, and then an action (func()).\"\n"
  },
  {
    "path": "convey/doc.go",
    "content": "// Package convey contains all of the public-facing entry points to this project.\n// This means that it should never be required of the user to import any other\n// packages from this project as they serve internal purposes.\npackage convey\n\nimport \"github.com/smartystreets/goconvey/convey/reporting\"\n\n////////////////////////////////// suite //////////////////////////////////\n\n// C is the Convey context which you can optionally obtain in your action\n// by calling Convey like:\n//\n//   Convey(..., func(c C) {\n//     ...\n//   })\n//\n// See the documentation on Convey for more details.\n//\n// All methods in this context behave identically to the global functions of the\n// same name in this package.\ntype C interface {\n\tConvey(items ...any)\n\tSkipConvey(items ...any)\n\tFocusConvey(items ...any)\n\n\tSo(actual any, assert Assertion, expected ...any)\n\tSoMsg(msg string, actual any, assert Assertion, expected ...any)\n\tSkipSo(stuff ...any)\n\n\tReset(action func())\n\n\tPrintln(items ...any) (int, error)\n\tPrint(items ...any) (int, error)\n\tPrintf(format string, items ...any) (int, error)\n}\n\n// Convey is the method intended for use when declaring the scopes of\n// a specification. Each scope has a description and a func() which may contain\n// other calls to Convey(), Reset() or Should-style assertions. Convey calls can\n// be nested as far as you see fit.\n//\n// IMPORTANT NOTE: The top-level Convey() within a Test method\n// must conform to the following signature:\n//\n//     Convey(description string, t *testing.T, action func())\n//\n// All other calls should look like this (no need to pass in *testing.T):\n//\n//     Convey(description string, action func())\n//\n// Don't worry, goconvey will panic if you get it wrong so you can fix it.\n//\n// Additionally, you may explicitly obtain access to the Convey context by doing:\n//\n//     Convey(description string, action func(c C))\n//\n// You may need to do this if you want to pass the context through to a\n// goroutine, or to close over the context in a handler to a library which\n// calls your handler in a goroutine (httptest comes to mind).\n//\n// All Convey()-blocks also accept an optional parameter of FailureMode which sets\n// how goconvey should treat failures for So()-assertions in the block and\n// nested blocks. See the constants in this file for the available options.\n//\n// By default it will inherit from its parent block and the top-level blocks\n// default to the FailureHalts setting.\n//\n// This parameter is inserted before the block itself:\n//\n//     Convey(description string, t *testing.T, mode FailureMode, action func())\n//     Convey(description string, mode FailureMode, action func())\n//\n// See the examples package for, well, examples.\nfunc Convey(items ...any) {\n\tif ctx := getCurrentContext(); ctx == nil {\n\t\trootConvey(items...)\n\t} else {\n\t\tctx.Convey(items...)\n\t}\n}\n\n// SkipConvey is analogous to Convey except that the scope is not executed\n// (which means that child scopes defined within this scope are not run either).\n// The reporter will be notified that this step was skipped.\nfunc SkipConvey(items ...any) {\n\tConvey(append(items, skipConvey)...)\n}\n\n// FocusConvey is has the inverse effect of SkipConvey. If the top-level\n// Convey is changed to `FocusConvey`, only nested scopes that are defined\n// with FocusConvey will be run. The rest will be ignored completely. This\n// is handy when debugging a large suite that runs a misbehaving function\n// repeatedly as you can disable all but one of that function\n// without swaths of `SkipConvey` calls, just a targeted chain of calls\n// to FocusConvey.\nfunc FocusConvey(items ...any) {\n\tConvey(append(items, focusConvey)...)\n}\n\n// Reset registers a cleanup function to be run after each Convey()\n// in the same scope. See the examples package for a simple use case.\nfunc Reset(action func()) {\n\tmustGetCurrentContext().Reset(action)\n}\n\n/////////////////////////////////// Assertions ///////////////////////////////////\n\n// Assertion is an alias for a function with a signature that the convey.So()\n// method can handle. Any future or custom assertions should conform to this\n// method signature. The return value should be an empty string if the assertion\n// passes and a well-formed failure message if not.\ntype Assertion func(actual any, expected ...any) string\n\nconst assertionSuccess = \"\"\n\n// So is the means by which assertions are made against the system under test.\n// The majority of exported names in the assertions package begin with the word\n// 'Should' and describe how the first argument (actual) should compare with any\n// of the final (expected) arguments. How many final arguments are accepted\n// depends on the particular assertion that is passed in as the assert argument.\n// See the examples package for use cases and the assertions package for\n// documentation on specific assertion methods. A failing assertion will\n// cause t.Fail() to be invoked--you should never call this method (or other\n// failure-inducing methods) in your test code. Leave that to GoConvey.\nfunc So(actual any, assert Assertion, expected ...any) {\n\tmustGetCurrentContext().So(actual, assert, expected...)\n}\n\n// SoMsg is an extension of So that allows you to specify a message to report on error.\nfunc SoMsg(msg string, actual any, assert Assertion, expected ...any) {\n\tmustGetCurrentContext().SoMsg(msg, actual, assert, expected...)\n}\n\n// SkipSo is analogous to So except that the assertion that would have been passed\n// to So is not executed and the reporter is notified that the assertion was skipped.\nfunc SkipSo(stuff ...any) {\n\tmustGetCurrentContext().SkipSo()\n}\n\n// FailureMode is a type which determines how the So() blocks should fail\n// if their assertion fails. See constants further down for acceptable values\ntype FailureMode string\n\n// StackMode is a type which determines whether the So() blocks should report\n// stack traces their assertion fails. See constants further down for acceptable values\ntype StackMode string\n\nconst (\n\n\t// FailureContinues is a failure mode which prevents failing\n\t// So()-assertions from halting Convey-block execution, instead\n\t// allowing the test to continue past failing So()-assertions.\n\tFailureContinues FailureMode = \"continue\"\n\n\t// FailureHalts is the default setting for a top-level Convey()-block\n\t// and will cause all failing So()-assertions to halt further execution\n\t// in that test-arm and continue on to the next arm.\n\tFailureHalts FailureMode = \"halt\"\n\n\t// FailureInherits is the default setting for failure-mode, it will\n\t// default to the failure-mode of the parent block. You should never\n\t// need to specify this mode in your tests..\n\tFailureInherits FailureMode = \"inherits\"\n\n\t// StackError is a stack mode which tells Convey to print stack traces\n\t// only for errors and not for test failures\n\tStackError StackMode = \"error\"\n\n\t// StackFail is a stack mode which tells Convey to print stack traces\n\t// for both errors and test failures\n\tStackFail StackMode = \"fail\"\n\n\t// StackInherits is the default setting for stack-mode, it will\n\t// default to the stack-mode of the parent block. You should never\n\t// need to specify this mode in your tests..\n\tStackInherits StackMode = \"inherits\"\n)\n\nfunc (f FailureMode) combine(other FailureMode) FailureMode {\n\tif other == FailureInherits {\n\t\treturn f\n\t}\n\treturn other\n}\n\nvar defaultFailureMode FailureMode = FailureHalts\n\n// SetDefaultFailureMode allows you to specify the default failure mode\n// for all Convey blocks. It is meant to be used in an init function to\n// allow the default mode to be changed across all tests for an entire packgae\n// but it can be used anywhere.\nfunc SetDefaultFailureMode(mode FailureMode) {\n\tif mode == FailureContinues || mode == FailureHalts {\n\t\tdefaultFailureMode = mode\n\t} else {\n\t\tpanic(\"You may only use the constants named 'FailureContinues' and 'FailureHalts' as default failure modes.\")\n\t}\n}\n\nfunc (s StackMode) combine(other StackMode) StackMode {\n\tif other == StackInherits {\n\t\treturn s\n\t}\n\treturn other\n}\n\nvar defaultStackMode StackMode = StackError\n\n// SetDefaultStackMode allows you to specify the default stack mode\n// for all Convey blocks. It is meant to be used in an init function to\n// allow the default mode to be changed across all tests for an entire packgae\n// but it can be used anywhere.\nfunc SetDefaultStackMode(mode StackMode) {\n\tif mode == StackError || mode == StackFail {\n\t\tdefaultStackMode = mode\n\t} else {\n\t\tpanic(\"You may only use the constants named 'StackError' and 'StackFail' as default stack modes.\")\n\t}\n}\n\n//////////////////////////////////// Print functions ////////////////////////////////////\n\n// Print is analogous to fmt.Print (and it even calls fmt.Print). It ensures that\n// output is aligned with the corresponding scopes in the web UI.\nfunc Print(items ...any) (written int, err error) {\n\treturn mustGetCurrentContext().Print(items...)\n}\n\n// Print is analogous to fmt.Println (and it even calls fmt.Println). It ensures that\n// output is aligned with the corresponding scopes in the web UI.\nfunc Println(items ...any) (written int, err error) {\n\treturn mustGetCurrentContext().Println(items...)\n}\n\n// Print is analogous to fmt.Printf (and it even calls fmt.Printf). It ensures that\n// output is aligned with the corresponding scopes in the web UI.\nfunc Printf(format string, items ...any) (written int, err error) {\n\treturn mustGetCurrentContext().Printf(format, items...)\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n// SuppressConsoleStatistics prevents automatic printing of console statistics.\n// Calling PrintConsoleStatistics explicitly will force printing of statistics.\nfunc SuppressConsoleStatistics() {\n\treporting.SuppressConsoleStatistics()\n}\n\n// PrintConsoleStatistics may be called at any time to print assertion statistics.\n// Generally, the best place to do this would be in a TestMain function,\n// after all tests have been run. Something like this:\n//\n// func TestMain(m *testing.M) {\n//     convey.SuppressConsoleStatistics()\n//     result := m.Run()\n//     convey.PrintConsoleStatistics()\n//     os.Exit(result)\n// }\n//\nfunc PrintConsoleStatistics() {\n\treporting.PrintConsoleStatistics()\n}\n"
  },
  {
    "path": "convey/focused_execution_test.go",
    "content": "package convey\n\nimport \"testing\"\n\nfunc TestFocusOnlyAtTopLevel(t *testing.T) {\n\toutput := prepare()\n\n\tFocusConvey(\"hi\", t, func() {\n\t\toutput += \"done\"\n\t})\n\n\texpectEqual(t, \"done\", output)\n}\n\nfunc TestFocus(t *testing.T) {\n\toutput := prepare()\n\n\tFocusConvey(\"hi\", t, func() {\n\t\toutput += \"1\"\n\n\t\tConvey(\"bye\", func() {\n\t\t\toutput += \"2\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"1\", output)\n}\n\nfunc TestNestedFocus(t *testing.T) {\n\toutput := prepare()\n\n\tFocusConvey(\"hi\", t, func() {\n\t\toutput += \"1\"\n\n\t\tConvey(\"This shouldn't run\", func() {\n\t\t\toutput += \"boink!\"\n\t\t})\n\n\t\tFocusConvey(\"This should run\", func() {\n\t\t\toutput += \"2\"\n\n\t\t\tFocusConvey(\"The should run too\", func() {\n\t\t\t\toutput += \"3\"\n\n\t\t\t})\n\n\t\t\tConvey(\"The should NOT run\", func() {\n\t\t\t\toutput += \"blah blah blah!\"\n\t\t\t})\n\t\t})\n\t})\n\n\texpectEqual(t, \"123\", output)\n}\n\nfunc TestForgotTopLevelFocus(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"1\", t, func() {\n\t\toutput += \"1\"\n\n\t\tFocusConvey(\"This will be run because the top-level lacks Focus\", func() {\n\t\t\toutput += \"2\"\n\t\t})\n\n\t\tConvey(\"3\", func() {\n\t\t\toutput += \"3\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"1213\", output)\n}\n"
  },
  {
    "path": "convey/gotest/doc_test.go",
    "content": "package gotest\n"
  },
  {
    "path": "convey/gotest/utils.go",
    "content": "// Package gotest contains internal functionality. Although this package\n// contains one or more exported names it is not intended for public\n// consumption. See the examples package for how to use this project.\npackage gotest\n\nimport (\n\t\"runtime\"\n\t\"strings\"\n)\n\nfunc ResolveExternalCaller() (file string, line int, name string) {\n\tvar caller_id uintptr\n\tcallers := runtime.Callers(0, callStack)\n\n\tfor x := 0; x < callers; x++ {\n\t\tcaller_id, file, line, _ = runtime.Caller(x)\n\t\tif strings.HasSuffix(file, \"_test.go\") || strings.HasSuffix(file, \"_tests.go\") {\n\t\t\tname = runtime.FuncForPC(caller_id).Name()\n\t\t\treturn\n\t\t}\n\t}\n\tfile, line, name = \"<unknown file>\", -1, \"<unknown name>\"\n\treturn // panic?\n}\n\nconst maxStackDepth = 100 // This had better be enough...\n\nvar callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth)\n"
  },
  {
    "path": "convey/init.go",
    "content": "package convey\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\t\"github.com/jtolds/gls\"\n\t\"github.com/smarty/assertions\"\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n)\n\nfunc init() {\n\tassertions.GoConveyMode(true)\n\n\tdeclareFlags()\n\n\tctxMgr = gls.NewContextManager()\n}\n\nfunc declareFlags() {\n\tflag.BoolVar(&json, \"convey-json\", false, \"When true, emits results in JSON blocks. Default: 'false'\")\n\tflag.BoolVar(&silent, \"convey-silent\", false, \"When true, all output from GoConvey is suppressed.\")\n\tflag.BoolVar(&story, \"convey-story\", false, \"When true, emits story output, otherwise emits dot output. When not provided, this flag mirrors the value of the '-test.v' flag\")\n\n\tif noStoryFlagProvided() {\n\t\tstory = verboseEnabled\n\t}\n\n\t// FYI: flag.Parse() is called from the testing package.\n}\n\nfunc noStoryFlagProvided() bool {\n\treturn !story && !storyDisabled\n}\n\nfunc buildReporter() reporting.Reporter {\n\tselectReporter := os.Getenv(\"GOCONVEY_REPORTER\")\n\n\tswitch {\n\tcase testReporter != nil:\n\t\treturn testReporter\n\tcase json || selectReporter == \"json\":\n\t\treturn reporting.BuildJsonReporter()\n\tcase silent || selectReporter == \"silent\":\n\t\treturn reporting.BuildSilentReporter()\n\tcase selectReporter == \"dot\":\n\t\t// Story is turned on when verbose is set, so we need to check for dot reporter first.\n\t\treturn reporting.BuildDotReporter()\n\tcase story || selectReporter == \"story\":\n\t\treturn reporting.BuildStoryReporter()\n\tdefault:\n\t\treturn reporting.BuildDotReporter()\n\t}\n}\n\nvar (\n\tctxMgr *gls.ContextManager\n\n\t// only set by internal tests\n\ttestReporter reporting.Reporter\n)\n\nvar (\n\tjson   bool\n\tsilent bool\n\tstory  bool\n\n\tverboseEnabled = flagFound(\"-test.v=true\")\n\tstoryDisabled  = flagFound(\"-story=false\")\n)\n\n// flagFound parses the command line args manually for flags defined in other\n// packages. Like the '-v' flag from the \"testing\" package, for instance.\nfunc flagFound(flagValue string) bool {\n\tfor _, arg := range os.Args {\n\t\tif arg == flagValue {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "convey/isolated_execution_test.go",
    "content": "package convey\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestSingleScope(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"hi\", t, func() {\n\t\toutput += \"done\"\n\t})\n\n\texpectEqual(t, \"done\", output)\n}\n\nfunc TestSingleScopeWithMultipleConveys(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"1\", t, func() {\n\t\toutput += \"1\"\n\t})\n\n\tConvey(\"2\", t, func() {\n\t\toutput += \"2\"\n\t})\n\n\texpectEqual(t, \"12\", output)\n}\n\nfunc TestNestedScopes(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"a\", t, func() {\n\t\toutput += \"a \"\n\n\t\tConvey(\"bb\", func() {\n\t\t\toutput += \"bb \"\n\n\t\t\tConvey(\"ccc\", func() {\n\t\t\t\toutput += \"ccc | \"\n\t\t\t})\n\t\t})\n\t})\n\n\texpectEqual(t, \"a bb ccc | \", output)\n}\n\nfunc TestNestedScopesWithIsolatedExecution(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"a\", t, func() {\n\t\toutput += \"a \"\n\n\t\tConvey(\"aa\", func() {\n\t\t\toutput += \"aa \"\n\n\t\t\tConvey(\"aaa\", func() {\n\t\t\t\toutput += \"aaa | \"\n\t\t\t})\n\n\t\t\tConvey(\"aaa1\", func() {\n\t\t\t\toutput += \"aaa1 | \"\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"ab\", func() {\n\t\t\toutput += \"ab \"\n\n\t\t\tConvey(\"abb\", func() {\n\t\t\t\toutput += \"abb | \"\n\t\t\t})\n\t\t})\n\t})\n\n\texpectEqual(t, \"a aa aaa | a aa aaa1 | a ab abb | \", output)\n}\n\nfunc TestSingleScopeWithConveyAndNestedReset(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"1\", t, func() {\n\t\toutput += \"1\"\n\n\t\tReset(func() {\n\t\t\toutput += \"a\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"1a\", output)\n}\n\nfunc TestPanicingReset(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"1\", t, func() {\n\t\toutput += \"1\"\n\n\t\tReset(func() {\n\t\t\tpanic(\"nooo\")\n\t\t})\n\n\t\tConvey(\"runs since the reset hasn't yet\", func() {\n\t\t\toutput += \"a\"\n\t\t})\n\n\t\tConvey(\"but this doesnt\", func() {\n\t\t\toutput += \"nope\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"1a\", output)\n}\n\nfunc TestSingleScopeWithMultipleRegistrationsAndReset(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"reset after each nested convey\", t, func() {\n\t\tConvey(\"first output\", func() {\n\t\t\toutput += \"1\"\n\t\t})\n\n\t\tConvey(\"second output\", func() {\n\t\t\toutput += \"2\"\n\t\t})\n\n\t\tReset(func() {\n\t\t\toutput += \"a\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"1a2a\", output)\n}\n\nfunc TestSingleScopeWithMultipleRegistrationsAndMultipleResets(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"each reset is run at end of each nested convey\", t, func() {\n\t\tConvey(\"1\", func() {\n\t\t\toutput += \"1\"\n\t\t})\n\n\t\tConvey(\"2\", func() {\n\t\t\toutput += \"2\"\n\t\t})\n\n\t\tReset(func() {\n\t\t\toutput += \"a\"\n\t\t})\n\n\t\tReset(func() {\n\t\t\toutput += \"b\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"1ab2ab\", output)\n}\n\nfunc Test_Failure_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"This step fails\", t, func() {\n\t\tSo(1, ShouldEqual, 2)\n\n\t\tConvey(\"this should NOT be executed\", func() {\n\t\t\toutput += \"a\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"\", output)\n}\n\nfunc Test_Panic_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"This step panics\", t, func() {\n\t\tConvey(\"this happens, because the panic didn't happen yet\", func() {\n\t\t\toutput += \"1\"\n\t\t})\n\n\t\toutput += \"a\"\n\n\t\tConvey(\"this should NOT be executed\", func() {\n\t\t\toutput += \"2\"\n\t\t})\n\n\t\toutput += \"b\"\n\n\t\tpanic(\"Hi\")\n\n\t\toutput += \"nope\"\n\t})\n\n\texpectEqual(t, \"1ab\", output)\n}\n\nfunc Test_Panic_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"This is the parent\", t, func() {\n\t\tConvey(\"This step panics\", func() {\n\t\t\tpanic(\"Hi\")\n\t\t\toutput += \"1\"\n\t\t})\n\n\t\tConvey(\"This sibling should execute\", func() {\n\t\t\toutput += \"2\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"2\", output)\n}\n\nfunc Test_Failure_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"This is the parent\", t, func() {\n\t\tConvey(\"This step fails\", func() {\n\t\t\tSo(1, ShouldEqual, 2)\n\t\t\toutput += \"1\"\n\t\t})\n\n\t\tConvey(\"This sibling should execute\", func() {\n\t\t\toutput += \"2\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"2\", output)\n}\n\nfunc TestResetsAreAlwaysExecutedAfterScope_Panics(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"This is the parent\", t, func() {\n\t\tConvey(\"This step panics\", func() {\n\t\t\tpanic(\"Hi\")\n\t\t\toutput += \"1\"\n\t\t})\n\n\t\tConvey(\"This sibling step does not panic\", func() {\n\t\t\toutput += \"a\"\n\n\t\t\tReset(func() {\n\t\t\t\toutput += \"b\"\n\t\t\t})\n\t\t})\n\n\t\tReset(func() {\n\t\t\toutput += \"2\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"2ab2\", output)\n}\n\nfunc TestResetsAreAlwaysExecutedAfterScope_Failures(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"This is the parent\", t, func() {\n\t\tConvey(\"This step fails\", func() {\n\t\t\tSo(1, ShouldEqual, 2)\n\t\t\toutput += \"1\"\n\t\t})\n\n\t\tConvey(\"This sibling step does not fail\", func() {\n\t\t\toutput += \"a\"\n\n\t\t\tReset(func() {\n\t\t\t\toutput += \"b\"\n\t\t\t})\n\t\t})\n\n\t\tReset(func() {\n\t\t\toutput += \"2\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"2ab2\", output)\n}\n\nfunc TestSkipTopLevel(t *testing.T) {\n\toutput := prepare()\n\n\tSkipConvey(\"hi\", t, func() {\n\t\toutput += \"This shouldn't be executed!\"\n\t})\n\n\texpectEqual(t, \"\", output)\n}\n\nfunc TestSkipNestedLevel(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"hi\", t, func() {\n\t\toutput += \"yes\"\n\n\t\tSkipConvey(\"bye\", func() {\n\t\t\toutput += \"no\"\n\t\t})\n\t})\n\n\texpectEqual(t, \"yes\", output)\n}\n\nfunc TestSkipNestedLevelSkipsAllChildLevels(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"hi\", t, func() {\n\t\toutput += \"yes\"\n\n\t\tSkipConvey(\"bye\", func() {\n\t\t\toutput += \"no\"\n\n\t\t\tConvey(\"byebye\", func() {\n\t\t\t\toutput += \"no-no\"\n\t\t\t})\n\t\t})\n\t})\n\n\texpectEqual(t, \"yes\", output)\n}\n\nfunc TestIterativeConveys(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"Test\", t, func() {\n\t\tfor x := 0; x < 10; x++ {\n\t\t\ty := strconv.Itoa(x)\n\n\t\t\tConvey(y, func() {\n\t\t\t\toutput += y\n\t\t\t})\n\t\t}\n\t})\n\n\texpectEqual(t, \"0123456789\", output)\n}\n\nfunc TestClosureVariables(t *testing.T) {\n\toutput := prepare()\n\n\ti := 0\n\n\tConvey(\"A\", t, func() {\n\t\ti = i + 1\n\t\tj := i\n\n\t\toutput += \"A\" + strconv.Itoa(i) + \" \"\n\n\t\tConvey(\"B\", func() {\n\t\t\tk := j\n\t\t\tj = j + 1\n\n\t\t\toutput += \"B\" + strconv.Itoa(k) + \" \"\n\n\t\t\tConvey(\"C\", func() {\n\t\t\t\toutput += \"C\" + strconv.Itoa(k) + strconv.Itoa(j) + \" \"\n\t\t\t})\n\n\t\t\tConvey(\"D\", func() {\n\t\t\t\toutput += \"D\" + strconv.Itoa(k) + strconv.Itoa(j) + \" \"\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"C\", func() {\n\t\t\toutput += \"C\" + strconv.Itoa(j) + \" \"\n\t\t})\n\t})\n\n\toutput += \"D\" + strconv.Itoa(i) + \" \"\n\n\texpectEqual(t, \"A1 B1 C12 A2 B2 D23 A3 C3 D3 \", output)\n}\n\nfunc TestClosureVariablesWithReset(t *testing.T) {\n\toutput := prepare()\n\n\ti := 0\n\n\tConvey(\"A\", t, func() {\n\t\ti = i + 1\n\t\tj := i\n\n\t\toutput += \"A\" + strconv.Itoa(i) + \" \"\n\n\t\tReset(func() {\n\t\t\toutput += \"R\" + strconv.Itoa(i) + strconv.Itoa(j) + \" \"\n\t\t})\n\n\t\tConvey(\"B\", func() {\n\t\t\toutput += \"B\" + strconv.Itoa(j) + \" \"\n\t\t})\n\n\t\tConvey(\"C\", func() {\n\t\t\toutput += \"C\" + strconv.Itoa(j) + \" \"\n\t\t})\n\t})\n\n\toutput += \"D\" + strconv.Itoa(i) + \" \"\n\n\texpectEqual(t, \"A1 B1 R11 A2 C2 R22 D2 \", output)\n}\n\nfunc TestWrappedSimple(t *testing.T) {\n\tprepare()\n\toutput := resetTestString{\"\"}\n\n\tConvey(\"A\", t, func() {\n\t\tfunc() {\n\t\t\toutput.output += \"A \"\n\n\t\t\tConvey(\"B\", func() {\n\t\t\t\toutput.output += \"B \"\n\n\t\t\t\tConvey(\"C\", func() {\n\t\t\t\t\toutput.output += \"C \"\n\t\t\t\t})\n\n\t\t\t})\n\n\t\t\tConvey(\"D\", func() {\n\t\t\t\toutput.output += \"D \"\n\t\t\t})\n\t\t}()\n\t})\n\n\texpectEqual(t, \"A B C A D \", output.output)\n}\n\ntype resetTestString struct {\n\toutput string\n}\n\nfunc addReset(o *resetTestString, f func()) func() {\n\treturn func() {\n\t\tReset(func() {\n\t\t\to.output += \"R \"\n\t\t})\n\n\t\tf()\n\t}\n}\n\nfunc TestWrappedReset(t *testing.T) {\n\tprepare()\n\toutput := resetTestString{\"\"}\n\n\tConvey(\"A\", t, addReset(&output, func() {\n\t\toutput.output += \"A \"\n\n\t\tConvey(\"B\", func() {\n\t\t\toutput.output += \"B \"\n\t\t})\n\n\t\tConvey(\"C\", func() {\n\t\t\toutput.output += \"C \"\n\t\t})\n\t}))\n\n\texpectEqual(t, \"A B R A C R \", output.output)\n}\n\nfunc TestWrappedReset2(t *testing.T) {\n\tprepare()\n\toutput := resetTestString{\"\"}\n\n\tConvey(\"A\", t, func() {\n\t\tReset(func() {\n\t\t\toutput.output += \"R \"\n\t\t})\n\n\t\tfunc() {\n\t\t\toutput.output += \"A \"\n\n\t\t\tConvey(\"B\", func() {\n\t\t\t\toutput.output += \"B \"\n\n\t\t\t\tConvey(\"C\", func() {\n\t\t\t\t\toutput.output += \"C \"\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"D\", func() {\n\t\t\t\toutput.output += \"D \"\n\t\t\t})\n\t\t}()\n\t})\n\n\texpectEqual(t, \"A B C R A D R \", output.output)\n}\n\nfunc TestInfiniteLoopWithTrailingFail(t *testing.T) {\n\tdone := make(chan int)\n\n\tgo func() {\n\t\tConvey(\"This fails\", t, func() {\n\t\t\tConvey(\"and this is run\", func() {\n\t\t\t\tSo(true, ShouldEqual, true)\n\t\t\t})\n\n\t\t\t/* And this prevents the whole block to be marked as run */\n\t\t\tSo(false, ShouldEqual, true)\n\t\t})\n\n\t\tdone <- 1\n\t}()\n\n\tselect {\n\tcase <-done:\n\t\treturn\n\tcase <-time.After(1 * time.Millisecond):\n\t\tt.Fail()\n\t}\n}\n\nfunc TestOutermostResetInvokedForGrandchildren(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, func() {\n\t\toutput += \"A \"\n\n\t\tReset(func() {\n\t\t\toutput += \"rA \"\n\t\t})\n\n\t\tConvey(\"B\", func() {\n\t\t\toutput += \"B \"\n\n\t\t\tReset(func() {\n\t\t\t\toutput += \"rB \"\n\t\t\t})\n\n\t\t\tConvey(\"C\", func() {\n\t\t\t\toutput += \"C \"\n\n\t\t\t\tReset(func() {\n\t\t\t\t\toutput += \"rC \"\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"D\", func() {\n\t\t\t\toutput += \"D \"\n\n\t\t\t\tReset(func() {\n\t\t\t\t\toutput += \"rD \"\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t})\n\n\texpectEqual(t, \"A B C rC rB rA A B D rD rB rA \", output)\n}\n\nfunc TestFailureOption(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureHalts, func() {\n\t\toutput += \"A \"\n\t\tSo(true, ShouldEqual, true)\n\t\toutput += \"B \"\n\t\tSo(false, ShouldEqual, true)\n\t\toutput += \"C \"\n\t})\n\n\texpectEqual(t, \"A B \", output)\n}\n\nfunc TestFailureOption2(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, func() {\n\t\toutput += \"A \"\n\t\tSo(true, ShouldEqual, true)\n\t\toutput += \"B \"\n\t\tSo(false, ShouldEqual, true)\n\t\toutput += \"C \"\n\t})\n\n\texpectEqual(t, \"A B \", output)\n}\n\nfunc TestFailureOption3(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureContinues, func() {\n\t\toutput += \"A \"\n\t\tSo(true, ShouldEqual, true)\n\t\toutput += \"B \"\n\t\tSo(false, ShouldEqual, true)\n\t\toutput += \"C \"\n\t})\n\n\texpectEqual(t, \"A B C \", output)\n}\n\nfunc TestFailureOptionInherit(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureContinues, func() {\n\t\toutput += \"A1 \"\n\t\tSo(false, ShouldEqual, true)\n\t\toutput += \"A2 \"\n\n\t\tConvey(\"B\", func() {\n\t\t\toutput += \"B1 \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"B2 \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"B3 \"\n\t\t})\n\t})\n\n\texpectEqual(t, \"A1 A2 B1 B2 B3 \", output)\n}\n\nfunc TestFailureOptionInherit2(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureHalts, func() {\n\t\toutput += \"A1 \"\n\t\tSo(false, ShouldEqual, true)\n\t\toutput += \"A2 \"\n\n\t\tConvey(\"B\", func() {\n\t\t\toutput += \"A1 \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"A2 \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"A3 \"\n\t\t})\n\t})\n\n\texpectEqual(t, \"A1 \", output)\n}\n\nfunc TestFailureOptionInherit3(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureHalts, func() {\n\t\toutput += \"A1 \"\n\t\tSo(true, ShouldEqual, true)\n\t\toutput += \"A2 \"\n\n\t\tConvey(\"B\", func() {\n\t\t\toutput += \"B1 \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"B2 \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"B3 \"\n\t\t})\n\t})\n\n\texpectEqual(t, \"A1 A2 B1 B2 \", output)\n}\n\nfunc TestFailureOptionNestedOverride(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureContinues, func() {\n\t\toutput += \"A \"\n\t\tSo(false, ShouldEqual, true)\n\t\toutput += \"B \"\n\n\t\tConvey(\"C\", FailureHalts, func() {\n\t\t\toutput += \"C \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"D \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"E \"\n\t\t})\n\t})\n\n\texpectEqual(t, \"A B C D \", output)\n}\n\nfunc TestFailureOptionNestedOverride2(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureHalts, func() {\n\t\toutput += \"A \"\n\t\tSo(true, ShouldEqual, true)\n\t\toutput += \"B \"\n\n\t\tConvey(\"C\", FailureContinues, func() {\n\t\t\toutput += \"C \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"D \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"E \"\n\t\t})\n\t})\n\n\texpectEqual(t, \"A B C D E \", output)\n}\n\nfunc TestMultipleInvocationInheritance(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureHalts, func() {\n\t\toutput += \"A1 \"\n\t\tSo(true, ShouldEqual, true)\n\t\toutput += \"A2 \"\n\n\t\tConvey(\"B\", FailureContinues, func() {\n\t\t\toutput += \"B1 \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"B2 \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"B3 \"\n\t\t})\n\n\t\tConvey(\"C\", func() {\n\t\t\toutput += \"C1 \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"C2 \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"C3 \"\n\t\t})\n\t})\n\n\texpectEqual(t, \"A1 A2 B1 B2 B3 A1 A2 C1 C2 \", output)\n}\n\nfunc TestMultipleInvocationInheritance2(t *testing.T) {\n\toutput := prepare()\n\n\tConvey(\"A\", t, FailureContinues, func() {\n\t\toutput += \"A1 \"\n\t\tSo(true, ShouldEqual, true)\n\t\toutput += \"A2 \"\n\t\tSo(false, ShouldEqual, true)\n\t\toutput += \"A3 \"\n\n\t\tConvey(\"B\", FailureHalts, func() {\n\t\t\toutput += \"B1 \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"B2 \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"B3 \"\n\t\t})\n\n\t\tConvey(\"C\", func() {\n\t\t\toutput += \"C1 \"\n\t\t\tSo(true, ShouldEqual, true)\n\t\t\toutput += \"C2 \"\n\t\t\tSo(false, ShouldEqual, true)\n\t\t\toutput += \"C3 \"\n\t\t})\n\t})\n\n\texpectEqual(t, \"A1 A2 A3 B1 B2 A1 A2 A3 C1 C2 C3 \", output)\n}\n\nfunc TestSetDefaultFailureMode(t *testing.T) {\n\toutput := prepare()\n\n\tSetDefaultFailureMode(FailureContinues) // the default is normally FailureHalts\n\tdefer SetDefaultFailureMode(FailureHalts)\n\n\tConvey(\"A\", t, func() {\n\t\toutput += \"A1 \"\n\t\tSo(true, ShouldBeFalse)\n\t\toutput += \"A2 \"\n\t})\n\n\texpectEqual(t, \"A1 A2 \", output)\n}\n\nfunc prepare() string {\n\ttestReporter = newNilReporter()\n\treturn \"\"\n}\n"
  },
  {
    "path": "convey/nilReporter.go",
    "content": "package convey\n\nimport (\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n)\n\ntype nilReporter struct{}\n\nfunc (self *nilReporter) BeginStory(story *reporting.StoryReport)  {}\nfunc (self *nilReporter) Enter(scope *reporting.ScopeReport)       {}\nfunc (self *nilReporter) Report(report *reporting.AssertionResult) {}\nfunc (self *nilReporter) Exit()                                    {}\nfunc (self *nilReporter) EndStory()                                {}\nfunc (self *nilReporter) Write(p []byte) (int, error)              { return len(p), nil }\nfunc newNilReporter() *nilReporter                                 { return &nilReporter{} }\n"
  },
  {
    "path": "convey/reporting/console.go",
    "content": "package reporting\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype console struct{}\n\nfunc (self *console) Write(p []byte) (n int, err error) {\n\treturn fmt.Print(string(p))\n}\n\nfunc NewConsole() io.Writer {\n\treturn new(console)\n}\n"
  },
  {
    "path": "convey/reporting/doc.go",
    "content": "// Package reporting contains internal functionality related\n// to console reporting and output. Although this package has\n// exported names is not intended for public consumption. See the\n// examples package for how to use this project.\npackage reporting\n"
  },
  {
    "path": "convey/reporting/dot.go",
    "content": "package reporting\n\nimport \"fmt\"\n\ntype dot struct{ out *Printer }\n\nfunc (self *dot) BeginStory(story *StoryReport) {}\n\nfunc (self *dot) Enter(scope *ScopeReport) {}\n\nfunc (self *dot) Report(report *AssertionResult) {\n\tif report.Error != nil {\n\t\tfmt.Print(redColor)\n\t\tself.out.Insert(dotError)\n\t} else if report.Failure != \"\" {\n\t\tfmt.Print(yellowColor)\n\t\tself.out.Insert(dotFailure)\n\t} else if report.Skipped {\n\t\tfmt.Print(yellowColor)\n\t\tself.out.Insert(dotSkip)\n\t} else {\n\t\tfmt.Print(greenColor)\n\t\tself.out.Insert(dotSuccess)\n\t}\n\tfmt.Print(resetColor)\n}\n\nfunc (self *dot) Exit() {}\n\nfunc (self *dot) EndStory() {}\n\nfunc (self *dot) Write(content []byte) (written int, err error) {\n\treturn len(content), nil // no-op\n}\n\nfunc NewDotReporter(out *Printer) *dot {\n\tself := new(dot)\n\tself.out = out\n\treturn self\n}\n"
  },
  {
    "path": "convey/reporting/dot_test.go",
    "content": "package reporting\n\nimport (\n\t\"errors\"\n\t\"testing\"\n)\n\nfunc TestDotReporterAssertionPrinting(t *testing.T) {\n\tmonochrome()\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\treporter := NewDotReporter(printer)\n\n\treporter.Report(NewSuccessReport())\n\treporter.Report(NewFailureReport(\"failed\", false))\n\treporter.Report(NewErrorReport(errors.New(\"error\")))\n\treporter.Report(NewSkipReport())\n\n\texpected := dotSuccess + dotFailure + dotError + dotSkip\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"\\nExpected: '%s'\\nActual:  '%s'\", expected, file.buffer)\n\t}\n}\n\nfunc TestDotReporterOnlyReportsAssertions(t *testing.T) {\n\tmonochrome()\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\treporter := NewDotReporter(printer)\n\n\treporter.BeginStory(nil)\n\treporter.Enter(nil)\n\treporter.Exit()\n\treporter.EndStory()\n\n\tif file.buffer != \"\" {\n\t\tt.Errorf(\"\\nExpected: '(blank)'\\nActual:  '%s'\", file.buffer)\n\t}\n}\n"
  },
  {
    "path": "convey/reporting/gotest.go",
    "content": "package reporting\n\ntype gotestReporter struct{ test T }\n\nfunc (self *gotestReporter) BeginStory(story *StoryReport) {\n\tself.test = story.Test\n}\n\nfunc (self *gotestReporter) Enter(scope *ScopeReport) {}\n\nfunc (self *gotestReporter) Report(r *AssertionResult) {\n\tif !passed(r) {\n\t\tself.test.Fail()\n\t}\n}\n\nfunc (self *gotestReporter) Exit() {}\n\nfunc (self *gotestReporter) EndStory() {\n\tself.test = nil\n}\n\nfunc (self *gotestReporter) Write(content []byte) (written int, err error) {\n\treturn len(content), nil // no-op\n}\n\nfunc NewGoTestReporter() *gotestReporter {\n\treturn new(gotestReporter)\n}\n\nfunc passed(r *AssertionResult) bool {\n\treturn r.Error == nil && r.Failure == \"\"\n}\n"
  },
  {
    "path": "convey/reporting/gotest_test.go",
    "content": "package reporting\n\nimport \"testing\"\n\nfunc TestReporterReceivesSuccessfulReport(t *testing.T) {\n\treporter := NewGoTestReporter()\n\ttest := new(fakeTest)\n\treporter.BeginStory(NewStoryReport(test))\n\treporter.Report(NewSuccessReport())\n\n\tif test.failed {\n\t\tt.Errorf(\"Should have have marked test as failed--the report reflected success.\")\n\t}\n}\n\nfunc TestReporterReceivesFailureReport(t *testing.T) {\n\treporter := NewGoTestReporter()\n\ttest := new(fakeTest)\n\treporter.BeginStory(NewStoryReport(test))\n\treporter.Report(NewFailureReport(\"This is a failure.\", false))\n\n\tif !test.failed {\n\t\tt.Errorf(\"Test should have been marked as failed (but it wasn't).\")\n\t}\n}\n\nfunc TestReporterReceivesErrorReport(t *testing.T) {\n\treporter := NewGoTestReporter()\n\ttest := new(fakeTest)\n\treporter.BeginStory(NewStoryReport(test))\n\treporter.Report(NewErrorReport(\"This is an error.\"))\n\n\tif !test.failed {\n\t\tt.Errorf(\"Test should have been marked as failed (but it wasn't).\")\n\t}\n}\n\nfunc TestReporterIsResetAtTheEndOfTheStory(t *testing.T) {\n\tdefer catch(t)\n\treporter := NewGoTestReporter()\n\ttest := new(fakeTest)\n\treporter.BeginStory(NewStoryReport(test))\n\treporter.EndStory()\n\n\treporter.Report(NewSuccessReport())\n}\n\nfunc TestReporterNoopMethods(t *testing.T) {\n\treporter := NewGoTestReporter()\n\treporter.Enter(NewScopeReport(\"title\"))\n\treporter.Exit()\n}\n\nfunc catch(t *testing.T) {\n\tif r := recover(); r != nil {\n\t\tt.Log(\"Getting to this point means we've passed (because we caught a panic appropriately).\")\n\t}\n}\n\ntype fakeTest struct {\n\tfailed bool\n}\n\nfunc (self *fakeTest) Fail() {\n\tself.failed = true\n}\n"
  },
  {
    "path": "convey/reporting/init.go",
    "content": "package reporting\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n)\n\nfunc init() {\n\tif !isColorableTerminal() {\n\t\tmonochrome()\n\t}\n\n\tif runtime.GOOS == \"windows\" {\n\t\tsuccess, failure, error_ = dotSuccess, dotFailure, dotError\n\t}\n}\n\nfunc BuildJsonReporter() Reporter {\n\tout := NewPrinter(NewConsole())\n\treturn NewReporters(\n\t\tNewGoTestReporter(),\n\t\tNewJsonReporter(out))\n}\nfunc BuildDotReporter() Reporter {\n\tout := NewPrinter(NewConsole())\n\treturn NewReporters(\n\t\tNewGoTestReporter(),\n\t\tNewDotReporter(out),\n\t\tNewProblemReporter(out),\n\t\tconsoleStatistics)\n}\nfunc BuildStoryReporter() Reporter {\n\tout := NewPrinter(NewConsole())\n\treturn NewReporters(\n\t\tNewGoTestReporter(),\n\t\tNewStoryReporter(out),\n\t\tNewProblemReporter(out),\n\t\tconsoleStatistics)\n}\nfunc BuildSilentReporter() Reporter {\n\tout := NewPrinter(NewConsole())\n\treturn NewReporters(\n\t\tNewGoTestReporter(),\n\t\tNewSilentProblemReporter(out))\n}\n\nvar (\n\tnewline         = \"\\n\"\n\tsuccess         = \"✔\"\n\tfailure         = \"✘\"\n\terror_          = \"🔥\"\n\tskip            = \"⚠\"\n\tdotSuccess      = \".\"\n\tdotFailure      = \"x\"\n\tdotError        = \"E\"\n\tdotSkip         = \"S\"\n\terrorTemplate   = \"* %s \\nLine %d: - %v \\n%s\\n\"\n\tfailureTemplate = \"* %s \\nLine %d:\\n%s\\n\"\n\tstackTemplate   = \"%s\\n\"\n)\n\nvar (\n\tgreenColor  = \"\\033[32m\"\n\tyellowColor = \"\\033[33m\"\n\tredColor    = \"\\033[31m\"\n\tresetColor  = \"\\033[0m\"\n)\n\nvar consoleStatistics = NewStatisticsReporter(NewPrinter(NewConsole()))\n\nfunc SuppressConsoleStatistics() { consoleStatistics.Suppress() }\nfunc PrintConsoleStatistics()    { consoleStatistics.PrintSummary() }\n\n// QuietMode disables all console output symbols. This is only meant to be used\n// for tests that are internal to goconvey where the output is distracting or\n// otherwise not needed in the test output.\nfunc QuietMode() {\n\tsuccess, failure, error_, skip, dotSuccess, dotFailure, dotError, dotSkip = \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\"\n}\n\nfunc monochrome() {\n\tgreenColor, yellowColor, redColor, resetColor = \"\", \"\", \"\", \"\"\n}\n\nfunc isColorableTerminal() bool {\n\treturn strings.Contains(os.Getenv(\"TERM\"), \"color\")\n}\n\n// This interface allows us to pass the *testing.T struct\n// throughout the internals of this tool without ever\n// having to import the \"testing\" package.\ntype T interface {\n\tFail()\n}\n"
  },
  {
    "path": "convey/reporting/json.go",
    "content": "// TODO: under unit test\n\npackage reporting\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype JsonReporter struct {\n\tout        *Printer\n\tcurrentKey []string\n\tcurrent    *ScopeResult\n\tindex      map[string]*ScopeResult\n\tscopes     []*ScopeResult\n}\n\nfunc (self *JsonReporter) depth() int { return len(self.currentKey) }\n\nfunc (self *JsonReporter) BeginStory(story *StoryReport) {}\n\nfunc (self *JsonReporter) Enter(scope *ScopeReport) {\n\tself.currentKey = append(self.currentKey, scope.Title)\n\tID := strings.Join(self.currentKey, \"|\")\n\tif _, found := self.index[ID]; !found {\n\t\tnext := newScopeResult(scope.Title, self.depth(), scope.File, scope.Line)\n\t\tself.scopes = append(self.scopes, next)\n\t\tself.index[ID] = next\n\t}\n\tself.current = self.index[ID]\n}\n\nfunc (self *JsonReporter) Report(report *AssertionResult) {\n\tself.current.Assertions = append(self.current.Assertions, report)\n}\n\nfunc (self *JsonReporter) Exit() {\n\tself.currentKey = self.currentKey[:len(self.currentKey)-1]\n}\n\nfunc (self *JsonReporter) EndStory() {\n\tself.report()\n\tself.reset()\n}\nfunc (self *JsonReporter) report() {\n\tscopes := []string{}\n\tfor _, scope := range self.scopes {\n\t\tserialized, err := json.Marshal(scope)\n\t\tif err != nil {\n\t\t\tself.out.Println(jsonMarshalFailure)\n\t\t\tpanic(err)\n\t\t}\n\t\tvar buffer bytes.Buffer\n\t\tjson.Indent(&buffer, serialized, \"\", \"  \")\n\t\tscopes = append(scopes, buffer.String())\n\t}\n\tself.out.Print(fmt.Sprintf(\"%s\\n%s,\\n%s\\n\", OpenJson, strings.Join(scopes, \",\"), CloseJson))\n}\nfunc (self *JsonReporter) reset() {\n\tself.scopes = []*ScopeResult{}\n\tself.index = map[string]*ScopeResult{}\n\tself.currentKey = nil\n}\n\nfunc (self *JsonReporter) Write(content []byte) (written int, err error) {\n\tself.current.Output += string(content)\n\treturn len(content), nil\n}\n\nfunc NewJsonReporter(out *Printer) *JsonReporter {\n\tself := new(JsonReporter)\n\tself.out = out\n\tself.reset()\n\treturn self\n}\n\nconst OpenJson = \">->->OPEN-JSON->->->\"   // \"⌦\"\nconst CloseJson = \"<-<-<-CLOSE-JSON<-<-<\" // \"⌫\"\nconst jsonMarshalFailure = `\n\nGOCONVEY_JSON_MARSHALL_FAILURE: There was an error when attempting to convert test results to JSON.\nPlease file a bug report and reference the code that caused this failure if possible.\n\nHere's the panic:\n\n`\n"
  },
  {
    "path": "convey/reporting/printer.go",
    "content": "package reporting\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\ntype Printer struct {\n\tout    io.Writer\n\tprefix string\n}\n\nfunc (self *Printer) Println(message string, values ...any) {\n\tformatted := self.format(message, values...) + newline\n\tself.out.Write([]byte(formatted))\n}\n\nfunc (self *Printer) Print(message string, values ...any) {\n\tformatted := self.format(message, values...)\n\tself.out.Write([]byte(formatted))\n}\n\nfunc (self *Printer) Insert(text string) {\n\tself.out.Write([]byte(text))\n}\n\nfunc (self *Printer) format(message string, values ...any) string {\n\tvar formatted string\n\tif len(values) == 0 {\n\t\tformatted = self.prefix + message\n\t} else {\n\t\tformatted = self.prefix + fmt_Sprintf(message, values...)\n\t}\n\tindented := strings.Replace(formatted, newline, newline+self.prefix, -1)\n\treturn strings.TrimRight(indented, space)\n}\n\n// Extracting fmt.Sprintf to a separate variable circumvents go vet, which, as of go 1.10 is run with go test.\nvar fmt_Sprintf = fmt.Sprintf\n\nfunc (self *Printer) Indent() {\n\tself.prefix += pad\n}\n\nfunc (self *Printer) Dedent() {\n\tif len(self.prefix) >= padLength {\n\t\tself.prefix = self.prefix[:len(self.prefix)-padLength]\n\t}\n}\n\nfunc NewPrinter(out io.Writer) *Printer {\n\tself := new(Printer)\n\tself.out = out\n\treturn self\n}\n\nconst space = \" \"\nconst pad = space + space\nconst padLength = len(pad)\n"
  },
  {
    "path": "convey/reporting/printer_test.go",
    "content": "package reporting\n\nimport \"testing\"\n\nfunc TestPrint(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst expected = \"Hello, World!\"\n\n\tprinter.Print(expected)\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintFormat(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\ttemplate := \"Hi, %s\"\n\tname := \"Ralph\"\n\texpected := \"Hi, Ralph\"\n\n\tprinter.Print(template, name)\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintPreservesEncodedStrings(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst expected = \"= -> %%3D\"\n\tprinter.Print(expected)\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintln(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst expected = \"Hello, World!\"\n\n\tprinter.Println(expected)\n\n\tif file.buffer != expected+\"\\n\" {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintlnFormat(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\ttemplate := \"Hi, %s\"\n\tname := \"Ralph\"\n\texpected := \"Hi, Ralph\\n\"\n\n\tprinter.Println(template, name)\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintlnPreservesEncodedStrings(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst expected = \"= -> %%3D\"\n\tprinter.Println(expected)\n\n\tif file.buffer != expected+\"\\n\" {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintIndented(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst message = \"Hello, World!\\nGoodbye, World!\"\n\tconst expected = \"  Hello, World!\\n  Goodbye, World!\"\n\n\tprinter.Indent()\n\tprinter.Print(message)\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintDedented(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst expected = \"Hello, World!\\nGoodbye, World!\"\n\n\tprinter.Indent()\n\tprinter.Dedent()\n\tprinter.Print(expected)\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintlnIndented(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst message = \"Hello, World!\\nGoodbye, World!\"\n\tconst expected = \"  Hello, World!\\n  Goodbye, World!\\n\"\n\n\tprinter.Indent()\n\tprinter.Println(message)\n\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestPrintlnDedented(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\tconst expected = \"Hello, World!\\nGoodbye, World!\"\n\n\tprinter.Indent()\n\tprinter.Dedent()\n\tprinter.Println(expected)\n\n\tif file.buffer != expected+\"\\n\" {\n\t\tt.Errorf(\"Expected '%s' to equal '%s'.\", expected, file.buffer)\n\t}\n}\n\nfunc TestDedentTooFarShouldNotPanic(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tt.Error(\"Should not have panicked!\")\n\t\t}\n\t}()\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\n\tprinter.Dedent()\n\n\tt.Log(\"Getting to this point without panicking means we passed.\")\n}\n\nfunc TestInsert(t *testing.T) {\n\tfile := newMemoryFile()\n\tprinter := NewPrinter(file)\n\n\tprinter.Indent()\n\tprinter.Print(\"Hi\")\n\tprinter.Insert(\" there\")\n\tprinter.Dedent()\n\n\texpected := \"  Hi there\"\n\tif file.buffer != expected {\n\t\tt.Errorf(\"Should have written '%s' but instead wrote '%s'.\", expected, file.buffer)\n\t}\n}\n\n////////////////// memoryFile ////////////////////\n\ntype memoryFile struct {\n\tbuffer string\n}\n\nfunc (self *memoryFile) Write(p []byte) (n int, err error) {\n\tself.buffer += string(p)\n\treturn len(p), nil\n}\n\nfunc (self *memoryFile) String() string {\n\treturn self.buffer\n}\n\nfunc newMemoryFile() *memoryFile {\n\treturn new(memoryFile)\n}\n"
  },
  {
    "path": "convey/reporting/problems.go",
    "content": "package reporting\n\nimport \"fmt\"\n\ntype problem struct {\n\tsilent   bool\n\tout      *Printer\n\terrors   []*AssertionResult\n\tfailures []*AssertionResult\n}\n\nfunc (self *problem) BeginStory(story *StoryReport) {}\n\nfunc (self *problem) Enter(scope *ScopeReport) {}\n\nfunc (self *problem) Report(report *AssertionResult) {\n\tif report.Error != nil {\n\t\tself.errors = append(self.errors, report)\n\t} else if report.Failure != \"\" {\n\t\tself.failures = append(self.failures, report)\n\t}\n}\n\nfunc (self *problem) Exit() {}\n\nfunc (self *problem) EndStory() {\n\tself.show(self.showErrors, redColor)\n\tself.show(self.showFailures, yellowColor)\n\tself.prepareForNextStory()\n}\nfunc (self *problem) show(display func(), color string) {\n\tif !self.silent {\n\t\tfmt.Print(color)\n\t}\n\tdisplay()\n\tif !self.silent {\n\t\tfmt.Print(resetColor)\n\t}\n\tself.out.Dedent()\n}\nfunc (self *problem) showErrors() {\n\tfor i, e := range self.errors {\n\t\tif i == 0 {\n\t\t\tself.out.Println(\"\\nErrors:\\n\")\n\t\t\tself.out.Indent()\n\t\t}\n\t\tself.out.Println(errorTemplate, e.File, e.Line, e.Error, e.StackTrace)\n\t}\n}\nfunc (self *problem) showFailures() {\n\tfor i, f := range self.failures {\n\t\tif i == 0 {\n\t\t\tself.out.Println(\"\\nFailures:\\n\")\n\t\t\tself.out.Indent()\n\t\t}\n\t\tself.out.Println(failureTemplate, f.File, f.Line, f.Failure)\n\t\tif f.StackTrace != \"\" {\n\t\t\tself.out.Println(stackTemplate, f.StackTrace)\n\t\t}\n\t}\n}\n\nfunc (self *problem) Write(content []byte) (written int, err error) {\n\treturn len(content), nil // no-op\n}\n\nfunc NewProblemReporter(out *Printer) *problem {\n\tself := new(problem)\n\tself.out = out\n\tself.prepareForNextStory()\n\treturn self\n}\n\nfunc NewSilentProblemReporter(out *Printer) *problem {\n\tself := NewProblemReporter(out)\n\tself.silent = true\n\treturn self\n}\n\nfunc (self *problem) prepareForNextStory() {\n\tself.errors = []*AssertionResult{}\n\tself.failures = []*AssertionResult{}\n}\n"
  },
  {
    "path": "convey/reporting/problems_test.go",
    "content": "package reporting\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestNoopProblemReporterActions(t *testing.T) {\n\tfile, reporter := setup()\n\treporter.BeginStory(nil)\n\treporter.Enter(nil)\n\treporter.Exit()\n\texpected := \"\"\n\tactual := file.String()\n\tif expected != actual {\n\t\tt.Errorf(\"Expected: '(blank)'\\nActual:  '%s'\", actual)\n\t}\n}\n\nfunc TestReporterPrintsFailuresAndErrorsAtTheEndOfTheStory(t *testing.T) {\n\tfile, reporter := setup()\n\treporter.Report(NewFailureReport(\"failed\", false))\n\treporter.Report(NewErrorReport(\"error\"))\n\treporter.Report(NewSuccessReport())\n\treporter.EndStory()\n\n\tresult := file.String()\n\tif !strings.Contains(result, \"Errors:\\n\") {\n\t\tt.Errorf(\"Expected errors, found none.\")\n\t}\n\tif !strings.Contains(result, \"Failures:\\n\") {\n\t\tt.Errorf(\"Expected failures, found none.\")\n\t}\n\n\t// Each stack trace looks like: `* /path/to/file.go`, so look for `* `.\n\t// With go 1.4+ there is a line in some stack traces that looks like this:\n\t//   `testing.(*M).Run(0x2082d60a0, 0x25b7c0)`\n\t// So we can't just look for \"*\" anymore.\n\tproblemCount := strings.Count(result, \"* \")\n\tif problemCount != 2 {\n\t\tt.Errorf(\"Expected one failure and one error (total of 2 '*' characters). Got %d\", problemCount)\n\t}\n}\n\nfunc setup() (file *memoryFile, reporter *problem) {\n\tmonochrome()\n\tfile = newMemoryFile()\n\tprinter := NewPrinter(file)\n\treporter = NewProblemReporter(printer)\n\treturn\n}\n"
  },
  {
    "path": "convey/reporting/reporter.go",
    "content": "package reporting\n\nimport \"io\"\n\ntype Reporter interface {\n\tBeginStory(story *StoryReport)\n\tEnter(scope *ScopeReport)\n\tReport(r *AssertionResult)\n\tExit()\n\tEndStory()\n\tio.Writer\n}\n\ntype reporters struct{ collection []Reporter }\n\nfunc (self *reporters) BeginStory(s *StoryReport) { self.foreach(func(r Reporter) { r.BeginStory(s) }) }\nfunc (self *reporters) Enter(s *ScopeReport)      { self.foreach(func(r Reporter) { r.Enter(s) }) }\nfunc (self *reporters) Report(a *AssertionResult) { self.foreach(func(r Reporter) { r.Report(a) }) }\nfunc (self *reporters) Exit()                     { self.foreach(func(r Reporter) { r.Exit() }) }\nfunc (self *reporters) EndStory()                 { self.foreach(func(r Reporter) { r.EndStory() }) }\n\nfunc (self *reporters) Write(contents []byte) (written int, err error) {\n\tself.foreach(func(r Reporter) {\n\t\twritten, err = r.Write(contents)\n\t})\n\treturn written, err\n}\n\nfunc (self *reporters) foreach(action func(Reporter)) {\n\tfor _, r := range self.collection {\n\t\taction(r)\n\t}\n}\n\nfunc NewReporters(collection ...Reporter) *reporters {\n\tself := new(reporters)\n\tself.collection = collection\n\treturn self\n}\n"
  },
  {
    "path": "convey/reporting/reporter_test.go",
    "content": "package reporting\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n)\n\nfunc TestEachNestedReporterReceivesTheCallFromTheContainingReporter(t *testing.T) {\n\tfake1 := newFakeReporter()\n\tfake2 := newFakeReporter()\n\treporter := NewReporters(fake1, fake2)\n\n\treporter.BeginStory(nil)\n\tassertTrue(t, fake1.begun)\n\tassertTrue(t, fake2.begun)\n\n\treporter.Enter(NewScopeReport(\"scope\"))\n\tassertTrue(t, fake1.entered)\n\tassertTrue(t, fake2.entered)\n\n\treporter.Report(NewSuccessReport())\n\tassertTrue(t, fake1.reported)\n\tassertTrue(t, fake2.reported)\n\n\treporter.Exit()\n\tassertTrue(t, fake1.exited)\n\tassertTrue(t, fake2.exited)\n\n\treporter.EndStory()\n\tassertTrue(t, fake1.ended)\n\tassertTrue(t, fake2.ended)\n\n\tcontent := []byte(\"hi\")\n\twritten, err := reporter.Write(content)\n\tassertTrue(t, fake1.written)\n\tassertTrue(t, fake2.written)\n\tassertEqual(t, written, len(content))\n\tassertNil(t, err)\n\n}\n\nfunc assertTrue(t *testing.T, value bool) {\n\tif !value {\n\t\t_, _, line, _ := runtime.Caller(1)\n\t\tt.Errorf(\"Value should have been true (but was false). See line %d\", line)\n\t}\n}\n\nfunc assertEqual(t *testing.T, expected, actual int) {\n\tif actual != expected {\n\t\t_, _, line, _ := runtime.Caller(1)\n\t\tt.Errorf(\"Value should have been %d (but was %d). See line %d\", expected, actual, line)\n\t}\n}\n\nfunc assertNil(t *testing.T, err error) {\n\tif err != nil {\n\t\t_, _, line, _ := runtime.Caller(1)\n\t\tt.Errorf(\"Error should have been <nil> (but wasn't). See line %d. %v\", err, line)\n\t}\n}\n\ntype fakeReporter struct {\n\tbegun    bool\n\tentered  bool\n\treported bool\n\texited   bool\n\tended    bool\n\twritten  bool\n}\n\nfunc newFakeReporter() *fakeReporter {\n\treturn &fakeReporter{}\n}\n\nfunc (self *fakeReporter) BeginStory(story *StoryReport) {\n\tself.begun = true\n}\nfunc (self *fakeReporter) Enter(scope *ScopeReport) {\n\tself.entered = true\n}\nfunc (self *fakeReporter) Report(report *AssertionResult) {\n\tself.reported = true\n}\nfunc (self *fakeReporter) Exit() {\n\tself.exited = true\n}\nfunc (self *fakeReporter) EndStory() {\n\tself.ended = true\n}\nfunc (self *fakeReporter) Write(content []byte) (int, error) {\n\tself.written = true\n\treturn len(content), nil\n}\n"
  },
  {
    "path": "convey/reporting/reporting.goconvey",
    "content": "#ignore\n-timeout=1s\n"
  },
  {
    "path": "convey/reporting/reports.go",
    "content": "package reporting\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/smartystreets/goconvey/convey/gotest\"\n)\n\n////////////////// ScopeReport ////////////////////\n\ntype ScopeReport struct {\n\tTitle string\n\tFile  string\n\tLine  int\n}\n\nfunc NewScopeReport(title string) *ScopeReport {\n\tfile, line, _ := gotest.ResolveExternalCaller()\n\tself := new(ScopeReport)\n\tself.Title = title\n\tself.File = file\n\tself.Line = line\n\treturn self\n}\n\n////////////////// ScopeResult ////////////////////\n\ntype ScopeResult struct {\n\tTitle      string\n\tFile       string\n\tLine       int\n\tDepth      int\n\tAssertions []*AssertionResult\n\tOutput     string\n}\n\nfunc newScopeResult(title string, depth int, file string, line int) *ScopeResult {\n\tself := new(ScopeResult)\n\tself.Title = title\n\tself.Depth = depth\n\tself.File = file\n\tself.Line = line\n\tself.Assertions = []*AssertionResult{}\n\treturn self\n}\n\n/////////////////// StoryReport /////////////////////\n\ntype StoryReport struct {\n\tTest T\n\tName string\n\tFile string\n\tLine int\n}\n\nfunc NewStoryReport(test T) *StoryReport {\n\tfile, line, name := gotest.ResolveExternalCaller()\n\tname = removePackagePath(name)\n\tself := new(StoryReport)\n\tself.Test = test\n\tself.Name = name\n\tself.File = file\n\tself.Line = line\n\treturn self\n}\n\n// name comes in looking like \"github.com/smartystreets/goconvey/examples.TestName\".\n// We only want the stuff after the last '.', which is the name of the test function.\nfunc removePackagePath(name string) string {\n\tparts := strings.Split(name, \".\")\n\treturn parts[len(parts)-1]\n}\n\n/////////////////// FailureView ////////////////////////\n\n// FailureView is also declared in github.com/smarty/assertions.\n// The json struct tags should be equal in both declarations.\ntype FailureView struct {\n\tMessage  string `json:\"Message\"`\n\tExpected string `json:\"Expected\"`\n\tActual   string `json:\"Actual\"`\n}\n\n////////////////////AssertionResult //////////////////////\n\ntype AssertionResult struct {\n\tFile       string\n\tLine       int\n\tExpected   string\n\tActual     string\n\tFailure    string\n\tError      any\n\tStackTrace string\n\tSkipped    bool\n}\n\nfunc NewFailureReport(failure string, showStack bool) *AssertionResult {\n\treport := new(AssertionResult)\n\treport.File, report.Line = caller()\n\tif showStack {\n\t\treport.StackTrace = stackTrace()\n\t}\n\tparseFailure(failure, report)\n\treturn report\n}\nfunc parseFailure(failure string, report *AssertionResult) {\n\tview := new(FailureView)\n\terr := json.Unmarshal([]byte(failure), view)\n\tif err == nil {\n\t\treport.Failure = view.Message\n\t\treport.Expected = view.Expected\n\t\treport.Actual = view.Actual\n\t} else {\n\t\treport.Failure = failure\n\t}\n}\nfunc NewErrorReport(err any) *AssertionResult {\n\treport := new(AssertionResult)\n\treport.File, report.Line = caller()\n\treport.StackTrace = fullStackTrace()\n\treport.Error = fmt.Sprintf(\"%v\", err)\n\treturn report\n}\nfunc NewSuccessReport() *AssertionResult {\n\treturn new(AssertionResult)\n}\nfunc NewSkipReport() *AssertionResult {\n\treport := new(AssertionResult)\n\treport.File, report.Line = caller()\n\treport.StackTrace = fullStackTrace()\n\treport.Skipped = true\n\treturn report\n}\n\nfunc caller() (file string, line int) {\n\tfile, line, _ = gotest.ResolveExternalCaller()\n\treturn\n}\n\nfunc stackTrace() string {\n\tbuffer := make([]byte, 1024*64)\n\tn := runtime.Stack(buffer, false)\n\treturn removeInternalEntries(string(buffer[:n]))\n}\nfunc fullStackTrace() string {\n\tbuffer := make([]byte, 1024*64)\n\tn := runtime.Stack(buffer, true)\n\treturn removeInternalEntries(string(buffer[:n]))\n}\nfunc removeInternalEntries(stack string) string {\n\tlines := strings.Split(stack, newline)\n\tfiltered := []string{}\n\tfor _, line := range lines {\n\t\tif !isExternal(line) {\n\t\t\tfiltered = append(filtered, line)\n\t\t}\n\t}\n\treturn strings.Join(filtered, newline)\n}\nfunc isExternal(line string) bool {\n\tfor _, p := range internalPackages {\n\t\tif strings.Contains(line, p) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// NOTE: any new packages that host goconvey packages will need to be added here!\n// An alternative is to scan the goconvey directory and then exclude stuff like\n// the examples package but that's nasty too.\nvar internalPackages = []string{\n\t\"goconvey/assertions\",\n\t\"goconvey/convey\",\n\t\"goconvey/execution\",\n\t\"goconvey/gotest\",\n\t\"goconvey/reporting\",\n}\n"
  },
  {
    "path": "convey/reporting/statistics.go",
    "content": "package reporting\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\nfunc (self *statistics) BeginStory(story *StoryReport) {}\n\nfunc (self *statistics) Enter(scope *ScopeReport) {}\n\nfunc (self *statistics) Report(report *AssertionResult) {\n\tself.Lock()\n\tdefer self.Unlock()\n\n\tif !self.failing && report.Failure != \"\" {\n\t\tself.failing = true\n\t}\n\tif !self.erroring && report.Error != nil {\n\t\tself.erroring = true\n\t}\n\tif report.Skipped {\n\t\tself.skipped += 1\n\t} else {\n\t\tself.total++\n\t}\n}\n\nfunc (self *statistics) Exit() {}\n\nfunc (self *statistics) EndStory() {\n\tself.Lock()\n\tdefer self.Unlock()\n\n\tif !self.suppressed {\n\t\tself.printSummaryLocked()\n\t}\n}\n\nfunc (self *statistics) Suppress() {\n\tself.Lock()\n\tdefer self.Unlock()\n\tself.suppressed = true\n}\n\nfunc (self *statistics) PrintSummary() {\n\tself.Lock()\n\tdefer self.Unlock()\n\tself.printSummaryLocked()\n}\n\nfunc (self *statistics) printSummaryLocked() {\n\tself.reportAssertionsLocked()\n\tself.reportSkippedSectionsLocked()\n\tself.completeReportLocked()\n}\nfunc (self *statistics) reportAssertionsLocked() {\n\tself.decideColorLocked()\n\tself.out.Print(\"\\n%d total %s\", self.total, plural(\"assertion\", self.total))\n}\nfunc (self *statistics) decideColorLocked() {\n\tif self.failing && !self.erroring {\n\t\tfmt.Print(yellowColor)\n\t} else if self.erroring {\n\t\tfmt.Print(redColor)\n\t} else {\n\t\tfmt.Print(greenColor)\n\t}\n}\nfunc (self *statistics) reportSkippedSectionsLocked() {\n\tif self.skipped > 0 {\n\t\tfmt.Print(yellowColor)\n\t\tself.out.Print(\" (one or more sections skipped)\")\n\t}\n}\nfunc (self *statistics) completeReportLocked() {\n\tfmt.Print(resetColor)\n\tself.out.Print(\"\\n\")\n\tself.out.Print(\"\\n\")\n}\n\nfunc (self *statistics) Write(content []byte) (written int, err error) {\n\treturn len(content), nil // no-op\n}\n\nfunc NewStatisticsReporter(out *Printer) *statistics {\n\tself := statistics{}\n\tself.out = out\n\treturn &self\n}\n\ntype statistics struct {\n\tsync.Mutex\n\n\tout        *Printer\n\ttotal      int\n\tfailing    bool\n\terroring   bool\n\tskipped    int\n\tsuppressed bool\n}\n\nfunc plural(word string, count int) string {\n\tif count == 1 {\n\t\treturn word\n\t}\n\treturn word + \"s\"\n}\n"
  },
  {
    "path": "convey/reporting/story.go",
    "content": "// TODO: in order for this reporter to be completely honest\n// we need to retrofit to be more like the json reporter such that:\n// 1. it maintains ScopeResult collections, which count assertions\n// 2. it reports only after EndStory(), so that all tick marks\n//    are placed near the appropriate title.\n// 3. Under unit test\n\npackage reporting\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype story struct {\n\tout        *Printer\n\ttitlesById map[string]string\n\tcurrentKey []string\n}\n\nfunc (self *story) BeginStory(story *StoryReport) {}\n\nfunc (self *story) Enter(scope *ScopeReport) {\n\tself.out.Indent()\n\n\tself.currentKey = append(self.currentKey, scope.Title)\n\tID := strings.Join(self.currentKey, \"|\")\n\n\tif _, found := self.titlesById[ID]; !found {\n\t\tself.out.Println(\"\")\n\t\tself.out.Print(scope.Title)\n\t\tself.out.Insert(\" \")\n\t\tself.titlesById[ID] = scope.Title\n\t}\n}\n\nfunc (self *story) Report(report *AssertionResult) {\n\tif report.Error != nil {\n\t\tfmt.Print(redColor)\n\t\tself.out.Insert(error_)\n\t} else if report.Failure != \"\" {\n\t\tfmt.Print(yellowColor)\n\t\tself.out.Insert(failure)\n\t} else if report.Skipped {\n\t\tfmt.Print(yellowColor)\n\t\tself.out.Insert(skip)\n\t} else {\n\t\tfmt.Print(greenColor)\n\t\tself.out.Insert(success)\n\t}\n\tfmt.Print(resetColor)\n}\n\nfunc (self *story) Exit() {\n\tself.out.Dedent()\n\tself.currentKey = self.currentKey[:len(self.currentKey)-1]\n}\n\nfunc (self *story) EndStory() {\n\tself.titlesById = make(map[string]string)\n\tself.out.Println(\"\\n\")\n}\n\nfunc (self *story) Write(content []byte) (written int, err error) {\n\treturn len(content), nil // no-op\n}\n\nfunc NewStoryReporter(out *Printer) *story {\n\tself := new(story)\n\tself.out = out\n\tself.titlesById = make(map[string]string)\n\treturn self\n}\n"
  },
  {
    "path": "convey/reporting_hooks_test.go",
    "content": "package convey\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"path\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n)\n\nfunc TestSingleScopeReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSo(1, ShouldEqual, 1)\n\t})\n\n\texpectEqual(t, \"Begin|A|Success|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestNestedScopeReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tConvey(\"B\", func() {\n\t\t\tSo(1, ShouldEqual, 1)\n\t\t})\n\t})\n\n\texpectEqual(t, \"Begin|A|B|Success|Exit|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestFailureReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSo(1, ShouldBeNil)\n\t})\n\n\texpectEqual(t, \"Begin|A|Failure|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestFirstFailureEndsScopeExecution(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSo(1, ShouldBeNil)\n\t\tSo(nil, ShouldBeNil)\n\t})\n\n\texpectEqual(t, \"Begin|A|Failure|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestComparisonFailureDeserializedAndReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSo(\"hi\", ShouldEqual, \"bye\")\n\t})\n\n\texpectEqual(t, `Begin|A|Failure(\"bye\"/\"hi\")|Exit|End`, myReporter.wholeStory())\n}\n\nfunc TestNestedFailureReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tConvey(\"B\", func() {\n\t\t\tSo(2, ShouldBeNil)\n\t\t})\n\t})\n\n\texpectEqual(t, \"Begin|A|B|Failure|Exit|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestSuccessAndFailureReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSo(nil, ShouldBeNil)\n\t\tSo(1, ShouldBeNil)\n\t})\n\n\texpectEqual(t, \"Begin|A|Success|Failure|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestIncompleteActionReportedAsSkipped(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tConvey(\"B\", nil)\n\t})\n\n\texpectEqual(t, \"Begin|A|B|Skipped|Exit|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestSkippedConveyReportedAsSkipped(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSkipConvey(\"B\", func() {\n\t\t\tSo(1, ShouldEqual, 1)\n\t\t})\n\t})\n\n\texpectEqual(t, \"Begin|A|B|Skipped|Exit|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestMultipleSkipsAreReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tConvey(\"0\", func() {\n\t\t\tSo(nil, ShouldBeNil)\n\t\t})\n\n\t\tSkipConvey(\"1\", func() {})\n\t\tSkipConvey(\"2\", func() {})\n\n\t\tConvey(\"3\", nil)\n\t\tConvey(\"4\", nil)\n\n\t\tConvey(\"5\", func() {\n\t\t\tSo(nil, ShouldBeNil)\n\t\t})\n\t})\n\n\texpected := \"Begin\" +\n\t\t\"|A|0|Success|Exit|Exit\" +\n\t\t\"|A|1|Skipped|Exit|Exit\" +\n\t\t\"|A|2|Skipped|Exit|Exit\" +\n\t\t\"|A|3|Skipped|Exit|Exit\" +\n\t\t\"|A|4|Skipped|Exit|Exit\" +\n\t\t\"|A|5|Success|Exit|Exit\" +\n\t\t\"|End\"\n\n\texpectEqual(t, expected, myReporter.wholeStory())\n}\n\nfunc TestSkippedAssertionIsNotReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSkipSo(1, ShouldEqual, 1)\n\t})\n\n\texpectEqual(t, \"Begin|A|Skipped|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestMultipleSkippedAssertionsAreNotReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSkipSo(1, ShouldEqual, 1)\n\t\tSo(1, ShouldEqual, 1)\n\t\tSkipSo(1, ShouldEqual, 1)\n\t})\n\n\texpectEqual(t, \"Begin|A|Skipped|Success|Skipped|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestErrorByManualPanicReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tpanic(\"Gopher alert!\")\n\t})\n\n\texpectEqual(t, \"Begin|A|Error|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestIterativeConveysReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tfor x := 0; x < 3; x++ {\n\t\t\tConvey(strconv.Itoa(x), func() {\n\t\t\t\tSo(x, ShouldEqual, x)\n\t\t\t})\n\t\t}\n\t})\n\n\texpectEqual(t, \"Begin|A|0|Success|Exit|Exit|A|1|Success|Exit|Exit|A|2|Success|Exit|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestNestedIterativeConveysReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tfor x := 0; x < 3; x++ {\n\t\t\tConvey(strconv.Itoa(x), func() {\n\t\t\t\tfor y := 0; y < 3; y++ {\n\t\t\t\t\tConvey(\"< \"+strconv.Itoa(y), func() {\n\t\t\t\t\t\tSo(x, ShouldBeLessThan, y)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\texpectEqual(t, (\"Begin|\" +\n\t\t\"A|0|< 0|Failure|Exit|Exit|Exit|\" +\n\t\t\"A|0|< 1|Success|Exit|Exit|Exit|\" +\n\t\t\"A|0|< 2|Success|Exit|Exit|Exit|\" +\n\t\t\"A|1|< 0|Failure|Exit|Exit|Exit|\" +\n\t\t\"A|1|< 1|Failure|Exit|Exit|Exit|\" +\n\t\t\"A|1|< 2|Success|Exit|Exit|Exit|\" +\n\t\t\"A|2|< 0|Failure|Exit|Exit|Exit|\" +\n\t\t\"A|2|< 1|Failure|Exit|Exit|Exit|\" +\n\t\t\"A|2|< 2|Failure|Exit|Exit|Exit|\" +\n\t\t\"End\"), myReporter.wholeStory())\n}\n\nfunc TestEmbeddedAssertionReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\tConvey(\"A\", test, func(c C) {\n\t\tts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\tc.So(r.FormValue(\"msg\"), ShouldEqual, \"ping\")\n\t\t}))\n\t\thttp.DefaultClient.Get(ts.URL + \"?msg=ping\")\n\t})\n\n\texpectEqual(t, \"Begin|A|Success|Exit|End\", myReporter.wholeStory())\n}\n\nfunc TestEmbeddedContextHelperReported(t *testing.T) {\n\tmyReporter, test := setupFakeReporter()\n\n\thelper := func(c C) http.HandlerFunc {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\tc.Convey(\"Embedded\", func() {\n\t\t\t\tSo(r.FormValue(\"msg\"), ShouldEqual, \"ping\")\n\t\t\t})\n\t\t})\n\t}\n\n\tConvey(\"A\", test, func(c C) {\n\t\tts := httptest.NewServer(helper(c))\n\t\thttp.DefaultClient.Get(ts.URL + \"?msg=ping\")\n\t})\n\n\texpectEqual(t, \"Begin|A|Embedded|Success|Exit|Exit|End\", myReporter.wholeStory())\n}\n\nfunc expectEqual(t *testing.T, expected any, actual any) {\n\tif expected != actual {\n\t\t_, file, line, _ := runtime.Caller(1)\n\t\tt.Errorf(\"Expected '%v' to be '%v' but it wasn't. See '%s' at line %d.\",\n\t\t\tactual, expected, path.Base(file), line)\n\t}\n}\n\nfunc setupFakeReporter() (*fakeReporter, *fakeGoTest) {\n\tmyReporter := new(fakeReporter)\n\tmyReporter.calls = []string{}\n\ttestReporter = myReporter\n\treturn myReporter, new(fakeGoTest)\n}\n\ntype fakeReporter struct {\n\tcalls []string\n}\n\nfunc (self *fakeReporter) BeginStory(story *reporting.StoryReport) {\n\tself.calls = append(self.calls, \"Begin\")\n}\n\nfunc (self *fakeReporter) Enter(scope *reporting.ScopeReport) {\n\tself.calls = append(self.calls, scope.Title)\n}\n\nfunc (self *fakeReporter) Report(report *reporting.AssertionResult) {\n\tif report.Error != nil {\n\t\tself.calls = append(self.calls, \"Error\")\n\t} else if report.Failure != \"\" {\n\t\tmessage := \"Failure\"\n\t\tif report.Expected != \"\" || report.Actual != \"\" {\n\t\t\tmessage += fmt.Sprintf(\"(%s/%s)\", report.Expected, report.Actual)\n\t\t}\n\t\tself.calls = append(self.calls, message)\n\t} else if report.Skipped {\n\t\tself.calls = append(self.calls, \"Skipped\")\n\t} else {\n\t\tself.calls = append(self.calls, \"Success\")\n\t}\n}\n\nfunc (self *fakeReporter) Exit() {\n\tself.calls = append(self.calls, \"Exit\")\n}\n\nfunc (self *fakeReporter) EndStory() {\n\tself.calls = append(self.calls, \"End\")\n}\n\nfunc (self *fakeReporter) Write(content []byte) (int, error) {\n\treturn len(content), nil // no-op\n}\n\nfunc (self *fakeReporter) wholeStory() string {\n\treturn strings.Join(self.calls, \"|\")\n}\n\n////////////////////////////////\n\ntype fakeGoTest struct{}\n\nfunc (self *fakeGoTest) Fail()                             {}\nfunc (self *fakeGoTest) Fatalf(format string, args ...any) {}\n\nvar test t = new(fakeGoTest)\n"
  },
  {
    "path": "convey/stack_trace_test.go",
    "content": "package convey\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n)\n\nvar goroutineRE = regexp.MustCompile(`goroutine \\d+ \\[`)\n\n// countGoroutines takes a test output file and counts the number of goroutines\n// that were mentioned inside it. This does this by hunting for lines such as\n// \"goroutine 42 [running]\", while excluding secondary mentions of already-counted\n// goroutines.\nfunc countGoroutines(testOutput string) int {\n\treturn len(goroutineRE.FindAllStringSubmatch(testOutput, -1))\n}\n\nfunc TestStackTrace(t *testing.T) {\n\tfile, test := setupFileReporter()\n\n\tConvey(\"A\", test, func() {\n\t\tSo(1, ShouldEqual, 2)\n\t})\n\n\tif !strings.Contains(file.String(), \"Failures:\\n\") {\n\t\tt.Errorf(\"Expected errors, found none.\")\n\t}\n\tif strings.Contains(file.String(), \"goroutine \") {\n\t\tt.Errorf(\"Found stack trace, expected none.\")\n\t}\n\n\tConvey(\"A\", test, StackFail, func() {\n\t\tSo(1, ShouldEqual, 2)\n\t})\n\n\tif !strings.Contains(file.String(), \"goroutine \") {\n\t\tt.Errorf(\"Expected stack trace, found none.\")\n\t}\n}\n\nfunc TestSetDefaultStackMode(t *testing.T) {\n\tfile, test := setupFileReporter()\n\tSetDefaultStackMode(StackFail) // the default is normally StackError\n\tdefer SetDefaultStackMode(StackError)\n\n\tConvey(\"A\", test, func() {\n\t\tSo(1, ShouldEqual, 2)\n\t})\n\n\tif !strings.Contains(file.String(), \"goroutine \") {\n\t\tt.Errorf(\"Expected stack trace, found none.\")\n\t}\n}\n\nfunc TestStackModeMultipleInvocationInheritance(t *testing.T) {\n\tfile, test := setupFileReporter()\n\n\t// initial convey should default to StaskError, so no stack trace\n\tConvey(\"A\", test, FailureContinues, func() {\n\t\tSo(1, ShouldEqual, 2)\n\n\t\t// nested convey has explicit StaskFail, so should emit stack trace\n\t\tConvey(\"B\", StackFail, func() {\n\t\t\tSo(1, ShouldEqual, 2)\n\t\t})\n\t})\n\tstackCount := countGoroutines(file.String())\n\tif stackCount != 1 {\n\t\tt.Errorf(\"Expected 1 stack trace, found %d.\", stackCount)\n\t\tfmt.Printf(\"RESULT: %s \\n\", file.String())\n\t}\n}\n\nfunc TestStackModeMultipleInvocationInheritance2(t *testing.T) {\n\tfile, test := setupFileReporter()\n\n\t// Explicit StackFail, expect stack trace\n\tConvey(\"A\", test, FailureContinues, StackFail, func() {\n\t\tSo(1, ShouldEqual, 2)\n\n\t\t// Nested Convey inherits StackFail, expect stack trace\n\t\tConvey(\"B\", func() {\n\t\t\tSo(1, ShouldEqual, 2)\n\t\t})\n\t})\n\n\tstackCount := countGoroutines(file.String())\n\tif stackCount != 2 {\n\t\tt.Errorf(\"Expected 2 stack traces, found %d.\", stackCount)\n\t}\n}\n\nfunc TestStackModeMultipleInvocationInheritance3(t *testing.T) {\n\tfile, test := setupFileReporter()\n\n\t// Explicit StackFail, expect stack trace\n\tConvey(\"A\", test, FailureContinues, StackFail, func() {\n\t\tSo(1, ShouldEqual, 2)\n\n\t\t// Nested Convey explicitly sets StackError, so no stack trace\n\t\tConvey(\"B\", StackError, func() {\n\t\t\tSo(1, ShouldEqual, 2)\n\t\t})\n\t})\n\n\tstackCount := countGoroutines(file.String())\n\tif stackCount != 1 {\n\t\tt.Errorf(\"Expected 1 stack trace1, found %d.\", stackCount)\n\t}\n}\n\nfunc setupFileReporter() (*memoryFile, *fakeGoTest) {\n\t//monochrome()\n\tfile := newMemoryFile()\n\tprinter := reporting.NewPrinter(file)\n\treporter := reporting.NewProblemReporter(printer)\n\ttestReporter = reporter\n\n\treturn file, new(fakeGoTest)\n}\n\n////////////////// memoryFile ////////////////////\n\ntype memoryFile struct {\n\tbuffer string\n}\n\nfunc (mf *memoryFile) Write(p []byte) (n int, err error) {\n\tmf.buffer += string(p)\n\treturn len(p), nil\n}\n\nfunc (mf *memoryFile) String() string {\n\treturn mf.buffer\n}\n\nfunc newMemoryFile() *memoryFile {\n\treturn new(memoryFile)\n}\n\n// func monochrome() {\n// \tgreenColor, yellowColor, redColor, resetColor = \"\", \"\", \"\", \"\"\n// }\n"
  },
  {
    "path": "convey/story_conventions_test.go",
    "content": "package convey\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc expectPanic(t *testing.T, f string) any {\n\tr := recover()\n\tif r != nil {\n\t\tif cp, ok := r.(*conveyErr); ok {\n\t\t\tif cp.fmt != f {\n\t\t\t\tt.Error(\"Incorrect panic message.\")\n\t\t\t}\n\t\t} else {\n\t\t\tt.Errorf(\"Incorrect panic type. %s\", reflect.TypeOf(r))\n\t\t}\n\t} else {\n\t\tt.Error(\"Expected panic but none occurred\")\n\t}\n\treturn r\n}\n\nfunc TestMissingTopLevelGoTestReferenceCausesPanic(t *testing.T) {\n\toutput := map[string]bool{}\n\n\tdefer expectEqual(t, false, output[\"good\"])\n\tdefer expectPanic(t, missingGoTest)\n\n\tConvey(\"Hi\", func() {\n\t\toutput[\"bad\"] = true // this shouldn't happen\n\t})\n}\n\nfunc TestMissingTopLevelGoTestReferenceAfterGoodExample(t *testing.T) {\n\toutput := map[string]bool{}\n\n\tdefer func() {\n\t\texpectEqual(t, true, output[\"good\"])\n\t\texpectEqual(t, false, output[\"bad\"])\n\t}()\n\tdefer expectPanic(t, missingGoTest)\n\n\tConvey(\"Good example\", t, func() {\n\t\toutput[\"good\"] = true\n\t})\n\n\tConvey(\"Bad example\", func() {\n\t\toutput[\"bad\"] = true // shouldn't happen\n\t})\n}\n\nfunc TestExtraReferencePanics(t *testing.T) {\n\toutput := map[string]bool{}\n\n\tdefer expectEqual(t, false, output[\"bad\"])\n\tdefer expectPanic(t, extraGoTest)\n\n\tConvey(\"Good example\", t, func() {\n\t\tConvey(\"Bad example - passing in *testing.T a second time!\", t, func() {\n\t\t\toutput[\"bad\"] = true // shouldn't happen\n\t\t})\n\t})\n}\n\nfunc TestParseRegistrationMissingRequiredElements(t *testing.T) {\n\tdefer expectPanic(t, parseError)\n\n\tConvey()\n}\n\nfunc TestParseRegistration_MissingNameString(t *testing.T) {\n\tdefer expectPanic(t, parseError)\n\n\tConvey(func() {})\n}\n\nfunc TestParseRegistration_MissingActionFunc(t *testing.T) {\n\tdefer expectPanic(t, parseError)\n\n\tConvey(\"Hi there\", 12345)\n}\n\nfunc TestFailureModeNoContext(t *testing.T) {\n\tConvey(\"Foo\", t, func() {\n\t\tdone := make(chan int, 1)\n\t\tgo func() {\n\t\t\tdefer func() { done <- 1 }()\n\t\t\tdefer expectPanic(t, noStackContext)\n\t\t\tSo(len(\"I have no context\"), ShouldBeGreaterThan, 0)\n\t\t}()\n\t\t<-done\n\t})\n}\n\nfunc TestFailureModeDuplicateSuite(t *testing.T) {\n\tConvey(\"cool\", t, func() {\n\t\tdefer expectPanic(t, multipleIdenticalConvey)\n\n\t\tConvey(\"dup\", nil)\n\t\tConvey(\"dup\", nil)\n\t})\n}\n\nfunc TestFailureModeIndeterminentSuiteNames(t *testing.T) {\n\tdefer expectPanic(t, differentConveySituations)\n\n\tname := \"bob\"\n\tConvey(\"cool\", t, func() {\n\t\tfor i := 0; i < 3; i++ {\n\t\t\tConvey(name, func() {})\n\t\t\tname += \"bob\"\n\t\t}\n\t})\n}\n\nfunc TestFailureModeNestedIndeterminentSuiteNames(t *testing.T) {\n\tdefer expectPanic(t, differentConveySituations)\n\n\tname := \"bob\"\n\tConvey(\"cool\", t, func() {\n\t\tConvey(\"inner\", func() {\n\t\t\tfor i := 0; i < 3; i++ {\n\t\t\t\tConvey(name, func() {})\n\t\t\t\tname += \"bob\"\n\t\t\t}\n\t\t})\n\t})\n}\n\nfunc TestFailureModeParameterButMissing(t *testing.T) {\n\tdefer expectPanic(t, parseError)\n\n\tprepare()\n\n\tConvey(\"Foobar\", t, FailureHalts)\n}\n\nfunc TestFailureModeParameterWithAction(t *testing.T) {\n\tprepare()\n\n\tConvey(\"Foobar\", t, FailureHalts, func() {})\n}\n\nfunc TestExtraConveyParameters(t *testing.T) {\n\tdefer expectPanic(t, parseError)\n\n\tprepare()\n\n\tConvey(\"Foobar\", t, FailureHalts, func() {}, \"This is not supposed to be here\")\n}\n\nfunc TestExtraConveyParameters2(t *testing.T) {\n\tdefer expectPanic(t, parseError)\n\n\tprepare()\n\n\tConvey(\"Foobar\", t, func() {}, \"This is not supposed to be here\")\n}\n\nfunc TestExtraConveyParameters3(t *testing.T) {\n\tdefer expectPanic(t, parseError)\n\n\toutput := prepare()\n\n\tConvey(\"A\", t, func() {\n\t\toutput += \"A \"\n\n\t\tConvey(\"B\", func() {\n\t\t\toutput += \"B \"\n\t\t}, \"This is not supposed to be here\")\n\t})\n\n\texpectEqual(t, \"A \", output)\n}\n"
  },
  {
    "path": "convey/update_assertions.sh",
    "content": "#!/usr/bin/env bash\n\ncd \"$(dirname $(realpath $0))\"\n\nASSERTIONS=($(\n  go tool nm \"$(go list -export -f '{{.Export}}' github.com/smarty/assertions)\" |\\\n    awk '/ T github\\.com\\/smarty\\/assertions\\.Should/{split($3, a, \".\"); print a[3]}' |\\\n    sort | uniq))\n\n(\n  echo \"package convey\"\n  echo\n  echo \"// DO NOT EDIT: generated by update_assertions.sh\"\n  echo\n  echo \"//go:generate ./update_assertions.sh\"\n  echo\n  echo \"import \\\"github.com/smarty/assertions\\\"\"\n  echo\n  echo \"// These assertions are forwarded from github.com/smarty/assertions\"\n  echo \"// in order to make convey self-contained.\"\n  echo \"var (\"\n\n  for assertion in \"${ASSERTIONS[@]}\"\n  do\n    echo \"  $assertion = assertions.$assertion\"\n  done\n\n  echo \")\"\n) > ./assertions.go\n\ngo fmt ./assertions.go\n"
  },
  {
    "path": "examples/assertion_examples_test.go",
    "content": "package examples\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n)\n\nfunc TestAssertionsAreAvailableFromConveyPackage(t *testing.T) {\n\tSetDefaultFailureMode(FailureContinues)\n\tdefer SetDefaultFailureMode(FailureHalts)\n\n\tConvey(\"Equality assertions should be accessible\", t, func() {\n\t\tthing1a := thing{a: \"asdf\"}\n\t\tthing1b := thing{a: \"asdf\"}\n\t\tthing2 := thing{a: \"qwer\"}\n\n\t\tSo(1, ShouldEqual, 1)\n\t\tSo(1, ShouldNotEqual, 2)\n\t\tSo(1, ShouldAlmostEqual, 1.000000000000001)\n\t\tSo(1, ShouldNotAlmostEqual, 2, 0.5)\n\t\tSo(thing1a, ShouldResemble, thing1b)\n\t\tSo(thing1a, ShouldNotResemble, thing2)\n\t\tSo(&thing1a, ShouldPointTo, &thing1a)\n\t\tSo(&thing1a, ShouldNotPointTo, &thing1b)\n\t\tSo(nil, ShouldBeNil)\n\t\tSo(1, ShouldNotBeNil)\n\t\tSo(true, ShouldBeTrue)\n\t\tSo(false, ShouldBeFalse)\n\t\tSo(0, ShouldBeZeroValue)\n\t\tSo(1, ShouldNotBeZeroValue)\n\t})\n\n\tConvey(\"Numeric comparison assertions should be accessible\", t, func() {\n\t\tSo(1, ShouldBeGreaterThan, 0)\n\t\tSo(1, ShouldBeGreaterThanOrEqualTo, 1)\n\t\tSo(1, ShouldBeLessThan, 2)\n\t\tSo(1, ShouldBeLessThanOrEqualTo, 1)\n\t\tSo(1, ShouldBeBetween, 0, 2)\n\t\tSo(1, ShouldNotBeBetween, 2, 4)\n\t\tSo(1, ShouldBeBetweenOrEqual, 1, 2)\n\t\tSo(1, ShouldNotBeBetweenOrEqual, 2, 4)\n\t})\n\n\tConvey(\"Container assertions should be accessible\", t, func() {\n\t\tSo([]int{1, 2, 3}, ShouldContain, 2)\n\t\tSo([]int{1, 2, 3}, ShouldNotContain, 4)\n\t\tSo(map[int]int{1: 1, 2: 2, 3: 3}, ShouldContainKey, 2)\n\t\tSo(map[int]int{1: 1, 2: 2, 3: 3}, ShouldNotContainKey, 4)\n\t\tSo(1, ShouldBeIn, []int{1, 2, 3})\n\t\tSo(4, ShouldNotBeIn, []int{1, 2, 3})\n\t\tSo([]int{}, ShouldBeEmpty)\n\t\tSo([]int{1}, ShouldNotBeEmpty)\n\t\tSo([]int{1, 2}, ShouldHaveLength, 2)\n\t})\n\n\tConvey(\"String assertions should be accessible\", t, func() {\n\t\tSo(\"asdf\", ShouldStartWith, \"a\")\n\t\tSo(\"asdf\", ShouldNotStartWith, \"z\")\n\t\tSo(\"asdf\", ShouldEndWith, \"df\")\n\t\tSo(\"asdf\", ShouldNotEndWith, \"as\")\n\t\tSo(\"\", ShouldBeBlank)\n\t\tSo(\"asdf\", ShouldNotBeBlank)\n\t\tSo(\"asdf\", ShouldContainSubstring, \"sd\")\n\t\tSo(\"asdf\", ShouldNotContainSubstring, \"af\")\n\t})\n\n\tConvey(\"Panic recovery assertions should be accessible\", t, func() {\n\t\tSo(panics, ShouldPanic)\n\t\tSo(func() {}, ShouldNotPanic)\n\t\tSo(panics, ShouldPanicWith, \"Goofy Gophers!\")\n\t\tSo(panics, ShouldNotPanicWith, \"Guileless Gophers!\")\n\t})\n\n\tConvey(\"Type-checking assertions should be accessible\", t, func() {\n\n\t\t// NOTE: Values or pointers may be checked.  If a value is passed,\n\t\t// it will be cast as a pointer to the value to avoid cases where\n\t\t// the struct being tested takes pointer receivers. Go allows values\n\t\t// or pointers to be passed as receivers on methods with a value\n\t\t// receiver, but only pointers on methods with pointer receivers.\n\t\t// See:\n\t\t// http://golang.org/doc/effective_go.html#pointers_vs_values\n\t\t// http://golang.org/doc/effective_go.html#blank_implements\n\t\t// http://blog.golang.org/laws-of-reflection\n\n\t\tSo(1, ShouldHaveSameTypeAs, 0)\n\t\tSo(1, ShouldNotHaveSameTypeAs, \"1\")\n\n\t\tSo(bytes.NewBufferString(\"\"), ShouldImplement, (*io.Reader)(nil))\n\t\tSo(\"string\", ShouldNotImplement, (*io.Reader)(nil))\n\t})\n\n\tConvey(\"Time assertions should be accessible\", t, func() {\n\t\tjanuary1, _ := time.Parse(timeLayout, \"2013-01-01 00:00\")\n\t\tjanuary2, _ := time.Parse(timeLayout, \"2013-01-02 00:00\")\n\t\tjanuary3, _ := time.Parse(timeLayout, \"2013-01-03 00:00\")\n\t\tjanuary4, _ := time.Parse(timeLayout, \"2013-01-04 00:00\")\n\t\tjanuary5, _ := time.Parse(timeLayout, \"2013-01-05 00:00\")\n\t\toneDay, _ := time.ParseDuration(\"24h0m0s\")\n\n\t\tSo(january1, ShouldHappenBefore, january4)\n\t\tSo(january1, ShouldHappenOnOrBefore, january1)\n\t\tSo(january2, ShouldHappenAfter, january1)\n\t\tSo(january2, ShouldHappenOnOrAfter, january2)\n\t\tSo(january3, ShouldHappenBetween, january2, january5)\n\t\tSo(january3, ShouldHappenOnOrBetween, january3, january5)\n\t\tSo(january1, ShouldNotHappenOnOrBetween, january2, january5)\n\t\tSo(january2, ShouldHappenWithin, oneDay, january3)\n\t\tSo(january5, ShouldNotHappenWithin, oneDay, january1)\n\t\tSo([]time.Time{january1, january2}, ShouldBeChronological)\n\t})\n}\n\ntype thing struct {\n\ta string\n}\n\nfunc panics() {\n\tpanic(\"Goofy Gophers!\")\n}\n\nconst timeLayout = \"2006-01-02 15:04\"\n"
  },
  {
    "path": "examples/bowling_game.go",
    "content": "package examples\n\n// Game contains the state of a bowling game.\ntype Game struct {\n\trolls   []int\n\tcurrent int\n}\n\n// NewGame allocates and starts a new game of bowling.\nfunc NewGame() *Game {\n\tgame := new(Game)\n\tgame.rolls = make([]int, maxThrowsPerGame)\n\treturn game\n}\n\n// Roll rolls the ball and knocks down the number of pins specified by pins.\nfunc (self *Game) Roll(pins int) {\n\tself.rolls[self.current] = pins\n\tself.current++\n}\n\n// Score calculates and returns the player's current score.\nfunc (self *Game) Score() (sum int) {\n\tfor throw, frame := 0, 0; frame < framesPerGame; frame++ {\n\t\tif self.isStrike(throw) {\n\t\t\tsum += self.strikeBonusFor(throw)\n\t\t\tthrow += 1\n\t\t} else if self.isSpare(throw) {\n\t\t\tsum += self.spareBonusFor(throw)\n\t\t\tthrow += 2\n\t\t} else {\n\t\t\tsum += self.framePointsAt(throw)\n\t\t\tthrow += 2\n\t\t}\n\t}\n\treturn sum\n}\n\n// isStrike determines if a given throw is a strike or not. A strike is knocking\n// down all pins in one throw.\nfunc (self *Game) isStrike(throw int) bool {\n\treturn self.rolls[throw] == allPins\n}\n\n// strikeBonusFor calculates and returns the strike bonus for a throw.\nfunc (self *Game) strikeBonusFor(throw int) int {\n\treturn allPins + self.framePointsAt(throw+1)\n}\n\n// isSpare determines if a given frame is a spare or not. A spare is knocking\n// down all pins in one frame with two throws.\nfunc (self *Game) isSpare(throw int) bool {\n\treturn self.framePointsAt(throw) == allPins\n}\n\n// spareBonusFor calculates and returns the spare bonus for a throw.\nfunc (self *Game) spareBonusFor(throw int) int {\n\treturn allPins + self.rolls[throw+2]\n}\n\n// framePointsAt computes and returns the score in a frame specified by throw.\nfunc (self *Game) framePointsAt(throw int) int {\n\treturn self.rolls[throw] + self.rolls[throw+1]\n}\n\nconst (\n\t// allPins is the number of pins allocated per fresh throw.\n\tallPins          = 10\n\t\n\t// framesPerGame is the number of frames per bowling game.\n\tframesPerGame    = 10\n\t\n\t// maxThrowsPerGame is the maximum number of throws possible in a single game.\n\tmaxThrowsPerGame = 21\n)\n"
  },
  {
    "path": "examples/bowling_game_test.go",
    "content": "/*\n\nReference: http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata\n\nSee the very first link (which happens to be the very first word of\nthe first paragraph) on the page for a tutorial.\n\n*/\n\npackage examples\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n)\n\nfunc TestBowlingGameScoring(t *testing.T) {\n\tConvey(\"Given a fresh score card\", t, func() {\n\t\tgame := NewGame()\n\n\t\tConvey(\"When all gutter balls are thrown\", func() {\n\t\t\tgame.rollMany(20, 0)\n\n\t\t\tConvey(\"The score should be zero\", func() {\n\t\t\t\tSo(game.Score(), ShouldEqual, 0)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When all throws knock down only one pin\", func() {\n\t\t\tgame.rollMany(20, 1)\n\n\t\t\tConvey(\"The score should be 20\", func() {\n\t\t\t\tSo(game.Score(), ShouldEqual, 20)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When a spare is thrown\", func() {\n\t\t\tgame.rollSpare()\n\t\t\tgame.Roll(3)\n\t\t\tgame.rollMany(17, 0)\n\n\t\t\tConvey(\"The score should include a spare bonus.\", func() {\n\t\t\t\tSo(game.Score(), ShouldEqual, 16)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When a strike is thrown\", func() {\n\t\t\tgame.rollStrike()\n\t\t\tgame.Roll(3)\n\t\t\tgame.Roll(4)\n\t\t\tgame.rollMany(16, 0)\n\n\t\t\tConvey(\"The score should include a strike bonus.\", func() {\n\t\t\t\tSo(game.Score(), ShouldEqual, 24)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When all strikes are thrown\", func() {\n\t\t\tgame.rollMany(21, 10)\n\n\t\t\tConvey(\"The score should be 300.\", func() {\n\t\t\t\tSo(game.Score(), ShouldEqual, 300)\n\t\t\t})\n\t\t})\n\t})\n}\n\nfunc (self *Game) rollMany(times, pins int) {\n\tfor x := 0; x < times; x++ {\n\t\tself.Roll(pins)\n\t}\n}\nfunc (self *Game) rollSpare() {\n\tself.Roll(5)\n\tself.Roll(5)\n}\nfunc (self *Game) rollStrike() {\n\tself.Roll(10)\n}\n"
  },
  {
    "path": "examples/doc.go",
    "content": "// Package examples contains, well, examples of how to use goconvey to\n// specify behavior of a system under test. It contains a well-known example\n// by Robert C. Martin called \"Bowling Game Kata\" as well as another very\n// trivial example that demonstrates Reset() and some of the assertions.\npackage examples\n"
  },
  {
    "path": "examples/examples.goconvey",
    "content": "// Uncomment the next line to disable the package when running the GoConvey UI:\n//IGNORE\n\n// Uncomment the next line to limit testing to the specified test function name pattern:\n//-run=TestAssertionsAreAvailableFromConveyPackage\n\n// Uncomment the next line to limit testing to those tests that don't bail when testing.Short() is true:\n//-short\n\n// include any additional `go test` flags or application-specific flags below:\n\n-timeout=1s\n"
  },
  {
    "path": "examples/simple_example_test.go",
    "content": "package examples\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n)\n\nfunc TestIntegerManipulation(t *testing.T) {\n\tt.Parallel()\n\n\tConvey(\"Given a starting integer value\", t, func() {\n\t\tx := 42\n\n\t\tConvey(\"When incremented\", func() {\n\t\t\tx++\n\n\t\t\tConvey(\"The value should be greater by one\", func() {\n\t\t\t\tSo(x, ShouldEqual, 43)\n\t\t\t})\n\t\t\tConvey(\"The value should NOT be what it used to be\", func() {\n\t\t\t\tSo(x, ShouldNotEqual, 42)\n\t\t\t})\n\t\t})\n\t\tConvey(\"When decremented\", func() {\n\t\t\tx--\n\n\t\t\tConvey(\"The value should be lesser by one\", func() {\n\t\t\t\tSo(x, ShouldEqual, 41)\n\t\t\t})\n\t\t\tConvey(\"The value should NOT be what it used to be\", func() {\n\t\t\t\tSo(x, ShouldNotEqual, 42)\n\t\t\t})\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/smartystreets/goconvey\n\ngo 1.21.7\n\nrequire (\n\tgithub.com/jtolds/gls v4.20.0+incompatible\n\tgithub.com/smarty/assertions v1.15.1\n\tgolang.org/x/tools v0.18.0\n)\n\nrequire (\n\tgithub.com/gopherjs/gopherjs v1.17.2 // indirect\n\tgolang.org/x/mod v0.15.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=\ngithub.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=\ngithub.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=\ngithub.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=\ngithub.com/smarty/assertions v1.15.1 h1:812oFiXI+G55vxsFf+8bIZ1ux30qtkdqzKbEFwyX3Tk=\ngithub.com/smarty/assertions v1.15.1/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=\ngolang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=\ngolang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=\ngolang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=\ngolang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=\n"
  },
  {
    "path": "goconvey.go",
    "content": "// This executable provides an HTTP server that watches for file system changes\n// to .go files within the working directory (and all nested go packages).\n// Navigating to the configured host and port in a web browser will display the\n// latest results of running `go test` in each go package.\npackage main\n\nimport (\n\t\"context\"\n\t\"embed\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"golang.org/x/tools/go/packages\"\n\n\t\"github.com/smartystreets/goconvey/web/server/api\"\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n\t\"github.com/smartystreets/goconvey/web/server/executor\"\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n\t\"github.com/smartystreets/goconvey/web/server/parser\"\n\t\"github.com/smartystreets/goconvey/web/server/system\"\n\t\"github.com/smartystreets/goconvey/web/server/watch\"\n)\n\nfunc init() {\n\tflag.IntVar(&port, \"port\", 8080, \"The port at which to serve http.\")\n\tflag.StringVar(&host, \"host\", \"127.0.0.1\", \"The host at which to serve http.\")\n\tflag.DurationVar(&nap, \"poll\", quarterSecond, \"The interval to wait between polling the file system for changes.\")\n\tflag.IntVar(&parallelPackages, \"packages\", 10, \"The number of packages to test in parallel. Higher == faster but more costly in terms of computing.\")\n\tflag.StringVar(&gobin, \"gobin\", \"go\", \"The path to the 'go' binary (default: search on the PATH).\")\n\tflag.BoolVar(&cover, \"cover\", true, \"Enable package-level coverage statistics.\")\n\tflag.IntVar(&depth, \"depth\", -1, \"The directory scanning depth. If -1, scan infinitely deep directory structures. 0: scan working directory. 1+: Scan into nested directories, limited to value.\")\n\tflag.StringVar(&timeout, \"timeout\", \"0\", \"The test execution timeout if none is specified in the *.goconvey file (default is '0', which is the same as not providing this option).\")\n\tflag.StringVar(&watchedSuffixes, \"watchedSuffixes\", \".go\", \"A comma separated list of file suffixes to watch for modifications.\")\n\tflag.StringVar(&excludedDirs, \"excludedDirs\", \"vendor,node_modules\", \"A comma separated list of directories that will be excluded from being watched.\")\n\tflag.StringVar(&workDir, \"workDir\", \"\", \"set goconvey working directory (default current directory).\")\n\tflag.BoolVar(&autoLaunchBrowser, \"launchBrowser\", true, \"toggle auto launching of browser.\")\n\tflag.BoolVar(&leakTemp, \"leakTemp\", false, \"leak temp dir with coverage reports.\")\n\n\tlog.SetOutput(os.Stdout)\n\tlog.SetFlags(log.LstdFlags | log.Lshortfile)\n}\n\nfunc main() {\n\tflag.Parse()\n\n\tprintHeader()\n\n\ttmpDir, err := ioutil.TempDir(\"\", \"*.goconvey\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\treports := filepath.Join(tmpDir, \"coverage_out\")\n\tif err := os.Mkdir(reports, 0700); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tif leakTemp {\n\t\tlog.Printf(\"leaking temporary directory %q\\n\", tmpDir)\n\t} else {\n\t\tdefer func() {\n\t\t\tif err := os.RemoveAll(tmpDir); err != nil {\n\t\t\t\tlog.Printf(\"failed to clean temporary directory %q: %s\\n\", tmpDir, err)\n\t\t\t}\n\t\t}()\n\t}\n\n\tdone := make(chan os.Signal)\n\tsignal.Notify(done, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)\n\n\tworking := getWorkDir()\n\tshell := system.NewShell(gobin, reports, cover, timeout)\n\n\twatcherInput := make(chan messaging.WatcherCommand)\n\twatcherOutput := make(chan messaging.Folders)\n\texcludedDirItems := strings.Split(excludedDirs, `,`)\n\twatcher := watch.NewWatcher(working, depth, nap, watcherInput, watcherOutput, watchedSuffixes, excludedDirItems)\n\n\tparser := parser.NewParser(parser.ParsePackageResults)\n\ttester := executor.NewConcurrentTester(shell)\n\ttester.SetBatchSize(parallelPackages)\n\n\tlongpollChan := make(chan chan string)\n\texecutor := executor.NewExecutor(tester, parser, longpollChan)\n\tserver := api.NewHTTPServer(working, watcherInput, executor, longpollChan)\n\tlistener := createListener()\n\tgo runTestOnUpdates(watcherOutput, executor, server)\n\tgo watcher.Listen()\n\tif autoLaunchBrowser {\n\t\tgo launchBrowser(listener.Addr().String())\n\t}\n\tsrv := serveHTTP(reports, server, listener)\n\n\t<-done\n\tlog.Println(\"shutting down\")\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel()\n\tif err := srv.Shutdown(ctx); err != nil {\n\t\tlog.Printf(\"failed to shutdown: %s\\n\", err)\n\t}\n}\n\nfunc printHeader() {\n\tlog.Println(\"GoConvey server: \")\n\tserverVersion := \"<unknown>\"\n\tif binfo, ok := debug.ReadBuildInfo(); ok {\n\t\tserverVersion = binfo.Main.Version\n\t}\n\tlog.Println(\"  version:\", serverVersion)\n\tlog.Println(\"  host:\", host)\n\tlog.Println(\"  port:\", port)\n\tlog.Println(\"  poll:\", nap)\n\tlog.Println(\"  cover:\", cover)\n\tlog.Println()\n}\n\nfunc browserCmd() (string, bool) {\n\tbrowser := map[string]string{\n\t\t\"darwin\":  \"open\",\n\t\t\"linux\":   \"xdg-open\",\n\t\t\"windows\": \"start\",\n\t}\n\tcmd, ok := browser[runtime.GOOS]\n\treturn cmd, ok\n}\n\nfunc launchBrowser(addr string) {\n\tbrowser, ok := browserCmd()\n\tif !ok {\n\t\tlog.Printf(\"Skipped launching browser for this OS: %s\", runtime.GOOS)\n\t\treturn\n\t}\n\n\tlog.Printf(\"Launching browser on %s\", addr)\n\turl := fmt.Sprintf(\"http://%s\", addr)\n\tcmd := exec.Command(browser, url)\n\n\toutput, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\tlog.Println(string(output))\n}\n\nfunc runTestOnUpdates(queue chan messaging.Folders, executor contract.Executor, server contract.Server) {\n\tfor update := range queue {\n\t\tlog.Println(\"Received request from watcher to execute tests...\")\n\t\tpackages := extractPackages(update)\n\t\toutput := executor.ExecuteTests(packages)\n\t\troot := extractRoot(update, packages)\n\t\tserver.ReceiveUpdate(root, output)\n\t}\n}\n\nfunc extractPackages(folderList messaging.Folders) []*contract.Package {\n\tpackageList := []*contract.Package{}\n\tfor _, folder := range folderList {\n\t\tif isInsideTestdata(folder) {\n\t\t\tcontinue\n\t\t}\n\t\thasImportCycle := testFilesImportTheirOwnPackage(folder.Path)\n\t\tpackageName := resolvePackageName(folder.Path)\n\t\tpackageList = append(\n\t\t\tpackageList,\n\t\t\tcontract.NewPackage(folder, packageName, hasImportCycle),\n\t\t)\n\t}\n\treturn packageList\n}\n\n// For packages that operate on Go source code files, such as Go tooling, it is\n// important to have a location that will not be considered part of package\n// source to store those files. The official Go tooling selected the testdata\n// folder for this purpose, so we need to ignore folders inside testdata.\nfunc isInsideTestdata(folder *messaging.Folder) bool {\n\trelativePath, err := filepath.Rel(folder.Root, folder.Path)\n\tif err != nil {\n\t\t// There should never be a folder that's not inside the root, but if\n\t\t// there is, we can presumably count it as outside a testdata folder as\n\t\t// well\n\t\treturn false\n\t}\n\n\tfor _, directory := range strings.Split(filepath.ToSlash(relativePath), \"/\") {\n\t\tif directory == \"testdata\" {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc extractRoot(folderList messaging.Folders, packageList []*contract.Package) string {\n\tpath := packageList[0].Path\n\tfolder := folderList[path]\n\treturn folder.Root\n}\n\nfunc createListener() net.Listener {\n\tl, err := net.Listen(\"tcp\", fmt.Sprintf(\"%s:%d\", host, port))\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\tif l == nil {\n\t\tos.Exit(1)\n\t}\n\treturn l\n}\n\n//go:embed web/client\nvar static embed.FS\n\nfunc serveHTTP(reports string, server contract.Server, listener net.Listener) *http.Server {\n\twebclient, err := fs.Sub(static, \"web/client\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\thttp.Handle(\"/\", http.FileServer(http.FS(webclient)))\n\n\thttp.HandleFunc(\"/watch\", server.Watch)\n\thttp.HandleFunc(\"/ignore\", server.Ignore)\n\thttp.HandleFunc(\"/reinstate\", server.Reinstate)\n\thttp.HandleFunc(\"/latest\", server.Results)\n\thttp.HandleFunc(\"/execute\", server.Execute)\n\thttp.HandleFunc(\"/status\", server.Status)\n\thttp.HandleFunc(\"/status/poll\", server.LongPollStatus)\n\thttp.HandleFunc(\"/pause\", server.TogglePause)\n\n\thttp.Handle(\"/reports/\", http.StripPrefix(\"/reports/\", http.FileServer(http.Dir(reports))))\n\n\tlog.Printf(\"Serving HTTP at: http://%s\\n\", listener.Addr())\n\tret := &http.Server{}\n\tgo func() {\n\t\terr := ret.Serve(listener)\n\t\tif err != nil {\n\t\t\tlog.Println(err)\n\t\t}\n\t}()\n\treturn ret\n}\n\nfunc exists(path string) (bool, error) {\n\t_, err := os.Stat(path)\n\tif err == nil {\n\t\treturn true, nil\n\t}\n\tif os.IsNotExist(err) {\n\t\treturn false, nil\n\t}\n\treturn false, err\n}\n\nfunc getWorkDir() string {\n\tworking := \"\"\n\tvar err error\n\tif workDir != \"\" {\n\t\tworking = workDir\n\t} else {\n\t\tworking, err = os.Getwd()\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t}\n\tresult, err := exists(working)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tif !result {\n\t\tlog.Fatalf(\"Path:%s does not exists\", working)\n\t}\n\treturn working\n}\n\nvar (\n\tport              int\n\thost              string\n\tgobin             string\n\tnap               time.Duration\n\tparallelPackages  int\n\tcover             bool\n\tdepth             int\n\ttimeout           string\n\twatchedSuffixes   string\n\texcludedDirs      string\n\tautoLaunchBrowser bool\n\tleakTemp          bool\n\n\tquarterSecond = time.Millisecond * 250\n\tworkDir       string\n)\n\nconst (\n\tseparator = string(filepath.Separator)\n\tendGoPath = separator + \"src\" + separator\n)\n\n// This method exists because of a bug in the go cover tool that\n// causes an infinite loop when you try to run `go test -cover`\n// on a package that has an import cycle defined in one of it's\n// test files. Yuck.\nfunc testFilesImportTheirOwnPackage(packagePath string) bool {\n\tmeta, err := packages.Load(\n\t\t&packages.Config{\n\t\t\tMode:  packages.NeedName | packages.NeedImports,\n\t\t\tTests: true,\n\t\t},\n\t\tpackagePath,\n\t)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\ttestPackageID := fmt.Sprintf(\"%s [%s.test]\", meta[0], meta[0])\n\n\tfor _, testPackage := range meta[1:] {\n\t\tif testPackage.ID != testPackageID {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor dependency := range testPackage.Imports {\n\t\t\tif dependency == meta[0].PkgPath {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\tbreak\n\t}\n\treturn false\n}\n\nfunc resolvePackageName(path string) string {\n\tpkg, err := packages.Load(\n\t\t&packages.Config{\n\t\t\tMode: packages.NeedName,\n\t\t},\n\t\tpath,\n\t)\n\tif err == nil {\n\t\treturn pkg[0].PkgPath\n\t}\n\n\tnameArr := strings.Split(path, endGoPath)\n\treturn nameArr[len(nameArr)-1]\n}\n"
  },
  {
    "path": "web/client/composer.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n\t\t<title>GoConvey Composer</title>\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"/resources/css/composer.css\">\n\t\t<script src=\"/resources/js/lib/markup.js\"></script>\n\t\t<script src=\"/resources/js/lib/taboverride.js\"></script>\n\t\t<script src=\"/resources/js/lib/jquery.js\"></script>\n\t\t<script src=\"/resources/js/composer.js\"></script>\n\t</head>\n\t<body>\n\t\t<header>\n\t\t\t<h1>\n\t\t\t\t<span class=\"logo\">GoConvey</span>\n\t\t\t\t<span class=\"afterlogo\">Composer</span>\n\t\t\t</h1>\n\t\t</header>\n\t\t<main>\n\t\t\t<textarea id=\"input\" placeholder=\"Type test cases here, one per line, with tab indentation\"></textarea>\n\t\t\t<div id=\"output\"></div>\n\t\t</main>\n\n<script id=\"tpl-convey\" type=\"text/template\">{{.}}{{if .|notTestFunc}}{{depth|indent}}Convey(\"{{title}}\", {{if showT}}t, {{/if}}{{if stories|empty}}nil{{else}}func() {\n\n{{stories|recursivelyRender}}{{depth|indent}}}{{/if}})\n{{else}}func {{title|properCase|safeFunc}}(t *testing.T) {\n\n{{stories|recursivelyRender}}}\n{{/if}}\n{{/.}}</script>\n\n\n\t</body>\n</html>"
  },
  {
    "path": "web/client/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<title>GoConvey</title>\n\t\t<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n\t\t<link rel=\"stylesheet\" href=\"/resources/fonts/FontAwesome/css/font-awesome.css\">\n\t\t<link rel=\"stylesheet\" href=\"/resources/css/tipsy.css\">\n\t\t<link rel=\"stylesheet\" href=\"/resources/css/common.css\">\n\t\t<link rel=\"icon\" class=\"favicon\" href=\"/favicon.ico\" type=\"image/vnd.microsoft.icon\">\n\t\t<link rel=\"shortcut icon\" class=\"favicon\" href=\"/favicon.ico\" type=\"image/vnd.microsoft.icon\">\n\t\t<script src=\"/resources/js/lib/markup.js\"></script>\n\t\t<script src=\"/resources/js/lib/moment.js\"></script>\n\t\t<script src=\"/resources/js/lib/ansispan.js\"></script>\n\t\t<script src=\"/resources/js/lib/diff_match_patch.js\"></script>\n\t\t<script src=\"/resources/js/lib/jquery.js\"></script>\n\t\t<script src=\"/resources/js/lib/jquery-ui.js\"></script>\n\t\t<script src=\"/resources/js/lib/jquery.pretty-text-diff.js\"></script>\n\t\t<script src=\"/resources/js/lib/jquery.tipsy.js\"></script>\n\n\t\t<!-- Script ordering is important -->\n\t\t<script src=\"/resources/js/poller.js\"></script>\n\t\t<script src=\"/resources/js/convey.js\"></script>\n\t\t<script src=\"/resources/js/config.js\"></script>\n\t\t<script src=\"/resources/js/goconvey.js\"></script>\n\t</head>\n\t<body>\n\t\t<header>\n\t\t\t<div class=\"overall ok\">\n\t\t\t\t<div class=\"status\">PASS</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"toggler narrow\" data-toggle=\"controls\">\n\t\t\t\tControls\n\t\t\t</div>\n\n\t\t\t<div id=\"controls\" class=\"controls hide-narrow\">\n\t\t\t\t<div class=\"server-not-down\">\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li id=\"logo\" title=\"Powered by GoConvey\"><a href=\"https://github.com/smartystreets/goconvey\" target=\"_blank\">GoConvey</a></li>\n\t\t\t\t\t</ul>\n\n\t\t\t\t\t<div class=\"float-left\" id=\"path-container\">\n\t\t\t\t\t\t<input type=\"text\" id=\"path\" placeholder=\"Watched directory\" title=\"Change watched directory\">\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<ul class=\"float-right\" id=\"control-buttons\">\n\t\t\t\t\t\t<li class=\"fa fa-pause\" id=\"play-pause\" title=\"Play/pause tests\"></li>\n\t\t\t\t\t\t<li class=\"fa fa-refresh\" id=\"run-tests\" title=\"Run tests\"></li>\n\t\t\t\t\t\t<li class=\"fa fa-history\" id=\"show-history\" title=\"Test history\"></li>\n\t\t\t\t\t\t<li class=\"fa fa-bell-o\" id=\"toggle-notif\" title=\"Toggle notifications\"></li>\n\t\t\t\t\t\t<li class=\"fa fa-cog\" id=\"show-settings\" title=\"Settings\"></li>\n\t\t\t\t\t\t<li class=\"fa fa-pencil-square-o\" id=\"show-gen\" title=\"Composer\"></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"server-down\">\n\t\t\t\t\t<span class=\"flash\">NOTICE:</span>\n\t\t\t\t\t<span class=\"notice-message\"><!-- Populated by Javascript --></span>\n\t\t\t\t</div>\n\n\t\t\t\t<hr class=\"clear\">\n\n\n\t\t\t\t<div class=\"expandable settings settings-general\">\n\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t<div class=\"setting\">\n\t\t\t\t\t\t\t<div class=\"setting-meta\">\n\t\t\t\t\t\t\t\tTheme\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"setting-val\">\n\t\t\t\t\t\t\t\t<ol class=\"enum\" id=\"theme\"><!-- Populated by Javascript --></ol>\n\t\t\t\t\t\t\t\t<script id=\"tpl-theme-enum\" type=\"text/template\">\n\t\t\t\t\t\t\t\t\t{{.}}<li data-theme=\"{{id}}\">{{name}}</li>{{/.}}\n\t\t\t\t\t\t\t\t</script>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"setting\">\n\t\t\t\t\t\t\t<div class=\"setting-meta\">\n\t\t\t\t\t\t\t\tDefault\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"setting-val\">\n\t\t\t\t\t\t\t\t<ol class=\"enum\" id=\"pkg-expand-collapse\">\n\t\t\t\t\t\t\t\t\t<li data-pkg-expand-collapse=\"expanded\">Expand All</li>\n\t\t\t\t\t\t\t\t\t<li data-pkg-expand-collapse=\"collapsed\">Collapse All</li>\n\t\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"setting\">\n\t\t\t\t\t\t\t<div class=\"setting-meta\">\n\t\t\t\t\t\t\t\tDebug Output\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"setting-val\">\n\t\t\t\t\t\t\t\t<ol class=\"enum\" id=\"show-debug-output\">\n\t\t\t\t\t\t\t\t\t<li data-show-debug-output=\"show\">All</li>\n\t\t\t\t\t\t\t\t\t<li data-show-debug-output=\"fail\">Failed</li>\n\t\t\t\t\t\t\t\t\t<li data-show-debug-output=\"hide\">None</li>\n\t\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"setting\">\n\t\t\t\t\t\t\t<div class=\"setting-meta\">\n\t\t\t\t\t\t\t\tEffects\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"setting-val\">\n\t\t\t\t\t\t\t\t<ol class=\"enum\" id=\"ui-effects\">\n\t\t\t\t\t\t\t\t\t<li data-ui-effects=\"true\">Cinematic</li>\n\t\t\t\t\t\t\t\t\t<li data-ui-effects=\"false\">Off</li>\n\t\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"expandable history\">\n\t\t\t\t\t<div class=\"container\"><!-- Populated by Javascript --></div>\n\t\t\t\t\t<script id=\"tpl-history\" type=\"text/template\">\n\t\t\t\t\t\t<div class=\"item {{overall.status.class}} frame-{{id}}\" data-frameid=\"{{id}}\">\n\t\t\t\t\t\t\t<div class=\"status momentjs\" id=\"frame-{{id}}\"></div>\n\t\t\t\t\t\t\t<div class=\"summary\">{{overall.status.text|upcase}}<br>{{overall.passed}}/{{overall.assertions}} pass<br>{{overall.failures}} fail, {{overall.skipped}} skip</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</script>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"expandable settings settings-notification\">\n\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t<div class=\"setting\">\n\t\t\t\t\t\t\t<div class=\"setting-meta\">\n\t\t\t\t\t\t\t\tNotifications\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"setting-val\">\n\t\t\t\t\t\t\t\t<ol class=\"enum\" id=\"notification\">\n\t\t\t\t\t\t\t\t\t<li data-notification=\"true\">On</li>\n\t\t\t\t\t\t\t\t\t<li data-notification=\"false\">Off</li>\n\t\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"setting\">\n\t\t\t\t\t\t\t<div class=\"setting-meta\">\n\t\t\t\t\t\t\t\tLevel\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"setting-val\">\n\t\t\t\t\t\t\t\t<ol class=\"enum\" id=\"notification-level\">\n\t\t\t\t\t\t\t\t\t<li data-notification-level=\".*\">Always</li>\n\t\t\t\t\t\t\t\t\t<li data-notification-level=\"fail|panic\">Fail or Panic</li>\n\t\t\t\t\t\t\t\t\t<li data-notification-level=\"ok\">Success Only</li>\n\t\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\n\t\t\t</div>\n\t\t</header>\n\n\n\n\n\n\n\t\t<div class=\"frame cf\">\n\n\n\t\t\t<div class=\"col\" id=\"col-1\">\n\t\t\t\t<div class=\"toggler\" data-toggle=\"coverage\">\n\t\t\t\t\tCoverage\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable\" id=\"coverage\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-coverage\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t<div class=\"pkg-cover\">\n\t\t\t\t\t\t\t<div class=\"pkg-cover-bar\" data-pkg=\"{{PackageName}}\" data-width=\"{{Coverage|coveragePct}}\"></div>\n\t\t\t\t\t\t\t<div class=\"pkg-cover-name rtl pad-right{{if Coverage|coveragePct|equals>0}} no-coverage{{/if}}\" title=\"{{Coverage|coveragePct}}% coverage\">\n\t\t\t\t\t\t\t\t<a class=\"fa fa-level-down\" href=\"#pkg-{{_id}}\" style=\"padding: 0 5px;\"></a>{{if Coverage|more>0}}<a href=\"/reports/{{PackageName|coverageReportName}}.html\" target=\"_blank\">{{PackageName|boldPkgName}}</a>{{else}}{{PackageName|boldPkgName}}{{/if}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\n\n\n\t\t\t\t<div class=\"toggler\" data-toggle=\"ignored\">\n\t\t\t\t\tIgnored\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable\" id=\"ignored\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-ignored\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t<div class=\"rtl pkg-list\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<a class=\"fa fa-level-down\" href=\"#pkg-{{_id}}\" style=\"padding: 0 5px;\"></a>{{PackageName|boldPkgName}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\n\n\t\t\t\t<div class=\"toggler\" data-toggle=\"notestfn\">\n\t\t\t\t\tNo Test Functions\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable\" id=\"notestfn\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-notestfn\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t<div class=\"rtl pkg-list\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t\t{{PackageName|boldPkgName}}<br>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\n\n\t\t\t\t<div class=\"toggler\" data-toggle=\"notestfiles\">\n\t\t\t\t\tNo Test Files\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable\" id=\"notestfiles\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-notestfiles\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t<div class=\"rtl pkg-list\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t\t{{PackageName|boldPkgName}}<br>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\n\n\n\t\t\t\t<div class=\"toggler\" data-toggle=\"nogofiles\">\n\t\t\t\t\tNo Go Files\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable\" id=\"nogofiles\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-nogofiles\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t<div class=\"rtl pkg-list\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t\t{{PackageName|boldPkgName}}<br>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\t\t\t</div>\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t<div class=\"col\" id=\"col-2\">\n\n\t\t\t\t<div class=\"toggler buildfailures\" data-toggle=\"buildfailures\">\n\t\t\t\t\tBuild Failures\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable buildfailures\" id=\"buildfailures\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-buildfailures\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t<div class=\"buildfail\">\n\t\t\t\t\t\t\t<div class=\"buildfail-pkg\"><i class=\"fa fa-wrench\"></i>&nbsp; {{PackageName|boldPkgName}}</div>\n\t\t\t\t\t\t\t<div class=\"buildfail-output\">{{BuildOutput|htmlSafe|ansiColours}}</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\n\n\n\t\t\t\t<div class=\"toggler panics\" data-toggle=\"panics\">\n\t\t\t\t\tPanics\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable panics\" id=\"panics\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-panics\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t<div class=\"panic\">\n\t\t\t\t\t\t\t<div class=\"panic-pkg\">\n\t\t\t\t\t\t\t\t<i class=\"fa fa-bomb\"></i>&nbsp; {{_pkg|boldPkgName}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"panic-details\">\n\t\t\t\t\t\t\t<div class=\"panic-story\">\n\t\t\t\t\t\t\t<div class=\"panic-file\">\n\t\t\t\t\t\t\t\t{{if File|notempty}}\n\t\t\t\t\t\t\t\t<a href=\"goconvey://open/?url=file://{{File|url}}&line={{Line}}\">{{File|relativePath}}{{if Line|more>0}}:{{Line}}{{/if}}&nbsp; <i class=\"fa fa-external-link\"></i></a>\n\t\t\t\t\t\t\t\t{{else}}\n\t\t\t\t\t\t\t\t<b>{{TestName}}</b>\n\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{{if _path|notempty}}\n\t\t\t\t\t\t{{_path}}\n\t\t\t\t\t\t\t<div class=\"story-links{{if Depth|more>-1}} depth-{{Depth}}{{/if}}\"><a href=\"#test-{{_id}}\">{{Title|htmlSafe|ansiColours}}</a></div>\n\t\t\t\t\t\t{{/_path}}\n\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t{{if StackTrace|notempty}}<div class=\"depth-{{_maxDepth}} panic-summary\">{{Error}}</div>{{/if}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"panic-output\">{{if StackTrace|empty}}{{Error|htmlSafe|ansiColours}}{{else}}{{StackTrace|htmlSafe|ansiColours}}{{/if}}</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\n\n\n\n\t\t\t\t<div class=\"toggler failures\" data-toggle=\"failures\">\n\t\t\t\t\tFailures\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable failures\" id=\"failures\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-failures\" type=\"text/template\">\n\t\t\t\t\t<div class=\"templated\">\n\t\t\t\t\t\t{{.}}\n\t\t\t\t\t\t<div class=\"failure\">\n\t\t\t\t\t\t\t<div class=\"failure-pkg\"><i class=\"fa fa-file-code-o\"></i>&nbsp; {{_pkg|boldPkgName}}</div>\n\t\t\t\t\t\t\t<div class=\"failure-details\">\n\t\t\t\t\t\t\t\t<div class=\"failure-story\">\n\t\t\t\t\t\t\t\t\t<div class=\"failure-file\">\n\t\t\t\t\t\t\t\t\t\t{{if File|notempty}}\n\t\t\t\t\t\t\t\t\t\t<a href=\"goconvey://open/?url=file://{{File|url}}&line={{Line}}\">{{File|relativePath}}{{if Line|more>0}}:{{Line}}{{/if}}&nbsp; <i class=\"fa fa-external-link\"></i></a>\n\t\t\t\t\t\t\t\t\t\t{{else}}\n\t\t\t\t\t\t\t\t\t\t<b class=\"test-name-link\"><a href=\"#test-{{_id}}\">{{TestName}}</a></b>\n\t\t\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{{if _path|notempty}}\n\t\t\t\t\t\t\t\t{{_path}}\n\t\t\t\t\t\t\t\t\t<div class=\"story-links{{if Depth|more>-1}} depth-{{Depth}}{{/if}}\"><a href=\"#test-{{_id}}\">{{Title|htmlSafe|ansiColours}}</a></div>\n\t\t\t\t\t\t\t\t{{/_path}}\n\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"failure-output\">{{if Failure|notempty}}{{Failure|htmlSafe|ansiColours}}{{else}}{{if Message|notempty}}{{Message|htmlSafe|ansiColours}}{{else}}{{StackTrace|htmlSafe|ansiColours}}{{/if}}{{/if}}</div>\n\t\t\t\t\t\t\t\t{{if .|needsDiff}}\n\t\t\t\t\t\t\t\t<table class=\"diffviewer\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td class=\"exp\">Expected</td>\n\t\t\t\t\t\t\t\t\t\t<td class=\"original\">{{Expected|htmlSafe|ansiColours}}</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td class=\"act\">Actual</td>\n\t\t\t\t\t\t\t\t\t\t<td class=\"changed\">{{Actual|htmlSafe|ansiColours}}</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td>Diff</td>\n\t\t\t\t\t\t\t\t\t\t<td class=\"diff\"></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{/.}}\n\t\t\t\t\t</div>\n\t\t\t\t</script>\n\n\n\n\n\t\t\t\t<div class=\"toggler stories\" data-toggle=\"stories\">\n\t\t\t\t\tStories\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable stories\" id=\"stories\"><!-- Populated by Javascript --></div>\n\n\t\t\t\t<script id=\"tpl-stories\" type=\"text/template\">\n\t\t\t\t\t<table>\n\t\t\t\t\t{{.}}\n\t\t\t\t\t\t<tr class=\"story-pkg expanded pkg-{{_id}}\" data-pkg=\"{{_id}}\" data-pkg-name=\"{{PackageName}}\" data-pkg-state=\"expanded\" id=\"pkg-{{_id}}\">\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<span class=\"pkg-toggle-container\">\n\t\t\t\t\t\t\t\t\t<a href=\"javascript:\" class=\"fa fa-minus-square-o pkg-toggle\"></a>\n\t\t\t\t\t\t\t\t\t<span class=\"toggle-all-pkg\">ALL</span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"story-pkg-name\">\n\t\t\t\t\t\t\t\t{{PackageName|boldPkgName}}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"story-pkg-summary\">\n\t\t\t\t\t\t\t\t{{if _panicked|more>0}}<span class=\"story-pkg-panic-count\"><span class=\"statusicon panic\"><i class=\"fa fa-bolt\"></i></span> {{_panicked}}\n\t\t\t\t\t\t\t\t&nbsp;</span>{{/if}}\n\t\t\t\t\t\t\t\t{{if _failed|more>0}}<span class=\"story-pkg-failure-count\"><span class=\"statusicon fail\">&#10007;</span> {{_failed}}\n\t\t\t\t\t\t\t\t&nbsp;</span>{{/if}}\n\t\t\t\t\t\t\t\t{{if _passed|more>0}}<span class=\"story-pkg-pass-count\"><span class=\"statusicon ok\">&#10003;</span> {{_passed}}</span>{{/if}}\n\t\t\t\t\t\t\t\t{{if _skipped|more>0}}<span class=\"story-pkg-skip-count\">&nbsp; <span class=\"statusicon skip\"><b>S</b></span> {{_skipped}}</span>{{/if}}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"story-pkg-watch-td\">\n\t\t\t\t\t\t\t\t{{if Outcome|equals>disabled}}\n\t\t\t\t\t\t\t\t<span class=\"fa fa-lg fa-eye-slash disabled\" title=\"Disabled\"></span>\n\t\t\t\t\t\t\t\t{{else}}\n\t\t\t\t\t\t\t\t<a class=\"fa fa-lg ignore {{if Outcome|notequals>ignored}}fa-eye unwatch{{else}}fa-eye-slash watch clr-red{{/if}}\" href=\"javascript:\" title=\"Toggle ignore\" data-pkg=\"{{PackageName}}\"></a>\n\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t{{TestResults}}\n\t\t\t\t\t\t<tr id=\"test-{{_id}}\" class=\"story-line {{if _status.class}}{{_status.class}}{{else}}skip{{/if}} test-{{_id}} pkg-{{_pkgid}}\">\n\t\t\t\t\t\t\t<td class=\"story-line-status\"></td>\n\t\t\t\t\t\t\t<td class=\"story-line-summary-container\">\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{{if Stories|empty}} <!-- Not apparently a GoConvey test -->\n\t\t\t\t\t\t\t\t\t\t{{if _passed}}<span class=\"statusicon ok\">&#10003;</span><br>{{/if}}\n\t\t\t\t\t\t\t\t\t\t{{if _failed}}<span class=\"statusicon fail\">&#10007;</span><br>{{/if}}\n\t\t\t\t\t\t\t\t\t\t{{if _panicked}}<span class=\"statusicon panic\"><i class=\"fa fa-bolt\"></i></span><br>{{/if}}\n\t\t\t\t\t\t\t\t\t\t{{if _skipped}}<span class=\"statusicon skip\"><b>S</b></span><br>{{/if}}\n\t\t\t\t\t\t\t\t\t{{/if}}\n\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td colspan=\"3\" class=\"depth-0 story-line-desc\">\n\t\t\t\t\t\t\t\t<b>{{TestName|htmlSafe|ansiColours}}</b>\n\t\t\t\t\t\t\t\t{{if Message}}<div class=\"message\">{{Message|htmlSafe|ansiColours}}</div>{{/if}}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\n\n\t\t\t\t\t\t\t{{Stories}}\n\t\t\t\t\t\t\t<tr class=\"story-line {{if _status.class}}{{_status.class}}{{else}}skip{{/if}} pkg-{{_pkgid}}\"  id=\"test-{{_id}}\">\n\t\t\t\t\t\t\t\t<td class=\"story-line-status\"></td>\n\t\t\t\t\t\t\t\t<td class=\"story-line-summary-container\">\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{{if _passed}}<span class=\"statusicon ok\">&#10003; {{_passed}}</span><br>{{/if}}\n\t\t\t\t\t\t\t\t\t{{if _failed}}<span class=\"statusicon fail\">&#10007; {{_failed}}</span><br>{{/if}}\n\t\t\t\t\t\t\t\t\t{{if _panicked}}<span class=\"statusicon panic\"><i class=\"fa fa-bolt\"></i> {{_panicked}}</span><br>{{/if}}\n\t\t\t\t\t\t\t\t\t{{if _skipped}}<span class=\"statusicon skip\"><b>S</b> {{_skipped}}</span><br>{{/if}}\n\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td colspan=\"3\" class=\"depth-{{Depth}} story-line-desc\">\n\t\t\t\t\t\t\t\t\t{{Title|htmlSafe|ansiColours}}\n\t\t\t\t\t\t\t\t\t{{if Output}}<div class=\"message\">{{Output|htmlSafe|ansiColours}}</div>{{/if}}\n\t\t\t\t\t\t\t\t\t{{if _failed}}\n\t\t\t\t\t\t\t\t\t\t{{Assertions}}\n\t\t\t\t\t\t\t\t\t\t\t{{if _failed}}\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"failure\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"failure-details\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"failure-output\">{{if Failure|notempty}}{{Failure|htmlSafe|ansiColours}}{{else}}{{if Message|notempty}}{{Message|htmlSafe|ansiColours}}{{else}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{StackTrace|htmlSafe|ansiColours}}{{/if}}{{/if}}</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t\t\t\t{{/Assertions}}\n\t\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t\t\t{{if _panicked}}\n\t\t\t\t\t\t\t\t\t\t{{Assertions}}\n\t\t\t\t\t\t\t\t\t\t\t{{if _panicked}}\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"panic\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"panic-details\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"panic-output\">{{if Panic|notempty}}{{Panic|htmlSafe|ansiColours}}{{else}}{{if Message|notempty}}{{Message|htmlSafe|ansiColours}}{{else}}{{StackTrace|htmlSafe|ansiColours}}{{/if}}{{/if}}</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t\t\t\t{{/Assertions}}\n\t\t\t\t\t\t\t\t\t{{/if}}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t{{/Stories}}\n\n\n\t\t\t\t\t\t{{/TestResults}}\n\t\t\t\t\t{{/.}}\n\t\t\t\t\t</table>\n\t\t\t\t</script>\n\t\t\t</div>\n\n\n\n\t\t\t<div class=\"col\" id=\"col-3\">\n\t\t\t\t<div class=\"toggler\" data-toggle=\"log\">\n\t\t\t\t\tLOG\n\t\t\t\t</div>\n\t\t\t\t<div class=\"togglable log\" id=\"log\"><!-- Populated by Javascript --></div>\n\t\t\t\t<script id=\"tpl-log-line\" type=\"text/template\">\n\t\t\t\t\t<div class=\"line\"><span class=\"timestamp\">[{{time}}]</span> {{msg|clean}}</div>\n\t\t\t\t</script>\n\t\t\t</div>\n\n\t\t</div>\n\n\t\t<footer>\n\t\t\t<section>\n\t\t\t\t<span id=\"summary\">\n\t\t\t\t\t<span class=\"info\" id=\"time\"><!-- Populated by Javascript --></span>\n\t\t\t\t\t<span class=\"info\" id=\"last-test-container\">Last test <span id=\"last-test\"><!-- Populated by Javascript --></span></span>\n\t\t\t\t\t<span class=\"info\" id=\"assert-count\"><!-- Populated by Javascript --></span>\n\t\t\t\t\t<span class=\"info fail-clr\" id=\"fail-count\"><!-- Populated by Javascript --></span>\n\t\t\t\t\t<span class=\"info panic-clr\" id=\"panic-count\"><!-- Populated by Javascript --></span>\n\t\t\t\t\t<span class=\"info skip-clr\" id=\"skip-count\"><!-- Populated by Javascript --></span>\n\t\t\t\t\t<span class=\"momentjs\" id=\"duration\"><!-- Populated by Javascript --></span>\n\t\t\t\t</span>\n\t\t\t\t<span id=\"narrow-summary\">\n\t\t\t\t\t<span id=\"narrow-assert-count\"><!-- Populated by Javascript --></span>:\n\t\t\t\t\t<span class=\"fail-clr\" id=\"narrow-fail-count\"><!-- Populated by Javascript --></span> /\n\t\t\t\t\t<span class=\"panic-clr\" id=\"narrow-panic-count\"><!-- Populated by Javascript --></span> /\n\t\t\t\t\t<span class=\"skip-clr\" id=\"narrow-skip-count\"><!-- Populated by Javascript --></span>\n\t\t\t\t</span>\n\t\t\t</section>\n\t\t\t<section>\n\t\t\t\t<span class=\"server-not-down\">\n\t\t\t\t\t<span class=\"recording\">\n\t\t\t\t\t\t<i class=\"fa fa-circle\"></i> LIVE\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"replay\" title=\"Click for current test results\">\n\t\t\t\t\t\t<i class=\"fa fa-play\"></i> REPLAY\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"paused\">\n\t\t\t\t\t\t<i class=\"fa fa-pause\"></i> PAUSED\n\t\t\t\t\t</span>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"server-down\">\n\t\t\t\t\t<i class=\"fa fa-exclamation-triangle fa-lg flash\"></i>\n\t\t\t\t\t<span class=\"notice-message\"><!-- Populated by Javascript --></span>\n\t\t\t\t</span>\n\t\t\t</section>\n\t\t</footer>\n\n\t</body>\n</html>\n"
  },
  {
    "path": "web/client/resources/css/common.css",
    "content": "/* Eric Meyer's Reset CSS v2.0 */\nhtml,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tsrc: local(\"Open Sans\"), url(\"../fonts/Open_Sans/OpenSans-Regular.ttf\");\n}\n@font-face {\n\tfont-family: 'Orbitron';\n\tsrc: local(\"Orbitron\"), url(\"../fonts/Orbitron/Orbitron-Regular.ttf\");\n}\n@font-face {\n\tfont-family: 'Oswald';\n\tsrc: local(\"Oswald\"), url(\"../fonts/Oswald/Oswald-Regular.ttf\");\n}\n\n::selection {\n\tbackground: #87AFBC;\n\tcolor: #FFF;\n\ttext-shadow: none;\n}\n\n::-moz-selection {\n\tbackground: #87AFBC;\n\tcolor: #FFF;\n\ttext-shadow: none;\n}\n\n::-webkit-input-placeholder {\n\tfont-style: italic;\n}\n:-moz-placeholder {\n\tfont-style: italic;\n}\n::-moz-placeholder {\n\tfont-style: italic;\n}\n:-ms-input-placeholder {\n\tfont-style: italic;\n}\n\n\n\nhtml, body {\n\theight: 100%;\n\tmin-height: 100%;\n}\n\nbody {\n\t-webkit-transform: translate3d(0, 0, 0);\t/* attempts to fix Chrome glitching on Mac */\n\tbackground-position: fixed;\n\tbackground-repeat: no-repeat;\n\tfont-family: Menlo, Monaco, 'Courier New', monospace;\n\tline-height: 1.5em;\n\tfont-size: 14px;\n\toverflow: hidden;\n\tdisplay: none;\n}\n\na {\n\ttext-decoration: none;\n}\n\na:hover {\n\ttext-decoration: underline;\n}\n\na.fa {\n\ttext-decoration: none;\n}\n\nb {\n\tfont-weight: bold;\n}\n\ni {\n\tfont-style: italic;\n}\n\nhr {\n\tborder: 0;\n\tbackground: 0;\n\theight: 0;\n\tmargin: 0;\n\tpadding: 0;\n}\n\ninput[type=text] {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\n\tbackground: none;\n\tborder: none;\n\tborder-bottom-width: 1px;\n\tborder-bottom-style: solid;\n\toutline: none;\n\tpadding-bottom: .1em;\n\tfont: 300 18px/1.5em 'Open Sans', sans-serif;\n}\n\n.overall {\n\tpadding: 30px 0 15px;\n\tposition: relative;\n\tz-index: 50;\n}\n\n.status {\n\tline-height: 1em;\n\tfont-family: 'Orbitron', monospace;\n\ttext-align: center;\n}\n\n.overall .status {\n\tfont-size: 46px;\n\tletter-spacing: 5px;\n\ttext-transform: uppercase;\n\twhite-space: nowrap;\n}\n\n.toggler {\n\tfont-size: 10px;\n\tpadding: 3px 5px;\n\ttext-decoration: none;\n\ttext-transform: uppercase;\n\tcursor: pointer;\n\tline-height: 1.5em;\n}\n\n.toggler.narrow {\n\tdisplay: none;\n}\n\n.togglable {\n\toverflow-x: auto;\n}\n\n.controls {\n\tfont-size: 18px;\n\tline-height: 1em;\n}\n\n.controls li {\n\ttext-decoration: none;\n\tdisplay: block;\n\tfloat: left;\n\tpadding: .75em;\n\tcursor: pointer;\n}\n\n.server-down {\n\tdisplay: none;\n\ttext-align: center;\n\tpadding: 10px 0;\n}\n\nfooter .server-down {\n\tpadding: 8px 15px;\n\ttext-transform: uppercase;\n}\n\n#logo {\n\tfont-family: 'Oswald', 'Impact', 'Arial Black', sans-serif;\n}\n\n#path-container {\n\tmargin-top: .4em;\n}\n\n#path {\n\twidth: 100%;\n\ttext-align: center;\n\tborder-bottom-width: 0;\n}\n\n#path:hover,\n#path:focus {\n\tborder-bottom-width: 1px;\n}\n\n.expandable {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\n\tborder-top-width: 1px;\n\tborder-top-style: solid;\n\toverflow-y: hidden;\n\toverflow-x: auto;\n\ttext-align: center;\n\twhite-space: nowrap;\n\tdisplay: none;\n}\n\n.settings {\n\twhite-space: normal;\n\toverflow-x: auto;\n\twhite-space: nowrap;\n}\n\n.settings .setting-meta,\n.settings .setting-val {\n\tdisplay: inline-block;\n}\n\n.settings .container {\n\tpadding: 15px 0;\n}\n\n.settings .setting {\n\tfont-size: 13px;\n\tdisplay: inline-block;\n\tmargin-right: 5%;\n}\n\n.settings .setting:first-child {\n\tmargin-left: 5%;\n}\n\n.settings .setting .setting-meta {\n\ttext-align: right;\n\tpadding-right: 1em;\n\tvertical-align: middle;\n\tmax-width: 150px;\n}\n\n.settings .setting .setting-meta small {\n\tfont-size: 8px;\n\ttext-transform: uppercase;\n\tdisplay: block;\n\tline-height: 1.25em;\n}\n\n.history .container {\n\tpadding: 15px 0 15px 25%;\n}\n\n.history .item {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\n\ttransition: all .1s linear;\n\t-moz-transition: all .1s linear;\n\t-webkit-transition: all .1s linear;\n\t-o-transition: all .1s linear;\n\n\tdisplay: inline-block;\n\ttext-align: left;\n\tmargin: 0 20px;\n\tpadding: 20px;\n\theight: 100%;\n\twidth: 175px;\n\topacity: .7;\n\tcursor: pointer;\n}\n\n.history .item:hover {\n\topacity: 1;\n}\n\n.history .item:nth-child(odd):hover {\n\t-webkit-transform: scale(1.1) rotate(5deg);\n\t-moz-transform: scale(1.1) rotate(5deg);\n}\n\n.history .item:nth-child(even):hover {\n\t-webkit-transform: scale(1.1) rotate(-5deg);\n\t-moz-transform: scale(1.1) rotate(-5deg);\n}\n\n.history .item .summary {\n\tfont: 14px/1.5em 'Monaco', 'Menlo', 'Courier New', monospace;\n}\n\n.history .item.selected {\n\topacity: 1;\n}\n\n.history .status {\n\tfont-size: 13px;\n}\n\n\n\n\n\n\n.frame {\n\tposition: relative;\n\tz-index: 0;\n\twidth: 100%;\n}\n\n.frame .col {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\n\tborder-right-width: 1px;\n\tborder-right-style: solid;\n\tfloat: left;\n\theight: 100%;\n\toverflow-y: auto;\n}\n\n.frame .col:first-child {\n\tborder-left: none;\n}\n\n.frame .col:last-child {\n\tborder-right: none;\n}\n\n\n#col-1 {\n\twidth: 15%;\n}\n\n#col-2 {\n\twidth: 60%;\n}\n\n#col-3 {\n\twidth: 25%;\n}\n\n#coverage {\n\tfont-size: 10px;\n\twhite-space: nowrap;\n}\n\n#coverage-color-template {\n\tdisplay: none;\n}\n\n.rtl {\n\tdirection: rtl;\n}\n\n.pkg-cover {\n\tposition: relative;\n}\n\n.pkg-cover a {\n\tcolor: inherit !important;\n\ttext-decoration: none;\n}\n\n.pkg-cover-bar {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\theight: 100%;\n\tz-index: 1;\n}\n\n.pkg-cover-name {\n\tposition: relative;\n\tz-index: 2;\n}\n\n.pkg-cover-name,\n.pkg-list {\n\tfont-family: 'Menlo', monospace;\n\tfont-size: 10px;\n\tpadding-right: 2%;\n\twhite-space: nowrap;\n}\n\n.buildfail-pkg,\n.panic-pkg,\n.failure-pkg {\n\tpadding: 5px 10px;\n\tfont: 14px 'Open Sans', sans-serif;\n}\n\n.buildfail-output,\n.panic-output,\n.failure-output {\n\tpadding: 10px;\n\tfont-size: 12px;\n\tline-height: 1.25em;\n\toverflow-y: auto;\n\twhite-space: pre-wrap;\n\tfont-family: 'Menlo', monospace;\n}\n\n.panic-story,\n.failure-story {\n\tfont-size: 10px;\n\tline-height: 1.25em;\n\tfont-family: 'Open Sans', sans-serif;\n}\n\n.panic-summary {\n\tfont-size: 14px;\n\tfont-weight: bold;\n\tline-height: 1.5em;\n}\n\n.panic-file,\n.failure-file {\n\tfont-size: 13px;\n\tline-height: 1.5em;\n}\n\n.diffviewer {\n\tborder-collapse: collapse;\n\twidth: 100%;\n}\n\n.diffviewer td {\n\tborder-bottom-width: 1px;\n\tborder-bottom-style: solid;\n\tpadding: 2px 5px;\n\tfont-size: 14px;\n}\n\n.diffviewer .original,\n.diffviewer .changed,\n.diffviewer .diff {\n\twhite-space: pre-wrap;\n}\n\n.diffviewer tr:first-child td {\n\tborder-top-width: 1px;\n\tborder-top-style: solid;\n}\n\n.diffviewer td:first-child {\n\twidth: 65px;\n\tfont-size: 10px;\n\tborder-right-width: 1px;\n\tborder-right-style: solid;\n\ttext-transform: uppercase;\n}\n\n.diff ins {\n\ttext-decoration: none;\n}\n\n\n\n#stories table {\n\twidth: 100%;\n}\n\n\n.story-pkg {\n\tcursor: pointer;\n}\n\n.story-pkg td {\n\tfont: 16px 'Open Sans', sans-serif;\n\twhite-space: nowrap;\n\tpadding: 10px;\n}\n\n.story-pkg td:first-child {\n\twidth: 1em;\n}\n\n.story-line {\n\tfont: 12px 'Open Sans', sans-serif;\n\tcursor: default;\n}\n\n.story-line td {\n\tpadding-top: 7px;\n\tpadding-bottom: 7px;\n}\n\n.pkg-toggle-container {\n\tposition: relative;\n\tdisplay: inline-block;\n}\n\n.toggle-all-pkg {\n\tfont-size: 10px;\n\ttext-transform: uppercase;\n\tposition: absolute;\n\tpadding: 5px;\n\tfont-family: 'Menlo', 'Open Sans', sans-serif;\n\tdisplay: none;\n}\n\n.story-line-summary-container {\n\tpadding: 0 10px 0 10px;\n\twhite-space: nowrap;\n\twidth: 35px;\n\ttext-align: center;\n}\n\n.story-line-status {\n\twidth: 6px;\n\tmin-width: 6px;\n\theight: 100%;\n}\n\n.story-line-desc {\n\tpadding: 5px;\n}\n\n.story-line-desc .message {\n\tfont-family: 'Menlo', monospace;\n\twhite-space: pre-wrap;\n}\n\n.statusicon {\n\tfont: 14px 'Open Sans', sans-serif;\n}\n\n.statusicon.skip {\n\tfont-size: 16px;\n}\n\n\n.depth-0 { padding-left: 1.5em !important; }\n.depth-1 { padding-left: 3em !important; }\n.depth-2 { padding-left: 4.5em !important; }\n.depth-3 { padding-left: 6em !important; }\n.depth-4 { padding-left: 7.5em !important; }\n.depth-5 { padding-left: 9em !important; }\n.depth-6 { padding-left: 10.5em !important; }\n.depth-7 { padding-left: 11em !important; }\n\n\n.log {\n\tfont-size: 11px;\n\tline-height: 1.5em;\n\tpadding: 5px;\n\tpadding-bottom: .5em;\n}\n\n.log .line {\n\twhite-space: pre-wrap;\n\tpadding-left: 2em;\n\ttext-indent: -2em;\n}\n\n\n\n\n\nfooter {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 0;\n\tpadding: 5px 15px;\n\twidth: 100%;\n\tborder-top-width: 1px;\n\tborder-top-style: solid;\n\tfont-size: 12px;\n}\n\nfooter section {\n\tfloat: left;\n}\n\nfooter section:first-child {\n\twidth: 80%;\n}\n\nfooter section:last-child {\n\ttext-align: right;\n\twidth: 20%;\n}\n\nfooter .info {\n\tpadding: 0 10px;\n}\n\nfooter .info:first-child {\n\tpadding-left: 0;\n}\n\n#narrow-summary {\n\tdisplay: none;\n}\n\nfooter .replay,\nfooter .paused {\n\tdisplay: none;\n}\n\nfooter .replay {\n\tcursor: pointer;\n}\n\nfooter .server-down .notice-message {\n\tfont-size: 10px;\n}\n\n\n\n\n.rel {\n\tposition: relative;\n}\n\n.text-right {\n\ttext-align: right;\n}\n\n.text-center {\n\ttext-align: center;\n}\n\n.text-left {\n\ttext-align: left;\n}\n\n.float-left {\n\tfloat: left;\n}\n\n.float-right {\n\tfloat: right;\n}\n\n.clear {\n\tclear: both;\n}\n\n.nowrap {\n\twhite-space: nowrap;\n}\n\n.clr-blue {\n\tcolor: #2B597F;\n}\n\n.show {\n\tdisplay: block;\n}\n\n.hide {\n\tdisplay: none;\n}\n\n.enum {\n\tcursor: pointer;\n\tdisplay: inline-block;\n\tfont-size: 12px;\n\tborder-width: 1px;\n\tborder-style: solid;\n\tborder-radius: 9px;\n\tvertical-align: middle;\n}\n\n.enum > li {\n\tdisplay: block;\n\tfloat: left;\n\tpadding: 5px 12px;\n\tborder-left-width: 1px;\n\tborder-left-style: solid;\n}\n\n.enum > li:first-child {\n\tborder-left: 0px;\n\tborder-top-left-radius: 8px;\n\tborder-bottom-left-radius: 8px;\n}\n\n.enum > li:last-child {\n\tborder-top-right-radius: 8px;\n\tborder-bottom-right-radius: 8px;\n}\n\n\n\n\n\n\n\n\n.disabled {\n\tcursor: default !important;\n\tbackground: transparent !important;\n}\n\n.spin-once {\n\t-webkit-animation: fa-spin 0.5s 1 ease;\n\tanimation: fa-spin 0.5s 1 ease;\n}\n\n.spin-slowly {\n\t-webkit-animation: fa-spin .75s infinite linear;\n\tanimation: fa-spin .75s infinite linear;\n}\n\n.throb {\n\t-webkit-animation: throb 2.5s ease-in-out infinite;\n\t-moz-animation: throb 2.5s ease-in-out infinite;\n\t-o-animation: throb 2.5s ease-in-out infinite;\n\tanimation: throb 2.5s ease-in-out infinite;\n}\n\n.flash {\n\t-webkit-animation: flash 4s linear infinite;\n\t-moz-animation: flash 4s linear infinite;\n\t-o-animation: flash 4s linear infinite;\n\tanimation: flash 4s linear infinite;\n}\n\n\n\n\n\n/* Clearfix */\n.cf:before,\n.cf:after {\n\tcontent: \" \";\n\tdisplay: table;\n}\n.cf:after {\n\tclear: both;\n}\n\n\n\n\n\n\n@media (max-width: 1099px) {\n\t#col-1 {\n\t\twidth: 25%;\n\t}\n\n\t#col-2 {\n\t\twidth: 75%;\n\t\tborder-right: none;\n\t}\n\n\t#col-3 {\n\t\tdisplay: none;\n\t}\n\n\tfooter #duration {\n\t\tdisplay: none;\n\t}\n}\n\n@media (max-width: 900px) {\n\tfooter #last-test-container {\n\t\tdisplay: none;\n\t}\n}\n\n@media (min-width: 850px) and (max-width: 1220px) {\n\t#path {\n\t\tfont-size: 14px;\n\t\tmargin-top: 5px;\n\t}\n}\n\n@media (min-width: 700px) and (max-width: 849px) {\n\t#path {\n\t\tfont-size: 12px;\n\t\tmargin-top: 8px;\n\t}\n}\n\n@media (max-width: 799px) {\n\t#col-1 {\n\t\tdisplay: none;\n\t}\n\n\t#col-2 {\n\t\twidth: 100%;\n\t}\n\n\t#stories .story-pkg-name {\n\t\tfont-size: 14px;\n\t}\n\n\t#stories .story-pkg-watch-td {\n\t\tdisplay: none;\n\t}\n}\n\n@media (max-width: 700px) {\n\t#path-container {\n\t\tdisplay: none;\n\t}\n\n\tfooter #time {\n\t\tdisplay: none;\n\t}\n\n\tfooter .info {\n\t\tpadding: 0 5px;\n\t}\n\n\tfooter .server-down .notice-message {\n\t\tdisplay: none;\n\t}\n}\n\n@media (max-width: 499px) {\n\t.toggler.narrow {\n\t\tdisplay: block;\n\t}\n\n\t#show-gen {\n\t\tdisplay: none;\n\t}\n\n\t.hide-narrow {\n\t\tdisplay: none;\n\t}\n\n\t.show-narrow {\n\t\tdisplay: block;\n\t}\n\n\t.overall .status {\n\t\tfont-size: 28px;\n\t\tletter-spacing: 1px;\n\t}\n\n\t.toggler {\n\t\tdisplay: block;\n\t}\n\n\t.controls ul {\n\t\ttext-align: center;\n\t\tfloat: none;\n\t}\n\n\t.controls li {\n\t\tdisplay: inline-block;\n\t\tfloat: none;\n\t}\n\n\t.enum > li {\n\t\tfloat: left;\n\t\tdisplay: block;\n\t}\n\n\t#logo {\n\t\tdisplay: none;\n\t}\n\n\t.history .item {\n\t\tmargin: 0 5px;\n\t}\n\n\t.history .item .summary {\n\t\tdisplay: none;\n\t}\n\n\t.server-down {\n\t\tfont-size: 14px;\n\t}\n\n\t#stories .story-pkg-name {\n\t\tfont-size: 16px;\n\t}\n\t\n\t#stories .not-pkg-name {\n\t\tdisplay: none;\n\t}\n\n\tfooter #duration {\n\t\tdisplay: none;\n\t}\n\n\tfooter #summary {\n\t\tdisplay: none;\n\t}\n\n\tfooter #narrow-summary {\n\t\tdisplay: inline;\n\t}\n}\n\n\n\n\n/**\n\tCustom CSS Animations\n**/\n\n\n\n@-webkit-keyframes throb {\n\t0% { opacity: 1; }\n\t50% { opacity: .35; }\n\t100% { opacity: 1; }\n}\n@-moz-keyframes throb {\n\t0% { opacity: 1; }\n\t50% { opacity: .35; }\n\t100% { opacity: 1; }\n}\n@-o-keyframes throb {\n\t0% { opacity: 1; }\n\t50% { opacity: .35; }\n\t100% { opacity: 1; }\n}\n@keyframes throb {\n\t0% { opacity: 1; }\n\t50% { opacity: .35; }\n\t100% { opacity: 1; }\n}\n\n\n@-webkit-keyframes flash {\n\t70% { opacity: 1; }\n\t90% { opacity: 0; }\n\t98% { opacity: 0; }\n\t100% { opacity: 1; }\n}\n@-moz-keyframes flash {\n\t70% { opacity: 1; }\n\t90% { opacity: 0; }\n\t98% { opacity: 0; }\n\t100% { opacity: 1; }\n}\n@-o-keyframes flash {\n\t70% { opacity: 1; }\n\t90% { opacity: 0; }\n\t98% { opacity: 0; }\n\t100% { opacity: 1; }\n}\n@keyframes flash {\n\t70% { opacity: 1; }\n\t90% { opacity: 0; }\n\t98% { opacity: 0; }\n\t100% { opacity: 1; }\n}\n\n\n\n\n\n\n\n\n\n\n\n/*\n#coverage {\n\tperspective: 1000;\n}\n\n#coverage .pkg-cover {\n\t-webkit-transition: .7s;\n\ttransform-style: preserve-3d;\n\tposition: relative;\n}\n\n#coverage:hover .pkg-cover {\n\t-webkit-transform: rotateX(180deg);\n}*/\n"
  },
  {
    "path": "web/client/resources/css/composer.css",
    "content": "/* Eric Meyer's Reset CSS v2.0 */\nhtml,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tsrc: local(\"Open Sans\"), url(\"../fonts/Open_Sans/OpenSans-Regular.ttf\");\n}\n@font-face {\n\tfont-family: 'Oswald';\n\tsrc: local(\"Oswald\"), url(\"../fonts/Oswald/Oswald-Regular.ttf\");\n}\n\nbody {\n\tfont-family: 'Open Sans', 'Helvetica Neue', sans-serif;\n\tfont-size: 16px;\n}\n\nheader {\n\tbackground: #2C3F49;\n\tpadding: 10px;\n}\n\n.logo {\n\tfont-family: Oswald, sans-serif;\n\tfont-size: 24px;\n\tmargin-right: 5px;\n\tcolor: #DDD;\n}\n\n.afterlogo {\n\tfont-size: 12px;\n\ttext-transform: uppercase;\n\tposition: relative;\n\ttop: -3px;\n\tcolor: #999;\n}\n\n#input,\n#output {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\n\tpadding: 15px;\n\theight: 80%;\n\tfloat: left;\n\toverflow: auto;\n}\n\n#input {\n\tborder: 0;\n\tfont: 300 18px/1.5em 'Open Sans';\n\tresize: none;\n\toutline: none;\n\twidth: 50%;\n}\n\n#output {\n\twidth: 50%;\n\tdisplay: inline-block;\n\tbackground: #F0F0F0;\n\tfont: 14px/1.25em 'Menlo', 'Monaco', 'Courier New', monospace;\n\tborder-left: 1px solid #CCC;\n\twhite-space: pre-wrap;\n}"
  },
  {
    "path": "web/client/resources/css/themes/dark-bigtext.css",
    "content": "/* This is a fork of the dark.css theme. The only changes from dark.css are near the very end. */\n\n::-webkit-scrollbar {\n\twidth: 10px;\n\theight: 10px;\n}\n\n::-webkit-scrollbar-corner {\n\tbackground: transparent;\n}\n\n::-webkit-scrollbar-thumb {\n\tbackground-color: rgba(255, 255, 255, .35);\n\tborder-radius: 10px;\n}\n\nbody {\n\tcolor: #D0D0D0;\n\tbackground: fixed #040607;\n\tbackground: fixed -moz-linear-gradient(top, hsl(200,27%,2%) 0%, hsl(203,29%,26%) 100%);\n\tbackground: fixed -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(200,27%,2%)), color-stop(100%,hsl(203,29%,26%)));\n\tbackground: fixed -webkit-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tbackground: fixed -o-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tbackground: fixed -ms-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tbackground: fixed linear-gradient(to bottom, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#040607', endColorstr='#2f4756',GradientType=0 );\n}\n\na,\n.toggle-all-pkg {\n\tcolor: #247D9E;\n}\n\na:hover,\n.toggle-all-pkg:hover {\n\tcolor: #33B5E5;\n}\n\ninput[type=text] {\n\tborder-bottom-color: #33B5E5;\n\tcolor: #BBB;\n}\n\n::-webkit-input-placeholder {\n\tcolor: #555;\n}\n:-moz-placeholder {\n\tcolor: #555;\n}\n::-moz-placeholder {\n\tcolor: #555;\n}\n:-ms-input-placeholder {\n\tcolor: #555;\n}\n\n.overall {\n\t/*\n\t\tUsing box-shadow here is not very performant but allows us\n\t\tto animate the change of the background color much more easily.\n\t\tThis box-shadow is an ALTERNATIVE, not supplement, to using gradients\n\t\tin this case.\n\t*/\n\tbox-shadow: inset 0 150px 100px -110px rgba(0, 0, 0, .5);\n}\n\n.overall.ok {\n\tbackground: #688E00;\n}\n\n.overall.fail {\n\tbackground: #DB8700;\n}\n\n.overall.panic {\n\tbackground: #A80000;\n}\n\n.overall.buildfail {\n\tbackground: #A4A8AA;\n}\n\n.overall .status {\n\tcolor: #EEE;\n}\n\n.server-down {\n\tbackground: rgba(255, 45, 45, 0.55);\n\tcolor: #FFF;\n}\n\n.toggler {\n\tbackground: #132535;\n}\n\n.toggler:hover {\n\tbackground: #1C374F;\n}\n\n.controls {\n\tborder-bottom: 1px solid #33B5E5;\n}\n\n.controls li {\n\tcolor: #2A5A84;\n}\n\n.controls li:hover {\n\tbackground: #132535;\n\tcolor: #33B5E5;\n}\n\n.sel {\n\tbackground: #33B5E5 !important;\n\tcolor: #FFF !important;\n}\n\n.pkg-cover-name {\n\ttext-shadow: 1px 1px 0px #000;\n}\n\n.pkg-cover-name b, \n.story-pkg-name b {\n\tcolor: #FFF;\n\tfont-weight: bold;\n}\n\n.pkg-cover:hover,\n.pkg-cover:hover b {\n\tcolor: #FFF;\n}\n\n.expandable {\n\tborder-top-color: #33B5E5;\n}\n\n.expandable {\n\tbackground: rgba(0, 0, 0, .2);\n}\n\n.history .item.ok {\n\tbackground: #3f5400;\n\tbackground: -moz-linear-gradient(top, hsl(75,100%,16%) 0%, hsl(76,100%,28%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(75,100%,16%)), color-stop(100%,hsl(76,100%,28%)));\n\tbackground: -webkit-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3f5400', endColorstr='#698f00',GradientType=0 );\n}\n\n.history .item.fail {\n\tbackground: #7f4e00;\n\tbackground: -moz-linear-gradient(top, hsl(37,100%,25%) 0%, hsl(37,100%,43%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(37,100%,25%)), color-stop(100%,hsl(37,100%,43%)));\n\tbackground: -webkit-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7f4e00', endColorstr='#db8700',GradientType=0 );\n}\n\n.history .item.panic {\n\tbackground: #660000;\n\tbackground: -moz-linear-gradient(top, hsl(0,100%,20%) 0%, hsl(0,100%,33%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(0,100%,20%)), color-stop(100%,hsl(0,100%,33%)));\n\tbackground: -webkit-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#660000', endColorstr='#a80000',GradientType=0 );\n}\n\n.history .item.buildfail {\n\tbackground: #282f33;\n\tbackground: -moz-linear-gradient(top, hsl(202,12%,18%) 0%, hsl(208,5%,48%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(202,12%,18%)), color-stop(100%,hsl(208,5%,48%)));\n\tbackground: -webkit-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#282f33', endColorstr='#757c82',GradientType=0 );\n}\n\n.enum {\n\tborder-color: #2B597F;\n}\n\n.enum > li {\n\tborder-left-color: #2B597F;\n}\n\n.enum > li:hover {\n\tbackground: rgba(55, 114, 163, .25);\n}\n\n.group {\n\tbackground: -moz-linear-gradient(top, rgba(16,59,71,0) 0%, rgba(16,59,71,1) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(16,59,71,0)), color-stop(100%,rgba(16,59,71,1)));\n\tbackground: -webkit-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tbackground: -o-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tbackground: -ms-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tbackground: linear-gradient(to top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00103b47', endColorstr='#103b47',GradientType=0 );\n}\n\n.stats {\n\tcolor: #FFF;\n}\n\n.error {\n\tcolor: #F58888 !important;\n\tbackground: rgba(255, 45, 45, 0.35) !important;\n}\n\n.spin-slowly,\n.spin-once {\n\tcolor: #33B5E5 !important;\n}\n\n.frame .col,\nfooter {\n\tborder-color: #33B5E5;\n}\n\nfooter {\n\tbackground: rgba(0, 0, 0, .5);\n}\n\nfooter .recording .fa {\n\tcolor: #CC0000;\n}\n\nfooter .replay .fa {\n\tcolor: #33B5E5;\n}\n\nfooter .paused .fa {\n\tcolor: #AAA;\n}\n\nfooter .recording.replay .fa {\n\tcolor: #33B5E5;\n}\n\n\n\n.buildfail-pkg {\n\tbackground: rgba(255, 255, 255, .1);\n}\n.buildfail-output {\n\tbackground: rgba(255, 255, 255, .2);\n}\n\n\n\n.panic-pkg {\n\tbackground: rgba(255, 0, 0, .3);\n}\n.panic-story {\n\tpadding: 10px;\n\tbackground: rgba(255, 0, 0, .1);\n}\n.panic-story a,\n.panic-summary {\n\tcolor: #E94A4A;\n}\n.panic-output {\n\tcolor: #FF8181;\n}\n\n\n\n.failure-pkg {\n\tbackground: rgba(255, 153, 0, .42);\n}\n.failure-story {\n\tpadding: 10px;\n\tbackground: rgba(255, 153, 0, .1);\n}\n.failure-story a {\n\tcolor: #FFB518;\n}\n.failure-output {\n\tcolor: #FFBD47;\n}\n.failure-file {\n\tcolor: #FFF;\n}\n\n\n.diffviewer td {\n\tborder-color: rgba(0, 0, 0, .3);\n}\n\n/* prettyTextDiff expected/deleted colors */\n.diffviewer .exp,\n.diff del {\n\tbackground: rgba(131, 252, 131, 0.22);\n}\n\n/* prettyTextDiff actual/inserted colors */\n.diffviewer .act,\n.diff ins {\n\tbackground: rgba(255, 52, 52, 0.33);\n}\n\n\n\n.story-links a,\n.test-name-link a {\n\tcolor: inherit;\n}\n\n\n\n.story-pkg {\n\tbackground: rgba(0, 0, 0, .4);\n}\n\n.story-pkg:hover {\n\tbackground: rgba(255, 255, 255, .05);\n}\n\n.story-line + .story-line {\n\tborder-top: 1px dashed rgba(255, 255, 255, .08);\n}\n\n.story-line-desc .message {\n\tcolor: #999;\n}\n\n.story-line-summary-container {\n\tborder-right: 1px dashed #333;\n}\n\n.story-line.ok .story-line-status { background: #008000; }\n.story-line.ok:hover, .story-line.ok.story-line-sel { background: rgba(0, 128, 0, .1); }\n\n.story-line.fail .story-line-status { background: #EA9C4D; }\n.story-line.fail:hover, .story-line.fail.story-line-sel { background: rgba(234, 156, 77, .1); }\n\n.story-line.panic .story-line-status { background: #FF3232; }\n.story-line.panic:hover, .story-line.panic.story-line-sel { background: rgba(255, 50, 50, .1); }\n\n.story-line.skip .story-line-status { background: #AAA; }\n.story-line.skip:hover, .story-line.skip.story-line-sel { background: rgba(255, 255, 255, .1); }\n\n.statusicon.ok { color: #76C13C; }\n.statusicon.fail, .fail-clr { color: #EA9C4D; }\n.statusicon.panic, .statusicon.panic .fa, .panic-clr { color: #FF3232; }\n.statusicon.skip, .skip-clr { color: #888; }\n\n\n.log .timestamp {\n\tcolor: #999;\n}\n\n\n.clr-red {\n\tcolor: #FF2222;\n}\n\n\n.tipsy-inner {\n\tbackground-color: #FAFAFA;\n\tcolor: #222;\n}\n\n.tipsy-arrow {\n\tborder: 8px dashed #FAFAFA;\n}\n\n.tipsy-arrow-n,\n.tipsy-arrow-s,\n.tipsy-arrow-e,\n.tipsy-arrow-w,\n{\n\tborder-color: #FAFAFA;\n}\n\n/***************************************************************/\n/*************************** Tweaks ****************************/\n/***************************************************************/\n\n\n/* More space for stories */\ndiv#col-3 { display: none; } /* hides the log */\ndiv#col-2 { width: 85%; }    /* fill it in with stories */\n\n/* Bigger Text */\n.story-line       { font-size: 16px; }\n.story-line b     { font-size: 20px; }\ntd.story-pkg-name { font-size: 24px; }\n\n/* Smaller Header */\ndiv.overall      { padding: 10px 0 0px; }\n.overall .status { font-size: 36px; }\n\n/***************************************************************/\n"
  },
  {
    "path": "web/client/resources/css/themes/dark.css",
    "content": "::-webkit-scrollbar {\n\twidth: 10px;\n\theight: 10px;\n}\n\n::-webkit-scrollbar-corner {\n\tbackground: transparent;\n}\n\n::-webkit-scrollbar-thumb {\n\tbackground-color: rgba(255, 255, 255, .35);\n\tborder-radius: 10px;\n}\n\nbody {\n\tcolor: #D0D0D0;\n\tbackground: fixed #040607;\n\tbackground: fixed -moz-linear-gradient(top, hsl(200,27%,2%) 0%, hsl(203,29%,26%) 100%);\n\tbackground: fixed -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(200,27%,2%)), color-stop(100%,hsl(203,29%,26%)));\n\tbackground: fixed -webkit-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tbackground: fixed -o-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tbackground: fixed -ms-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tbackground: fixed linear-gradient(to bottom, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#040607', endColorstr='#2f4756',GradientType=0 );\n}\n\na,\n.toggle-all-pkg {\n\tcolor: #247D9E;\n}\n\na:hover,\n.toggle-all-pkg:hover {\n\tcolor: #33B5E5;\n}\n\ninput[type=text] {\n\tborder-bottom-color: #33B5E5;\n\tcolor: #BBB;\n}\n\n::-webkit-input-placeholder {\n\tcolor: #555;\n}\n:-moz-placeholder {\n\tcolor: #555;\n}\n::-moz-placeholder {\n\tcolor: #555;\n}\n:-ms-input-placeholder {\n\tcolor: #555;\n}\n\n.overall {\n\t/*\n\t\tUsing box-shadow here is not very performant but allows us\n\t\tto animate the change of the background color much more easily.\n\t\tThis box-shadow is an ALTERNATIVE, not supplement, to using gradients\n\t\tin this case.\n\t*/\n\tbox-shadow: inset 0 150px 100px -110px rgba(0, 0, 0, .5);\n}\n\n.overall.ok {\n\tbackground: #688E00;\n}\n\n.overall.fail {\n\tbackground: #DB8700;\n}\n\n.overall.panic {\n\tbackground: #A80000;\n}\n\n.overall.buildfail {\n\tbackground: #A4A8AA;\n}\n\n.overall .status {\n\tcolor: #EEE;\n}\n\n.server-down {\n\tbackground: rgba(255, 45, 45, 0.55);\n\tcolor: #FFF;\n}\n\n.toggler {\n\tbackground: #132535;\n}\n\n.toggler:hover {\n\tbackground: #1C374F;\n}\n\n.controls {\n\tborder-bottom: 1px solid #33B5E5;\n}\n\n.controls li {\n\tcolor: #2A5A84;\n}\n\n.controls li:hover {\n\tbackground: #132535;\n\tcolor: #33B5E5;\n}\n\n.sel {\n\tbackground: #33B5E5 !important;\n\tcolor: #FFF !important;\n}\n\n.pkg-cover-name {\n\ttext-shadow: 1px 1px 0px #000;\n}\n\n.pkg-cover-name b, \n.story-pkg-name b {\n\tcolor: #FFF;\n\tfont-weight: bold;\n}\n\n.pkg-cover:hover,\n.pkg-cover:hover b {\n\tcolor: #FFF;\n}\n\n.expandable {\n\tborder-top-color: #33B5E5;\n}\n\n.expandable {\n\tbackground: rgba(0, 0, 0, .2);\n}\n\n.history .item.ok {\n\tbackground: #3f5400;\n\tbackground: -moz-linear-gradient(top, hsl(75,100%,16%) 0%, hsl(76,100%,28%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(75,100%,16%)), color-stop(100%,hsl(76,100%,28%)));\n\tbackground: -webkit-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3f5400', endColorstr='#698f00',GradientType=0 );\n}\n\n.history .item.fail {\n\tbackground: #7f4e00;\n\tbackground: -moz-linear-gradient(top, hsl(37,100%,25%) 0%, hsl(37,100%,43%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(37,100%,25%)), color-stop(100%,hsl(37,100%,43%)));\n\tbackground: -webkit-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7f4e00', endColorstr='#db8700',GradientType=0 );\n}\n\n.history .item.panic {\n\tbackground: #660000;\n\tbackground: -moz-linear-gradient(top, hsl(0,100%,20%) 0%, hsl(0,100%,33%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(0,100%,20%)), color-stop(100%,hsl(0,100%,33%)));\n\tbackground: -webkit-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#660000', endColorstr='#a80000',GradientType=0 );\n}\n\n.history .item.buildfail {\n\tbackground: #282f33;\n\tbackground: -moz-linear-gradient(top, hsl(202,12%,18%) 0%, hsl(208,5%,48%) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(202,12%,18%)), color-stop(100%,hsl(208,5%,48%)));\n\tbackground: -webkit-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tbackground: -o-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tbackground: -ms-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tbackground: linear-gradient(to bottom, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#282f33', endColorstr='#757c82',GradientType=0 );\n}\n\n.enum {\n\tborder-color: #2B597F;\n}\n\n.enum > li {\n\tborder-left-color: #2B597F;\n}\n\n.enum > li:hover {\n\tbackground: rgba(55, 114, 163, .25);\n}\n\n.group {\n\tbackground: -moz-linear-gradient(top, rgba(16,59,71,0) 0%, rgba(16,59,71,1) 100%);\n\tbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(16,59,71,0)), color-stop(100%,rgba(16,59,71,1)));\n\tbackground: -webkit-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tbackground: -o-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tbackground: -ms-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tbackground: linear-gradient(to top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00103b47', endColorstr='#103b47',GradientType=0 );\n}\n\n.stats {\n\tcolor: #FFF;\n}\n\n.error {\n\tcolor: #F58888 !important;\n\tbackground: rgba(255, 45, 45, 0.35) !important;\n}\n\n.spin-slowly,\n.spin-once {\n\tcolor: #33B5E5 !important;\n}\n\n.frame .col,\nfooter {\n\tborder-color: #33B5E5;\n}\n\nfooter {\n\tbackground: rgba(0, 0, 0, .5);\n}\n\nfooter .recording .fa {\n\tcolor: #CC0000;\n}\n\nfooter .replay .fa {\n\tcolor: #33B5E5;\n}\n\nfooter .paused .fa {\n\tcolor: #AAA;\n}\n\nfooter .recording.replay .fa {\n\tcolor: #33B5E5;\n}\n\n\n\n.buildfail-pkg {\n\tbackground: rgba(255, 255, 255, .1);\n}\n.buildfail-output {\n\tbackground: rgba(255, 255, 255, .2);\n}\n\n\n\n.panic-pkg {\n\tbackground: rgba(255, 0, 0, .3);\n}\n.panic-story {\n\tpadding: 10px;\n\tbackground: rgba(255, 0, 0, .1);\n}\n.panic-story a,\n.panic-summary {\n\tcolor: #E94A4A;\n}\n.panic-output {\n\tcolor: #FF8181;\n}\n\n\n\n.failure-pkg {\n\tbackground: rgba(255, 153, 0, .42);\n}\n.failure-story {\n\tpadding: 10px;\n\tbackground: rgba(255, 153, 0, .1);\n}\n.failure-story a {\n\tcolor: #FFB518;\n}\n.failure-output {\n\tcolor: #FFBD47;\n}\n.failure-file {\n\tcolor: #FFF;\n}\n\n\n.diffviewer td {\n\tborder-color: rgba(0, 0, 0, .3);\n}\n\n/* prettyTextDiff expected/deleted colors */\n.diffviewer .exp,\n.diff del {\n\tbackground: rgba(131, 252, 131, 0.22);\n}\n\n/* prettyTextDiff actual/inserted colors */\n.diffviewer .act,\n.diff ins {\n\tbackground: rgba(255, 52, 52, 0.33);\n}\n\n\n\n.story-links a,\n.test-name-link a {\n\tcolor: inherit;\n}\n\n\n\n.story-pkg {\n\tbackground: rgba(0, 0, 0, .4);\n}\n\n.story-pkg:hover {\n\tbackground: rgba(255, 255, 255, .05);\n}\n\n.story-line + .story-line {\n\tborder-top: 1px dashed rgba(255, 255, 255, .08);\n}\n\n.story-line-desc .message {\n\tcolor: #999;\n}\n\n.story-line-summary-container {\n\tborder-right: 1px dashed #333;\n}\n\n.story-line.ok .story-line-status { background: #008000; }\n.story-line.ok:hover, .story-line.ok.story-line-sel { background: rgba(0, 128, 0, .1); }\n\n.story-line.fail .story-line-status { background: #EA9C4D; }\n.story-line.fail:hover, .story-line.fail.story-line-sel { background: rgba(234, 156, 77, .1); }\n\n.story-line.panic .story-line-status { background: #FF3232; }\n.story-line.panic:hover, .story-line.panic.story-line-sel { background: rgba(255, 50, 50, .1); }\n\n.story-line.skip .story-line-status { background: #AAA; }\n.story-line.skip:hover, .story-line.skip.story-line-sel { background: rgba(255, 255, 255, .1); }\n\n.statusicon.ok { color: #76C13C; }\n.statusicon.fail, .fail-clr { color: #EA9C4D; }\n.statusicon.panic, .statusicon.panic .fa, .panic-clr { color: #FF3232; }\n.statusicon.skip, .skip-clr { color: #888; }\n\n.ansi-green { color: #76C13C; }\n.ansi-yellow { color: #EA9C4D; }\n.ansi-red { color: #FF3232; }\n.ansi-black { color: #000000; }\n.ansi-blue { color: #FF3232; }\n.ansi-purple { color: #C646C6; }\n.ansi-cyan { color: #00CDCD; }\n.ansi-white { color: #FFFFFF; }\n\n.log .timestamp {\n\tcolor: #999;\n}\n\n\n.clr-red {\n\tcolor: #FF2222;\n}\n\n\n.tipsy-inner {\n\tbackground-color: #FAFAFA;\n\tcolor: #222;\n}\n\n.tipsy-arrow {\n\tborder: 8px dashed #FAFAFA;\n}\n\n.tipsy-arrow-n,\n.tipsy-arrow-s,\n.tipsy-arrow-e,\n.tipsy-arrow-w,\n{\n\tborder-color: #FAFAFA;\n}\n"
  },
  {
    "path": "web/client/resources/css/themes/light.css",
    "content": "::-webkit-scrollbar-thumb {\n\tbackground-color: rgba(0, 0, 0, .35);\n\tborder-radius: 10px;\n}\n\n::-webkit-input-placeholder {\n    color: #CCC;\n}\n:-moz-placeholder {\n\tcolor: #CCC;\n}\n::-moz-placeholder {\n\tcolor: #CCC;\n}\n:-ms-input-placeholder {\n\tcolor: #CCC;\n}\n\nbody {\n\tcolor: #444;\n\tbackground: #F4F4F4;\n}\n\na {\n\tcolor: #247D9E;\n}\n\na:hover {\n\tcolor: #33B5E5;\n}\n\n.overall.ok,\n.history .item.ok {\n\tbackground: #8CB700; /* Can't decide: #5AA02C */\n}\n\n.overall.fail,\n.history .item.fail {\n\tbackground: #E79C07;\n}\n\n.overall.panic,\n.history .item.panic {\n\tbackground: #BB0000;\n}\n\n.overall.buildfail,\n.history .item.buildfail {\n\tbackground: #828c95;\n}\n\n.overall .status {\n\tcolor: #EEE;\n}\n\n.server-down {\n\tbackground: #BB0000;\n\tcolor: #FFF;\n}\n\n.toggler {\n\tbackground: #6887A3;\n\tcolor: #FFF;\n}\n\n.toggler:hover {\n\tbackground: #465B6D;\n}\n\n.toggler .fa {\n\tcolor: #FFF;\n}\n\n#logo {\n\tcolor: #6887A3;\n}\n\n.controls {\n\tborder-bottom: 1px solid #33B5E5;\n}\n\nli.fa,\na.fa,\n.toggle-all-pkg {\n\tcolor: #6887A3;\n}\n\nli.fa:hover,\na.fa:hover,\n.toggle-all-pkg:hover {\n\tcolor: #465B6D;\n}\n\nli.fa:active,\na.fa:active,\n.toggle-all-pkg:active {\n\tcolor: #33B5E5;\n}\n\n.controls li,\n.enum > li {\n\tborder-left-color: #33B5E5;\n}\n\n.controls li:hover,\n.enum > li:hover {\n\tbackground: #CFE6F9;\n}\n\n.enum {\n\tborder-color: #33B5E5;\n}\n\n.sel {\n\tbackground: #33B5E5 !important;\n\tcolor: #FFF !important;\n}\n\n.pkg-cover-name b, \n.story-pkg-name b {\n\tcolor: #000;\n\tfont-weight: bold;\n}\n\n.expandable {\n\tbackground: rgba(0, 0, 0, .1);\n\tborder-top-color: #33B5E5;\n}\n\n.history .item {\n\tcolor: #FFF;\n}\n\n.spin-slowly,\n.spin-once {\n\tcolor: #33B5E5 !important;\n}\n\n\ninput[type=text] {\n\tborder-bottom-color: #33B5E5;\n\tcolor: #333;\n}\n\n.error {\n\tcolor: #CC0000 !important;\n\tbackground: #FFD2D2 !important;\n}\n\n\nfooter {\n\tbackground: #F4F4F4;\n}\n\n.frame .col,\nfooter {\n\tborder-color: #33B5E5;\n}\n\nfooter .recording .fa {\n\tcolor: #CC0000;\n}\n\nfooter .replay .fa {\n\tcolor: #33B5E5;\n}\n\nfooter .paused .fa {\n\tcolor: #333;\n}\n\n\n.buildfail-pkg {\n\tbackground: #CCC;\n}\n.buildfail-output {\n\tbackground: #EEE;\n}\n\n\n\n.panic-pkg {\n\tbackground: #E94D4D;\n\tcolor: #FFF;\n}\n.panics .panic-details {\n\tborder: 5px solid #E94D4D;\n\tborder-top: 0;\n\tborder-bottom: 0;\n}\n.panic-details {\n\tcolor: #CC0000;\n}\n.panics .panic:last-child .panic-details {\n\tborder-bottom: 5px solid #E94D4D;\n}\n.panic-story {\n\tpadding: 10px;\n}\n.panics .panic-output {\n\tbackground: #FFF;\n}\n\n\n\n\n.failure-pkg {\n\tbackground: #FFA300;\n\tcolor: #FFF;\n}\n.failures .failure-details {\n\tborder: 5px solid #FFA300;\n\tborder-top: 0;\n\tborder-bottom: 0;\n}\n.failures .failure:last-child .failure-details {\n\tborder-bottom: 5px solid #FFA300;\n}\n.failure-story {\n\tpadding: 10px;\n\tcolor: #A87A00;\n}\n.stories .failure-output {\n\tcolor: #EA9C4D;\n}\n.failures .failure-output {\n\tbackground: #FFF;\n}\n.failure-file {\n\tcolor: #000;\n}\n\n.diffviewer td {\n\tborder-color: #CCC;\n\tbackground: #FFF;\n}\n\n/* prettyTextDiff expected/deleted colors */\n.diffviewer .exp,\n.diff del {\n\tbackground: #ADFFAD;\n}\n\n/* prettyTextDiff actual/inserted colors */\n.diffviewer .act,\n.diff ins {\n\tbackground: #FFC0C0;\n}\n\n\n\n.story-links a,\n.test-name-link a {\n\tcolor: inherit;\n}\n\n\n\n.story-pkg {\n\tbackground: #E8E8E8;\n}\n\n.story-pkg:hover {\n\tbackground: #DFDFDF;\n}\n\n.story-line {\n\tbackground: #FFF;\n}\n\n.story-line-desc .message {\n\tcolor: #888;\n}\n\n.story-line + .story-line {\n\tborder-top: 1px dashed #DDD;\n}\n\n.story-line-summary-container {\n\tborder-right: 1px dashed #DDD;\n}\n\n.story-line.ok .story-line-status { background: #8CB700; }\n.story-line.ok:hover, .story-line.ok.story-line-sel { background: #F4FFD8; }\n\n.story-line.fail .story-line-status { background: #E79C07; }\n.story-line.fail:hover, .story-line.fail.story-line-sel { background: #FFF1DB; }\n\n.story-line.panic .story-line-status { background: #DD0606; }\n.story-line.panic:hover, .story-line.panic.story-line-sel { background: #FFE8E8; }\n\n.story-line.skip .story-line-status { background: #4E4E4E; }\n.story-line.skip:hover, .story-line.skip.story-line-sel { background: #F2F2F2; }\n\n.statusicon.ok { color: #76C13C; }\n.statusicon.fail, .fail-clr { color: #EA9C4D; }\n.statusicon.panic, .statusicon.panic .fa, .panic-clr { color: #FF3232; }\n.statusicon.skip, .skip-clr { color: #AAA; }\n\n.ansi-green { color: #76C13C; }\n.ansi-yellow   { color: #EA9C4D; }\n\n.log .timestamp {\n\tcolor: #999;\n}\n\n.clr-red,\na.clr-red {\n\tcolor: #CC0000;\n}\n\n\n.tipsy-inner {\n\tbackground-color: #000;\n\tcolor: #FFF;\n}\n\n.tipsy-arrow {\n\tborder: 8px dashed #000;\n}\n\n.tipsy-arrow-n,\n.tipsy-arrow-s,\n.tipsy-arrow-e,\n.tipsy-arrow-w,\n{\n\tborder-color: #000;\n}\n"
  },
  {
    "path": "web/client/resources/css/tipsy.css",
    "content": ".tipsy {\n\tfont-size: 12px;\n\tposition: absolute;\n\tpadding: 8px;\n\tz-index: 100000;\n\tfont-family: 'Open Sans';\n\tline-height: 1.25em;\n}\n\n.tipsy-inner {\n\tmax-width: 200px;\n\tpadding: 5px 7px;\n\ttext-align: center;\n}\n\n/* Rounded corners */\n/*.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }*/\n\n/* Shadow */\n/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/\n\n.tipsy-arrow {\n\tposition: absolute;\n\twidth: 0;\n\theight: 0;\n\tline-height: 0;\n}\n\n.tipsy-n .tipsy-arrow,\n.tipsy-nw .tipsy-arrow,\n.tipsy-ne .tipsy-arrow {\n\tborder-bottom-style: solid;\n\tborder-top: none;\n\tborder-left-color: transparent;\n\tborder-right-color: transparent;\n}\n\n\n.tipsy-n .tipsy-arrow {\n\ttop: 0px;\n\tleft: 50%;\n\tmargin-left: -7px;\n}\n.tipsy-nw .tipsy-arrow {\n\ttop: 0;\n\tleft: 10px;\n}\n.tipsy-ne .tipsy-arrow {\n\ttop: 0;\n\tright: 10px;\n}\n\n.tipsy-s .tipsy-arrow,\n.tipsy-sw .tipsy-arrow,\n.tipsy-se .tipsy-arrow {\n\tborder-top-style: solid;\n\tborder-bottom: none;\n\tborder-left-color: transparent;\n\tborder-right-color: transparent;\n}\n\t\n\n.tipsy-s .tipsy-arrow {\n\tbottom: 0;\n\tleft: 50%;\n\tmargin-left: -7px;\n}\n\n.tipsy-sw .tipsy-arrow {\n\tbottom: 0;\n\tleft: 10px;\n}\n\n.tipsy-se .tipsy-arrow {\n\tbottom: 0;\n\tright: 10px;\n}\n\n.tipsy-e .tipsy-arrow {\n\tright: 0;\n\ttop: 50%;\n\tmargin-top: -7px;\n\tborder-left-style: solid;\n\tborder-right: none;\n\tborder-top-color: transparent;\n\tborder-bottom-color: transparent;\n}\n\n.tipsy-w .tipsy-arrow {\n\tleft: 0;\n\ttop: 50%;\n\tmargin-top: -7px;\n\tborder-right-style: solid;\n\tborder-left: none;\n\tborder-top-color: transparent;\n\tborder-bottom-color: transparent;\n}"
  },
  {
    "path": "web/client/resources/fonts/FontAwesome/README.md",
    "content": "#[Font Awesome v4.5.0](http://fontawesome.io)\n###The iconic font and CSS framework\n\nFont Awesome is a full suite of 605 pictographic icons for easy scalable vector graphics on websites,\ncreated and maintained by [Dave Gandy](http://twitter.com/davegandy).\nStay up to date with the latest release and announcements on Twitter:\n[@fontawesome](http://twitter.com/fontawesome).\n\nGet started at http://fontawesome.io!\n\n##License\n- The Font Awesome font is licensed under the SIL OFL 1.1:\n  - http://scripts.sil.org/OFL\n- Font Awesome CSS, LESS, and Sass files are licensed under the MIT License:\n  - http://opensource.org/licenses/mit-license.html\n- The Font Awesome documentation is licensed under the CC BY 3.0 License:\n  - http://creativecommons.org/licenses/by/3.0/\n- Attribution is no longer required as of Font Awesome 3.0, but much appreciated:\n  - `Font Awesome by Dave Gandy - http://fontawesome.io`\n- Full details: http://fontawesome.io/license\n\n##Changelog\n- [v4.5.0 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?q=milestone%3A4.5.0+is%3Aclosed)\n- [v4.4.0 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?q=milestone%3A4.4.0+is%3Aclosed)\n- [v4.3.0 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?q=milestone%3A4.3.0+is%3Aclosed)\n- [v4.2.0 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=12&page=1&state=closed)\n- [v4.1.0 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=6&page=1&state=closed)\n- [v4.0.3 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=9&page=1&state=closed)\n- [v4.0.2 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=8&page=1&state=closed)\n- [v4.0.1 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=7&page=1&state=closed)\n- [v4.0.0 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=2&page=1&state=closed)\n- [v3.2.1 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=5&page=1&state=closed)\n- [v3.2.0 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=3&page=1&state=closed)\n- [v3.1.1 GitHub milestones](https://github.com/FortAwesome/Font-Awesome/issues?milestone=4&page=1&state=closed)\n- v3.1.0 - Added 54 icons, icon stacking styles, flipping and rotating icons, removed Sass support\n- v3.0.2 - much improved rendering and alignment in IE7\n- v3.0.1 - much improved rendering in webkit, various bug fixes\n- v3.0.0 - all icons redesigned from scratch, optimized for Bootstrap's 14px default\n\n## Contributing\n\nPlease read through our [contributing guidelines](https://github.com/FortAwesome/Font-Awesome/blob/master/CONTRIBUTING.md).\nIncluded are directions for opening issues, coding standards, and notes on development.\n\n##Versioning\n\nFont Awesome will be maintained under the Semantic Versioning guidelines as much as possible. Releases will be numbered\nwith the following format:\n\n`<major>.<minor>.<patch>`\n\nAnd constructed with the following guidelines:\n\n* Breaking backward compatibility bumps the major (and resets the minor and patch)\n* New additions, including new icons, without breaking backward compatibility bumps the minor (and resets the patch)\n* Bug fixes and misc changes bumps the patch\n\nFor more information on SemVer, please visit http://semver.org.\n\n##Author\n- Email: dave@fontawesome.io\n- Twitter: http://twitter.com/davegandy\n- GitHub: https://github.com/davegandy\n\n##Component\nTo include as a [component](http://github.com/component/component), just run\n\n    $ component install FortAwesome/Font-Awesome\n\nOr add\n\n    \"FortAwesome/Font-Awesome\": \"*\"\n\nto the `dependencies` in your `component.json`.\n\n## Hacking on Font Awesome\n\n**Before you can build the project**, you must first have the following installed:\n\n- [Ruby](https://www.ruby-lang.org/en/)\n- Ruby Development Headers\n  - **Ubuntu:** `sudo apt-get install ruby-dev` *(Only if you're __NOT__ using `rbenv` or `rvm`)*\n  - **Windows:** [DevKit](http://rubyinstaller.org/)\n- [Bundler](http://bundler.io/) (Run `gem install bundler` to install).\n- [Node Package Manager (AKA NPM)](https://docs.npmjs.com/getting-started/installing-node)\n- [Less](http://lesscss.org/) (Run `npm install -g less` to install).\n- [Less Plugin: Clean CSS](https://github.com/less/less-plugin-clean-css) (Run `npm install -g less-plugin-clean-css` to install).\n\nFrom the root of the repository, install the tools used to develop.\n\n    $ bundle install\n    $ npm install\n\nBuild the project and documentation:\n\n    $ bundle exec jekyll build\n\nOr serve it on a local server on http://localhost:7998/Font-Awesome/:\n\n    $ bundle exec jekyll -w serve\n"
  },
  {
    "path": "web/client/resources/fonts/FontAwesome/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('../fonts/fontawesome-webfont.eot?v=4.5.0');\n  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.28571429em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14285714em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.14285714em;\n  width: 2.14285714em;\n  top: 0.14285714em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714286em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.fa-pull-left {\n  float: left;\n}\n.fa-pull-right {\n  float: right;\n}\n.fa.fa-pull-left {\n  margin-right: .3em;\n}\n.fa.fa-pull-right {\n  margin-left: .3em;\n}\n/* Deprecated as of 4.4.0 */\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n  animation: fa-spin 1s infinite steps(8);\n}\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook-f:before,\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-feed:before,\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before,\n.fa-gratipay:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n.fa-space-shuttle:before {\n  content: \"\\f197\";\n}\n.fa-slack:before {\n  content: \"\\f198\";\n}\n.fa-envelope-square:before {\n  content: \"\\f199\";\n}\n.fa-wordpress:before {\n  content: \"\\f19a\";\n}\n.fa-openid:before {\n  content: \"\\f19b\";\n}\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\\f19c\";\n}\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\\f19d\";\n}\n.fa-yahoo:before {\n  content: \"\\f19e\";\n}\n.fa-google:before {\n  content: \"\\f1a0\";\n}\n.fa-reddit:before {\n  content: \"\\f1a1\";\n}\n.fa-reddit-square:before {\n  content: \"\\f1a2\";\n}\n.fa-stumbleupon-circle:before {\n  content: \"\\f1a3\";\n}\n.fa-stumbleupon:before {\n  content: \"\\f1a4\";\n}\n.fa-delicious:before {\n  content: \"\\f1a5\";\n}\n.fa-digg:before {\n  content: \"\\f1a6\";\n}\n.fa-pied-piper:before {\n  content: \"\\f1a7\";\n}\n.fa-pied-piper-alt:before {\n  content: \"\\f1a8\";\n}\n.fa-drupal:before {\n  content: \"\\f1a9\";\n}\n.fa-joomla:before {\n  content: \"\\f1aa\";\n}\n.fa-language:before {\n  content: \"\\f1ab\";\n}\n.fa-fax:before {\n  content: \"\\f1ac\";\n}\n.fa-building:before {\n  content: \"\\f1ad\";\n}\n.fa-child:before {\n  content: \"\\f1ae\";\n}\n.fa-paw:before {\n  content: \"\\f1b0\";\n}\n.fa-spoon:before {\n  content: \"\\f1b1\";\n}\n.fa-cube:before {\n  content: \"\\f1b2\";\n}\n.fa-cubes:before {\n  content: \"\\f1b3\";\n}\n.fa-behance:before {\n  content: \"\\f1b4\";\n}\n.fa-behance-square:before {\n  content: \"\\f1b5\";\n}\n.fa-steam:before {\n  content: \"\\f1b6\";\n}\n.fa-steam-square:before {\n  content: \"\\f1b7\";\n}\n.fa-recycle:before {\n  content: \"\\f1b8\";\n}\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\\f1b9\";\n}\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\\f1ba\";\n}\n.fa-tree:before {\n  content: \"\\f1bb\";\n}\n.fa-spotify:before {\n  content: \"\\f1bc\";\n}\n.fa-deviantart:before {\n  content: \"\\f1bd\";\n}\n.fa-soundcloud:before {\n  content: \"\\f1be\";\n}\n.fa-database:before {\n  content: \"\\f1c0\";\n}\n.fa-file-pdf-o:before {\n  content: \"\\f1c1\";\n}\n.fa-file-word-o:before {\n  content: \"\\f1c2\";\n}\n.fa-file-excel-o:before {\n  content: \"\\f1c3\";\n}\n.fa-file-powerpoint-o:before {\n  content: \"\\f1c4\";\n}\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\\f1c5\";\n}\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\\f1c6\";\n}\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\\f1c7\";\n}\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\\f1c8\";\n}\n.fa-file-code-o:before {\n  content: \"\\f1c9\";\n}\n.fa-vine:before {\n  content: \"\\f1ca\";\n}\n.fa-codepen:before {\n  content: \"\\f1cb\";\n}\n.fa-jsfiddle:before {\n  content: \"\\f1cc\";\n}\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\\f1cd\";\n}\n.fa-circle-o-notch:before {\n  content: \"\\f1ce\";\n}\n.fa-ra:before,\n.fa-rebel:before {\n  content: \"\\f1d0\";\n}\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\\f1d1\";\n}\n.fa-git-square:before {\n  content: \"\\f1d2\";\n}\n.fa-git:before {\n  content: \"\\f1d3\";\n}\n.fa-y-combinator-square:before,\n.fa-yc-square:before,\n.fa-hacker-news:before {\n  content: \"\\f1d4\";\n}\n.fa-tencent-weibo:before {\n  content: \"\\f1d5\";\n}\n.fa-qq:before {\n  content: \"\\f1d6\";\n}\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\\f1d7\";\n}\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\\f1d8\";\n}\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\\f1d9\";\n}\n.fa-history:before {\n  content: \"\\f1da\";\n}\n.fa-circle-thin:before {\n  content: \"\\f1db\";\n}\n.fa-header:before {\n  content: \"\\f1dc\";\n}\n.fa-paragraph:before {\n  content: \"\\f1dd\";\n}\n.fa-sliders:before {\n  content: \"\\f1de\";\n}\n.fa-share-alt:before {\n  content: \"\\f1e0\";\n}\n.fa-share-alt-square:before {\n  content: \"\\f1e1\";\n}\n.fa-bomb:before {\n  content: \"\\f1e2\";\n}\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\\f1e3\";\n}\n.fa-tty:before {\n  content: \"\\f1e4\";\n}\n.fa-binoculars:before {\n  content: \"\\f1e5\";\n}\n.fa-plug:before {\n  content: \"\\f1e6\";\n}\n.fa-slideshare:before {\n  content: \"\\f1e7\";\n}\n.fa-twitch:before {\n  content: \"\\f1e8\";\n}\n.fa-yelp:before {\n  content: \"\\f1e9\";\n}\n.fa-newspaper-o:before {\n  content: \"\\f1ea\";\n}\n.fa-wifi:before {\n  content: \"\\f1eb\";\n}\n.fa-calculator:before {\n  content: \"\\f1ec\";\n}\n.fa-paypal:before {\n  content: \"\\f1ed\";\n}\n.fa-google-wallet:before {\n  content: \"\\f1ee\";\n}\n.fa-cc-visa:before {\n  content: \"\\f1f0\";\n}\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\";\n}\n.fa-cc-discover:before {\n  content: \"\\f1f2\";\n}\n.fa-cc-amex:before {\n  content: \"\\f1f3\";\n}\n.fa-cc-paypal:before {\n  content: \"\\f1f4\";\n}\n.fa-cc-stripe:before {\n  content: \"\\f1f5\";\n}\n.fa-bell-slash:before {\n  content: \"\\f1f6\";\n}\n.fa-bell-slash-o:before {\n  content: \"\\f1f7\";\n}\n.fa-trash:before {\n  content: \"\\f1f8\";\n}\n.fa-copyright:before {\n  content: \"\\f1f9\";\n}\n.fa-at:before {\n  content: \"\\f1fa\";\n}\n.fa-eyedropper:before {\n  content: \"\\f1fb\";\n}\n.fa-paint-brush:before {\n  content: \"\\f1fc\";\n}\n.fa-birthday-cake:before {\n  content: \"\\f1fd\";\n}\n.fa-area-chart:before {\n  content: \"\\f1fe\";\n}\n.fa-pie-chart:before {\n  content: \"\\f200\";\n}\n.fa-line-chart:before {\n  content: \"\\f201\";\n}\n.fa-lastfm:before {\n  content: \"\\f202\";\n}\n.fa-lastfm-square:before {\n  content: \"\\f203\";\n}\n.fa-toggle-off:before {\n  content: \"\\f204\";\n}\n.fa-toggle-on:before {\n  content: \"\\f205\";\n}\n.fa-bicycle:before {\n  content: \"\\f206\";\n}\n.fa-bus:before {\n  content: \"\\f207\";\n}\n.fa-ioxhost:before {\n  content: \"\\f208\";\n}\n.fa-angellist:before {\n  content: \"\\f209\";\n}\n.fa-cc:before {\n  content: \"\\f20a\";\n}\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\\f20b\";\n}\n.fa-meanpath:before {\n  content: \"\\f20c\";\n}\n.fa-buysellads:before {\n  content: \"\\f20d\";\n}\n.fa-connectdevelop:before {\n  content: \"\\f20e\";\n}\n.fa-dashcube:before {\n  content: \"\\f210\";\n}\n.fa-forumbee:before {\n  content: \"\\f211\";\n}\n.fa-leanpub:before {\n  content: \"\\f212\";\n}\n.fa-sellsy:before {\n  content: \"\\f213\";\n}\n.fa-shirtsinbulk:before {\n  content: \"\\f214\";\n}\n.fa-simplybuilt:before {\n  content: \"\\f215\";\n}\n.fa-skyatlas:before {\n  content: \"\\f216\";\n}\n.fa-cart-plus:before {\n  content: \"\\f217\";\n}\n.fa-cart-arrow-down:before {\n  content: \"\\f218\";\n}\n.fa-diamond:before {\n  content: \"\\f219\";\n}\n.fa-ship:before {\n  content: \"\\f21a\";\n}\n.fa-user-secret:before {\n  content: \"\\f21b\";\n}\n.fa-motorcycle:before {\n  content: \"\\f21c\";\n}\n.fa-street-view:before {\n  content: \"\\f21d\";\n}\n.fa-heartbeat:before {\n  content: \"\\f21e\";\n}\n.fa-venus:before {\n  content: \"\\f221\";\n}\n.fa-mars:before {\n  content: \"\\f222\";\n}\n.fa-mercury:before {\n  content: \"\\f223\";\n}\n.fa-intersex:before,\n.fa-transgender:before {\n  content: \"\\f224\";\n}\n.fa-transgender-alt:before {\n  content: \"\\f225\";\n}\n.fa-venus-double:before {\n  content: \"\\f226\";\n}\n.fa-mars-double:before {\n  content: \"\\f227\";\n}\n.fa-venus-mars:before {\n  content: \"\\f228\";\n}\n.fa-mars-stroke:before {\n  content: \"\\f229\";\n}\n.fa-mars-stroke-v:before {\n  content: \"\\f22a\";\n}\n.fa-mars-stroke-h:before {\n  content: \"\\f22b\";\n}\n.fa-neuter:before {\n  content: \"\\f22c\";\n}\n.fa-genderless:before {\n  content: \"\\f22d\";\n}\n.fa-facebook-official:before {\n  content: \"\\f230\";\n}\n.fa-pinterest-p:before {\n  content: \"\\f231\";\n}\n.fa-whatsapp:before {\n  content: \"\\f232\";\n}\n.fa-server:before {\n  content: \"\\f233\";\n}\n.fa-user-plus:before {\n  content: \"\\f234\";\n}\n.fa-user-times:before {\n  content: \"\\f235\";\n}\n.fa-hotel:before,\n.fa-bed:before {\n  content: \"\\f236\";\n}\n.fa-viacoin:before {\n  content: \"\\f237\";\n}\n.fa-train:before {\n  content: \"\\f238\";\n}\n.fa-subway:before {\n  content: \"\\f239\";\n}\n.fa-medium:before {\n  content: \"\\f23a\";\n}\n.fa-yc:before,\n.fa-y-combinator:before {\n  content: \"\\f23b\";\n}\n.fa-optin-monster:before {\n  content: \"\\f23c\";\n}\n.fa-opencart:before {\n  content: \"\\f23d\";\n}\n.fa-expeditedssl:before {\n  content: \"\\f23e\";\n}\n.fa-battery-4:before,\n.fa-battery-full:before {\n  content: \"\\f240\";\n}\n.fa-battery-3:before,\n.fa-battery-three-quarters:before {\n  content: \"\\f241\";\n}\n.fa-battery-2:before,\n.fa-battery-half:before {\n  content: \"\\f242\";\n}\n.fa-battery-1:before,\n.fa-battery-quarter:before {\n  content: \"\\f243\";\n}\n.fa-battery-0:before,\n.fa-battery-empty:before {\n  content: \"\\f244\";\n}\n.fa-mouse-pointer:before {\n  content: \"\\f245\";\n}\n.fa-i-cursor:before {\n  content: \"\\f246\";\n}\n.fa-object-group:before {\n  content: \"\\f247\";\n}\n.fa-object-ungroup:before {\n  content: \"\\f248\";\n}\n.fa-sticky-note:before {\n  content: \"\\f249\";\n}\n.fa-sticky-note-o:before {\n  content: \"\\f24a\";\n}\n.fa-cc-jcb:before {\n  content: \"\\f24b\";\n}\n.fa-cc-diners-club:before {\n  content: \"\\f24c\";\n}\n.fa-clone:before {\n  content: \"\\f24d\";\n}\n.fa-balance-scale:before {\n  content: \"\\f24e\";\n}\n.fa-hourglass-o:before {\n  content: \"\\f250\";\n}\n.fa-hourglass-1:before,\n.fa-hourglass-start:before {\n  content: \"\\f251\";\n}\n.fa-hourglass-2:before,\n.fa-hourglass-half:before {\n  content: \"\\f252\";\n}\n.fa-hourglass-3:before,\n.fa-hourglass-end:before {\n  content: \"\\f253\";\n}\n.fa-hourglass:before {\n  content: \"\\f254\";\n}\n.fa-hand-grab-o:before,\n.fa-hand-rock-o:before {\n  content: \"\\f255\";\n}\n.fa-hand-stop-o:before,\n.fa-hand-paper-o:before {\n  content: \"\\f256\";\n}\n.fa-hand-scissors-o:before {\n  content: \"\\f257\";\n}\n.fa-hand-lizard-o:before {\n  content: \"\\f258\";\n}\n.fa-hand-spock-o:before {\n  content: \"\\f259\";\n}\n.fa-hand-pointer-o:before {\n  content: \"\\f25a\";\n}\n.fa-hand-peace-o:before {\n  content: \"\\f25b\";\n}\n.fa-trademark:before {\n  content: \"\\f25c\";\n}\n.fa-registered:before {\n  content: \"\\f25d\";\n}\n.fa-creative-commons:before {\n  content: \"\\f25e\";\n}\n.fa-gg:before {\n  content: \"\\f260\";\n}\n.fa-gg-circle:before {\n  content: \"\\f261\";\n}\n.fa-tripadvisor:before {\n  content: \"\\f262\";\n}\n.fa-odnoklassniki:before {\n  content: \"\\f263\";\n}\n.fa-odnoklassniki-square:before {\n  content: \"\\f264\";\n}\n.fa-get-pocket:before {\n  content: \"\\f265\";\n}\n.fa-wikipedia-w:before {\n  content: \"\\f266\";\n}\n.fa-safari:before {\n  content: \"\\f267\";\n}\n.fa-chrome:before {\n  content: \"\\f268\";\n}\n.fa-firefox:before {\n  content: \"\\f269\";\n}\n.fa-opera:before {\n  content: \"\\f26a\";\n}\n.fa-internet-explorer:before {\n  content: \"\\f26b\";\n}\n.fa-tv:before,\n.fa-television:before {\n  content: \"\\f26c\";\n}\n.fa-contao:before {\n  content: \"\\f26d\";\n}\n.fa-500px:before {\n  content: \"\\f26e\";\n}\n.fa-amazon:before {\n  content: \"\\f270\";\n}\n.fa-calendar-plus-o:before {\n  content: \"\\f271\";\n}\n.fa-calendar-minus-o:before {\n  content: \"\\f272\";\n}\n.fa-calendar-times-o:before {\n  content: \"\\f273\";\n}\n.fa-calendar-check-o:before {\n  content: \"\\f274\";\n}\n.fa-industry:before {\n  content: \"\\f275\";\n}\n.fa-map-pin:before {\n  content: \"\\f276\";\n}\n.fa-map-signs:before {\n  content: \"\\f277\";\n}\n.fa-map-o:before {\n  content: \"\\f278\";\n}\n.fa-map:before {\n  content: \"\\f279\";\n}\n.fa-commenting:before {\n  content: \"\\f27a\";\n}\n.fa-commenting-o:before {\n  content: \"\\f27b\";\n}\n.fa-houzz:before {\n  content: \"\\f27c\";\n}\n.fa-vimeo:before {\n  content: \"\\f27d\";\n}\n.fa-black-tie:before {\n  content: \"\\f27e\";\n}\n.fa-fonticons:before {\n  content: \"\\f280\";\n}\n.fa-reddit-alien:before {\n  content: \"\\f281\";\n}\n.fa-edge:before {\n  content: \"\\f282\";\n}\n.fa-credit-card-alt:before {\n  content: \"\\f283\";\n}\n.fa-codiepie:before {\n  content: \"\\f284\";\n}\n.fa-modx:before {\n  content: \"\\f285\";\n}\n.fa-fort-awesome:before {\n  content: \"\\f286\";\n}\n.fa-usb:before {\n  content: \"\\f287\";\n}\n.fa-product-hunt:before {\n  content: \"\\f288\";\n}\n.fa-mixcloud:before {\n  content: \"\\f289\";\n}\n.fa-scribd:before {\n  content: \"\\f28a\";\n}\n.fa-pause-circle:before {\n  content: \"\\f28b\";\n}\n.fa-pause-circle-o:before {\n  content: \"\\f28c\";\n}\n.fa-stop-circle:before {\n  content: \"\\f28d\";\n}\n.fa-stop-circle-o:before {\n  content: \"\\f28e\";\n}\n.fa-shopping-bag:before {\n  content: \"\\f290\";\n}\n.fa-shopping-basket:before {\n  content: \"\\f291\";\n}\n.fa-hashtag:before {\n  content: \"\\f292\";\n}\n.fa-bluetooth:before {\n  content: \"\\f293\";\n}\n.fa-bluetooth-b:before {\n  content: \"\\f294\";\n}\n.fa-percent:before {\n  content: \"\\f295\";\n}\n"
  },
  {
    "path": "web/client/resources/fonts/Open_Sans/LICENSE.txt",
    "content": "\r\n                                 Apache License\r\n                           Version 2.0, January 2004\r\n                        http://www.apache.org/licenses/\r\n\r\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n   1. Definitions.\r\n\r\n      \"License\" shall mean the terms and conditions for use, reproduction,\r\n      and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n      \"Licensor\" shall mean the copyright owner or entity authorized by\r\n      the copyright owner that is granting the License.\r\n\r\n      \"Legal Entity\" shall mean the union of the acting entity and all\r\n      other entities that control, are controlled by, or are under common\r\n      control with that entity. For the purposes of this definition,\r\n      \"control\" means (i) the power, direct or indirect, to cause the\r\n      direction or management of such entity, whether by contract or\r\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n      outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n      exercising permissions granted by this License.\r\n\r\n      \"Source\" form shall mean the preferred form for making modifications,\r\n      including but not limited to software source code, documentation\r\n      source, and configuration files.\r\n\r\n      \"Object\" form shall mean any form resulting from mechanical\r\n      transformation or translation of a Source form, including but\r\n      not limited to compiled object code, generated documentation,\r\n      and conversions to other media types.\r\n\r\n      \"Work\" shall mean the work of authorship, whether in Source or\r\n      Object form, made available under the License, as indicated by a\r\n      copyright notice that is included in or attached to the work\r\n      (an example is provided in the Appendix below).\r\n\r\n      \"Derivative Works\" shall mean any work, whether in Source or Object\r\n      form, that is based on (or derived from) the Work and for which the\r\n      editorial revisions, annotations, elaborations, or other modifications\r\n      represent, as a whole, an original work of authorship. For the purposes\r\n      of this License, Derivative Works shall not include works that remain\r\n      separable from, or merely link (or bind by name) to the interfaces of,\r\n      the Work and Derivative Works thereof.\r\n\r\n      \"Contribution\" shall mean any work of authorship, including\r\n      the original version of the Work and any modifications or additions\r\n      to that Work or Derivative Works thereof, that is intentionally\r\n      submitted to Licensor for inclusion in the Work by the copyright owner\r\n      or by an individual or Legal Entity authorized to submit on behalf of\r\n      the copyright owner. For the purposes of this definition, \"submitted\"\r\n      means any form of electronic, verbal, or written communication sent\r\n      to the Licensor or its representatives, including but not limited to\r\n      communication on electronic mailing lists, source code control systems,\r\n      and issue tracking systems that are managed by, or on behalf of, the\r\n      Licensor for the purpose of discussing and improving the Work, but\r\n      excluding communication that is conspicuously marked or otherwise\r\n      designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n      on behalf of whom a Contribution has been received by Licensor and\r\n      subsequently incorporated within the Work.\r\n\r\n   2. Grant of Copyright License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      copyright license to reproduce, prepare Derivative Works of,\r\n      publicly display, publicly perform, sublicense, and distribute the\r\n      Work and such Derivative Works in Source or Object form.\r\n\r\n   3. Grant of Patent License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      (except as stated in this section) patent license to make, have made,\r\n      use, offer to sell, sell, import, and otherwise transfer the Work,\r\n      where such license applies only to those patent claims licensable\r\n      by such Contributor that are necessarily infringed by their\r\n      Contribution(s) alone or by combination of their Contribution(s)\r\n      with the Work to which such Contribution(s) was submitted. If You\r\n      institute patent litigation against any entity (including a\r\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n      or a Contribution incorporated within the Work constitutes direct\r\n      or contributory patent infringement, then any patent licenses\r\n      granted to You under this License for that Work shall terminate\r\n      as of the date such litigation is filed.\r\n\r\n   4. Redistribution. You may reproduce and distribute copies of the\r\n      Work or Derivative Works thereof in any medium, with or without\r\n      modifications, and in Source or Object form, provided that You\r\n      meet the following conditions:\r\n\r\n      (a) You must give any other recipients of the Work or\r\n          Derivative Works a copy of this License; and\r\n\r\n      (b) You must cause any modified files to carry prominent notices\r\n          stating that You changed the files; and\r\n\r\n      (c) You must retain, in the Source form of any Derivative Works\r\n          that You distribute, all copyright, patent, trademark, and\r\n          attribution notices from the Source form of the Work,\r\n          excluding those notices that do not pertain to any part of\r\n          the Derivative Works; and\r\n\r\n      (d) If the Work includes a \"NOTICE\" text file as part of its\r\n          distribution, then any Derivative Works that You distribute must\r\n          include a readable copy of the attribution notices contained\r\n          within such NOTICE file, excluding those notices that do not\r\n          pertain to any part of the Derivative Works, in at least one\r\n          of the following places: within a NOTICE text file distributed\r\n          as part of the Derivative Works; within the Source form or\r\n          documentation, if provided along with the Derivative Works; or,\r\n          within a display generated by the Derivative Works, if and\r\n          wherever such third-party notices normally appear. The contents\r\n          of the NOTICE file are for informational purposes only and\r\n          do not modify the License. You may add Your own attribution\r\n          notices within Derivative Works that You distribute, alongside\r\n          or as an addendum to the NOTICE text from the Work, provided\r\n          that such additional attribution notices cannot be construed\r\n          as modifying the License.\r\n\r\n      You may add Your own copyright statement to Your modifications and\r\n      may provide additional or different license terms and conditions\r\n      for use, reproduction, or distribution of Your modifications, or\r\n      for any such Derivative Works as a whole, provided Your use,\r\n      reproduction, and distribution of the Work otherwise complies with\r\n      the conditions stated in this License.\r\n\r\n   5. Submission of Contributions. Unless You explicitly state otherwise,\r\n      any Contribution intentionally submitted for inclusion in the Work\r\n      by You to the Licensor shall be under the terms and conditions of\r\n      this License, without any additional terms or conditions.\r\n      Notwithstanding the above, nothing herein shall supersede or modify\r\n      the terms of any separate license agreement you may have executed\r\n      with Licensor regarding such Contributions.\r\n\r\n   6. Trademarks. This License does not grant permission to use the trade\r\n      names, trademarks, service marks, or product names of the Licensor,\r\n      except as required for reasonable and customary use in describing the\r\n      origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n   7. Disclaimer of Warranty. Unless required by applicable law or\r\n      agreed to in writing, Licensor provides the Work (and each\r\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n      implied, including, without limitation, any warranties or conditions\r\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n      PARTICULAR PURPOSE. You are solely responsible for determining the\r\n      appropriateness of using or redistributing the Work and assume any\r\n      risks associated with Your exercise of permissions under this License.\r\n\r\n   8. Limitation of Liability. In no event and under no legal theory,\r\n      whether in tort (including negligence), contract, or otherwise,\r\n      unless required by applicable law (such as deliberate and grossly\r\n      negligent acts) or agreed to in writing, shall any Contributor be\r\n      liable to You for damages, including any direct, indirect, special,\r\n      incidental, or consequential damages of any character arising as a\r\n      result of this License or out of the use or inability to use the\r\n      Work (including but not limited to damages for loss of goodwill,\r\n      work stoppage, computer failure or malfunction, or any and all\r\n      other commercial damages or losses), even if such Contributor\r\n      has been advised of the possibility of such damages.\r\n\r\n   9. Accepting Warranty or Additional Liability. While redistributing\r\n      the Work or Derivative Works thereof, You may choose to offer,\r\n      and charge a fee for, acceptance of support, warranty, indemnity,\r\n      or other liability obligations and/or rights consistent with this\r\n      License. However, in accepting such obligations, You may act only\r\n      on Your own behalf and on Your sole responsibility, not on behalf\r\n      of any other Contributor, and only if You agree to indemnify,\r\n      defend, and hold each Contributor harmless for any liability\r\n      incurred by, or claims asserted against, such Contributor by reason\r\n      of your accepting any such warranty or additional liability.\r\n\r\n   END OF TERMS AND CONDITIONS\r\n\r\n   APPENDIX: How to apply the Apache License to your work.\r\n\r\n      To apply the Apache License to your work, attach the following\r\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\r\n      replaced with your own identifying information. (Don't include\r\n      the brackets!)  The text should be enclosed in the appropriate\r\n      comment syntax for the file format. We also recommend that a\r\n      file or class name and description of purpose be included on the\r\n      same \"printed page\" as the copyright notice for easier\r\n      identification within third-party archives.\r\n\r\n   Copyright [yyyy] [name of copyright owner]\r\n\r\n   Licensed under the Apache License, Version 2.0 (the \"License\");\r\n   you may not use this file except in compliance with the License.\r\n   You may obtain a copy of the License at\r\n\r\n       http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n   Unless required by applicable law or agreed to in writing, software\r\n   distributed under the License is distributed on an \"AS IS\" BASIS,\r\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n   See the License for the specific language governing permissions and\r\n   limitations under the License.\r\n"
  },
  {
    "path": "web/client/resources/fonts/Orbitron/OFL.txt",
    "content": "Copyright (c) 2009, Matt McInerney (matt@pixelspread.com),\r\nwith Reserved Font Name Orbitron.\r\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\r\nThis license is copied below, and is also available with a FAQ at:\r\nhttp://scripts.sil.org/OFL\r\n\r\n\r\n-----------------------------------------------------------\r\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r\n-----------------------------------------------------------\r\n\r\nPREAMBLE\r\nThe goals of the Open Font License (OFL) are to stimulate worldwide\r\ndevelopment of collaborative font projects, to support the font creation\r\nefforts of academic and linguistic communities, and to provide a free and\r\nopen framework in which fonts may be shared and improved in partnership\r\nwith others.\r\n\r\nThe OFL allows the licensed fonts to be used, studied, modified and\r\nredistributed freely as long as they are not sold by themselves. The\r\nfonts, including any derivative works, can be bundled, embedded, \r\nredistributed and/or sold with any software provided that any reserved\r\nnames are not used by derivative works. The fonts and derivatives,\r\nhowever, cannot be released under any other type of license. The\r\nrequirement for fonts to remain under this license does not apply\r\nto any document created using the fonts or their derivatives.\r\n\r\nDEFINITIONS\r\n\"Font Software\" refers to the set of files released by the Copyright\r\nHolder(s) under this license and clearly marked as such. This may\r\ninclude source files, build scripts and documentation.\r\n\r\n\"Reserved Font Name\" refers to any names specified as such after the\r\ncopyright statement(s).\r\n\r\n\"Original Version\" refers to the collection of Font Software components as\r\ndistributed by the Copyright Holder(s).\r\n\r\n\"Modified Version\" refers to any derivative made by adding to, deleting,\r\nor substituting -- in part or in whole -- any of the components of the\r\nOriginal Version, by changing formats or by porting the Font Software to a\r\nnew environment.\r\n\r\n\"Author\" refers to any designer, engineer, programmer, technical\r\nwriter or other person who contributed to the Font Software.\r\n\r\nPERMISSION & CONDITIONS\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of the Font Software, to use, study, copy, merge, embed, modify,\r\nredistribute, and sell modified and unmodified copies of the Font\r\nSoftware, subject to the following conditions:\r\n\r\n1) Neither the Font Software nor any of its individual components,\r\nin Original or Modified Versions, may be sold by itself.\r\n\r\n2) Original or Modified Versions of the Font Software may be bundled,\r\nredistributed and/or sold with any software, provided that each copy\r\ncontains the above copyright notice and this license. These can be\r\nincluded either as stand-alone text files, human-readable headers or\r\nin the appropriate machine-readable metadata fields within text or\r\nbinary files as long as those fields can be easily viewed by the user.\r\n\r\n3) No Modified Version of the Font Software may use the Reserved Font\r\nName(s) unless explicit written permission is granted by the corresponding\r\nCopyright Holder. This restriction only applies to the primary font name as\r\npresented to the users.\r\n\r\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r\nSoftware shall not be used to promote, endorse or advertise any\r\nModified Version, except to acknowledge the contribution(s) of the\r\nCopyright Holder(s) and the Author(s) or with their explicit written\r\npermission.\r\n\r\n5) The Font Software, modified or unmodified, in part or in whole,\r\nmust be distributed entirely under this license, and must not be\r\ndistributed under any other license. The requirement for fonts to\r\nremain under this license does not apply to any document created\r\nusing the Font Software.\r\n\r\nTERMINATION\r\nThis license becomes null and void if any of the above conditions are\r\nnot met.\r\n\r\nDISCLAIMER\r\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r\nOTHER DEALINGS IN THE FONT SOFTWARE.\r\n"
  },
  {
    "path": "web/client/resources/fonts/Oswald/OFL.txt",
    "content": "Copyright (c) 2011-2012, Vernon Adams (vern@newtypography.co.uk), with Reserved Font Names 'Oswald'\r\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\r\nThis license is copied below, and is also available with a FAQ at:\r\nhttp://scripts.sil.org/OFL\r\n\r\n\r\n-----------------------------------------------------------\r\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r\n-----------------------------------------------------------\r\n\r\nPREAMBLE\r\nThe goals of the Open Font License (OFL) are to stimulate worldwide\r\ndevelopment of collaborative font projects, to support the font creation\r\nefforts of academic and linguistic communities, and to provide a free and\r\nopen framework in which fonts may be shared and improved in partnership\r\nwith others.\r\n\r\nThe OFL allows the licensed fonts to be used, studied, modified and\r\nredistributed freely as long as they are not sold by themselves. The\r\nfonts, including any derivative works, can be bundled, embedded, \r\nredistributed and/or sold with any software provided that any reserved\r\nnames are not used by derivative works. The fonts and derivatives,\r\nhowever, cannot be released under any other type of license. The\r\nrequirement for fonts to remain under this license does not apply\r\nto any document created using the fonts or their derivatives.\r\n\r\nDEFINITIONS\r\n\"Font Software\" refers to the set of files released by the Copyright\r\nHolder(s) under this license and clearly marked as such. This may\r\ninclude source files, build scripts and documentation.\r\n\r\n\"Reserved Font Name\" refers to any names specified as such after the\r\ncopyright statement(s).\r\n\r\n\"Original Version\" refers to the collection of Font Software components as\r\ndistributed by the Copyright Holder(s).\r\n\r\n\"Modified Version\" refers to any derivative made by adding to, deleting,\r\nor substituting -- in part or in whole -- any of the components of the\r\nOriginal Version, by changing formats or by porting the Font Software to a\r\nnew environment.\r\n\r\n\"Author\" refers to any designer, engineer, programmer, technical\r\nwriter or other person who contributed to the Font Software.\r\n\r\nPERMISSION & CONDITIONS\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of the Font Software, to use, study, copy, merge, embed, modify,\r\nredistribute, and sell modified and unmodified copies of the Font\r\nSoftware, subject to the following conditions:\r\n\r\n1) Neither the Font Software nor any of its individual components,\r\nin Original or Modified Versions, may be sold by itself.\r\n\r\n2) Original or Modified Versions of the Font Software may be bundled,\r\nredistributed and/or sold with any software, provided that each copy\r\ncontains the above copyright notice and this license. These can be\r\nincluded either as stand-alone text files, human-readable headers or\r\nin the appropriate machine-readable metadata fields within text or\r\nbinary files as long as those fields can be easily viewed by the user.\r\n\r\n3) No Modified Version of the Font Software may use the Reserved Font\r\nName(s) unless explicit written permission is granted by the corresponding\r\nCopyright Holder. This restriction only applies to the primary font name as\r\npresented to the users.\r\n\r\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r\nSoftware shall not be used to promote, endorse or advertise any\r\nModified Version, except to acknowledge the contribution(s) of the\r\nCopyright Holder(s) and the Author(s) or with their explicit written\r\npermission.\r\n\r\n5) The Font Software, modified or unmodified, in part or in whole,\r\nmust be distributed entirely under this license, and must not be\r\ndistributed under any other license. The requirement for fonts to\r\nremain under this license does not apply to any document created\r\nusing the Font Software.\r\n\r\nTERMINATION\r\nThis license becomes null and void if any of the above conditions are\r\nnot met.\r\n\r\nDISCLAIMER\r\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r\nOTHER DEALINGS IN THE FONT SOFTWARE.\r\n"
  },
  {
    "path": "web/client/resources/js/composer.js",
    "content": "var composer = {\n\ttab: \"\\t\",\n\ttemplate: \"\",\n\tisFunc: function(scope)\n\t{\n\t\tif (!scope.title || typeof scope.depth === 'undefined')\n\t\t\treturn false;\n\n\t\treturn scope.title.indexOf(\"Test\") === 0 && scope.depth === 0;\n\t},\n\tdiscardLastKey: false\n};\n\n\n$(function()\n{\n\t// Begin layout sizing\n\tvar headerHeight = $('header').outerHeight();\n\tvar padding = $('#input, #output').css('padding-top').replace(\"px\", \"\") * 2 + 1;\n\tvar outputPlaceholder = $('#output').text();\n\n\t$(window).resize(function()\n\t{\n\t\t$('#input, #output').height($(window).height() - headerHeight - padding);\n\t});\n\n\t$(window).resize();\n\t// End layout sizing\n\n\n\t$('#input').keydown(function(e)\n\t{\n\t\t// 13=Enter, 16=Shift\n\t\tcomposer.discardLastKey = e.keyCode === 13\n\t\t\t\t\t\t\t\t|| e.keyCode === 16;\n\t}).keyup(function(e)\n\t{\n\t\tif (!composer.discardLastKey)\n\t\t\tgenerate($(this).val());\n\t});\n\n\tcomposer.template = $('#tpl-convey').text();\n\n\ttabOverride.set(document.getElementById('input'));\n\t$('#input').focus();\n});\n\n\n\n// Begin Markup.js custom pipes\nMark.pipes.recursivelyRender = function(val)\n{\n\treturn !val || val.length === 0 ? \"\\n\" : Mark.up(composer.template, val);\n}\n\nMark.pipes.indent = function(val)\n{\n\treturn new Array(val + 1).join(\"\\t\");\n}\n\nMark.pipes.notTestFunc = function(scope)\n{\n\treturn !composer.isFunc(scope);\n}\n\nMark.pipes.safeFunc = function(val)\n{\n\treturn val.replace(/[^a-z0-9_]/gi, '');\n}\n\nMark.pipes.properCase = function(str)\n{\n\tif (str.length === 0)\n\t\treturn \"\";\n\n\tstr = str.charAt(0).toUpperCase() + str.substr(1);\n\n\tif (str.length < 2)\n\t\treturn str;\n\n\treturn str.replace(/[\\s_][a-z]+/g, function(txt)\n\t{\n\t\treturn txt.charAt(0)\n\t\t\t\t+ txt.charAt(1).toUpperCase()\n\t\t\t\t+ txt.substr(2).toLowerCase();\n\t});\n}\n\nMark.pipes.showImports = function(item)\n{\n\tconsole.log(item);\n\tif (root.title === \"(root)\" && root.stories.length > 0)\n\t\treturn 'import (\\n\\t\"testing\"\\n\\t. \"github.com/smartystreets/goconvey/convey\"\\n)\\n';\n\telse\n\t\treturn \"\";\n}\n// End Markup.js custom pipes\n\n\nfunction generate(input)\n{\n\tvar root = parseInput(input);\n\t$('#output').text(Mark.up(composer.template, root.stories));\n\tif (root.stories.length > 0 && root.stories[0].title.substr(0, 4) === \"Test\")\n\t\t$('#output').prepend('import (\\n\\t\"testing\"\\n\\t. \"github.com/smartystreets/goconvey/convey\"\\n)\\n\\n');\n}\n\nfunction parseInput(input)\n{\n\tlines = input.split(\"\\n\");\n\n\tif (!lines)\n\t\treturn;\n\n\tvar root = {\n\t\ttitle: \"(root)\",\n\t\tstories: []\n\t};\n\n\tfor (i in lines)\n\t{\n\t\tline = lines[i];\n\t\tlineText = $.trim(line);\n\n\t\tif (!lineText)\n\t\t\tcontinue;\n\n\t\t// Figure out how deep to put this story\n\t\tindent = line.match(new RegExp(\"^\" + composer.tab + \"+\"));\n\t\ttabs = indent ? indent[0].length / composer.tab.length : 0;\n\n\t\t// Starting at root, traverse into the right spot in the arrays\n\t\tvar curScope = root, prevScope = root;\n\t\tfor (j = 0; j < tabs && curScope.stories.length > 0; j++)\n\t\t{\n\t\t\tcurScope = curScope.stories[curScope.stories.length - 1];\n\t\t\tprevScope = curScope;\n\t\t}\n\n\t\t// Don't go crazy, though! (avoid excessive indentation)\n\t\tif (tabs > curScope.depth + 1)\n\t\t\ttabs = curScope.depth + 1;\n\n\t\t// Only top-level Convey() calls need the *testing.T object passed in\n\t\tvar showT = composer.isFunc(prevScope)\n\t\t\t\t\t|| (!composer.isFunc(curScope)\n\t\t\t\t\t\t\t&& tabs === 0);\n\n\t\t// Save the story at this scope\n\t\tcurScope.stories.push({\n\t\t\ttitle: lineText.replace(/\"/g, \"\\\\\\\"\"),\t\t// escape quotes\n\t\t\tstories: [],\n\t\t\tdepth: tabs,\n\t\t\tshowT: showT\n\t\t});\n\t}\n\n\treturn root;\n}\n\nfunction suppress(event)\n{\n\tif (!event)\n\t\treturn false;\n\tif (event.preventDefault)\n\t\tevent.preventDefault();\n\tif (event.stopPropagation)\n\t\tevent.stopPropagation();\n\tevent.cancelBubble = true;\n\treturn false;\n}\n"
  },
  {
    "path": "web/client/resources/js/config.js",
    "content": "// Configure the GoConvey web UI client in here\n\nconvey.config = {\n\n\t// Install new themes by adding them here; the first one will be default\n\tthemes: {\n\t\t\"dark\":         { name: \"Dark\", filename: \"dark.css\", coverage: \"hsla({{hue}}, 75%, 30%, .5)\" },\n\t\t\"dark-bigtext\": { name: \"Dark-BigText\", filename: \"dark-bigtext.css\", coverage: \"hsla({{hue}}, 75%, 30%, .5)\" },\n\t\t\"light\":        { name: \"Light\", filename: \"light.css\", coverage: \"hsla({{hue}}, 62%, 75%, 1)\" }\n\t},\n\n\t// Path to the themes (end with forward-slash)\n\tthemePath: \"/resources/css/themes/\"\n\n};\n"
  },
  {
    "path": "web/client/resources/js/convey.js",
    "content": "var convey = {\n\n\t//\t*** Don't edit in here unless you're brave ***\n\n\tstatuses: {\t\t\t\t// contains some constants related to overall test status\n\t\tpass: { class: 'ok', text: \"Pass\" },\t// class name must also be that in the favicon file name\n\t\tfail: { class: 'fail', text: \"Fail\" },\n\t\tpanic: { class: 'panic', text: \"Panic\" },\n\t\tbuildfail: { class: 'buildfail', text: \"Build Failure\" }\n\t},\n\tframeCounter: 0,\t\t// gives each frame a unique ID\n\tmaxHistory: 20,\t\t\t// how many tests to keep in the history\n\tnotif: undefined,\t\t// the notification currently being displayed\n\tnotifTimer: undefined,\t// the timer that clears the notifications automatically\n\tpoller: new Poller(),\t// the server poller\n\tstatus: \"\",\t\t\t\t// what the _server_ is currently doing (not overall test results)\n\toverallClass: \"\",\t\t// class name of the \"overall\" status banner\n\ttheme: \"\",\t\t\t\t// theme currently being used\n\tpackageStates: {},\t\t// packages manually collapsed or expanded during this page's lifetime\n\tuiEffects: true,\t\t// whether visual effects are enabled\n\tframesOnSamePath: 0,\t// number of consecutive frames on this same watch path\n\tlayout: {\n\t\tselClass: \"sel\",\t// CSS class when an element is \"selected\"\n\t\theader: undefined,\t// container element of the header area (overall, controls)\n\t\tframe: undefined,\t// container element of the main body area (above footer)\n\t\tfooter: undefined\t// container element of the footer (stuck to bottom)\n\t},\n\thistory: [],\t\t\t// complete history of states (test results and aggregated data), including the current one\n\tmoments: {},\t\t\t// elements that display time relative to the current time, keyed by ID, with the moment() as a value\n\tintervals: {},\t\t\t// ntervals that execute periodically\n\tintervalFuncs: {\t\t// functions executed by each interval in convey.intervals\n\t\ttime: function()\n\t\t{\n\t\t\tvar t = new Date();\n\t\t\tvar h = zerofill(t.getHours(), 2);\n\t\t\tvar m = zerofill(t.getMinutes(), 2);\n\t\t\tvar s = zerofill(t.getSeconds(), 2);\n\t\t\t$('#time').text(h + \":\" + m + \":\" + s);\n\t\t},\n\t\tmomentjs: function()\n\t\t{\n\t\t\tfor (var id in convey.moments)\n\t\t\t\t$('#'+id).html(convey.moments[id].fromNow());\n\t\t}\n\t}\n};\n"
  },
  {
    "path": "web/client/resources/js/goconvey.js",
    "content": "$(init);\n\n$(window).load(function()\n{\n\t// Things may shift after all the elements (images/fonts) are loaded\n\t// In Chrome, calling reframe() doesn't work (maybe a quirk); we need to trigger resize\n\t$(window).resize();\n});\n\nfunction init()\n{\n\tlog(\"Welcome to GoConvey!\");\n\tlog(\"Initializing interface\");\n\tconvey.overall = emptyOverall();\n\tloadTheme();\n\t$('body').show();\n\tinitPoller();\n\twireup();\n\tlatest();\n}\n\nfunction loadTheme(thmID)\n{\n\tvar defaultTheme = \"dark\";\n\tvar linkTagId = \"themeRef\";\n\n\tif (!thmID)\n\t\tthmID = get('theme') || defaultTheme;\n\n\tlog(\"Initializing theme: \" + thmID);\n\n\tif (!convey.config.themes[thmID])\n\t{\n\t\treplacement = Object.keys(convey.config.themes)[0] || defaultTheme;\n\t\tlog(\"NOTICE: Could not find '\" + thmID + \"' theme; defaulting to '\" + replacement + \"'\");\n\t\tthmID = replacement;\n\t}\n\n\tconvey.theme = thmID;\n\tsave('theme', convey.theme);\n\n\tvar linkTag = $('#'+linkTagId);\n\tvar fullPath = convey.config.themePath\n\t\t\t\t\t+ convey.config.themes[convey.theme].filename;\n\n\tif (linkTag.length === 0)\n\t{\n\t\t$('head').append('<link rel=\"stylesheet\" href=\"'\n\t\t\t+ fullPath + '\" id=\"themeRef\">');\n\t}\n\telse\n\t\tlinkTag.attr('href', fullPath);\n\n\tcolorizeCoverageBars();\n}\n\nfunction initPoller()\n{\n\t$(convey.poller).on('serverstarting', function(event)\n\t{\n\t\tlog(\"Server is starting...\");\n\t\tconvey.status = \"starting\";\n\t\tshowServerDown(\"Server starting\");\n\t\t$('#run-tests').addClass('spin-slowly disabled');\n\t});\n\n\t$(convey.poller).on('pollsuccess', function(event, data)\n\t{\n\t\tif (convey.status !== \"starting\")\n\t\t\thideServerDown();\n\n\t\t// These two if statements determine if the server is now busy\n\t\t// (and wasn't before) or is not busy (regardless of whether it was before)\n\t\tif ((!convey.status || convey.status === \"idle\")\n\t\t\t\t&& data.status && data.status !== \"idle\")\n\t\t\t$('#run-tests').addClass('spin-slowly disabled');\n\t\telse if (convey.status !== \"idle\" && data.status === \"idle\")\n\t\t{\n\t\t\t$('#run-tests').removeClass('spin-slowly disabled');\n\t\t}\n\n\t\tswitch (data.status)\n\t\t{\n\t\t\tcase \"executing\":\n\t\t\t\t$(convey.poller).trigger('serverexec', data);\n\t\t\t\tbreak;\n\t\t\tcase \"idle\":\n\t\t\t\t$(convey.poller).trigger('serveridle', data);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconvey.status = data.status;\n\t});\n\n\t$(convey.poller).on('pollfail', function(event, data)\n\t{\n\t\tlog(\"Poll failed; server down\");\n\t\tconvey.status = \"down\";\n\t\tshowServerDown(\"Server down\");\n\t});\n\n\t$(convey.poller).on('serverexec', function(event, data)\n\t{\n\t\tlog(\"Server status: executing\");\n\t\t$('.favicon').attr('href', '/favicon.ico');\t// indicates running tests\n\t});\n\n\t$(convey.poller).on('serveridle', function(event, data)\n\t{\n\t\tlog(\"Server status: idle\");\n\t\tlog(\"Tests have finished executing\");\n\t\tlatest();\n\t});\n\n\tconvey.poller.start();\n}\n\nfunction wireup()\n{\n\tlog(\"Wireup\");\n\n\tcustomMarkupPipes();\n\n\tvar themes = [];\n\tfor (var k in convey.config.themes)\n\t\tthemes.push({ id: k, name: convey.config.themes[k].name });\n\t$('#theme').html(render('tpl-theme-enum', themes));\n\n\tenumSel(\"theme\", convey.theme);\n\n\tloadSettingsFromStorage();\n\n\t$('#stories').on('click', '.toggle-all-pkg', function(event)\n\t{\n\t\tif ($(this).closest('.story-pkg').data('pkg-state') === \"expanded\")\n\t\t\tcollapseAll();\n\t\telse\n\t\t\texpandAll();\n\t\treturn suppress(event);\n\t});\n\n\t// Wireup the settings switches\n\t$('.enum#theme').on('click', 'li:not(.sel)', function()\n\t{\n\t\tloadTheme($(this).data('theme'));\n\t});\n\t$('.enum#pkg-expand-collapse').on('click', 'li:not(.sel)', function()\n\t{\n\t\tvar newSetting = $(this).data('pkg-expand-collapse');\n\t\tconvey.packageStates = {};\n\t\tsave('pkg-expand-collapse', newSetting);\n\t\tif (newSetting === \"expanded\")\n\t\t\texpandAll();\n\t\telse\n\t\t\tcollapseAll();\n\t});\n\t$('.enum#show-debug-output').on('click', 'li:not(.sel)', function()\n\t{\n\t\tvar newSetting = $(this).data('show-debug-output');\n\t\tsave('show-debug-output', newSetting);\n\t\tsetDebugOutputUI(newSetting);\n\t});\n\t$('.enum#ui-effects').on('click', 'li:not(.sel)', function()\n\t{\n\t\tvar newSetting = $(this).data('ui-effects');\n\t\tconvey.uiEffects = newSetting;\n\t\tsave('ui-effects', newSetting);\n\t});\n\t// End settings wireup\n\n\t//wireup the notification-settings switches\n\t$('.enum#notification').on('click', 'li:not(.sel)', function()\n\t{\n\t\tvar enabled = $(this).data('notification');\n\t\tlog(\"Turning notifications \" + enabled ? 'on' : 'off');\n\t\tsave('notifications', enabled);\n\n\t\tif (notif() && 'Notification' in window)\n\t\t{\n\t\t\tif (Notification.permission !== 'denied')\n\t\t\t{\n\t\t\t\tNotification.requestPermission(function(per)\n\t\t\t\t{\n\t\t\t\t\tif (!('permission' in Notification))\n\t\t\t\t\t{\n\t\t\t\t\t\tNotification.permission = per;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\telse\n\t\t\t\tlog(\"Permission denied to show desktop notification\");\n\t\t}\n\n\t\tsetNotifUI()\n\t});\n\n\t$('.enum#notification-level').on('click', 'li:not(.sel)', function()\n\t{\n\t\tvar level = $(this).data('notification-level');\n\t\tconvey.notificationLevel = level;\n\t\tsave('notification-level', level);\n\t});\n\t// End notification-settings\n\n\tconvey.layout.header = $('header').first();\n\tconvey.layout.frame = $('.frame').first();\n\tconvey.layout.footer = $('footer').last();\n\n\tupdateWatchPath();\n\n\t$('#path').change(function()\n\t{\n\t\t// Updates the watched directory with the server and makes sure it exists\n\t\tvar tb = $(this);\n\t\tvar newpath = encodeURIComponent($.trim(tb.val()));\n\t\t$.post('/watch?root='+newpath)\n\t\t\t.done(function() { tb.removeClass('error'); })\n\t\t\t.fail(function() { tb.addClass('error'); });\n\t\tconvey.framesOnSamePath = 1;\n\t});\n\n\t$('#run-tests').click(function()\n\t{\n\t\tvar self = $(this);\n\t\tif (self.hasClass('spin-slowly') || self.hasClass('disabled'))\n\t\t\treturn;\n\t\tlog(\"Test run invoked from web UI\");\n\t\t$.get(\"/execute\");\n\t});\n\n\t$('#play-pause').click(function()\n\t{\n\t\t$.get('/pause');\n\n\t\tif ($(this).hasClass(convey.layout.selClass))\n\t\t{\n\t\t\t// Un-pausing\n\t\t\tif (!$('footer .replay').is(':visible'))\n\t\t\t\t$('footer .recording').show();\n\t\t\t$('footer .paused').hide();\n\t\t\tlog(\"Resuming auto-execution of tests\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Pausing\n\t\t\t$('footer .recording').hide();\n\t\t\t$('footer .paused').show();\n\t\t\tlog(\"Pausing auto-execution of tests\");\n\t\t}\n\n\t\t$(this).toggleClass(\"throb \" + convey.layout.selClass);\n\t});\n\n\t$('#toggle-notif').click(function()\n\t{\n\t\ttoggle($('.settings-notification'), $(this));\n\t});\n\n\t$('#show-history').click(function()\n\t{\n\t\ttoggle($('.history'), $(this));\n\t});\n\n\t$('#show-settings').click(function()\n\t{\n\t\ttoggle($('.settings-general'), $(this));\n\t});\n\n\t$('#show-gen').click(function() {\n\t\tvar writer = window.open(\"/composer.html\");\n\t\tif (window.focus)\n\t\t\twriter.focus();\n\t});\n\n\t$('.toggler').not('.narrow').prepend('<i class=\"fa fa-angle-up fa-lg\"></i>');\n\t$('.toggler.narrow').prepend('<i class=\"fa fa-angle-down fa-lg\"></i>');\n\n\t$('.toggler').not('.narrow').click(function()\n\t{\n\t\tvar target = $('#' + $(this).data('toggle'));\n\t\t$('.fa-angle-down, .fa-angle-up', this).toggleClass('fa-angle-down fa-angle-up');\n\t\ttarget.toggle();\n\t});\n\n\t$('.toggler.narrow').click(function()\n\t{\n\t\tvar target = $('#' + $(this).data('toggle'));\n\t\t$('.fa-angle-down, .fa-angle-up', this).toggleClass('fa-angle-down fa-angle-up');\n\t\ttarget.toggleClass('hide-narrow show-narrow');\n\t});\n\n\t// Enumerations are horizontal lists where one item can be selected at a time\n\t$('.enum').on('click', 'li', enumSel);\n\n\t// Start ticking time\n\tconvey.intervals.time = setInterval(convey.intervalFuncs.time, 1000);\n\tconvey.intervals.momentjs = setInterval(convey.intervalFuncs.momentjs, 5000);\n\tconvey.intervalFuncs.time();\n\n\t// Ignore/un-ignore package\n\t$('#stories').on('click', '.fa.ignore', function(event)\n\t{\n\t\tvar pkg = $(this).data('pkg');\n\t\tif ($(this).hasClass('disabled'))\n\t\t\treturn;\n\t\telse if ($(this).hasClass('unwatch'))\n\t\t\t$.get(\"/ignore\", { paths: pkg });\n\t\telse\n\t\t\t$.get(\"/reinstate\", { paths: pkg });\n\t\t$(this).toggleClass('watch unwatch fa-eye fa-eye-slash clr-red');\n\t\treturn suppress(event);\n\t});\n\n\t// Show \"All\" link when hovering the toggler on packages in the stories\n\t$('#stories').on({\n\t\tmouseenter: function() { $('.toggle-all-pkg', this).stop().show('fast'); },\n\t\tmouseleave: function() { $('.toggle-all-pkg', this).stop().hide('fast'); }\n\t}, '.pkg-toggle-container');\n\n\t// Toggle a package in the stories when clicked\n\t$('#stories').on('click', '.story-pkg', function(event)\n\t{\n\t\ttogglePackage(this, true);\n\t\treturn suppress(event);\n\t});\n\n\t// Select a story line when it is clicked\n\t$('#stories').on('click', '.story-line', function()\n\t{\n\t\t$('.story-line-sel').not(this).removeClass('story-line-sel');\n\t\t$(this).toggleClass('story-line-sel');\n\t});\n\n\t// Render a frame from the history when clicked\n\t$('.history .container').on('click', '.item', function(event)\n\t{\n\t\tvar frame = getFrame($(this).data(\"frameid\"));\n\t\tchangeStatus(frame.overall.status, true);\n\t\trenderFrame(frame);\n\t\t$(this).addClass('selected');\n\n\t\t// Update current status down in the footer\n\t\tif ($(this).is(':first-child'))\n\t\t{\n\t\t\t// Now on current frame\n\t\t\t$('footer .replay').hide();\n\n\t\t\tif ($('#play-pause').hasClass(convey.layout.selClass))\t// Was/is paused\n\t\t\t\t$('footer .paused').show();\n\t\t\telse\n\t\t\t\t$('footer .recording').show();\t\t// Was/is recording\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$('footer .recording, footer .replay').hide();\n\t\t\t$('footer .replay').show();\n\t\t}\n\t\treturn suppress(event);\n\t});\n\n\t$('footer').on('click', '.replay', function()\n\t{\n\t\t// Clicking \"REPLAY\" in the corner should bring them back to the current frame\n\t\t// and hide, if visible, the history panel for convenience\n\t\t$('.history .item:first-child').click();\n\t\tif ($('#show-history').hasClass('sel'))\n\t\t\t$('#show-history').click();\n\t});\n\n\t// Keyboard shortcuts!\n\t$(document).keydown(function(e)\n\t{\n\t\tif (e.ctrlKey || e.metaKey || e.shiftKey)\n\t\t\treturn;\n\n\t\tswitch (e.keyCode)\n\t\t{\n\t\t\tcase 67:\t\t// c\n\t\t\t\t$('#show-gen').click();\n\t\t\t\tbreak;\n\t\t\tcase 82:\t\t// r\n\t\t\t\t$('#run-tests').click();\n\t\t\t\tbreak;\n\t\t\tcase 78:\t\t// n\n\t\t\t\t$('#toggle-notif').click();\n\t\t\t\tbreak;\n\t\t\tcase 87:\t\t// w\n\t\t\t\t$('#path').focus();\n\t\t\t\tbreak;\n\t\t\tcase 80:\t\t// p\n\t\t\t\t$('#play-pause').click();\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn suppress(e);\n\t});\n\t$('body').on('keydown', 'input, textarea, select', function(e)\n\t{\n\t\t// If user is typing something, don't let this event bubble\n\t\t// up to the document to annoyingly fire keyboard shortcuts\n\t\te.stopPropagation();\n\t});\n\n\t// Wire-up the tipsy tooltips\n\tsetTooltips();\n\n\t// Keep everything positioned and sized properly on window resize\n\treframe();\n\t$(window).resize(reframe);\n}\n\nfunction setTooltips()\n{\n\tvar tips = {\n\t\t'#path': { delayIn: 500 },\n\t\t'#logo': { gravity: 'w' },\n\t\t'.controls li, .pkg-cover-name': { live: false },\n\t\t'footer .replay': { live: false, gravity: 'e' },\n\t\t'.ignore': { live: false, gravity: $.fn.tipsy.autoNS },\n\t\t'.disabled': { live: false, gravity: $.fn.tipsy.autoNS }\n\t};\n\n\tfor (var key in tips)\n\t{\n\t\t$(key).each(function(el)\n\t\t{\n\t\t\tif(!$(this).tipsy(true))\n\t\t\t\t$(this).tipsy(tips[key]);\n\t\t});\n\t}\n}\n\nfunction setDebugOutputUI(newSetting){\n\tvar $storyLine = $('.story-line');\n\tswitch(newSetting) {\n\t\tcase 'hide':\n\t\t\t$('.message', $storyLine).hide();\n\t\t\tbreak;\n\t\tcase 'fail':\n\t\t\t$('.message', $storyLine.not('.fail, .panic')).hide();\n\t\t\t$('.message', $storyLine.filter('.fail, .panic')).show();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t$('.message', $storyLine).show();\n\t\t\tbreak;\n\t}\n}\n\nfunction setNotifUI()\n{\n\tvar $toggleNotif = $('#toggle-notif').addClass(notif() ? \"fa-bell\" : \"fa-bell-o\");\n\t$toggleNotif.removeClass(!notif() ? \"fa-bell\" : \"fa-bell-o\");\n}\n\nfunction expandAll()\n{\n\t$('.story-pkg').each(function() { expandPackage($(this).data('pkg')); });\n}\n\nfunction collapseAll()\n{\n\t$('.story-pkg').each(function() { collapsePackage($(this).data('pkg')); });\n}\n\nfunction expandPackage(pkgId)\n{\n\tvar pkg = $('.story-pkg.pkg-'+pkgId);\n\tvar rows = $('.story-line.pkg-'+pkgId);\n\n\tpkg.data('pkg-state', \"expanded\").addClass('expanded').removeClass('collapsed');\n\n\t$('.pkg-toggle', pkg)\n\t\t.addClass('fa-minus-square-o')\n\t\t.removeClass('fa-plus-square-o');\n\n\trows.show();\n}\n\nfunction collapsePackage(pkgId)\n{\n\tvar pkg = $('.story-pkg.pkg-'+pkgId);\n\tvar rows = $('.story-line.pkg-'+pkgId);\n\n\tpkg.data('pkg-state', \"collapsed\").addClass('collapsed').removeClass('expanded');\n\n\t$('.pkg-toggle', pkg)\n\t\t.addClass('fa-plus-square-o')\n\t\t.removeClass('fa-minus-square-o');\n\n\trows.hide();\n}\n\nfunction togglePackage(storyPkgElem)\n{\n\tvar pkgId = $(storyPkgElem).data('pkg');\n\tif ($(storyPkgElem).data('pkg-state') === \"expanded\")\n\t{\n\t\tcollapsePackage(pkgId);\n\t\tconvey.packageStates[$(storyPkgElem).data('pkg-name')] = \"collapsed\";\n\t}\n\telse\n\t{\n\t\texpandPackage(pkgId);\n\t\tconvey.packageStates[$(storyPkgElem).data('pkg-name')] = \"expanded\";\n\t}\n}\n\nfunction loadSettingsFromStorage()\n{\n\tvar pkgExpCollapse = get(\"pkg-expand-collapse\");\n\tif (!pkgExpCollapse)\n\t{\n\t\tpkgExpCollapse = \"expanded\";\n\t\tsave(\"pkg-expand-collapse\", pkgExpCollapse);\n\t}\n\tenumSel(\"pkg-expand-collapse\", pkgExpCollapse);\n\n\tvar showDebugOutput = get(\"show-debug-output\");\n\tif (!showDebugOutput)\n\t{\n\t\tshowDebugOutput = \"show\";\n\t\tsave(\"show-debug-output\", showDebugOutput);\n\t}\n\tenumSel(\"show-debug-output\", showDebugOutput);\n\n\tvar uiEffects = get(\"ui-effects\");\n\tif (uiEffects === null)\n\t\tuiEffects = \"true\";\n\tconvey.uiEffects = uiEffects === \"true\";\n\tenumSel(\"ui-effects\", uiEffects);\n\n\tenumSel(\"notification\", \"\"+notif());\n\tvar notifLevel = get(\"notification-level\");\n\tif (notifLevel === null) \n\t{\n\t\tnotifLevel = '.*';\n\t}\n\tconvey.notificationLevel = notifLevel;\n\tenumSel(\"notification-level\", notifLevel);\n\n\tsetNotifUI();\n}\n\n\n\n\n\n\n\n\n\n\n\nfunction latest()\n{\n\tlog(\"Fetching latest test results\");\n\t$.getJSON(\"/latest\", process);\n}\n\nfunction process(data, status, jqxhr)\n{\n\tif (!data || !data.Revision)\n\t{\n\t\tlog(\"No data received or revision timestamp was missing\");\n\t\treturn;\n\t}\n\n\tif (data.Paused && !$('#play-pause').hasClass(convey.layout.selClass))\n\t{\n\t\t$('footer .recording').hide();\n\t\t$('footer .paused').show();\n\t\t$('#play-pause').toggleClass(\"throb \" + convey.layout.selClass);\n\t}\n\n\tif (current() && data.Revision === current().results.Revision)\n\t{\n\t\tlog(\"No changes\");\n\t\tchangeStatus(current().overall.status);\t// re-assures that status is unchanged\n\t\treturn;\n\t}\n\n\n\t// Put the new frame in the queue so we can use current() to get to it\n\tconvey.history.push(newFrame());\n\tconvey.framesOnSamePath++;\n\n\t// Store the raw results in our frame\n\tcurrent().results = data;\n\n\tlog(\"Updating watch path\");\n\tupdateWatchPath();\n\n\t// Remove all templated items from the DOM as we'll\n\t// replace them with new ones; also remove tipsy tooltips\n\t// that may have lingered around\n\t$('.templated, .tipsy').remove();\n\n\tvar uniqueID = 0;\n\tvar coverageAvgHelper = { countedPackages: 0, coverageSum: 0 };\n\tvar packages = {\n\t\ttested: [],\n\t\tignored: [],\n\t\tcoverage: {},\n\t\tnogofiles: [],\n\t\tnotestfiles: [],\n\t\tnotestfn: []\n\t};\n\n\tlog(\"Compiling package statistics\");\n\n\t// Look for failures and panics through the packages->tests->stories...\n\tfor (var i in data.Packages)\n\t{\n\t\tpkg = makeContext(data.Packages[i]);\n\t\tcurrent().overall.duration += pkg.Elapsed;\n\t\tpkg._id = uniqueID++;\n\n\t\tif (pkg.Outcome === \"build failure\")\n\t\t{\n\t\t\tcurrent().overall.failedBuilds++;\n\t\t\tcurrent().failedBuilds.push(pkg);\n\t\t\tcontinue;\n\t\t}\n\n\n\t\tif (pkg.Outcome === \"no go code\")\n\t\t\tpackages.nogofiles.push(pkg);\n\t\telse if (pkg.Outcome === \"no test files\")\n\t\t\tpackages.notestfiles.push(pkg);\n\t\telse if (pkg.Outcome === \"no test functions\")\n\t\t\tpackages.notestfn.push(pkg);\n\t\telse if (pkg.Outcome === \"ignored\" || pkg.Outcome === \"disabled\")\n\t\t\tpackages.ignored.push(pkg);\n\t\telse\n\t\t{\n\t\t\tif (pkg.Coverage >= 0)\n\t\t\t\tcoverageAvgHelper.coverageSum += pkg.Coverage;\n\t\t\tcoverageAvgHelper.countedPackages++;\n\t\t\tpackages.coverage[pkg.PackageName] = pkg.Coverage;\n\t\t\tpackages.tested.push(pkg);\n\t\t}\n\n\n\t\tfor (var j in pkg.TestResults)\n\t\t{\n\t\t\ttest = makeContext(pkg.TestResults[j]);\n\t\t\ttest._id = uniqueID++;\n\t\t\ttest._pkgid = pkg._id;\n\t\t\ttest._pkg = pkg.PackageName;\n\n\t\t\tif (test.Stories.length === 0)\n\t\t\t{\n\t\t\t\t// Here we've got ourselves a classic Go test,\n\t\t\t\t// not a GoConvey test that has stories and assertions\n\t\t\t\t// so we'll treat this whole test as a single assertion\n\t\t\t\tcurrent().overall.assertions++;\n\n\t\t\t\tif (test.Error)\n\t\t\t\t{\n\t\t\t\t\ttest._status = convey.statuses.panic;\n\t\t\t\t\tpkg._panicked++;\n\t\t\t\t\ttest._panicked++;\n\t\t\t\t\tcurrent().assertions.panicked.push(test);\n\t\t\t\t}\n\t\t\t\telse if (test.Passed === false)\n\t\t\t\t{\n\t\t\t\t\ttest._status = convey.statuses.fail;\n\t\t\t\t\tpkg._failed++;\n\t\t\t\t\ttest._failed++;\n\t\t\t\t\tcurrent().assertions.failed.push(test);\n\t\t\t\t}\n\t\t\t\telse if (test.Skipped)\n\t\t\t\t{\n\t\t\t\t\ttest._status = convey.statuses.skipped;\n\t\t\t\t\tpkg._skipped++;\n\t\t\t\t\ttest._skipped++;\n\t\t\t\t\tcurrent().assertions.skipped.push(test);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttest._status = convey.statuses.pass;\n\t\t\t\t\tpkg._passed++;\n\t\t\t\t\ttest._passed++;\n\t\t\t\t\tcurrent().assertions.passed.push(test);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\ttest._status = convey.statuses.pass;\n\n\t\t\tvar storyPath = [{ Depth: -1, Title: test.TestName, _id: test._id }];\t// Maintains the current assertion's story as we iterate\n\n\t\t\tfor (var k in test.Stories)\n\t\t\t{\n\t\t\t\tvar story = makeContext(test.Stories[k]);\n\n\t\t\t\tstory._id = uniqueID;\n\t\t\t\tstory._pkgid = pkg._id;\n\t\t\t\tcurrent().overall.assertions += story.Assertions.length;\n\n\t\t\t\t// Establish the current story path so we can report the context\n\t\t\t\t// of failures and panicks more conveniently at the top of the page\n\t\t\t\tif (storyPath.length > 0)\n\t\t\t\t\tfor (var x = storyPath[storyPath.length - 1].Depth; x >= test.Stories[k].Depth; x--)\n\t\t\t\t\t\tstoryPath.pop();\n\t\t\t\tstoryPath.push({ Depth: test.Stories[k].Depth, Title: test.Stories[k].Title, _id: test.Stories[k]._id });\n\n\n\t\t\t\tfor (var l in story.Assertions)\n\t\t\t\t{\n\t\t\t\t\tvar assertion = story.Assertions[l];\n\t\t\t\t\tassertion._id = uniqueID;\n\t\t\t\t\tassertion._pkg = pkg.PackageName;\n\t\t\t\t\tassertion._pkgId = pkg._id;\n\t\t\t\t\tassertion._failed = !!assertion.Failure;\n\t\t\t\t\tassertion._panicked = !!assertion.Error;\n\t\t\t\t\tassertion._maxDepth = storyPath[storyPath.length - 1].Depth;\n\t\t\t\t\t$.extend(assertion._path = [], storyPath);\n\n\t\t\t\t\tif (assertion.Failure)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrent().assertions.failed.push(assertion);\n\t\t\t\t\t\tpkg._failed++;\n\t\t\t\t\t\ttest._failed++;\n\t\t\t\t\t\tstory._failed++;\n\t\t\t\t\t}\n\t\t\t\t\tif (assertion.Error)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrent().assertions.panicked.push(assertion);\n\t\t\t\t\t\tpkg._panicked++;\n\t\t\t\t\t\ttest._panicked++;\n\t\t\t\t\t\tstory._panicked++;\n\t\t\t\t\t}\n\t\t\t\t\tif (assertion.Skipped)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrent().assertions.skipped.push(assertion);\n\t\t\t\t\t\tpkg._skipped++;\n\t\t\t\t\t\ttest._skipped++;\n\t\t\t\t\t\tstory._skipped++;\n\t\t\t\t\t}\n\t\t\t\t\tif (!assertion.Failure && !assertion.Error && !assertion.Skipped)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrent().assertions.passed.push(assertion);\n\t\t\t\t\t\tpkg._passed++;\n\t\t\t\t\t\ttest._passed++;\n\t\t\t\t\t\tstory._passed++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tassignStatus(story);\n\t\t\t\tuniqueID++;\n\t\t\t}\n\n\t\t\tif (!test.Passed && !test._failed && !test._panicked)\n\t\t\t{\n\t\t\t\t// Edge case: Developer is using the GoConvey DSL, but maybe\n\t\t\t\t// in some cases is using t.Error() instead of So() assertions.\n\t\t\t\t// This can be detected, assuming all child stories with\n\t\t\t\t// assertions (in this test) are passing.\n\t\t\t\ttest._status = convey.statuses.fail;\n\t\t\t\tpkg._failed++;\n\t\t\t\ttest._failed++;\n\t\t\t\tcurrent().assertions.failed.push(test);\n\t\t\t}\n\t\t}\n\t}\n\n\tcurrent().overall.passed = current().assertions.passed.length;\n\tcurrent().overall.panics = current().assertions.panicked.length;\n\tcurrent().overall.failures = current().assertions.failed.length;\n\tcurrent().overall.skipped = current().assertions.skipped.length;\n\n\tcurrent().overall.coverage = Math.round((coverageAvgHelper.coverageSum / (coverageAvgHelper.countedPackages || 1)) * 100) / 100;\n\tcurrent().overall.duration = Math.round(current().overall.duration * 1000) / 1000;\n\n\t// Compute the coverage delta (difference in overall coverage between now and last frame)\n\t// Only compare coverage on the same watch path\n\tvar coverDelta = current().overall.coverage;\n\tif (convey.framesOnSamePath > 2)\n\t\tcoverDelta = current().overall.coverage - convey.history[convey.history.length - 2].overall.coverage;\n\tcurrent().coverDelta = Math.round(coverDelta * 100) / 100;\n\n\n\t// Build failures trump panics,\n\t// Panics trump failures,\n\t// Failures trump pass.\n\tif (current().overall.failedBuilds)\n\t\tchangeStatus(convey.statuses.buildfail);\n\telse if (current().overall.panics)\n\t\tchangeStatus(convey.statuses.panic);\n\telse if (current().overall.failures)\n\t\tchangeStatus(convey.statuses.fail);\n\telse\n\t\tchangeStatus(convey.statuses.pass);\n\n\t// Save our organized package lists\n\tcurrent().packages = packages;\n\n\tlog(\"    Assertions: \" + current().overall.assertions);\n\tlog(\"        Passed: \" + current().overall.passed);\n\tlog(\"       Skipped: \" + current().overall.skipped);\n\tlog(\"      Failures: \" + current().overall.failures);\n\tlog(\"        Panics: \" + current().overall.panics);\n\tlog(\"Build Failures: \" + current().overall.failedBuilds);\n\tlog(\"      Coverage: \" + current().overall.coverage + \"% (\" + showCoverDelta(current().coverDelta) + \")\");\n\n\t// Save timestamp when this test was executed\n\tconvey.moments['last-test'] = moment();\n\n\n\n\t// Render... render ALL THE THINGS! (All model/state modifications are DONE!)\n\trenderFrame(current());\n\t// Now, just finish up miscellaneous UI things\n\n\n\t// Add this frame to the history pane\n\tvar framePiece = render('tpl-history', current());\n\t$('.history .container').prepend(framePiece);\n\t$('.history .item:first-child').addClass('selected');\n\tconvey.moments['frame-'+current().id] = moment();\n\tif (convey.history.length > convey.maxHistory)\n\t{\n\t\t// Delete the oldest frame out of the history pane if we have too many\n\t\tconvey.history.splice(0, 1);\n\t\t$('.history .container .item').last().remove();\n\t}\n\n\t// Now add the momentjs time to the new frame in the history\n\tconvey.intervalFuncs.momentjs();\n\n\t// Show notification, if enabled\n\tvar levelRegex = new RegExp(\"(\"+convey.notificationLevel+\")\", \"i\");\n\tif (notif() && current().overall.status.class.match(levelRegex))\n\t{\n\t\tlog(\"Showing notification\");\n\t\tif (convey.notif)\n\t\t{\n\t\t\tclearTimeout(convey.notifTimer);\n\t\t\tconvey.notif.close();\n\t\t}\n\n\t\tvar notifText = notifSummary(current());\n\n\t\tconvey.notif = new Notification(notifText.title, {\n\t\t\tbody: notifText.body,\n\t\t\ticon: $('.favicon').attr('href')\n\t\t});\n\n                convey.notif.onclick = function() { \n                  window.focus(); \n                };\n\n\t\tconvey.notifTimer = setTimeout(function() { convey.notif.close(); }, 5000);\n\t}\n\n\t// Update title in title bar\n\tif (current().overall.passed === current().overall.assertions && current().overall.status.class === \"ok\")\n\t\t$('title').text(\"GoConvey (ALL PASS)\");\n\telse\n\t\t$('title').text(\"GoConvey [\" + current().overall.status.text + \"] \" + current().overall.passed + \"/\" + current().overall.assertions);\n\n\tsetTooltips();\n\n\t// All done!\n\tlog(\"Processing complete\");\n}\n\n// Updates the entire UI given a frame from the history\nfunction renderFrame(frame)\n{\n\tlog(\"Rendering frame (id: \" + frame.id + \")\");\n\n\t$('#coverage').html(render('tpl-coverage', frame.packages.tested.sort(sortPackages)));\n\t$('#ignored').html(render('tpl-ignored', frame.packages.ignored.sort(sortPackages)));\n\t$('#nogofiles').html(render('tpl-nogofiles', frame.packages.nogofiles.sort(sortPackages)));\n\t$('#notestfiles').html(render('tpl-notestfiles', frame.packages.notestfiles.sort(sortPackages)));\n\t$('#notestfn').html(render('tpl-notestfn', frame.packages.notestfn.sort(sortPackages)));\n\n\tif (frame.overall.failedBuilds)\n\t{\n\t\t$('.buildfailures').show();\n\t\t$('#buildfailures').html(render('tpl-buildfailures', frame.failedBuilds));\n\t}\n\telse\n\t\t$('.buildfailures').hide();\n\n\tif (frame.overall.panics)\n\t{\n\t\t$('.panics').show();\n\t\t$('#panics').html(render('tpl-panics', frame.assertions.panicked));\n\t}\n\telse\n\t\t$('.panics').hide();\n\n\n\tif (frame.overall.failures)\n\t{\n\t\t$('.failures').show();\n\t\t$('#failures').html(render('tpl-failures', frame.assertions.failed));\n\t\t$(\".failure\").each(function() {\n\t\t\t$(this).prettyTextDiff();\n\t\t});\n\t}\n\telse\n\t\t$('.failures').hide();\n\n\t$('#stories').html(render('tpl-stories', frame.packages.tested.sort(sortPackages)));\n\t$('#stories').append(render('tpl-stories', frame.packages.ignored.sort(sortPackages)));\n\n\tvar pkgDefaultView = get('pkg-expand-collapse');\n\t$('.story-pkg.expanded').each(function()\n\t{\n\t\tif (pkgDefaultView === \"collapsed\" && convey.packageStates[$(this).data('pkg-name')] !== \"expanded\")\n\t\t\tcollapsePackage($(this).data('pkg'));\n\t});\n\n\tredrawCoverageBars();\n\n\t$('#assert-count').html(\"<b>\"+frame.overall.assertions+\"</b> assertion\"\n\t\t\t\t\t\t\t+ (frame.overall.assertions !== 1 ? \"s\" : \"\"));\n\t$('#skip-count').html(\"<b>\"+frame.assertions.skipped.length + \"</b> skipped\");\n\t$('#fail-count').html(\"<b>\"+frame.assertions.failed.length + \"</b> failed\");\n\t$('#panic-count').html(\"<b>\"+frame.assertions.panicked.length + \"</b> panicked\");\n\t$('#duration').html(\"<b>\"+frame.overall.duration + \"</b>s\");\n\n\t$('#narrow-assert-count').html(\"<b>\"+frame.overall.assertions+\"</b>\");\n\t$('#narrow-skip-count').html(\"<b>\"+frame.assertions.skipped.length + \"</b>\");\n\t$('#narrow-fail-count').html(\"<b>\"+frame.assertions.failed.length + \"</b>\");\n\t$('#narrow-panic-count').html(\"<b>\"+frame.assertions.panicked.length + \"</b>\");\n\n\t$('.history .item').removeClass('selected');\n\n\n\tsetDebugOutputUI(get('show-debug-output'));\n\n\tlog(\"Rendering finished\");\n}\n\n\n\n\n\n\n\nfunction enumSel(id, val)\n{\n\tif (typeof id === \"string\" && typeof val === \"string\")\n\t{\n\t\t$('.enum#'+id+' > li').each(function()\n\t\t{\n\t\t\tif ($(this).data(id).toString() === val)\n\t\t\t{\n\t\t\t\t$(this).addClass(convey.layout.selClass).siblings().removeClass(convey.layout.selClass);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t}\n\telse\n\t\t$(this).addClass(convey.layout.selClass).siblings().removeClass(convey.layout.selClass);\n}\n\nfunction toggle(jqelem, switchelem)\n{\n\tvar speed = 250;\n\tvar transition = 'easeInOutQuart';\n\tvar containerSel = '.container';\n\n\tif (!jqelem.is(':visible'))\n\t{\n\t\t$(containerSel, jqelem).css('opacity', 0);\n\t\tjqelem.stop().slideDown(speed, transition, function()\n\t\t{\n\t\t\tif (switchelem)\n\t\t\t\tswitchelem.toggleClass(convey.layout.selClass);\n\t\t\t$(containerSel, jqelem).stop().animate({\n\t\t\t\topacity: 1\n\t\t\t}, speed);\n\t\t\treframe();\n\t\t});\n\t}\n\telse\n\t{\n\t\t$(containerSel, jqelem).stop().animate({\n\t\t\topacity: 0\n\t\t}, speed, function()\n\t\t{\n\t\t\tif (switchelem)\n\t\t\t\tswitchelem.toggleClass(convey.layout.selClass);\n\t\t\tjqelem.stop().slideUp(speed, transition, function() { reframe(); });\n\t\t});\n\t}\n}\n\nfunction changeStatus(newStatus, isHistoricalFrame)\n{\n\tif (!newStatus || !newStatus.class || !newStatus.text)\n\t\tnewStatus = convey.statuses.pass;\n\n\tvar sameStatus = newStatus.class === convey.overallClass;\n\n\t// The CSS class .flash and the jQuery UI 'pulsate' effect don't play well together.\n\t// This series of callbacks does the flickering/pulsating as well as\n\t// enabling/disabling flashing in the proper order so that they don't overlap.\n\t// TODO: I suppose the pulsating could also be done with just CSS, maybe...?\n\n\tif (convey.uiEffects)\n\t{\n\t\tvar times = sameStatus ? 3 : 2;\n\t\tvar duration = sameStatus ? 500 : 300;\n\n\t\t$('.overall .status').removeClass('flash').effect(\"pulsate\", {times: times}, duration, function()\n\t\t{\n\t\t\t$(this).text(newStatus.text);\n\n\t\t\tif (newStatus !== convey.statuses.pass)\t// only flicker extra when not currently passing\n\t\t\t{\n\t\t\t\t$(this).effect(\"pulsate\", {times: 1}, 300, function()\n\t\t\t\t{\n\t\t\t\t\t$(this).effect(\"pulsate\", {times: 1}, 500, function()\n\t\t\t\t\t{\n\t\t\t\t\t\tif (newStatus === convey.statuses.panic\n\t\t\t\t\t\t\t\t|| newStatus === convey.statuses.buildfail)\n\t\t\t\t\t\t\t$(this).addClass('flash');\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t$(this).removeClass('flash');\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\telse\n\t\t$('.overall .status').text(newStatus.text);\n\n\tif (!sameStatus)\t// change the color\n\t\t$('.overall').switchClass(convey.overallClass, newStatus.class, 1000);\n\n\tif (!isHistoricalFrame)\n\t\tcurrent().overall.status = newStatus;\n\tconvey.overallClass = newStatus.class;\n\t$('.favicon').attr('href', '/resources/ico/goconvey-'+newStatus.class+'.ico');\n}\n\nfunction updateWatchPath()\n{\n\t$.get(\"/watch\", function(data)\n\t{\n\t\tvar newPath = $.trim(data);\n\t\tif (newPath !== $('#path').val())\n\t\t\tconvey.framesOnSamePath = 1;\n\t\t$('#path').val(newPath);\n\t});\n}\n\nfunction notifSummary(frame)\n{\n\tvar body = frame.overall.passed + \" passed, \";\n\n\tif (frame.overall.failedBuilds)\n\t\tbody += frame.overall.failedBuilds + \" build\" + (frame.overall.failedBuilds !== 1 ? \"s\" : \"\") + \" failed, \";\n\tif (frame.overall.failures)\n\t\tbody += frame.overall.failures + \" failed, \";\n\tif (frame.overall.panics)\n\t\tbody += frame.overall.panics + \" panicked, \";\n\tbody += frame.overall.skipped + \" skipped\";\n\n\tbody += \"\\r\\n\" + frame.overall.duration + \"s\";\n\n\tif (frame.coverDelta > 0)\n\t\tbody += \"\\r\\n↑ coverage (\" + showCoverDelta(frame.coverDelta) + \")\";\n\telse if (frame.coverDelta < 0)\n\t\tbody += \"\\r\\n↓ coverage (\" + showCoverDelta(frame.coverDelta) + \")\";\n\n\treturn {\n\t\ttitle: frame.overall.status.text.toUpperCase(),\n\t\tbody: body\n\t};\n}\n\nfunction redrawCoverageBars()\n{\n\t$('.pkg-cover-bar').each(function()\n\t{\n\t\tvar pkgName = $(this).data(\"pkg\");\n\t\tvar hue = $(this).data(\"width\");\n\t\tvar hueDiff = hue;\n\n\t\tif (convey.history.length > 1)\n\t\t{\n\t\t\tvar oldHue = convey.history[convey.history.length - 2].packages.coverage[pkgName] || 0;\n\t\t\t$(this).width(oldHue + \"%\");\n\t\t\thueDiff = hue - oldHue;\n\t\t}\n\n\t\t$(this).animate({\n\t\t\twidth: \"+=\" + hueDiff + \"%\"\n\t\t}, 1250);\n\t});\n\n\tcolorizeCoverageBars();\n}\n\nfunction colorizeCoverageBars()\n{\n\tvar colorTpl = convey.config.themes[convey.theme].coverage\n\t\t\t\t\t|| \"hsla({{hue}}, 75%, 30%, .3)\";\t//default color template\n\n\t$('.pkg-cover-bar').each(function()\n\t{\n\t\tvar hue = $(this).data(\"width\");\n\t\t$(this).css({\n\t\t\tbackground: colorTpl.replace(\"{{hue}}\", hue)\n\t\t});\n\t});\n}\n\n\nfunction getFrame(id)\n{\n\tfor (var i in convey.history)\n\t\tif (convey.history[i].id === id)\n\t\t\treturn convey.history[i];\n}\n\nfunction render(templateID, context)\n{\n\tvar tpl = $('#' + templateID).text();\n\treturn $($.trim(Mark.up(tpl, context)));\n}\n\nfunction reframe()\n{\n\tvar heightBelowHeader = $(window).height() - convey.layout.header.outerHeight();\n\tvar middleHeight = heightBelowHeader - convey.layout.footer.outerHeight();\n\tconvey.layout.frame.height(middleHeight);\n\n\tvar pathWidth = $(window).width() - $('#logo').outerWidth() - $('#control-buttons').outerWidth() - 10;\n\t$('#path-container').width(pathWidth);\n}\n\nfunction notif()\n{\n\treturn get('notifications') === \"true\";\t// stored as strings\n}\n\nfunction showServerDown(message)\n{\n\t$('.server-down .notice-message').text(message);\n\t$('.server-down').show();\n\t$('.server-not-down').hide();\n\treframe();\n}\n\nfunction hideServerDown()\n{\n\t$('.server-down').hide();\n\t$('.server-not-down').show();\n\treframe();\n}\n\nfunction log(msg)\n{\n\tvar jqLog = $('#log');\n\tif (jqLog.length > 0)\n\t{\n\t\tvar t = new Date();\n\t\tvar h = zerofill(t.getHours(), 2);\n\t\tvar m = zerofill(t.getMinutes(), 2);\n\t\tvar s = zerofill(t.getSeconds(), 2);\n\t\tvar ms = zerofill(t.getMilliseconds(), 3);\n\t\tdate = h + \":\" + m + \":\" + s + \".\" + ms;\n\n\t\t$(jqLog).append(render('tpl-log-line', { time: date, msg: msg }));\n\t\t$(jqLog).parent('.col').scrollTop(jqLog[0].scrollHeight);\n\t}\n\telse\n\t\tconsole.log(msg);\n}\n\nfunction zerofill(val, count)\n{\n\t// Cheers to http://stackoverflow.com/a/9744576/1048862\n\tvar pad = new Array(1 + count).join('0');\n\treturn (pad + val).slice(-pad.length);\n}\n\n// Sorts packages ascending by only the last part of their name\n// Can be passed into Array.sort()\nfunction sortPackages(a, b)\n{\n\tvar aPkg = splitPathName(a.PackageName);\n\tvar bPkg = splitPathName(b.PackageName);\n\n\tif (aPkg.length === 0 || bPkg.length === 0)\n\t\treturn 0;\n\n\tvar aName = aPkg.parts[aPkg.parts.length - 1].toLowerCase();\n\tvar bName = bPkg.parts[bPkg.parts.length - 1].toLowerCase();\n\n\tif (aName < bName)\n\t\treturn -1;\n\telse if (aName > bName)\n\t\treturn 1;\n\telse\n\t\treturn 0;\n\n\t/*\n\tMEMO: Use to sort by entire package name:\n\tif (a.PackageName < b.PackageName) return -1;\n\telse if (a.PackageName > b.PackageName) return 1;\n\telse return 0;\n\t*/\n}\n\nfunction get(key)\n{\n\tvar val = localStorage.getItem(key);\n\tif (val && (val[0] === '[' || val[0] === '{'))\n\t\treturn JSON.parse(val);\n\telse\n\t\treturn val;\n}\n\nfunction save(key, val)\n{\n\tif (typeof val === 'object')\n\t\tval = JSON.stringify(val);\n\telse if (typeof val === 'number' || typeof val === 'boolean')\n\t\tval = val.toString();\n\tlocalStorage.setItem(key, val);\n}\n\nfunction splitPathName(str)\n{\n\tvar delim = str.indexOf('\\\\') > -1 ? '\\\\' : '/';\n\treturn { delim: delim, parts: str.split(delim) };\n}\n\nfunction newFrame()\n{\n\treturn {\n\t\tresults: {},\t\t\t\t\t// response from server (with some of our own context info)\n\t\tpackages: {},\t\t\t\t\t// packages organized into statuses for convenience (like with coverage)\n\t\toverall: emptyOverall(),\t\t// overall status info, compiled from server's response\n\t\tassertions: emptyAssertions(),\t// lists of assertions, compiled from server's response\n\t\tfailedBuilds: [],\t\t\t\t// list of packages that failed to build\n\t\ttimestamp: moment(),\t\t\t// the timestamp of this \"freeze-state\"\n\t\tid: convey.frameCounter++,\t\t// unique ID for this frame\n\t\tcoverDelta: 0\t\t\t\t\t// difference in total coverage from the last frame to this one\n\t};\n}\n\nfunction emptyOverall()\n{\n\treturn {\n\t\tstatus: {},\n\t\tduration: 0,\n\t\tassertions: 0,\n\t\tpassed: 0,\n\t\tpanics: 0,\n\t\tfailures: 0,\n\t\tskipped: 0,\n\t\tfailedBuilds: 0,\n\t\tcoverage: 0\n\t};\n}\n\nfunction emptyAssertions()\n{\n\treturn {\n\t\tpassed: [],\n\t\tfailed: [],\n\t\tpanicked: [],\n\t\tskipped: []\n\t};\n}\n\nfunction makeContext(obj)\n{\n\tobj._passed = 0;\n\tobj._failed = 0;\n\tobj._panicked = 0;\n\tobj._skipped = 0;\n\tobj._status = '';\n\treturn obj;\n}\n\nfunction current()\n{\n\treturn convey.history[convey.history.length - 1];\n}\n\nfunction assignStatus(obj)\n{\n\tif (obj._skipped)\n\t\tobj._status = 'skip';\n\telse if (obj.Outcome === \"ignored\")\n\t\tobj._status = convey.statuses.ignored;\n\telse if (obj._panicked)\n\t\tobj._status = convey.statuses.panic;\n\telse if (obj._failed || obj.Outcome === \"failed\")\n\t\tobj._status = convey.statuses.fail;\n\telse\n\t\tobj._status = convey.statuses.pass;\n}\n\nfunction showCoverDelta(delta)\n{\n\tif (delta > 0)\n\t\treturn \"+\" + delta + \"%\";\n\telse if (delta === 0)\n\t\treturn \"±\" + delta + \"%\";\n\telse\n\t\treturn delta + \"%\";\n}\n\nfunction customMarkupPipes()\n{\n\t// MARKUP.JS custom pipes\n\tMark.pipes.relativePath = function(str)\n\t{\n\t\tbasePath = new RegExp($('#path').val()+'[\\\\/]', 'gi');\n\t\treturn str.replace(basePath, '');\n\t};\n\tMark.pipes.htmlSafe = function(str)\n\t{\n\t\treturn str.replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n\t};\n\tMark.pipes.ansiColours = ansispan;\n\tMark.pipes.boldPkgName = function(str)\n\t{\n\t\tvar pkg = splitPathName(str);\n\t\tpkg.parts[0] = '<span class=\"not-pkg-name\">' + pkg.parts[0];\n\t\tpkg.parts[pkg.parts.length - 1] = \"</span><b>\" + pkg.parts[pkg.parts.length - 1] + \"</b>\";\n\t\treturn pkg.parts.join(pkg.delim);\n\t};\n\tMark.pipes.needsDiff = function(test)\n\t{\n\t\treturn !!test.Failure && (test.Expected !== \"\" || test.Actual !== \"\");\n\t};\n\tMark.pipes.coveragePct = function(str)\n\t{\n\t\t// Expected input: 75% to be represented as: \"75.0\"\n\t\tvar num = parseInt(str);\t// we only need int precision\n\t\tif (num < 0)\n\t\t\treturn \"0\";\n\t\telse if (num <= 5)\n\t\t\treturn \"5\";\t// Still shows low coverage\n\t\telse if (num > 100)\n\t\t\tstr = \"100\";\n\t\treturn str;\n\t};\n\tMark.pipes.coverageDisplay = function(str)\n\t{\n\t\tvar num = parseFloat(str);\n\t\treturn num < 0 ? \"\" : num + \"% coverage\";\n\t};\n\tMark.pipes.coverageReportName = function(str)\n\t{\n\t\treturn str.replace(/\\//g, \"-\");\n\t};\n}\n\nfunction suppress(event)\n{\n\tif (!event)\n\t\treturn false;\n\tif (event.preventDefault)\n\t\tevent.preventDefault();\n\tif (event.stopPropagation)\n\t\tevent.stopPropagation();\n\tevent.cancelBubble = true;\n\treturn false;\n}\n"
  },
  {
    "path": "web/client/resources/js/lib/ansispan.js",
    "content": "/*\nCopyright (C) 2011 by Maciej Małecki\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n\nvar ansispan = function (str) {\n  Object.keys(ansispan.foregroundColors).forEach(function (ansi) {\n    var span = '<span class=\"ansi-' + ansispan.foregroundColors[ansi] + '\">';\n\n    //\n    // `\\033[Xm` == `\\033[0;Xm` sets foreground color to `X`.\n    //\n\n    str = str.replace(\n      new RegExp('\\033\\\\[' + ansi + 'm', 'g'),\n      span\n    ).replace(\n      new RegExp('\\033\\\\[0;' + ansi + 'm', 'g'),\n      span\n    );\n  });\n  //\n  // `\\033[1m` enables bold font, `\\033[22m` disables it\n  //\n  str = str.replace(/\\033\\[1m/g, '<b>').replace(/\\033\\[22m/g, '</b>');\n\n  //\n  // `\\033[3m` enables italics font, `\\033[23m` disables it\n  //\n  str = str.replace(/\\033\\[3m/g, '<i>').replace(/\\033\\[23m/g, '</i>');\n\n  str = str.replace(/\\033\\[m/g, '</span>');\n  str = str.replace(/\\033\\[0m/g, '</span>');\n  return str.replace(/\\033\\[39m/g, '</span>');\n};\n\nansispan.foregroundColors = {\n  '30': 'black',\n  '31': 'red',\n  '32': 'green',\n  '33': 'yellow',\n  '34': 'blue',\n  '35': 'purple',\n  '36': 'cyan',\n  '37': 'white'\n};\n\nif (typeof module !== 'undefined' && module.exports) {\n  module.exports = ansispan;\n}\n"
  },
  {
    "path": "web/client/resources/js/lib/diff_match_patch.js",
    "content": "/**\n * Diff Match and Patch\n *\n * Copyright 2006 Google Inc.\n * http://code.google.com/p/google-diff-match-patch/\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Computes the difference between two texts to create a patch.\n * Applies the patch onto another text, allowing for errors.\n * @author fraser@google.com (Neil Fraser)\n */\n\n/**\n * Class containing the diff, match and patch methods.\n * @constructor\n */\nfunction diff_match_patch() {\n\n  // Defaults.\n  // Redefine these in your program to override the defaults.\n\n  // Number of seconds to map a diff before giving up (0 for infinity).\n  this.Diff_Timeout = 1.0;\n  // Cost of an empty edit operation in terms of edit characters.\n  this.Diff_EditCost = 4;\n  // At what point is no match declared (0.0 = perfection, 1.0 = very loose).\n  this.Match_Threshold = 0.5;\n  // How far to search for a match (0 = exact location, 1000+ = broad match).\n  // A match this many characters away from the expected location will add\n  // 1.0 to the score (0.0 is a perfect match).\n  this.Match_Distance = 1000;\n  // When deleting a large block of text (over ~64 characters), how close do\n  // the contents have to be to match the expected contents. (0.0 = perfection,\n  // 1.0 = very loose).  Note that Match_Threshold controls how closely the\n  // end points of a delete need to match.\n  this.Patch_DeleteThreshold = 0.5;\n  // Chunk size for context length.\n  this.Patch_Margin = 4;\n\n  // The number of bits in an int.\n  this.Match_MaxBits = 32;\n}\n\n\n//  DIFF FUNCTIONS\n\n\n/**\n * The data structure representing a diff is an array of tuples:\n * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]\n * which means: delete 'Hello', add 'Goodbye' and keep ' world.'\n */\nvar DIFF_DELETE = -1;\nvar DIFF_INSERT = 1;\nvar DIFF_EQUAL = 0;\n\n/** @typedef {{0: number, 1: string}} */\ndiff_match_patch.Diff;\n\n\n/**\n * Find the differences between two texts.  Simplifies the problem by stripping\n * any common prefix or suffix off the texts before diffing.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean=} opt_checklines Optional speedup flag. If present and false,\n *     then don't run a line-level diff first to identify the changed areas.\n *     Defaults to true, which does a faster, slightly less optimal diff.\n * @param {number} opt_deadline Optional time when the diff should be complete\n *     by.  Used internally for recursive calls.  Users should set DiffTimeout\n *     instead.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_main = function(text1, text2, opt_checklines,\n    opt_deadline) {\n  // Set a deadline by which time the diff must be complete.\n  if (typeof opt_deadline == 'undefined') {\n    if (this.Diff_Timeout <= 0) {\n      opt_deadline = Number.MAX_VALUE;\n    } else {\n      opt_deadline = (new Date).getTime() + this.Diff_Timeout * 1000;\n    }\n  }\n  var deadline = opt_deadline;\n\n  // Check for null inputs.\n  if (text1 == null || text2 == null) {\n    throw new Error('Null input. (diff_main)');\n  }\n\n  // Check for equality (speedup).\n  if (text1 == text2) {\n    if (text1) {\n      return [[DIFF_EQUAL, text1]];\n    }\n    return [];\n  }\n\n  if (typeof opt_checklines == 'undefined') {\n    opt_checklines = true;\n  }\n  var checklines = opt_checklines;\n\n  // Trim off common prefix (speedup).\n  var commonlength = this.diff_commonPrefix(text1, text2);\n  var commonprefix = text1.substring(0, commonlength);\n  text1 = text1.substring(commonlength);\n  text2 = text2.substring(commonlength);\n\n  // Trim off common suffix (speedup).\n  commonlength = this.diff_commonSuffix(text1, text2);\n  var commonsuffix = text1.substring(text1.length - commonlength);\n  text1 = text1.substring(0, text1.length - commonlength);\n  text2 = text2.substring(0, text2.length - commonlength);\n\n  // Compute the diff on the middle block.\n  var diffs = this.diff_compute_(text1, text2, checklines, deadline);\n\n  // Restore the prefix and suffix.\n  if (commonprefix) {\n    diffs.unshift([DIFF_EQUAL, commonprefix]);\n  }\n  if (commonsuffix) {\n    diffs.push([DIFF_EQUAL, commonsuffix]);\n  }\n  this.diff_cleanupMerge(diffs);\n  return diffs;\n};\n\n\n/**\n * Find the differences between two texts.  Assumes that the texts do not\n * have any common prefix or suffix.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean} checklines Speedup flag.  If false, then don't run a\n *     line-level diff first to identify the changed areas.\n *     If true, then run a faster, slightly less optimal diff.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_compute_ = function(text1, text2, checklines,\n    deadline) {\n  var diffs;\n\n  if (!text1) {\n    // Just add some text (speedup).\n    return [[DIFF_INSERT, text2]];\n  }\n\n  if (!text2) {\n    // Just delete some text (speedup).\n    return [[DIFF_DELETE, text1]];\n  }\n\n  var longtext = text1.length > text2.length ? text1 : text2;\n  var shorttext = text1.length > text2.length ? text2 : text1;\n  var i = longtext.indexOf(shorttext);\n  if (i != -1) {\n    // Shorter text is inside the longer text (speedup).\n    diffs = [[DIFF_INSERT, longtext.substring(0, i)],\n             [DIFF_EQUAL, shorttext],\n             [DIFF_INSERT, longtext.substring(i + shorttext.length)]];\n    // Swap insertions for deletions if diff is reversed.\n    if (text1.length > text2.length) {\n      diffs[0][0] = diffs[2][0] = DIFF_DELETE;\n    }\n    return diffs;\n  }\n\n  if (shorttext.length == 1) {\n    // Single character string.\n    // After the previous speedup, the character can't be an equality.\n    return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n  }\n\n  // Check to see if the problem can be split in two.\n  var hm = this.diff_halfMatch_(text1, text2);\n  if (hm) {\n    // A half-match was found, sort out the return data.\n    var text1_a = hm[0];\n    var text1_b = hm[1];\n    var text2_a = hm[2];\n    var text2_b = hm[3];\n    var mid_common = hm[4];\n    // Send both pairs off for separate processing.\n    var diffs_a = this.diff_main(text1_a, text2_a, checklines, deadline);\n    var diffs_b = this.diff_main(text1_b, text2_b, checklines, deadline);\n    // Merge the results.\n    return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b);\n  }\n\n  if (checklines && text1.length > 100 && text2.length > 100) {\n    return this.diff_lineMode_(text1, text2, deadline);\n  }\n\n  return this.diff_bisect_(text1, text2, deadline);\n};\n\n\n/**\n * Do a quick line-level diff on both strings, then rediff the parts for\n * greater accuracy.\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_lineMode_ = function(text1, text2, deadline) {\n  // Scan the text on a line-by-line basis first.\n  var a = this.diff_linesToChars_(text1, text2);\n  text1 = a.chars1;\n  text2 = a.chars2;\n  var linearray = a.lineArray;\n\n  var diffs = this.diff_main(text1, text2, false, deadline);\n\n  // Convert the diff back to original text.\n  this.diff_charsToLines_(diffs, linearray);\n  // Eliminate freak matches (e.g. blank lines)\n  this.diff_cleanupSemantic(diffs);\n\n  // Rediff any replacement blocks, this time character-by-character.\n  // Add a dummy entry at the end.\n  diffs.push([DIFF_EQUAL, '']);\n  var pointer = 0;\n  var count_delete = 0;\n  var count_insert = 0;\n  var text_delete = '';\n  var text_insert = '';\n  while (pointer < diffs.length) {\n    switch (diffs[pointer][0]) {\n      case DIFF_INSERT:\n        count_insert++;\n        text_insert += diffs[pointer][1];\n        break;\n      case DIFF_DELETE:\n        count_delete++;\n        text_delete += diffs[pointer][1];\n        break;\n      case DIFF_EQUAL:\n        // Upon reaching an equality, check for prior redundancies.\n        if (count_delete >= 1 && count_insert >= 1) {\n          // Delete the offending records and add the merged ones.\n          diffs.splice(pointer - count_delete - count_insert,\n                       count_delete + count_insert);\n          pointer = pointer - count_delete - count_insert;\n          var a = this.diff_main(text_delete, text_insert, false, deadline);\n          for (var j = a.length - 1; j >= 0; j--) {\n            diffs.splice(pointer, 0, a[j]);\n          }\n          pointer = pointer + a.length;\n        }\n        count_insert = 0;\n        count_delete = 0;\n        text_delete = '';\n        text_insert = '';\n        break;\n    }\n    pointer++;\n  }\n  diffs.pop();  // Remove the dummy entry at the end.\n\n  return diffs;\n};\n\n\n/**\n * Find the 'middle snake' of a diff, split the problem in two\n * and return the recursively constructed diff.\n * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_bisect_ = function(text1, text2, deadline) {\n  // Cache the text lengths to prevent multiple calls.\n  var text1_length = text1.length;\n  var text2_length = text2.length;\n  var max_d = Math.ceil((text1_length + text2_length) / 2);\n  var v_offset = max_d;\n  var v_length = 2 * max_d;\n  var v1 = new Array(v_length);\n  var v2 = new Array(v_length);\n  // Setting all elements to -1 is faster in Chrome & Firefox than mixing\n  // integers and undefined.\n  for (var x = 0; x < v_length; x++) {\n    v1[x] = -1;\n    v2[x] = -1;\n  }\n  v1[v_offset + 1] = 0;\n  v2[v_offset + 1] = 0;\n  var delta = text1_length - text2_length;\n  // If the total number of characters is odd, then the front path will collide\n  // with the reverse path.\n  var front = (delta % 2 != 0);\n  // Offsets for start and end of k loop.\n  // Prevents mapping of space beyond the grid.\n  var k1start = 0;\n  var k1end = 0;\n  var k2start = 0;\n  var k2end = 0;\n  for (var d = 0; d < max_d; d++) {\n    // Bail out if deadline is reached.\n    if ((new Date()).getTime() > deadline) {\n      break;\n    }\n\n    // Walk the front path one step.\n    for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {\n      var k1_offset = v_offset + k1;\n      var x1;\n      if (k1 == -d || (k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1])) {\n        x1 = v1[k1_offset + 1];\n      } else {\n        x1 = v1[k1_offset - 1] + 1;\n      }\n      var y1 = x1 - k1;\n      while (x1 < text1_length && y1 < text2_length &&\n             text1.charAt(x1) == text2.charAt(y1)) {\n        x1++;\n        y1++;\n      }\n      v1[k1_offset] = x1;\n      if (x1 > text1_length) {\n        // Ran off the right of the graph.\n        k1end += 2;\n      } else if (y1 > text2_length) {\n        // Ran off the bottom of the graph.\n        k1start += 2;\n      } else if (front) {\n        var k2_offset = v_offset + delta - k1;\n        if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] != -1) {\n          // Mirror x2 onto top-left coordinate system.\n          var x2 = text1_length - v2[k2_offset];\n          if (x1 >= x2) {\n            // Overlap detected.\n            return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);\n          }\n        }\n      }\n    }\n\n    // Walk the reverse path one step.\n    for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {\n      var k2_offset = v_offset + k2;\n      var x2;\n      if (k2 == -d || (k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1])) {\n        x2 = v2[k2_offset + 1];\n      } else {\n        x2 = v2[k2_offset - 1] + 1;\n      }\n      var y2 = x2 - k2;\n      while (x2 < text1_length && y2 < text2_length &&\n             text1.charAt(text1_length - x2 - 1) ==\n             text2.charAt(text2_length - y2 - 1)) {\n        x2++;\n        y2++;\n      }\n      v2[k2_offset] = x2;\n      if (x2 > text1_length) {\n        // Ran off the left of the graph.\n        k2end += 2;\n      } else if (y2 > text2_length) {\n        // Ran off the top of the graph.\n        k2start += 2;\n      } else if (!front) {\n        var k1_offset = v_offset + delta - k2;\n        if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] != -1) {\n          var x1 = v1[k1_offset];\n          var y1 = v_offset + x1 - k1_offset;\n          // Mirror x2 onto top-left coordinate system.\n          x2 = text1_length - x2;\n          if (x1 >= x2) {\n            // Overlap detected.\n            return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);\n          }\n        }\n      }\n    }\n  }\n  // Diff took too long and hit the deadline or\n  // number of diffs equals number of characters, no commonality at all.\n  return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n};\n\n\n/**\n * Given the location of the 'middle snake', split the diff in two parts\n * and recurse.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} x Index of split point in text1.\n * @param {number} y Index of split point in text2.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @private\n */\ndiff_match_patch.prototype.diff_bisectSplit_ = function(text1, text2, x, y,\n    deadline) {\n  var text1a = text1.substring(0, x);\n  var text2a = text2.substring(0, y);\n  var text1b = text1.substring(x);\n  var text2b = text2.substring(y);\n\n  // Compute both diffs serially.\n  var diffs = this.diff_main(text1a, text2a, false, deadline);\n  var diffsb = this.diff_main(text1b, text2b, false, deadline);\n\n  return diffs.concat(diffsb);\n};\n\n\n/**\n * Split two texts into an array of strings.  Reduce the texts to a string of\n * hashes where each Unicode character represents one line.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {{chars1: string, chars2: string, lineArray: !Array.<string>}}\n *     An object containing the encoded text1, the encoded text2 and\n *     the array of unique strings.\n *     The zeroth element of the array of unique strings is intentionally blank.\n * @private\n */\ndiff_match_patch.prototype.diff_linesToChars_ = function(text1, text2) {\n  var lineArray = [];  // e.g. lineArray[4] == 'Hello\\n'\n  var lineHash = {};   // e.g. lineHash['Hello\\n'] == 4\n\n  // '\\x00' is a valid character, but various debuggers don't like it.\n  // So we'll insert a junk entry to avoid generating a null character.\n  lineArray[0] = '';\n\n  /**\n   * Split a text into an array of strings.  Reduce the texts to a string of\n   * hashes where each Unicode character represents one line.\n   * Modifies linearray and linehash through being a closure.\n   * @param {string} text String to encode.\n   * @return {string} Encoded string.\n   * @private\n   */\n  function diff_linesToCharsMunge_(text) {\n    var chars = '';\n    // Walk the text, pulling out a substring for each line.\n    // text.split('\\n') would would temporarily double our memory footprint.\n    // Modifying text would create many large strings to garbage collect.\n    var lineStart = 0;\n    var lineEnd = -1;\n    // Keeping our own length variable is faster than looking it up.\n    var lineArrayLength = lineArray.length;\n    while (lineEnd < text.length - 1) {\n      lineEnd = text.indexOf('\\n', lineStart);\n      if (lineEnd == -1) {\n        lineEnd = text.length - 1;\n      }\n      var line = text.substring(lineStart, lineEnd + 1);\n      lineStart = lineEnd + 1;\n\n      if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) :\n          (lineHash[line] !== undefined)) {\n        chars += String.fromCharCode(lineHash[line]);\n      } else {\n        chars += String.fromCharCode(lineArrayLength);\n        lineHash[line] = lineArrayLength;\n        lineArray[lineArrayLength++] = line;\n      }\n    }\n    return chars;\n  }\n\n  var chars1 = diff_linesToCharsMunge_(text1);\n  var chars2 = diff_linesToCharsMunge_(text2);\n  return {chars1: chars1, chars2: chars2, lineArray: lineArray};\n};\n\n\n/**\n * Rehydrate the text in a diff from a string of line hashes to real lines of\n * text.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @param {!Array.<string>} lineArray Array of unique strings.\n * @private\n */\ndiff_match_patch.prototype.diff_charsToLines_ = function(diffs, lineArray) {\n  for (var x = 0; x < diffs.length; x++) {\n    var chars = diffs[x][1];\n    var text = [];\n    for (var y = 0; y < chars.length; y++) {\n      text[y] = lineArray[chars.charCodeAt(y)];\n    }\n    diffs[x][1] = text.join('');\n  }\n};\n\n\n/**\n * Determine the common prefix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the start of each\n *     string.\n */\ndiff_match_patch.prototype.diff_commonPrefix = function(text1, text2) {\n  // Quick check for common null cases.\n  if (!text1 || !text2 || text1.charAt(0) != text2.charAt(0)) {\n    return 0;\n  }\n  // Binary search.\n  // Performance analysis: http://neil.fraser.name/news/2007/10/09/\n  var pointermin = 0;\n  var pointermax = Math.min(text1.length, text2.length);\n  var pointermid = pointermax;\n  var pointerstart = 0;\n  while (pointermin < pointermid) {\n    if (text1.substring(pointerstart, pointermid) ==\n        text2.substring(pointerstart, pointermid)) {\n      pointermin = pointermid;\n      pointerstart = pointermin;\n    } else {\n      pointermax = pointermid;\n    }\n    pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n  }\n  return pointermid;\n};\n\n\n/**\n * Determine the common suffix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of each string.\n */\ndiff_match_patch.prototype.diff_commonSuffix = function(text1, text2) {\n  // Quick check for common null cases.\n  if (!text1 || !text2 ||\n      text1.charAt(text1.length - 1) != text2.charAt(text2.length - 1)) {\n    return 0;\n  }\n  // Binary search.\n  // Performance analysis: http://neil.fraser.name/news/2007/10/09/\n  var pointermin = 0;\n  var pointermax = Math.min(text1.length, text2.length);\n  var pointermid = pointermax;\n  var pointerend = 0;\n  while (pointermin < pointermid) {\n    if (text1.substring(text1.length - pointermid, text1.length - pointerend) ==\n        text2.substring(text2.length - pointermid, text2.length - pointerend)) {\n      pointermin = pointermid;\n      pointerend = pointermin;\n    } else {\n      pointermax = pointermid;\n    }\n    pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n  }\n  return pointermid;\n};\n\n\n/**\n * Determine if the suffix of one string is the prefix of another.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of the first\n *     string and the start of the second string.\n * @private\n */\ndiff_match_patch.prototype.diff_commonOverlap_ = function(text1, text2) {\n  // Cache the text lengths to prevent multiple calls.\n  var text1_length = text1.length;\n  var text2_length = text2.length;\n  // Eliminate the null case.\n  if (text1_length == 0 || text2_length == 0) {\n    return 0;\n  }\n  // Truncate the longer string.\n  if (text1_length > text2_length) {\n    text1 = text1.substring(text1_length - text2_length);\n  } else if (text1_length < text2_length) {\n    text2 = text2.substring(0, text1_length);\n  }\n  var text_length = Math.min(text1_length, text2_length);\n  // Quick check for the worst case.\n  if (text1 == text2) {\n    return text_length;\n  }\n\n  // Start by looking for a single character match\n  // and increase length until no match is found.\n  // Performance analysis: http://neil.fraser.name/news/2010/11/04/\n  var best = 0;\n  var length = 1;\n  while (true) {\n    var pattern = text1.substring(text_length - length);\n    var found = text2.indexOf(pattern);\n    if (found == -1) {\n      return best;\n    }\n    length += found;\n    if (found == 0 || text1.substring(text_length - length) ==\n        text2.substring(0, length)) {\n      best = length;\n      length++;\n    }\n  }\n};\n\n\n/**\n * Do the two texts share a substring which is at least half the length of the\n * longer text?\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {Array.<string>} Five element Array, containing the prefix of\n *     text1, the suffix of text1, the prefix of text2, the suffix of\n *     text2 and the common middle.  Or null if there was no match.\n * @private\n */\ndiff_match_patch.prototype.diff_halfMatch_ = function(text1, text2) {\n  if (this.Diff_Timeout <= 0) {\n    // Don't risk returning a non-optimal diff if we have unlimited time.\n    return null;\n  }\n  var longtext = text1.length > text2.length ? text1 : text2;\n  var shorttext = text1.length > text2.length ? text2 : text1;\n  if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {\n    return null;  // Pointless.\n  }\n  var dmp = this;  // 'this' becomes 'window' in a closure.\n\n  /**\n   * Does a substring of shorttext exist within longtext such that the substring\n   * is at least half the length of longtext?\n   * Closure, but does not reference any external variables.\n   * @param {string} longtext Longer string.\n   * @param {string} shorttext Shorter string.\n   * @param {number} i Start index of quarter length substring within longtext.\n   * @return {Array.<string>} Five element Array, containing the prefix of\n   *     longtext, the suffix of longtext, the prefix of shorttext, the suffix\n   *     of shorttext and the common middle.  Or null if there was no match.\n   * @private\n   */\n  function diff_halfMatchI_(longtext, shorttext, i) {\n    // Start with a 1/4 length substring at position i as a seed.\n    var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));\n    var j = -1;\n    var best_common = '';\n    var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;\n    while ((j = shorttext.indexOf(seed, j + 1)) != -1) {\n      var prefixLength = dmp.diff_commonPrefix(longtext.substring(i),\n                                               shorttext.substring(j));\n      var suffixLength = dmp.diff_commonSuffix(longtext.substring(0, i),\n                                               shorttext.substring(0, j));\n      if (best_common.length < suffixLength + prefixLength) {\n        best_common = shorttext.substring(j - suffixLength, j) +\n            shorttext.substring(j, j + prefixLength);\n        best_longtext_a = longtext.substring(0, i - suffixLength);\n        best_longtext_b = longtext.substring(i + prefixLength);\n        best_shorttext_a = shorttext.substring(0, j - suffixLength);\n        best_shorttext_b = shorttext.substring(j + prefixLength);\n      }\n    }\n    if (best_common.length * 2 >= longtext.length) {\n      return [best_longtext_a, best_longtext_b,\n              best_shorttext_a, best_shorttext_b, best_common];\n    } else {\n      return null;\n    }\n  }\n\n  // First check if the second quarter is the seed for a half-match.\n  var hm1 = diff_halfMatchI_(longtext, shorttext,\n                             Math.ceil(longtext.length / 4));\n  // Check again based on the third quarter.\n  var hm2 = diff_halfMatchI_(longtext, shorttext,\n                             Math.ceil(longtext.length / 2));\n  var hm;\n  if (!hm1 && !hm2) {\n    return null;\n  } else if (!hm2) {\n    hm = hm1;\n  } else if (!hm1) {\n    hm = hm2;\n  } else {\n    // Both matched.  Select the longest.\n    hm = hm1[4].length > hm2[4].length ? hm1 : hm2;\n  }\n\n  // A half-match was found, sort out the return data.\n  var text1_a, text1_b, text2_a, text2_b;\n  if (text1.length > text2.length) {\n    text1_a = hm[0];\n    text1_b = hm[1];\n    text2_a = hm[2];\n    text2_b = hm[3];\n  } else {\n    text2_a = hm[0];\n    text2_b = hm[1];\n    text1_a = hm[2];\n    text1_b = hm[3];\n  }\n  var mid_common = hm[4];\n  return [text1_a, text1_b, text2_a, text2_b, mid_common];\n};\n\n\n/**\n * Reduce the number of edits by eliminating semantically trivial equalities.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupSemantic = function(diffs) {\n  var changes = false;\n  var equalities = [];  // Stack of indices where equalities are found.\n  var equalitiesLength = 0;  // Keeping our own length var is faster in JS.\n  /** @type {?string} */\n  var lastequality = null;\n  // Always equal to diffs[equalities[equalitiesLength - 1]][1]\n  var pointer = 0;  // Index of current position.\n  // Number of characters that changed prior to the equality.\n  var length_insertions1 = 0;\n  var length_deletions1 = 0;\n  // Number of characters that changed after the equality.\n  var length_insertions2 = 0;\n  var length_deletions2 = 0;\n  while (pointer < diffs.length) {\n    if (diffs[pointer][0] == DIFF_EQUAL) {  // Equality found.\n      equalities[equalitiesLength++] = pointer;\n      length_insertions1 = length_insertions2;\n      length_deletions1 = length_deletions2;\n      length_insertions2 = 0;\n      length_deletions2 = 0;\n      lastequality = diffs[pointer][1];\n    } else {  // An insertion or deletion.\n      if (diffs[pointer][0] == DIFF_INSERT) {\n        length_insertions2 += diffs[pointer][1].length;\n      } else {\n        length_deletions2 += diffs[pointer][1].length;\n      }\n      // Eliminate an equality that is smaller or equal to the edits on both\n      // sides of it.\n      if (lastequality && (lastequality.length <=\n          Math.max(length_insertions1, length_deletions1)) &&\n          (lastequality.length <= Math.max(length_insertions2,\n                                           length_deletions2))) {\n        // Duplicate record.\n        diffs.splice(equalities[equalitiesLength - 1], 0,\n                     [DIFF_DELETE, lastequality]);\n        // Change second copy to insert.\n        diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;\n        // Throw away the equality we just deleted.\n        equalitiesLength--;\n        // Throw away the previous equality (it needs to be reevaluated).\n        equalitiesLength--;\n        pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;\n        length_insertions1 = 0;  // Reset the counters.\n        length_deletions1 = 0;\n        length_insertions2 = 0;\n        length_deletions2 = 0;\n        lastequality = null;\n        changes = true;\n      }\n    }\n    pointer++;\n  }\n\n  // Normalize the diff.\n  if (changes) {\n    this.diff_cleanupMerge(diffs);\n  }\n  this.diff_cleanupSemanticLossless(diffs);\n\n  // Find any overlaps between deletions and insertions.\n  // e.g: <del>abcxxx</del><ins>xxxdef</ins>\n  //   -> <del>abc</del>xxx<ins>def</ins>\n  // e.g: <del>xxxabc</del><ins>defxxx</ins>\n  //   -> <ins>def</ins>xxx<del>abc</del>\n  // Only extract an overlap if it is as big as the edit ahead or behind it.\n  pointer = 1;\n  while (pointer < diffs.length) {\n    if (diffs[pointer - 1][0] == DIFF_DELETE &&\n        diffs[pointer][0] == DIFF_INSERT) {\n      var deletion = diffs[pointer - 1][1];\n      var insertion = diffs[pointer][1];\n      var overlap_length1 = this.diff_commonOverlap_(deletion, insertion);\n      var overlap_length2 = this.diff_commonOverlap_(insertion, deletion);\n      if (overlap_length1 >= overlap_length2) {\n        if (overlap_length1 >= deletion.length / 2 ||\n            overlap_length1 >= insertion.length / 2) {\n          // Overlap found.  Insert an equality and trim the surrounding edits.\n          diffs.splice(pointer, 0,\n              [DIFF_EQUAL, insertion.substring(0, overlap_length1)]);\n          diffs[pointer - 1][1] =\n              deletion.substring(0, deletion.length - overlap_length1);\n          diffs[pointer + 1][1] = insertion.substring(overlap_length1);\n          pointer++;\n        }\n      } else {\n        if (overlap_length2 >= deletion.length / 2 ||\n            overlap_length2 >= insertion.length / 2) {\n          // Reverse overlap found.\n          // Insert an equality and swap and trim the surrounding edits.\n          diffs.splice(pointer, 0,\n              [DIFF_EQUAL, deletion.substring(0, overlap_length2)]);\n          diffs[pointer - 1][0] = DIFF_INSERT;\n          diffs[pointer - 1][1] =\n              insertion.substring(0, insertion.length - overlap_length2);\n          diffs[pointer + 1][0] = DIFF_DELETE;\n          diffs[pointer + 1][1] =\n              deletion.substring(overlap_length2);\n          pointer++;\n        }\n      }\n      pointer++;\n    }\n    pointer++;\n  }\n};\n\n\n/**\n * Look for single edits surrounded on both sides by equalities\n * which can be shifted sideways to align the edit to a word boundary.\n * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupSemanticLossless = function(diffs) {\n  /**\n   * Given two strings, compute a score representing whether the internal\n   * boundary falls on logical boundaries.\n   * Scores range from 6 (best) to 0 (worst).\n   * Closure, but does not reference any external variables.\n   * @param {string} one First string.\n   * @param {string} two Second string.\n   * @return {number} The score.\n   * @private\n   */\n  function diff_cleanupSemanticScore_(one, two) {\n    if (!one || !two) {\n      // Edges are the best.\n      return 6;\n    }\n\n    // Each port of this function behaves slightly differently due to\n    // subtle differences in each language's definition of things like\n    // 'whitespace'.  Since this function's purpose is largely cosmetic,\n    // the choice has been made to use each language's native features\n    // rather than force total conformity.\n    var char1 = one.charAt(one.length - 1);\n    var char2 = two.charAt(0);\n    var nonAlphaNumeric1 = char1.match(diff_match_patch.nonAlphaNumericRegex_);\n    var nonAlphaNumeric2 = char2.match(diff_match_patch.nonAlphaNumericRegex_);\n    var whitespace1 = nonAlphaNumeric1 &&\n        char1.match(diff_match_patch.whitespaceRegex_);\n    var whitespace2 = nonAlphaNumeric2 &&\n        char2.match(diff_match_patch.whitespaceRegex_);\n    var lineBreak1 = whitespace1 &&\n        char1.match(diff_match_patch.linebreakRegex_);\n    var lineBreak2 = whitespace2 &&\n        char2.match(diff_match_patch.linebreakRegex_);\n    var blankLine1 = lineBreak1 &&\n        one.match(diff_match_patch.blanklineEndRegex_);\n    var blankLine2 = lineBreak2 &&\n        two.match(diff_match_patch.blanklineStartRegex_);\n\n    if (blankLine1 || blankLine2) {\n      // Five points for blank lines.\n      return 5;\n    } else if (lineBreak1 || lineBreak2) {\n      // Four points for line breaks.\n      return 4;\n    } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) {\n      // Three points for end of sentences.\n      return 3;\n    } else if (whitespace1 || whitespace2) {\n      // Two points for whitespace.\n      return 2;\n    } else if (nonAlphaNumeric1 || nonAlphaNumeric2) {\n      // One point for non-alphanumeric.\n      return 1;\n    }\n    return 0;\n  }\n\n  var pointer = 1;\n  // Intentionally ignore the first and last element (don't need checking).\n  while (pointer < diffs.length - 1) {\n    if (diffs[pointer - 1][0] == DIFF_EQUAL &&\n        diffs[pointer + 1][0] == DIFF_EQUAL) {\n      // This is a single edit surrounded by equalities.\n      var equality1 = diffs[pointer - 1][1];\n      var edit = diffs[pointer][1];\n      var equality2 = diffs[pointer + 1][1];\n\n      // First, shift the edit as far left as possible.\n      var commonOffset = this.diff_commonSuffix(equality1, edit);\n      if (commonOffset) {\n        var commonString = edit.substring(edit.length - commonOffset);\n        equality1 = equality1.substring(0, equality1.length - commonOffset);\n        edit = commonString + edit.substring(0, edit.length - commonOffset);\n        equality2 = commonString + equality2;\n      }\n\n      // Second, step character by character right, looking for the best fit.\n      var bestEquality1 = equality1;\n      var bestEdit = edit;\n      var bestEquality2 = equality2;\n      var bestScore = diff_cleanupSemanticScore_(equality1, edit) +\n          diff_cleanupSemanticScore_(edit, equality2);\n      while (edit.charAt(0) === equality2.charAt(0)) {\n        equality1 += edit.charAt(0);\n        edit = edit.substring(1) + equality2.charAt(0);\n        equality2 = equality2.substring(1);\n        var score = diff_cleanupSemanticScore_(equality1, edit) +\n            diff_cleanupSemanticScore_(edit, equality2);\n        // The >= encourages trailing rather than leading whitespace on edits.\n        if (score >= bestScore) {\n          bestScore = score;\n          bestEquality1 = equality1;\n          bestEdit = edit;\n          bestEquality2 = equality2;\n        }\n      }\n\n      if (diffs[pointer - 1][1] != bestEquality1) {\n        // We have an improvement, save it back to the diff.\n        if (bestEquality1) {\n          diffs[pointer - 1][1] = bestEquality1;\n        } else {\n          diffs.splice(pointer - 1, 1);\n          pointer--;\n        }\n        diffs[pointer][1] = bestEdit;\n        if (bestEquality2) {\n          diffs[pointer + 1][1] = bestEquality2;\n        } else {\n          diffs.splice(pointer + 1, 1);\n          pointer--;\n        }\n      }\n    }\n    pointer++;\n  }\n};\n\n// Define some regex patterns for matching boundaries.\ndiff_match_patch.nonAlphaNumericRegex_ = /[^a-zA-Z0-9]/;\ndiff_match_patch.whitespaceRegex_ = /\\s/;\ndiff_match_patch.linebreakRegex_ = /[\\r\\n]/;\ndiff_match_patch.blanklineEndRegex_ = /\\n\\r?\\n$/;\ndiff_match_patch.blanklineStartRegex_ = /^\\r?\\n\\r?\\n/;\n\n/**\n * Reduce the number of edits by eliminating operationally trivial equalities.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupEfficiency = function(diffs) {\n  var changes = false;\n  var equalities = [];  // Stack of indices where equalities are found.\n  var equalitiesLength = 0;  // Keeping our own length var is faster in JS.\n  /** @type {?string} */\n  var lastequality = null;\n  // Always equal to diffs[equalities[equalitiesLength - 1]][1]\n  var pointer = 0;  // Index of current position.\n  // Is there an insertion operation before the last equality.\n  var pre_ins = false;\n  // Is there a deletion operation before the last equality.\n  var pre_del = false;\n  // Is there an insertion operation after the last equality.\n  var post_ins = false;\n  // Is there a deletion operation after the last equality.\n  var post_del = false;\n  while (pointer < diffs.length) {\n    if (diffs[pointer][0] == DIFF_EQUAL) {  // Equality found.\n      if (diffs[pointer][1].length < this.Diff_EditCost &&\n          (post_ins || post_del)) {\n        // Candidate found.\n        equalities[equalitiesLength++] = pointer;\n        pre_ins = post_ins;\n        pre_del = post_del;\n        lastequality = diffs[pointer][1];\n      } else {\n        // Not a candidate, and can never become one.\n        equalitiesLength = 0;\n        lastequality = null;\n      }\n      post_ins = post_del = false;\n    } else {  // An insertion or deletion.\n      if (diffs[pointer][0] == DIFF_DELETE) {\n        post_del = true;\n      } else {\n        post_ins = true;\n      }\n      /*\n       * Five types to be split:\n       * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>\n       * <ins>A</ins>X<ins>C</ins><del>D</del>\n       * <ins>A</ins><del>B</del>X<ins>C</ins>\n       * <ins>A</del>X<ins>C</ins><del>D</del>\n       * <ins>A</ins><del>B</del>X<del>C</del>\n       */\n      if (lastequality && ((pre_ins && pre_del && post_ins && post_del) ||\n                           ((lastequality.length < this.Diff_EditCost / 2) &&\n                            (pre_ins + pre_del + post_ins + post_del) == 3))) {\n        // Duplicate record.\n        diffs.splice(equalities[equalitiesLength - 1], 0,\n                     [DIFF_DELETE, lastequality]);\n        // Change second copy to insert.\n        diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;\n        equalitiesLength--;  // Throw away the equality we just deleted;\n        lastequality = null;\n        if (pre_ins && pre_del) {\n          // No changes made which could affect previous entry, keep going.\n          post_ins = post_del = true;\n          equalitiesLength = 0;\n        } else {\n          equalitiesLength--;  // Throw away the previous equality.\n          pointer = equalitiesLength > 0 ?\n              equalities[equalitiesLength - 1] : -1;\n          post_ins = post_del = false;\n        }\n        changes = true;\n      }\n    }\n    pointer++;\n  }\n\n  if (changes) {\n    this.diff_cleanupMerge(diffs);\n  }\n};\n\n\n/**\n * Reorder and merge like edit sections.  Merge equalities.\n * Any edit section can move as long as it doesn't cross an equality.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n */\ndiff_match_patch.prototype.diff_cleanupMerge = function(diffs) {\n  diffs.push([DIFF_EQUAL, '']);  // Add a dummy entry at the end.\n  var pointer = 0;\n  var count_delete = 0;\n  var count_insert = 0;\n  var text_delete = '';\n  var text_insert = '';\n  var commonlength;\n  while (pointer < diffs.length) {\n    switch (diffs[pointer][0]) {\n      case DIFF_INSERT:\n        count_insert++;\n        text_insert += diffs[pointer][1];\n        pointer++;\n        break;\n      case DIFF_DELETE:\n        count_delete++;\n        text_delete += diffs[pointer][1];\n        pointer++;\n        break;\n      case DIFF_EQUAL:\n        // Upon reaching an equality, check for prior redundancies.\n        if (count_delete + count_insert > 1) {\n          if (count_delete !== 0 && count_insert !== 0) {\n            // Factor out any common prefixies.\n            commonlength = this.diff_commonPrefix(text_insert, text_delete);\n            if (commonlength !== 0) {\n              if ((pointer - count_delete - count_insert) > 0 &&\n                  diffs[pointer - count_delete - count_insert - 1][0] ==\n                  DIFF_EQUAL) {\n                diffs[pointer - count_delete - count_insert - 1][1] +=\n                    text_insert.substring(0, commonlength);\n              } else {\n                diffs.splice(0, 0, [DIFF_EQUAL,\n                                    text_insert.substring(0, commonlength)]);\n                pointer++;\n              }\n              text_insert = text_insert.substring(commonlength);\n              text_delete = text_delete.substring(commonlength);\n            }\n            // Factor out any common suffixies.\n            commonlength = this.diff_commonSuffix(text_insert, text_delete);\n            if (commonlength !== 0) {\n              diffs[pointer][1] = text_insert.substring(text_insert.length -\n                  commonlength) + diffs[pointer][1];\n              text_insert = text_insert.substring(0, text_insert.length -\n                  commonlength);\n              text_delete = text_delete.substring(0, text_delete.length -\n                  commonlength);\n            }\n          }\n          // Delete the offending records and add the merged ones.\n          if (count_delete === 0) {\n            diffs.splice(pointer - count_insert,\n                count_delete + count_insert, [DIFF_INSERT, text_insert]);\n          } else if (count_insert === 0) {\n            diffs.splice(pointer - count_delete,\n                count_delete + count_insert, [DIFF_DELETE, text_delete]);\n          } else {\n            diffs.splice(pointer - count_delete - count_insert,\n                count_delete + count_insert, [DIFF_DELETE, text_delete],\n                [DIFF_INSERT, text_insert]);\n          }\n          pointer = pointer - count_delete - count_insert +\n                    (count_delete ? 1 : 0) + (count_insert ? 1 : 0) + 1;\n        } else if (pointer !== 0 && diffs[pointer - 1][0] == DIFF_EQUAL) {\n          // Merge this equality with the previous one.\n          diffs[pointer - 1][1] += diffs[pointer][1];\n          diffs.splice(pointer, 1);\n        } else {\n          pointer++;\n        }\n        count_insert = 0;\n        count_delete = 0;\n        text_delete = '';\n        text_insert = '';\n        break;\n    }\n  }\n  if (diffs[diffs.length - 1][1] === '') {\n    diffs.pop();  // Remove the dummy entry at the end.\n  }\n\n  // Second pass: look for single edits surrounded on both sides by equalities\n  // which can be shifted sideways to eliminate an equality.\n  // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC\n  var changes = false;\n  pointer = 1;\n  // Intentionally ignore the first and last element (don't need checking).\n  while (pointer < diffs.length - 1) {\n    if (diffs[pointer - 1][0] == DIFF_EQUAL &&\n        diffs[pointer + 1][0] == DIFF_EQUAL) {\n      // This is a single edit surrounded by equalities.\n      if (diffs[pointer][1].substring(diffs[pointer][1].length -\n          diffs[pointer - 1][1].length) == diffs[pointer - 1][1]) {\n        // Shift the edit over the previous equality.\n        diffs[pointer][1] = diffs[pointer - 1][1] +\n            diffs[pointer][1].substring(0, diffs[pointer][1].length -\n                                        diffs[pointer - 1][1].length);\n        diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];\n        diffs.splice(pointer - 1, 1);\n        changes = true;\n      } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) ==\n          diffs[pointer + 1][1]) {\n        // Shift the edit over the next equality.\n        diffs[pointer - 1][1] += diffs[pointer + 1][1];\n        diffs[pointer][1] =\n            diffs[pointer][1].substring(diffs[pointer + 1][1].length) +\n            diffs[pointer + 1][1];\n        diffs.splice(pointer + 1, 1);\n        changes = true;\n      }\n    }\n    pointer++;\n  }\n  // If shifts were made, the diff needs reordering and another shift sweep.\n  if (changes) {\n    this.diff_cleanupMerge(diffs);\n  }\n};\n\n\n/**\n * loc is a location in text1, compute and return the equivalent location in\n * text2.\n * e.g. 'The cat' vs 'The big cat', 1->1, 5->8\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @param {number} loc Location within text1.\n * @return {number} Location within text2.\n */\ndiff_match_patch.prototype.diff_xIndex = function(diffs, loc) {\n  var chars1 = 0;\n  var chars2 = 0;\n  var last_chars1 = 0;\n  var last_chars2 = 0;\n  var x;\n  for (x = 0; x < diffs.length; x++) {\n    if (diffs[x][0] !== DIFF_INSERT) {  // Equality or deletion.\n      chars1 += diffs[x][1].length;\n    }\n    if (diffs[x][0] !== DIFF_DELETE) {  // Equality or insertion.\n      chars2 += diffs[x][1].length;\n    }\n    if (chars1 > loc) {  // Overshot the location.\n      break;\n    }\n    last_chars1 = chars1;\n    last_chars2 = chars2;\n  }\n  // Was the location was deleted?\n  if (diffs.length != x && diffs[x][0] === DIFF_DELETE) {\n    return last_chars2;\n  }\n  // Add the remaining character length.\n  return last_chars2 + (loc - last_chars1);\n};\n\n\n/**\n * Convert a diff array into a pretty HTML report.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} HTML representation.\n */\ndiff_match_patch.prototype.diff_prettyHtml = function(diffs) {\n  var html = [];\n  var pattern_amp = /&/g;\n  var pattern_lt = /</g;\n  var pattern_gt = />/g;\n  var pattern_para = /\\n/g;\n  for (var x = 0; x < diffs.length; x++) {\n    var op = diffs[x][0];    // Operation (insert, delete, equal)\n    var data = diffs[x][1];  // Text of change.\n    var text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;')\n        .replace(pattern_gt, '&gt;').replace(pattern_para, '&para;<br>');\n    switch (op) {\n      case DIFF_INSERT:\n        html[x] = '<ins style=\"background:#e6ffe6;\">' + text + '</ins>';\n        break;\n      case DIFF_DELETE:\n        html[x] = '<del style=\"background:#ffe6e6;\">' + text + '</del>';\n        break;\n      case DIFF_EQUAL:\n        html[x] = '<span>' + text + '</span>';\n        break;\n    }\n  }\n  return html.join('');\n};\n\n\n/**\n * Compute and return the source text (all equalities and deletions).\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} Source text.\n */\ndiff_match_patch.prototype.diff_text1 = function(diffs) {\n  var text = [];\n  for (var x = 0; x < diffs.length; x++) {\n    if (diffs[x][0] !== DIFF_INSERT) {\n      text[x] = diffs[x][1];\n    }\n  }\n  return text.join('');\n};\n\n\n/**\n * Compute and return the destination text (all equalities and insertions).\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} Destination text.\n */\ndiff_match_patch.prototype.diff_text2 = function(diffs) {\n  var text = [];\n  for (var x = 0; x < diffs.length; x++) {\n    if (diffs[x][0] !== DIFF_DELETE) {\n      text[x] = diffs[x][1];\n    }\n  }\n  return text.join('');\n};\n\n\n/**\n * Compute the Levenshtein distance; the number of inserted, deleted or\n * substituted characters.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {number} Number of changes.\n */\ndiff_match_patch.prototype.diff_levenshtein = function(diffs) {\n  var levenshtein = 0;\n  var insertions = 0;\n  var deletions = 0;\n  for (var x = 0; x < diffs.length; x++) {\n    var op = diffs[x][0];\n    var data = diffs[x][1];\n    switch (op) {\n      case DIFF_INSERT:\n        insertions += data.length;\n        break;\n      case DIFF_DELETE:\n        deletions += data.length;\n        break;\n      case DIFF_EQUAL:\n        // A deletion and an insertion is one substitution.\n        levenshtein += Math.max(insertions, deletions);\n        insertions = 0;\n        deletions = 0;\n        break;\n    }\n  }\n  levenshtein += Math.max(insertions, deletions);\n  return levenshtein;\n};\n\n\n/**\n * Crush the diff into an encoded string which describes the operations\n * required to transform text1 into text2.\n * E.g. =3\\t-2\\t+ing  -> Keep 3 chars, delete 2 chars, insert 'ing'.\n * Operations are tab-separated.  Inserted text is escaped using %xx notation.\n * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.\n * @return {string} Delta text.\n */\ndiff_match_patch.prototype.diff_toDelta = function(diffs) {\n  var text = [];\n  for (var x = 0; x < diffs.length; x++) {\n    switch (diffs[x][0]) {\n      case DIFF_INSERT:\n        text[x] = '+' + encodeURI(diffs[x][1]);\n        break;\n      case DIFF_DELETE:\n        text[x] = '-' + diffs[x][1].length;\n        break;\n      case DIFF_EQUAL:\n        text[x] = '=' + diffs[x][1].length;\n        break;\n    }\n  }\n  return text.join('\\t').replace(/%20/g, ' ');\n};\n\n\n/**\n * Given the original text1, and an encoded string which describes the\n * operations required to transform text1 into text2, compute the full diff.\n * @param {string} text1 Source string for the diff.\n * @param {string} delta Delta text.\n * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.\n * @throws {!Error} If invalid input.\n */\ndiff_match_patch.prototype.diff_fromDelta = function(text1, delta) {\n  var diffs = [];\n  var diffsLength = 0;  // Keeping our own length var is faster in JS.\n  var pointer = 0;  // Cursor in text1\n  var tokens = delta.split(/\\t/g);\n  for (var x = 0; x < tokens.length; x++) {\n    // Each token begins with a one character parameter which specifies the\n    // operation of this token (delete, insert, equality).\n    var param = tokens[x].substring(1);\n    switch (tokens[x].charAt(0)) {\n      case '+':\n        try {\n          diffs[diffsLength++] = [DIFF_INSERT, decodeURI(param)];\n        } catch (ex) {\n          // Malformed URI sequence.\n          throw new Error('Illegal escape in diff_fromDelta: ' + param);\n        }\n        break;\n      case '-':\n        // Fall through.\n      case '=':\n        var n = parseInt(param, 10);\n        if (isNaN(n) || n < 0) {\n          throw new Error('Invalid number in diff_fromDelta: ' + param);\n        }\n        var text = text1.substring(pointer, pointer += n);\n        if (tokens[x].charAt(0) == '=') {\n          diffs[diffsLength++] = [DIFF_EQUAL, text];\n        } else {\n          diffs[diffsLength++] = [DIFF_DELETE, text];\n        }\n        break;\n      default:\n        // Blank tokens are ok (from a trailing \\t).\n        // Anything else is an error.\n        if (tokens[x]) {\n          throw new Error('Invalid diff operation in diff_fromDelta: ' +\n                          tokens[x]);\n        }\n    }\n  }\n  if (pointer != text1.length) {\n    throw new Error('Delta length (' + pointer +\n        ') does not equal source text length (' + text1.length + ').');\n  }\n  return diffs;\n};\n\n\n//  MATCH FUNCTIONS\n\n\n/**\n * Locate the best instance of 'pattern' in 'text' near 'loc'.\n * @param {string} text The text to search.\n * @param {string} pattern The pattern to search for.\n * @param {number} loc The location to search around.\n * @return {number} Best match index or -1.\n */\ndiff_match_patch.prototype.match_main = function(text, pattern, loc) {\n  // Check for null inputs.\n  if (text == null || pattern == null || loc == null) {\n    throw new Error('Null input. (match_main)');\n  }\n\n  loc = Math.max(0, Math.min(loc, text.length));\n  if (text == pattern) {\n    // Shortcut (potentially not guaranteed by the algorithm)\n    return 0;\n  } else if (!text.length) {\n    // Nothing to match.\n    return -1;\n  } else if (text.substring(loc, loc + pattern.length) == pattern) {\n    // Perfect match at the perfect spot!  (Includes case of null pattern)\n    return loc;\n  } else {\n    // Do a fuzzy compare.\n    return this.match_bitap_(text, pattern, loc);\n  }\n};\n\n\n/**\n * Locate the best instance of 'pattern' in 'text' near 'loc' using the\n * Bitap algorithm.\n * @param {string} text The text to search.\n * @param {string} pattern The pattern to search for.\n * @param {number} loc The location to search around.\n * @return {number} Best match index or -1.\n * @private\n */\ndiff_match_patch.prototype.match_bitap_ = function(text, pattern, loc) {\n  if (pattern.length > this.Match_MaxBits) {\n    throw new Error('Pattern too long for this browser.');\n  }\n\n  // Initialise the alphabet.\n  var s = this.match_alphabet_(pattern);\n\n  var dmp = this;  // 'this' becomes 'window' in a closure.\n\n  /**\n   * Compute and return the score for a match with e errors and x location.\n   * Accesses loc and pattern through being a closure.\n   * @param {number} e Number of errors in match.\n   * @param {number} x Location of match.\n   * @return {number} Overall score for match (0.0 = good, 1.0 = bad).\n   * @private\n   */\n  function match_bitapScore_(e, x) {\n    var accuracy = e / pattern.length;\n    var proximity = Math.abs(loc - x);\n    if (!dmp.Match_Distance) {\n      // Dodge divide by zero error.\n      return proximity ? 1.0 : accuracy;\n    }\n    return accuracy + (proximity / dmp.Match_Distance);\n  }\n\n  // Highest score beyond which we give up.\n  var score_threshold = this.Match_Threshold;\n  // Is there a nearby exact match? (speedup)\n  var best_loc = text.indexOf(pattern, loc);\n  if (best_loc != -1) {\n    score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold);\n    // What about in the other direction? (speedup)\n    best_loc = text.lastIndexOf(pattern, loc + pattern.length);\n    if (best_loc != -1) {\n      score_threshold =\n          Math.min(match_bitapScore_(0, best_loc), score_threshold);\n    }\n  }\n\n  // Initialise the bit arrays.\n  var matchmask = 1 << (pattern.length - 1);\n  best_loc = -1;\n\n  var bin_min, bin_mid;\n  var bin_max = pattern.length + text.length;\n  var last_rd;\n  for (var d = 0; d < pattern.length; d++) {\n    // Scan for the best match; each iteration allows for one more error.\n    // Run a binary search to determine how far from 'loc' we can stray at this\n    // error level.\n    bin_min = 0;\n    bin_mid = bin_max;\n    while (bin_min < bin_mid) {\n      if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) {\n        bin_min = bin_mid;\n      } else {\n        bin_max = bin_mid;\n      }\n      bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min);\n    }\n    // Use the result from this iteration as the maximum for the next.\n    bin_max = bin_mid;\n    var start = Math.max(1, loc - bin_mid + 1);\n    var finish = Math.min(loc + bin_mid, text.length) + pattern.length;\n\n    var rd = Array(finish + 2);\n    rd[finish + 1] = (1 << d) - 1;\n    for (var j = finish; j >= start; j--) {\n      // The alphabet (s) is a sparse hash, so the following line generates\n      // warnings.\n      var charMatch = s[text.charAt(j - 1)];\n      if (d === 0) {  // First pass: exact match.\n        rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;\n      } else {  // Subsequent passes: fuzzy match.\n        rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) |\n                (((last_rd[j + 1] | last_rd[j]) << 1) | 1) |\n                last_rd[j + 1];\n      }\n      if (rd[j] & matchmask) {\n        var score = match_bitapScore_(d, j - 1);\n        // This match will almost certainly be better than any existing match.\n        // But check anyway.\n        if (score <= score_threshold) {\n          // Told you so.\n          score_threshold = score;\n          best_loc = j - 1;\n          if (best_loc > loc) {\n            // When passing loc, don't exceed our current distance from loc.\n            start = Math.max(1, 2 * loc - best_loc);\n          } else {\n            // Already passed loc, downhill from here on in.\n            break;\n          }\n        }\n      }\n    }\n    // No hope for a (better) match at greater error levels.\n    if (match_bitapScore_(d + 1, loc) > score_threshold) {\n      break;\n    }\n    last_rd = rd;\n  }\n  return best_loc;\n};\n\n\n/**\n * Initialise the alphabet for the Bitap algorithm.\n * @param {string} pattern The text to encode.\n * @return {!Object} Hash of character locations.\n * @private\n */\ndiff_match_patch.prototype.match_alphabet_ = function(pattern) {\n  var s = {};\n  for (var i = 0; i < pattern.length; i++) {\n    s[pattern.charAt(i)] = 0;\n  }\n  for (var i = 0; i < pattern.length; i++) {\n    s[pattern.charAt(i)] |= 1 << (pattern.length - i - 1);\n  }\n  return s;\n};\n\n\n//  PATCH FUNCTIONS\n\n\n/**\n * Increase the context until it is unique,\n * but don't let the pattern expand beyond Match_MaxBits.\n * @param {!diff_match_patch.patch_obj} patch The patch to grow.\n * @param {string} text Source text.\n * @private\n */\ndiff_match_patch.prototype.patch_addContext_ = function(patch, text) {\n  if (text.length == 0) {\n    return;\n  }\n  var pattern = text.substring(patch.start2, patch.start2 + patch.length1);\n  var padding = 0;\n\n  // Look for the first and last matches of pattern in text.  If two different\n  // matches are found, increase the pattern length.\n  while (text.indexOf(pattern) != text.lastIndexOf(pattern) &&\n         pattern.length < this.Match_MaxBits - this.Patch_Margin -\n         this.Patch_Margin) {\n    padding += this.Patch_Margin;\n    pattern = text.substring(patch.start2 - padding,\n                             patch.start2 + patch.length1 + padding);\n  }\n  // Add one chunk for good luck.\n  padding += this.Patch_Margin;\n\n  // Add the prefix.\n  var prefix = text.substring(patch.start2 - padding, patch.start2);\n  if (prefix) {\n    patch.diffs.unshift([DIFF_EQUAL, prefix]);\n  }\n  // Add the suffix.\n  var suffix = text.substring(patch.start2 + patch.length1,\n                              patch.start2 + patch.length1 + padding);\n  if (suffix) {\n    patch.diffs.push([DIFF_EQUAL, suffix]);\n  }\n\n  // Roll back the start points.\n  patch.start1 -= prefix.length;\n  patch.start2 -= prefix.length;\n  // Extend the lengths.\n  patch.length1 += prefix.length + suffix.length;\n  patch.length2 += prefix.length + suffix.length;\n};\n\n\n/**\n * Compute a list of patches to turn text1 into text2.\n * Use diffs if provided, otherwise compute it ourselves.\n * There are four ways to call this function, depending on what data is\n * available to the caller:\n * Method 1:\n * a = text1, b = text2\n * Method 2:\n * a = diffs\n * Method 3 (optimal):\n * a = text1, b = diffs\n * Method 4 (deprecated, use method 3):\n * a = text1, b = text2, c = diffs\n *\n * @param {string|!Array.<!diff_match_patch.Diff>} a text1 (methods 1,3,4) or\n * Array of diff tuples for text1 to text2 (method 2).\n * @param {string|!Array.<!diff_match_patch.Diff>} opt_b text2 (methods 1,4) or\n * Array of diff tuples for text1 to text2 (method 3) or undefined (method 2).\n * @param {string|!Array.<!diff_match_patch.Diff>} opt_c Array of diff tuples\n * for text1 to text2 (method 4) or undefined (methods 1,2,3).\n * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.\n */\ndiff_match_patch.prototype.patch_make = function(a, opt_b, opt_c) {\n  var text1, diffs;\n  if (typeof a == 'string' && typeof opt_b == 'string' &&\n      typeof opt_c == 'undefined') {\n    // Method 1: text1, text2\n    // Compute diffs from text1 and text2.\n    text1 = /** @type {string} */(a);\n    diffs = this.diff_main(text1, /** @type {string} */(opt_b), true);\n    if (diffs.length > 2) {\n      this.diff_cleanupSemantic(diffs);\n      this.diff_cleanupEfficiency(diffs);\n    }\n  } else if (a && typeof a == 'object' && typeof opt_b == 'undefined' &&\n      typeof opt_c == 'undefined') {\n    // Method 2: diffs\n    // Compute text1 from diffs.\n    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(a);\n    text1 = this.diff_text1(diffs);\n  } else if (typeof a == 'string' && opt_b && typeof opt_b == 'object' &&\n      typeof opt_c == 'undefined') {\n    // Method 3: text1, diffs\n    text1 = /** @type {string} */(a);\n    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_b);\n  } else if (typeof a == 'string' && typeof opt_b == 'string' &&\n      opt_c && typeof opt_c == 'object') {\n    // Method 4: text1, text2, diffs\n    // text2 is not used.\n    text1 = /** @type {string} */(a);\n    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_c);\n  } else {\n    throw new Error('Unknown call format to patch_make.');\n  }\n\n  if (diffs.length === 0) {\n    return [];  // Get rid of the null case.\n  }\n  var patches = [];\n  var patch = new diff_match_patch.patch_obj();\n  var patchDiffLength = 0;  // Keeping our own length var is faster in JS.\n  var char_count1 = 0;  // Number of characters into the text1 string.\n  var char_count2 = 0;  // Number of characters into the text2 string.\n  // Start with text1 (prepatch_text) and apply the diffs until we arrive at\n  // text2 (postpatch_text).  We recreate the patches one by one to determine\n  // context info.\n  var prepatch_text = text1;\n  var postpatch_text = text1;\n  for (var x = 0; x < diffs.length; x++) {\n    var diff_type = diffs[x][0];\n    var diff_text = diffs[x][1];\n\n    if (!patchDiffLength && diff_type !== DIFF_EQUAL) {\n      // A new patch starts here.\n      patch.start1 = char_count1;\n      patch.start2 = char_count2;\n    }\n\n    switch (diff_type) {\n      case DIFF_INSERT:\n        patch.diffs[patchDiffLength++] = diffs[x];\n        patch.length2 += diff_text.length;\n        postpatch_text = postpatch_text.substring(0, char_count2) + diff_text +\n                         postpatch_text.substring(char_count2);\n        break;\n      case DIFF_DELETE:\n        patch.length1 += diff_text.length;\n        patch.diffs[patchDiffLength++] = diffs[x];\n        postpatch_text = postpatch_text.substring(0, char_count2) +\n                         postpatch_text.substring(char_count2 +\n                             diff_text.length);\n        break;\n      case DIFF_EQUAL:\n        if (diff_text.length <= 2 * this.Patch_Margin &&\n            patchDiffLength && diffs.length != x + 1) {\n          // Small equality inside a patch.\n          patch.diffs[patchDiffLength++] = diffs[x];\n          patch.length1 += diff_text.length;\n          patch.length2 += diff_text.length;\n        } else if (diff_text.length >= 2 * this.Patch_Margin) {\n          // Time for a new patch.\n          if (patchDiffLength) {\n            this.patch_addContext_(patch, prepatch_text);\n            patches.push(patch);\n            patch = new diff_match_patch.patch_obj();\n            patchDiffLength = 0;\n            // Unlike Unidiff, our patch lists have a rolling context.\n            // http://code.google.com/p/google-diff-match-patch/wiki/Unidiff\n            // Update prepatch text & pos to reflect the application of the\n            // just completed patch.\n            prepatch_text = postpatch_text;\n            char_count1 = char_count2;\n          }\n        }\n        break;\n    }\n\n    // Update the current character count.\n    if (diff_type !== DIFF_INSERT) {\n      char_count1 += diff_text.length;\n    }\n    if (diff_type !== DIFF_DELETE) {\n      char_count2 += diff_text.length;\n    }\n  }\n  // Pick up the leftover patch if not empty.\n  if (patchDiffLength) {\n    this.patch_addContext_(patch, prepatch_text);\n    patches.push(patch);\n  }\n\n  return patches;\n};\n\n\n/**\n * Given an array of patches, return another array that is identical.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.\n */\ndiff_match_patch.prototype.patch_deepCopy = function(patches) {\n  // Making deep copies is hard in JavaScript.\n  var patchesCopy = [];\n  for (var x = 0; x < patches.length; x++) {\n    var patch = patches[x];\n    var patchCopy = new diff_match_patch.patch_obj();\n    patchCopy.diffs = [];\n    for (var y = 0; y < patch.diffs.length; y++) {\n      patchCopy.diffs[y] = patch.diffs[y].slice();\n    }\n    patchCopy.start1 = patch.start1;\n    patchCopy.start2 = patch.start2;\n    patchCopy.length1 = patch.length1;\n    patchCopy.length2 = patch.length2;\n    patchesCopy[x] = patchCopy;\n  }\n  return patchesCopy;\n};\n\n\n/**\n * Merge a set of patches onto the text.  Return a patched text, as well\n * as a list of true/false values indicating which patches were applied.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @param {string} text Old text.\n * @return {!Array.<string|!Array.<boolean>>} Two element Array, containing the\n *      new text and an array of boolean values.\n */\ndiff_match_patch.prototype.patch_apply = function(patches, text) {\n  if (patches.length == 0) {\n    return [text, []];\n  }\n\n  // Deep copy the patches so that no changes are made to originals.\n  patches = this.patch_deepCopy(patches);\n\n  var nullPadding = this.patch_addPadding(patches);\n  text = nullPadding + text + nullPadding;\n\n  this.patch_splitMax(patches);\n  // delta keeps track of the offset between the expected and actual location\n  // of the previous patch.  If there are patches expected at positions 10 and\n  // 20, but the first patch was found at 12, delta is 2 and the second patch\n  // has an effective expected position of 22.\n  var delta = 0;\n  var results = [];\n  for (var x = 0; x < patches.length; x++) {\n    var expected_loc = patches[x].start2 + delta;\n    var text1 = this.diff_text1(patches[x].diffs);\n    var start_loc;\n    var end_loc = -1;\n    if (text1.length > this.Match_MaxBits) {\n      // patch_splitMax will only provide an oversized pattern in the case of\n      // a monster delete.\n      start_loc = this.match_main(text, text1.substring(0, this.Match_MaxBits),\n                                  expected_loc);\n      if (start_loc != -1) {\n        end_loc = this.match_main(text,\n            text1.substring(text1.length - this.Match_MaxBits),\n            expected_loc + text1.length - this.Match_MaxBits);\n        if (end_loc == -1 || start_loc >= end_loc) {\n          // Can't find valid trailing context.  Drop this patch.\n          start_loc = -1;\n        }\n      }\n    } else {\n      start_loc = this.match_main(text, text1, expected_loc);\n    }\n    if (start_loc == -1) {\n      // No match found.  :(\n      results[x] = false;\n      // Subtract the delta for this failed patch from subsequent patches.\n      delta -= patches[x].length2 - patches[x].length1;\n    } else {\n      // Found a match.  :)\n      results[x] = true;\n      delta = start_loc - expected_loc;\n      var text2;\n      if (end_loc == -1) {\n        text2 = text.substring(start_loc, start_loc + text1.length);\n      } else {\n        text2 = text.substring(start_loc, end_loc + this.Match_MaxBits);\n      }\n      if (text1 == text2) {\n        // Perfect match, just shove the replacement text in.\n        text = text.substring(0, start_loc) +\n               this.diff_text2(patches[x].diffs) +\n               text.substring(start_loc + text1.length);\n      } else {\n        // Imperfect match.  Run a diff to get a framework of equivalent\n        // indices.\n        var diffs = this.diff_main(text1, text2, false);\n        if (text1.length > this.Match_MaxBits &&\n            this.diff_levenshtein(diffs) / text1.length >\n            this.Patch_DeleteThreshold) {\n          // The end points match, but the content is unacceptably bad.\n          results[x] = false;\n        } else {\n          this.diff_cleanupSemanticLossless(diffs);\n          var index1 = 0;\n          var index2;\n          for (var y = 0; y < patches[x].diffs.length; y++) {\n            var mod = patches[x].diffs[y];\n            if (mod[0] !== DIFF_EQUAL) {\n              index2 = this.diff_xIndex(diffs, index1);\n            }\n            if (mod[0] === DIFF_INSERT) {  // Insertion\n              text = text.substring(0, start_loc + index2) + mod[1] +\n                     text.substring(start_loc + index2);\n            } else if (mod[0] === DIFF_DELETE) {  // Deletion\n              text = text.substring(0, start_loc + index2) +\n                     text.substring(start_loc + this.diff_xIndex(diffs,\n                         index1 + mod[1].length));\n            }\n            if (mod[0] !== DIFF_DELETE) {\n              index1 += mod[1].length;\n            }\n          }\n        }\n      }\n    }\n  }\n  // Strip the padding off.\n  text = text.substring(nullPadding.length, text.length - nullPadding.length);\n  return [text, results];\n};\n\n\n/**\n * Add some padding on text start and end so that edges can match something.\n * Intended to be called only from within patch_apply.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @return {string} The padding string added to each side.\n */\ndiff_match_patch.prototype.patch_addPadding = function(patches) {\n  var paddingLength = this.Patch_Margin;\n  var nullPadding = '';\n  for (var x = 1; x <= paddingLength; x++) {\n    nullPadding += String.fromCharCode(x);\n  }\n\n  // Bump all the patches forward.\n  for (var x = 0; x < patches.length; x++) {\n    patches[x].start1 += paddingLength;\n    patches[x].start2 += paddingLength;\n  }\n\n  // Add some padding on start of first diff.\n  var patch = patches[0];\n  var diffs = patch.diffs;\n  if (diffs.length == 0 || diffs[0][0] != DIFF_EQUAL) {\n    // Add nullPadding equality.\n    diffs.unshift([DIFF_EQUAL, nullPadding]);\n    patch.start1 -= paddingLength;  // Should be 0.\n    patch.start2 -= paddingLength;  // Should be 0.\n    patch.length1 += paddingLength;\n    patch.length2 += paddingLength;\n  } else if (paddingLength > diffs[0][1].length) {\n    // Grow first equality.\n    var extraLength = paddingLength - diffs[0][1].length;\n    diffs[0][1] = nullPadding.substring(diffs[0][1].length) + diffs[0][1];\n    patch.start1 -= extraLength;\n    patch.start2 -= extraLength;\n    patch.length1 += extraLength;\n    patch.length2 += extraLength;\n  }\n\n  // Add some padding on end of last diff.\n  patch = patches[patches.length - 1];\n  diffs = patch.diffs;\n  if (diffs.length == 0 || diffs[diffs.length - 1][0] != DIFF_EQUAL) {\n    // Add nullPadding equality.\n    diffs.push([DIFF_EQUAL, nullPadding]);\n    patch.length1 += paddingLength;\n    patch.length2 += paddingLength;\n  } else if (paddingLength > diffs[diffs.length - 1][1].length) {\n    // Grow last equality.\n    var extraLength = paddingLength - diffs[diffs.length - 1][1].length;\n    diffs[diffs.length - 1][1] += nullPadding.substring(0, extraLength);\n    patch.length1 += extraLength;\n    patch.length2 += extraLength;\n  }\n\n  return nullPadding;\n};\n\n\n/**\n * Look through the patches and break up any which are longer than the maximum\n * limit of the match algorithm.\n * Intended to be called only from within patch_apply.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n */\ndiff_match_patch.prototype.patch_splitMax = function(patches) {\n  var patch_size = this.Match_MaxBits;\n  for (var x = 0; x < patches.length; x++) {\n    if (patches[x].length1 <= patch_size) {\n      continue;\n    }\n    var bigpatch = patches[x];\n    // Remove the big old patch.\n    patches.splice(x--, 1);\n    var start1 = bigpatch.start1;\n    var start2 = bigpatch.start2;\n    var precontext = '';\n    while (bigpatch.diffs.length !== 0) {\n      // Create one of several smaller patches.\n      var patch = new diff_match_patch.patch_obj();\n      var empty = true;\n      patch.start1 = start1 - precontext.length;\n      patch.start2 = start2 - precontext.length;\n      if (precontext !== '') {\n        patch.length1 = patch.length2 = precontext.length;\n        patch.diffs.push([DIFF_EQUAL, precontext]);\n      }\n      while (bigpatch.diffs.length !== 0 &&\n             patch.length1 < patch_size - this.Patch_Margin) {\n        var diff_type = bigpatch.diffs[0][0];\n        var diff_text = bigpatch.diffs[0][1];\n        if (diff_type === DIFF_INSERT) {\n          // Insertions are harmless.\n          patch.length2 += diff_text.length;\n          start2 += diff_text.length;\n          patch.diffs.push(bigpatch.diffs.shift());\n          empty = false;\n        } else if (diff_type === DIFF_DELETE && patch.diffs.length == 1 &&\n                   patch.diffs[0][0] == DIFF_EQUAL &&\n                   diff_text.length > 2 * patch_size) {\n          // This is a large deletion.  Let it pass in one chunk.\n          patch.length1 += diff_text.length;\n          start1 += diff_text.length;\n          empty = false;\n          patch.diffs.push([diff_type, diff_text]);\n          bigpatch.diffs.shift();\n        } else {\n          // Deletion or equality.  Only take as much as we can stomach.\n          diff_text = diff_text.substring(0,\n              patch_size - patch.length1 - this.Patch_Margin);\n          patch.length1 += diff_text.length;\n          start1 += diff_text.length;\n          if (diff_type === DIFF_EQUAL) {\n            patch.length2 += diff_text.length;\n            start2 += diff_text.length;\n          } else {\n            empty = false;\n          }\n          patch.diffs.push([diff_type, diff_text]);\n          if (diff_text == bigpatch.diffs[0][1]) {\n            bigpatch.diffs.shift();\n          } else {\n            bigpatch.diffs[0][1] =\n                bigpatch.diffs[0][1].substring(diff_text.length);\n          }\n        }\n      }\n      // Compute the head context for the next patch.\n      precontext = this.diff_text2(patch.diffs);\n      precontext =\n          precontext.substring(precontext.length - this.Patch_Margin);\n      // Append the end context for this patch.\n      var postcontext = this.diff_text1(bigpatch.diffs)\n                            .substring(0, this.Patch_Margin);\n      if (postcontext !== '') {\n        patch.length1 += postcontext.length;\n        patch.length2 += postcontext.length;\n        if (patch.diffs.length !== 0 &&\n            patch.diffs[patch.diffs.length - 1][0] === DIFF_EQUAL) {\n          patch.diffs[patch.diffs.length - 1][1] += postcontext;\n        } else {\n          patch.diffs.push([DIFF_EQUAL, postcontext]);\n        }\n      }\n      if (!empty) {\n        patches.splice(++x, 0, patch);\n      }\n    }\n  }\n};\n\n\n/**\n * Take a list of patches and return a textual representation.\n * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.\n * @return {string} Text representation of patches.\n */\ndiff_match_patch.prototype.patch_toText = function(patches) {\n  var text = [];\n  for (var x = 0; x < patches.length; x++) {\n    text[x] = patches[x];\n  }\n  return text.join('');\n};\n\n\n/**\n * Parse a textual representation of patches and return a list of Patch objects.\n * @param {string} textline Text representation of patches.\n * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.\n * @throws {!Error} If invalid input.\n */\ndiff_match_patch.prototype.patch_fromText = function(textline) {\n  var patches = [];\n  if (!textline) {\n    return patches;\n  }\n  var text = textline.split('\\n');\n  var textPointer = 0;\n  var patchHeader = /^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$/;\n  while (textPointer < text.length) {\n    var m = text[textPointer].match(patchHeader);\n    if (!m) {\n      throw new Error('Invalid patch string: ' + text[textPointer]);\n    }\n    var patch = new diff_match_patch.patch_obj();\n    patches.push(patch);\n    patch.start1 = parseInt(m[1], 10);\n    if (m[2] === '') {\n      patch.start1--;\n      patch.length1 = 1;\n    } else if (m[2] == '0') {\n      patch.length1 = 0;\n    } else {\n      patch.start1--;\n      patch.length1 = parseInt(m[2], 10);\n    }\n\n    patch.start2 = parseInt(m[3], 10);\n    if (m[4] === '') {\n      patch.start2--;\n      patch.length2 = 1;\n    } else if (m[4] == '0') {\n      patch.length2 = 0;\n    } else {\n      patch.start2--;\n      patch.length2 = parseInt(m[4], 10);\n    }\n    textPointer++;\n\n    while (textPointer < text.length) {\n      var sign = text[textPointer].charAt(0);\n      try {\n        var line = decodeURI(text[textPointer].substring(1));\n      } catch (ex) {\n        // Malformed URI sequence.\n        throw new Error('Illegal escape in patch_fromText: ' + line);\n      }\n      if (sign == '-') {\n        // Deletion.\n        patch.diffs.push([DIFF_DELETE, line]);\n      } else if (sign == '+') {\n        // Insertion.\n        patch.diffs.push([DIFF_INSERT, line]);\n      } else if (sign == ' ') {\n        // Minor equality.\n        patch.diffs.push([DIFF_EQUAL, line]);\n      } else if (sign == '@') {\n        // Start of next patch.\n        break;\n      } else if (sign === '') {\n        // Blank line?  Whatever.\n      } else {\n        // WTF?\n        throw new Error('Invalid patch mode \"' + sign + '\" in: ' + line);\n      }\n      textPointer++;\n    }\n  }\n  return patches;\n};\n\n\n/**\n * Class representing one patch operation.\n * @constructor\n */\ndiff_match_patch.patch_obj = function() {\n  /** @type {!Array.<!diff_match_patch.Diff>} */\n  this.diffs = [];\n  /** @type {?number} */\n  this.start1 = null;\n  /** @type {?number} */\n  this.start2 = null;\n  /** @type {number} */\n  this.length1 = 0;\n  /** @type {number} */\n  this.length2 = 0;\n};\n\n\n/**\n * Emmulate GNU diff's format.\n * Header: @@ -382,8 +481,9 @@\n * Indicies are printed as 1-based, not 0-based.\n * @return {string} The GNU diff string.\n */\ndiff_match_patch.patch_obj.prototype.toString = function() {\n  var coords1, coords2;\n  if (this.length1 === 0) {\n    coords1 = this.start1 + ',0';\n  } else if (this.length1 == 1) {\n    coords1 = this.start1 + 1;\n  } else {\n    coords1 = (this.start1 + 1) + ',' + this.length1;\n  }\n  if (this.length2 === 0) {\n    coords2 = this.start2 + ',0';\n  } else if (this.length2 == 1) {\n    coords2 = this.start2 + 1;\n  } else {\n    coords2 = (this.start2 + 1) + ',' + this.length2;\n  }\n  var text = ['@@ -' + coords1 + ' +' + coords2 + ' @@\\n'];\n  var op;\n  // Escape the body of the patch with %xx notation.\n  for (var x = 0; x < this.diffs.length; x++) {\n    switch (this.diffs[x][0]) {\n      case DIFF_INSERT:\n        op = '+';\n        break;\n      case DIFF_DELETE:\n        op = '-';\n        break;\n      case DIFF_EQUAL:\n        op = ' ';\n        break;\n    }\n    text[x + 1] = op + encodeURI(this.diffs[x][1]) + '\\n';\n  }\n  return text.join('').replace(/%20/g, ' ');\n};\n\n\n// Export these global variables so that they survive Google's JS compiler.\n// In a browser, 'this' will be 'window'.\n// Users of node.js should 'require' the uncompressed version since Google's\n// JS compiler may break the following exports for non-browser environments.\nthis['diff_match_patch'] = diff_match_patch;\nthis['DIFF_DELETE'] = DIFF_DELETE;\nthis['DIFF_INSERT'] = DIFF_INSERT;\nthis['DIFF_EQUAL'] = DIFF_EQUAL;\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery-ui.js",
    "content": "/*! jQuery UI - v1.10.4 - 2014-01-17\n* http://jqueryui.com\n* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.slider.js, jquery.ui.sortable.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js\n* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */\n\n(function( $, undefined ) {\n\nvar uuid = 0,\n\truniqueId = /^ui-id-\\d+$/;\n\n// $.ui might exist from components with no dependencies, e.g., $.ui.position\n$.ui = $.ui || {};\n\n$.extend( $.ui, {\n\tversion: \"1.10.4\",\n\n\tkeyCode: {\n\t\tBACKSPACE: 8,\n\t\tCOMMA: 188,\n\t\tDELETE: 46,\n\t\tDOWN: 40,\n\t\tEND: 35,\n\t\tENTER: 13,\n\t\tESCAPE: 27,\n\t\tHOME: 36,\n\t\tLEFT: 37,\n\t\tNUMPAD_ADD: 107,\n\t\tNUMPAD_DECIMAL: 110,\n\t\tNUMPAD_DIVIDE: 111,\n\t\tNUMPAD_ENTER: 108,\n\t\tNUMPAD_MULTIPLY: 106,\n\t\tNUMPAD_SUBTRACT: 109,\n\t\tPAGE_DOWN: 34,\n\t\tPAGE_UP: 33,\n\t\tPERIOD: 190,\n\t\tRIGHT: 39,\n\t\tSPACE: 32,\n\t\tTAB: 9,\n\t\tUP: 38\n\t}\n});\n\n// plugins\n$.fn.extend({\n\tfocus: (function( orig ) {\n\t\treturn function( delay, fn ) {\n\t\t\treturn typeof delay === \"number\" ?\n\t\t\t\tthis.each(function() {\n\t\t\t\t\tvar elem = this;\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t$( elem ).focus();\n\t\t\t\t\t\tif ( fn ) {\n\t\t\t\t\t\t\tfn.call( elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}, delay );\n\t\t\t\t}) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.focus ),\n\n\tscrollParent: function() {\n\t\tvar scrollParent;\n\t\tif (($.ui.ie && (/(static|relative)/).test(this.css(\"position\"))) || (/absolute/).test(this.css(\"position\"))) {\n\t\t\tscrollParent = this.parents().filter(function() {\n\t\t\t\treturn (/(relative|absolute|fixed)/).test($.css(this,\"position\")) && (/(auto|scroll)/).test($.css(this,\"overflow\")+$.css(this,\"overflow-y\")+$.css(this,\"overflow-x\"));\n\t\t\t}).eq(0);\n\t\t} else {\n\t\t\tscrollParent = this.parents().filter(function() {\n\t\t\t\treturn (/(auto|scroll)/).test($.css(this,\"overflow\")+$.css(this,\"overflow-y\")+$.css(this,\"overflow-x\"));\n\t\t\t}).eq(0);\n\t\t}\n\n\t\treturn (/fixed/).test(this.css(\"position\")) || !scrollParent.length ? $(document) : scrollParent;\n\t},\n\n\tzIndex: function( zIndex ) {\n\t\tif ( zIndex !== undefined ) {\n\t\t\treturn this.css( \"zIndex\", zIndex );\n\t\t}\n\n\t\tif ( this.length ) {\n\t\t\tvar elem = $( this[ 0 ] ), position, value;\n\t\t\twhile ( elem.length && elem[ 0 ] !== document ) {\n\t\t\t\t// Ignore z-index if position is set to a value where z-index is ignored by the browser\n\t\t\t\t// This makes behavior of this function consistent across browsers\n\t\t\t\t// WebKit always returns auto if the element is positioned\n\t\t\t\tposition = elem.css( \"position\" );\n\t\t\t\tif ( position === \"absolute\" || position === \"relative\" || position === \"fixed\" ) {\n\t\t\t\t\t// IE returns 0 when zIndex is not specified\n\t\t\t\t\t// other browsers return a string\n\t\t\t\t\t// we ignore the case of nested elements with an explicit value of 0\n\t\t\t\t\t// <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\n\t\t\t\t\tvalue = parseInt( elem.css( \"zIndex\" ), 10 );\n\t\t\t\t\tif ( !isNaN( value ) && value !== 0 ) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telem = elem.parent();\n\t\t\t}\n\t\t}\n\n\t\treturn 0;\n\t},\n\n\tuniqueId: function() {\n\t\treturn this.each(function() {\n\t\t\tif ( !this.id ) {\n\t\t\t\tthis.id = \"ui-id-\" + (++uuid);\n\t\t\t}\n\t\t});\n\t},\n\n\tremoveUniqueId: function() {\n\t\treturn this.each(function() {\n\t\t\tif ( runiqueId.test( this.id ) ) {\n\t\t\t\t$( this ).removeAttr( \"id\" );\n\t\t\t}\n\t\t});\n\t}\n});\n\n// selectors\nfunction focusable( element, isTabIndexNotNaN ) {\n\tvar map, mapName, img,\n\t\tnodeName = element.nodeName.toLowerCase();\n\tif ( \"area\" === nodeName ) {\n\t\tmap = element.parentNode;\n\t\tmapName = map.name;\n\t\tif ( !element.href || !mapName || map.nodeName.toLowerCase() !== \"map\" ) {\n\t\t\treturn false;\n\t\t}\n\t\timg = $( \"img[usemap=#\" + mapName + \"]\" )[0];\n\t\treturn !!img && visible( img );\n\t}\n\treturn ( /input|select|textarea|button|object/.test( nodeName ) ?\n\t\t!element.disabled :\n\t\t\"a\" === nodeName ?\n\t\t\telement.href || isTabIndexNotNaN :\n\t\t\tisTabIndexNotNaN) &&\n\t\t// the element and all of its ancestors must be visible\n\t\tvisible( element );\n}\n\nfunction visible( element ) {\n\treturn $.expr.filters.visible( element ) &&\n\t\t!$( element ).parents().addBack().filter(function() {\n\t\t\treturn $.css( this, \"visibility\" ) === \"hidden\";\n\t\t}).length;\n}\n\n$.extend( $.expr[ \":\" ], {\n\tdata: $.expr.createPseudo ?\n\t\t$.expr.createPseudo(function( dataName ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn !!$.data( elem, dataName );\n\t\t\t};\n\t\t}) :\n\t\t// support: jQuery <1.8\n\t\tfunction( elem, i, match ) {\n\t\t\treturn !!$.data( elem, match[ 3 ] );\n\t\t},\n\n\tfocusable: function( element ) {\n\t\treturn focusable( element, !isNaN( $.attr( element, \"tabindex\" ) ) );\n\t},\n\n\ttabbable: function( element ) {\n\t\tvar tabIndex = $.attr( element, \"tabindex\" ),\n\t\t\tisTabIndexNaN = isNaN( tabIndex );\n\t\treturn ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );\n\t}\n});\n\n// support: jQuery <1.8\nif ( !$( \"<a>\" ).outerWidth( 1 ).jquery ) {\n\t$.each( [ \"Width\", \"Height\" ], function( i, name ) {\n\t\tvar side = name === \"Width\" ? [ \"Left\", \"Right\" ] : [ \"Top\", \"Bottom\" ],\n\t\t\ttype = name.toLowerCase(),\n\t\t\torig = {\n\t\t\t\tinnerWidth: $.fn.innerWidth,\n\t\t\t\tinnerHeight: $.fn.innerHeight,\n\t\t\t\touterWidth: $.fn.outerWidth,\n\t\t\t\touterHeight: $.fn.outerHeight\n\t\t\t};\n\n\t\tfunction reduce( elem, size, border, margin ) {\n\t\t\t$.each( side, function() {\n\t\t\t\tsize -= parseFloat( $.css( elem, \"padding\" + this ) ) || 0;\n\t\t\t\tif ( border ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t\t}\n\t\t\t\tif ( margin ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"margin\" + this ) ) || 0;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn size;\n\t\t}\n\n\t\t$.fn[ \"inner\" + name ] = function( size ) {\n\t\t\tif ( size === undefined ) {\n\t\t\t\treturn orig[ \"inner\" + name ].call( this );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this ).css( type, reduce( this, size ) + \"px\" );\n\t\t\t});\n\t\t};\n\n\t\t$.fn[ \"outer\" + name] = function( size, margin ) {\n\t\t\tif ( typeof size !== \"number\" ) {\n\t\t\t\treturn orig[ \"outer\" + name ].call( this, size );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this).css( type, reduce( this, size, true, margin ) + \"px\" );\n\t\t\t});\n\t\t};\n\t});\n}\n\n// support: jQuery <1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)\nif ( $( \"<a>\" ).data( \"a-b\", \"a\" ).removeData( \"a-b\" ).data( \"a-b\" ) ) {\n\t$.fn.removeData = (function( removeData ) {\n\t\treturn function( key ) {\n\t\t\tif ( arguments.length ) {\n\t\t\t\treturn removeData.call( this, $.camelCase( key ) );\n\t\t\t} else {\n\t\t\t\treturn removeData.call( this );\n\t\t\t}\n\t\t};\n\t})( $.fn.removeData );\n}\n\n\n\n\n\n// deprecated\n$.ui.ie = !!/msie [\\w.]+/.exec( navigator.userAgent.toLowerCase() );\n\n$.support.selectstart = \"onselectstart\" in document.createElement( \"div\" );\n$.fn.extend({\n\tdisableSelection: function() {\n\t\treturn this.bind( ( $.support.selectstart ? \"selectstart\" : \"mousedown\" ) +\n\t\t\t\".ui-disableSelection\", function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t});\n\t},\n\n\tenableSelection: function() {\n\t\treturn this.unbind( \".ui-disableSelection\" );\n\t}\n});\n\n$.extend( $.ui, {\n\t// $.ui.plugin is deprecated. Use $.widget() extensions instead.\n\tplugin: {\n\t\tadd: function( module, option, set ) {\n\t\t\tvar i,\n\t\t\t\tproto = $.ui[ module ].prototype;\n\t\t\tfor ( i in set ) {\n\t\t\t\tproto.plugins[ i ] = proto.plugins[ i ] || [];\n\t\t\t\tproto.plugins[ i ].push( [ option, set[ i ] ] );\n\t\t\t}\n\t\t},\n\t\tcall: function( instance, name, args ) {\n\t\t\tvar i,\n\t\t\t\tset = instance.plugins[ name ];\n\t\t\tif ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor ( i = 0; i < set.length; i++ ) {\n\t\t\t\tif ( instance.options[ set[ i ][ 0 ] ] ) {\n\t\t\t\t\tset[ i ][ 1 ].apply( instance.element, args );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// only used by resizable\n\thasScroll: function( el, a ) {\n\n\t\t//If overflow is hidden, the element might have extra content, but the user wants to hide it\n\t\tif ( $( el ).css( \"overflow\" ) === \"hidden\") {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar scroll = ( a && a === \"left\" ) ? \"scrollLeft\" : \"scrollTop\",\n\t\t\thas = false;\n\n\t\tif ( el[ scroll ] > 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: determine which cases actually cause this to happen\n\t\t// if the element doesn't have the scroll set, see if it's possible to\n\t\t// set the scroll\n\t\tel[ scroll ] = 1;\n\t\thas = ( el[ scroll ] > 0 );\n\t\tel[ scroll ] = 0;\n\t\treturn has;\n\t}\n});\n\n})( jQuery );\n(function( $, undefined ) {\n\nvar uuid = 0,\n\tslice = Array.prototype.slice,\n\t_cleanData = $.cleanData;\n$.cleanData = function( elems ) {\n\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\ttry {\n\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t// http://bugs.jquery.com/ticket/8235\n\t\t} catch( e ) {}\n\t}\n\t_cleanData( elems );\n};\n\n$.widget = function( name, base, prototype ) {\n\tvar fullName, existingConstructor, constructor, basePrototype,\n\t\t// proxiedPrototype allows the provided prototype to remain unmodified\n\t\t// so that it can be used as a mixin for multiple widgets (#8876)\n\t\tproxiedPrototype = {},\n\t\tnamespace = name.split( \".\" )[ 0 ];\n\n\tname = name.split( \".\" )[ 1 ];\n\tfullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\t// create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\t\t// allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\t// extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\t\t// copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\t\t// track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t});\n\n\tbasePrototype = new base();\n\t// we need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = (function() {\n\t\t\tvar _super = function() {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t\t},\n\t\t\t\t_superApply = function( args ) {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t\t};\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super,\n\t\t\t\t\t__superApply = this._superApply,\n\t\t\t\t\treturnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t})();\n\t});\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t});\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor, child._proto );\n\t\t});\n\t\t// remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n};\n\n$.widget.extend = function( target ) {\n\tvar input = slice.call( arguments, 1 ),\n\t\tinputIndex = 0,\n\t\tinputLength = input.length,\n\t\tkey,\n\t\tvalue;\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\",\n\t\t\targs = slice.call( arguments, 1 ),\n\t\t\treturnValue = this;\n\n\t\t// allow multiple hashes to be passed on init\n\t\toptions = !isMethodCall && args.length ?\n\t\t\t$.widget.extend.apply( null, [ options ].concat(args) ) :\n\t\t\toptions;\n\n\t\tif ( isMethodCall ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar methodValue,\n\t\t\t\t\tinstance = $.data( this, fullName );\n\t\t\t\tif ( !instance ) {\n\t\t\t\t\treturn $.error( \"cannot call methods on \" + name + \" prior to initialization; \" +\n\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t}\n\t\t\t\tif ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name + \" widget instance\" );\n\t\t\t\t}\n\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\tmethodValue;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.each(function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} )._init();\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"<div>\",\n\toptions: {\n\t\tdisabled: false,\n\n\t\t// callbacks\n\t\tcreate: null\n\t},\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = uuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.document = $( element.style ?\n\t\t\t\t// element within the document\n\t\t\t\telement.ownerDocument :\n\t\t\t\t// element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[0].defaultView || this.document[0].parentWindow );\n\t\t}\n\n\t\tthis._create();\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\t_getCreateOptions: $.noop,\n\t_getCreateEventData: $.noop,\n\t_create: $.noop,\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tthis._destroy();\n\t\t// we can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t// 1.9 BC for #7810\n\t\t\t// TODO remove dual storage\n\t\t\t.removeData( this.widgetName )\n\t\t\t.removeData( this.widgetFullName )\n\t\t\t// support: jquery <1.6.3\n\t\t\t// http://bugs.jquery.com/ticket/9413\n\t\t\t.removeData( $.camelCase( this.widgetFullName ) );\n\t\tthis.widget()\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.removeClass(\n\t\t\t\tthis.widgetFullName + \"-disabled \" +\n\t\t\t\t\"ui-state-disabled\" );\n\n\t\t// clean up events and states\n\t\tthis.bindings.unbind( this.eventNamespace );\n\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t},\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key,\n\t\t\tparts,\n\t\t\tcurOption,\n\t\t\ti;\n\n\t\tif ( arguments.length === 0 ) {\n\t\t\t// don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\t\t\t// handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\t_setOption: function( key, value ) {\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget()\n\t\t\t\t.toggleClass( this.widgetFullName + \"-disabled ui-state-disabled\", !!value )\n\t\t\t\t.attr( \"aria-disabled\", value );\n\t\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tenable: function() {\n\t\treturn this._setOption( \"disabled\", false );\n\t},\n\tdisable: function() {\n\t\treturn this._setOption( \"disabled\", true );\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement,\n\t\t\tinstance = this;\n\n\t\t// no suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// no element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\t// accept selectors, DOM elements\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\t\t\t\t// allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^(\\w+)\\s*(.*)$/ ),\n\t\t\t\teventName = match[1] + instance.eventNamespace,\n\t\t\t\tselector = match[2];\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.delegate( selector, eventName, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.bind( eventName, handlerProxy );\n\t\t\t}\n\t\t});\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = (eventName || \"\").split( \" \" ).join( this.eventNamespace + \" \" ) + this.eventNamespace;\n\t\telement.unbind( eventName ).undelegate( eventName );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-hover\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig,\n\t\t\tcallback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\t\t// the original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[0], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\t\tvar hasOptions,\n\t\t\teffectName = !options ?\n\t\t\t\tmethod :\n\t\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\t\tdefaultEffect :\n\t\t\t\t\toptions.effect || defaultEffect;\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue(function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t});\n\t\t}\n\t};\n});\n\n})( jQuery );\n(function( $, undefined ) {\n\nvar mouseHandled = false;\n$( document ).mouseup( function() {\n\tmouseHandled = false;\n});\n\n$.widget(\"ui.mouse\", {\n\tversion: \"1.10.4\",\n\toptions: {\n\t\tcancel: \"input,textarea,button,select,option\",\n\t\tdistance: 1,\n\t\tdelay: 0\n\t},\n\t_mouseInit: function() {\n\t\tvar that = this;\n\n\t\tthis.element\n\t\t\t.bind(\"mousedown.\"+this.widgetName, function(event) {\n\t\t\t\treturn that._mouseDown(event);\n\t\t\t})\n\t\t\t.bind(\"click.\"+this.widgetName, function(event) {\n\t\t\t\tif (true === $.data(event.target, that.widgetName + \".preventClickEvent\")) {\n\t\t\t\t\t$.removeData(event.target, that.widgetName + \".preventClickEvent\");\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.started = false;\n\t},\n\n\t// TODO: make sure destroying one instance of mouse doesn't mess with\n\t// other instances of mouse\n\t_mouseDestroy: function() {\n\t\tthis.element.unbind(\".\"+this.widgetName);\n\t\tif ( this._mouseMoveDelegate ) {\n\t\t\t$(document)\n\t\t\t\t.unbind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t\t.unbind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\t\t}\n\t},\n\n\t_mouseDown: function(event) {\n\t\t// don't let more than one widget handle mouseStart\n\t\tif( mouseHandled ) { return; }\n\n\t\t// we may have missed mouseup (out of window)\n\t\t(this._mouseStarted && this._mouseUp(event));\n\n\t\tthis._mouseDownEvent = event;\n\n\t\tvar that = this,\n\t\t\tbtnIsLeft = (event.which === 1),\n\t\t\t// event.target.nodeName works around a bug in IE 8 with\n\t\t\t// disabled inputs (#7620)\n\t\t\telIsCancel = (typeof this.options.cancel === \"string\" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);\n\t\tif (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.mouseDelayMet = !this.options.delay;\n\t\tif (!this.mouseDelayMet) {\n\t\t\tthis._mouseDelayTimer = setTimeout(function() {\n\t\t\t\tthat.mouseDelayMet = true;\n\t\t\t}, this.options.delay);\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted = (this._mouseStart(event) !== false);\n\t\t\tif (!this._mouseStarted) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// Click event may never have fired (Gecko & Opera)\n\t\tif (true === $.data(event.target, this.widgetName + \".preventClickEvent\")) {\n\t\t\t$.removeData(event.target, this.widgetName + \".preventClickEvent\");\n\t\t}\n\n\t\t// these delegates are required to keep context\n\t\tthis._mouseMoveDelegate = function(event) {\n\t\t\treturn that._mouseMove(event);\n\t\t};\n\t\tthis._mouseUpDelegate = function(event) {\n\t\t\treturn that._mouseUp(event);\n\t\t};\n\t\t$(document)\n\t\t\t.bind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t.bind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\n\t\tevent.preventDefault();\n\n\t\tmouseHandled = true;\n\t\treturn true;\n\t},\n\n\t_mouseMove: function(event) {\n\t\t// IE mouseup check - mouseup happened when mouse was out of window\n\t\tif ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {\n\t\t\treturn this._mouseUp(event);\n\t\t}\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseDrag(event);\n\t\t\treturn event.preventDefault();\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted =\n\t\t\t\t(this._mouseStart(this._mouseDownEvent, event) !== false);\n\t\t\t(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));\n\t\t}\n\n\t\treturn !this._mouseStarted;\n\t},\n\n\t_mouseUp: function(event) {\n\t\t$(document)\n\t\t\t.unbind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t.unbind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseStarted = false;\n\n\t\t\tif (event.target === this._mouseDownEvent.target) {\n\t\t\t\t$.data(event.target, this.widgetName + \".preventClickEvent\", true);\n\t\t\t}\n\n\t\t\tthis._mouseStop(event);\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseDistanceMet: function(event) {\n\t\treturn (Math.max(\n\t\t\t\tMath.abs(this._mouseDownEvent.pageX - event.pageX),\n\t\t\t\tMath.abs(this._mouseDownEvent.pageY - event.pageY)\n\t\t\t) >= this.options.distance\n\t\t);\n\t},\n\n\t_mouseDelayMet: function(/* event */) {\n\t\treturn this.mouseDelayMet;\n\t},\n\n\t// These are placeholder methods, to be overriden by extending plugin\n\t_mouseStart: function(/* event */) {},\n\t_mouseDrag: function(/* event */) {},\n\t_mouseStop: function(/* event */) {},\n\t_mouseCapture: function(/* event */) { return true; }\n});\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.ui = $.ui || {};\n\nvar cachedScrollbarWidth,\n\tmax = Math.max,\n\tabs = Math.abs,\n\tround = Math.round,\n\trhorizontal = /left|center|right/,\n\trvertical = /top|center|bottom/,\n\troffset = /[\\+\\-]\\d+(\\.[\\d]+)?%?/,\n\trposition = /^\\w+/,\n\trpercent = /%$/,\n\t_position = $.fn.position;\n\nfunction getOffsets( offsets, width, height ) {\n\treturn [\n\t\tparseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),\n\t\tparseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )\n\t];\n}\n\nfunction parseCss( element, property ) {\n\treturn parseInt( $.css( element, property ), 10 ) || 0;\n}\n\nfunction getDimensions( elem ) {\n\tvar raw = elem[0];\n\tif ( raw.nodeType === 9 ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: 0, left: 0 }\n\t\t};\n\t}\n\tif ( $.isWindow( raw ) ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: elem.scrollTop(), left: elem.scrollLeft() }\n\t\t};\n\t}\n\tif ( raw.preventDefault ) {\n\t\treturn {\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\toffset: { top: raw.pageY, left: raw.pageX }\n\t\t};\n\t}\n\treturn {\n\t\twidth: elem.outerWidth(),\n\t\theight: elem.outerHeight(),\n\t\toffset: elem.offset()\n\t};\n}\n\n$.position = {\n\tscrollbarWidth: function() {\n\t\tif ( cachedScrollbarWidth !== undefined ) {\n\t\t\treturn cachedScrollbarWidth;\n\t\t}\n\t\tvar w1, w2,\n\t\t\tdiv = $( \"<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>\" ),\n\t\t\tinnerDiv = div.children()[0];\n\n\t\t$( \"body\" ).append( div );\n\t\tw1 = innerDiv.offsetWidth;\n\t\tdiv.css( \"overflow\", \"scroll\" );\n\n\t\tw2 = innerDiv.offsetWidth;\n\n\t\tif ( w1 === w2 ) {\n\t\t\tw2 = div[0].clientWidth;\n\t\t}\n\n\t\tdiv.remove();\n\n\t\treturn (cachedScrollbarWidth = w1 - w2);\n\t},\n\tgetScrollInfo: function( within ) {\n\t\tvar overflowX = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-x\" ),\n\t\t\toverflowY = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-y\" ),\n\t\t\thasOverflowX = overflowX === \"scroll\" ||\n\t\t\t\t( overflowX === \"auto\" && within.width < within.element[0].scrollWidth ),\n\t\t\thasOverflowY = overflowY === \"scroll\" ||\n\t\t\t\t( overflowY === \"auto\" && within.height < within.element[0].scrollHeight );\n\t\treturn {\n\t\t\twidth: hasOverflowY ? $.position.scrollbarWidth() : 0,\n\t\t\theight: hasOverflowX ? $.position.scrollbarWidth() : 0\n\t\t};\n\t},\n\tgetWithinInfo: function( element ) {\n\t\tvar withinElement = $( element || window ),\n\t\t\tisWindow = $.isWindow( withinElement[0] ),\n\t\t\tisDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;\n\t\treturn {\n\t\t\telement: withinElement,\n\t\t\tisWindow: isWindow,\n\t\t\tisDocument: isDocument,\n\t\t\toffset: withinElement.offset() || { left: 0, top: 0 },\n\t\t\tscrollLeft: withinElement.scrollLeft(),\n\t\t\tscrollTop: withinElement.scrollTop(),\n\t\t\twidth: isWindow ? withinElement.width() : withinElement.outerWidth(),\n\t\t\theight: isWindow ? withinElement.height() : withinElement.outerHeight()\n\t\t};\n\t}\n};\n\n$.fn.position = function( options ) {\n\tif ( !options || !options.of ) {\n\t\treturn _position.apply( this, arguments );\n\t}\n\n\t// make a copy, we don't want to modify arguments\n\toptions = $.extend( {}, options );\n\n\tvar atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,\n\t\ttarget = $( options.of ),\n\t\twithin = $.position.getWithinInfo( options.within ),\n\t\tscrollInfo = $.position.getScrollInfo( within ),\n\t\tcollision = ( options.collision || \"flip\" ).split( \" \" ),\n\t\toffsets = {};\n\n\tdimensions = getDimensions( target );\n\tif ( target[0].preventDefault ) {\n\t\t// force left top to allow flipping\n\t\toptions.at = \"left top\";\n\t}\n\ttargetWidth = dimensions.width;\n\ttargetHeight = dimensions.height;\n\ttargetOffset = dimensions.offset;\n\t// clone to reuse original targetOffset later\n\tbasePosition = $.extend( {}, targetOffset );\n\n\t// force my and at to have valid horizontal and vertical positions\n\t// if a value is missing or invalid, it will be converted to center\n\t$.each( [ \"my\", \"at\" ], function() {\n\t\tvar pos = ( options[ this ] || \"\" ).split( \" \" ),\n\t\t\thorizontalOffset,\n\t\t\tverticalOffset;\n\n\t\tif ( pos.length === 1) {\n\t\t\tpos = rhorizontal.test( pos[ 0 ] ) ?\n\t\t\t\tpos.concat( [ \"center\" ] ) :\n\t\t\t\trvertical.test( pos[ 0 ] ) ?\n\t\t\t\t\t[ \"center\" ].concat( pos ) :\n\t\t\t\t\t[ \"center\", \"center\" ];\n\t\t}\n\t\tpos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : \"center\";\n\t\tpos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : \"center\";\n\n\t\t// calculate offsets\n\t\thorizontalOffset = roffset.exec( pos[ 0 ] );\n\t\tverticalOffset = roffset.exec( pos[ 1 ] );\n\t\toffsets[ this ] = [\n\t\t\thorizontalOffset ? horizontalOffset[ 0 ] : 0,\n\t\t\tverticalOffset ? verticalOffset[ 0 ] : 0\n\t\t];\n\n\t\t// reduce to just the positions without the offsets\n\t\toptions[ this ] = [\n\t\t\trposition.exec( pos[ 0 ] )[ 0 ],\n\t\t\trposition.exec( pos[ 1 ] )[ 0 ]\n\t\t];\n\t});\n\n\t// normalize collision option\n\tif ( collision.length === 1 ) {\n\t\tcollision[ 1 ] = collision[ 0 ];\n\t}\n\n\tif ( options.at[ 0 ] === \"right\" ) {\n\t\tbasePosition.left += targetWidth;\n\t} else if ( options.at[ 0 ] === \"center\" ) {\n\t\tbasePosition.left += targetWidth / 2;\n\t}\n\n\tif ( options.at[ 1 ] === \"bottom\" ) {\n\t\tbasePosition.top += targetHeight;\n\t} else if ( options.at[ 1 ] === \"center\" ) {\n\t\tbasePosition.top += targetHeight / 2;\n\t}\n\n\tatOffset = getOffsets( offsets.at, targetWidth, targetHeight );\n\tbasePosition.left += atOffset[ 0 ];\n\tbasePosition.top += atOffset[ 1 ];\n\n\treturn this.each(function() {\n\t\tvar collisionPosition, using,\n\t\t\telem = $( this ),\n\t\t\telemWidth = elem.outerWidth(),\n\t\t\telemHeight = elem.outerHeight(),\n\t\t\tmarginLeft = parseCss( this, \"marginLeft\" ),\n\t\t\tmarginTop = parseCss( this, \"marginTop\" ),\n\t\t\tcollisionWidth = elemWidth + marginLeft + parseCss( this, \"marginRight\" ) + scrollInfo.width,\n\t\t\tcollisionHeight = elemHeight + marginTop + parseCss( this, \"marginBottom\" ) + scrollInfo.height,\n\t\t\tposition = $.extend( {}, basePosition ),\n\t\t\tmyOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );\n\n\t\tif ( options.my[ 0 ] === \"right\" ) {\n\t\t\tposition.left -= elemWidth;\n\t\t} else if ( options.my[ 0 ] === \"center\" ) {\n\t\t\tposition.left -= elemWidth / 2;\n\t\t}\n\n\t\tif ( options.my[ 1 ] === \"bottom\" ) {\n\t\t\tposition.top -= elemHeight;\n\t\t} else if ( options.my[ 1 ] === \"center\" ) {\n\t\t\tposition.top -= elemHeight / 2;\n\t\t}\n\n\t\tposition.left += myOffset[ 0 ];\n\t\tposition.top += myOffset[ 1 ];\n\n\t\t// if the browser doesn't support fractions, then round for consistent results\n\t\tif ( !$.support.offsetFractions ) {\n\t\t\tposition.left = round( position.left );\n\t\t\tposition.top = round( position.top );\n\t\t}\n\n\t\tcollisionPosition = {\n\t\t\tmarginLeft: marginLeft,\n\t\t\tmarginTop: marginTop\n\t\t};\n\n\t\t$.each( [ \"left\", \"top\" ], function( i, dir ) {\n\t\t\tif ( $.ui.position[ collision[ i ] ] ) {\n\t\t\t\t$.ui.position[ collision[ i ] ][ dir ]( position, {\n\t\t\t\t\ttargetWidth: targetWidth,\n\t\t\t\t\ttargetHeight: targetHeight,\n\t\t\t\t\telemWidth: elemWidth,\n\t\t\t\t\telemHeight: elemHeight,\n\t\t\t\t\tcollisionPosition: collisionPosition,\n\t\t\t\t\tcollisionWidth: collisionWidth,\n\t\t\t\t\tcollisionHeight: collisionHeight,\n\t\t\t\t\toffset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],\n\t\t\t\t\tmy: options.my,\n\t\t\t\t\tat: options.at,\n\t\t\t\t\twithin: within,\n\t\t\t\t\telem : elem\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tif ( options.using ) {\n\t\t\t// adds feedback as second argument to using callback, if present\n\t\t\tusing = function( props ) {\n\t\t\t\tvar left = targetOffset.left - position.left,\n\t\t\t\t\tright = left + targetWidth - elemWidth,\n\t\t\t\t\ttop = targetOffset.top - position.top,\n\t\t\t\t\tbottom = top + targetHeight - elemHeight,\n\t\t\t\t\tfeedback = {\n\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\telement: target,\n\t\t\t\t\t\t\tleft: targetOffset.left,\n\t\t\t\t\t\t\ttop: targetOffset.top,\n\t\t\t\t\t\t\twidth: targetWidth,\n\t\t\t\t\t\t\theight: targetHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\telement: {\n\t\t\t\t\t\t\telement: elem,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\twidth: elemWidth,\n\t\t\t\t\t\t\theight: elemHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\thorizontal: right < 0 ? \"left\" : left > 0 ? \"right\" : \"center\",\n\t\t\t\t\t\tvertical: bottom < 0 ? \"top\" : top > 0 ? \"bottom\" : \"middle\"\n\t\t\t\t\t};\n\t\t\t\tif ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {\n\t\t\t\t\tfeedback.horizontal = \"center\";\n\t\t\t\t}\n\t\t\t\tif ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {\n\t\t\t\t\tfeedback.vertical = \"middle\";\n\t\t\t\t}\n\t\t\t\tif ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {\n\t\t\t\t\tfeedback.important = \"horizontal\";\n\t\t\t\t} else {\n\t\t\t\t\tfeedback.important = \"vertical\";\n\t\t\t\t}\n\t\t\t\toptions.using.call( this, props, feedback );\n\t\t\t};\n\t\t}\n\n\t\telem.offset( $.extend( position, { using: using } ) );\n\t});\n};\n\n$.ui.position = {\n\tfit: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\touterWidth = within.width,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = withinOffset - collisionPosLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,\n\t\t\t\tnewOverRight;\n\n\t\t\t// element is wider than within\n\t\t\tif ( data.collisionWidth > outerWidth ) {\n\t\t\t\t// element is initially over the left side of within\n\t\t\t\tif ( overLeft > 0 && overRight <= 0 ) {\n\t\t\t\t\tnewOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\t\tposition.left += overLeft - newOverRight;\n\t\t\t\t// element is initially over right side of within\n\t\t\t\t} else if ( overRight > 0 && overLeft <= 0 ) {\n\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t// element is initially over both left and right sides of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overLeft > overRight ) {\n\t\t\t\t\t\tposition.left = withinOffset + outerWidth - data.collisionWidth;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far left -> align with left edge\n\t\t\t} else if ( overLeft > 0 ) {\n\t\t\t\tposition.left += overLeft;\n\t\t\t// too far right -> align with right edge\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tposition.left -= overRight;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.left = max( position.left - collisionPosLeft, position.left );\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\touterHeight = data.within.height,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = withinOffset - collisionPosTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,\n\t\t\t\tnewOverBottom;\n\n\t\t\t// element is taller than within\n\t\t\tif ( data.collisionHeight > outerHeight ) {\n\t\t\t\t// element is initially over the top of within\n\t\t\t\tif ( overTop > 0 && overBottom <= 0 ) {\n\t\t\t\t\tnewOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\t\tposition.top += overTop - newOverBottom;\n\t\t\t\t// element is initially over bottom of within\n\t\t\t\t} else if ( overBottom > 0 && overTop <= 0 ) {\n\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t// element is initially over both top and bottom of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overTop > overBottom ) {\n\t\t\t\t\t\tposition.top = withinOffset + outerHeight - data.collisionHeight;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far up -> align with top\n\t\t\t} else if ( overTop > 0 ) {\n\t\t\t\tposition.top += overTop;\n\t\t\t// too far down -> align with bottom edge\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tposition.top -= overBottom;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.top = max( position.top - collisionPosTop, position.top );\n\t\t\t}\n\t\t}\n\t},\n\tflip: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.left + within.scrollLeft,\n\t\t\t\touterWidth = within.width,\n\t\t\t\toffsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = collisionPosLeft - offsetLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,\n\t\t\t\tmyOffset = data.my[ 0 ] === \"left\" ?\n\t\t\t\t\t-data.elemWidth :\n\t\t\t\t\tdata.my[ 0 ] === \"right\" ?\n\t\t\t\t\t\tdata.elemWidth :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 0 ] === \"left\" ?\n\t\t\t\t\tdata.targetWidth :\n\t\t\t\t\tdata.at[ 0 ] === \"right\" ?\n\t\t\t\t\t\t-data.targetWidth :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 0 ],\n\t\t\t\tnewOverRight,\n\t\t\t\tnewOverLeft;\n\n\t\t\tif ( overLeft < 0 ) {\n\t\t\t\tnewOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\tif ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( overRight > 0 ) {\n\t\t\t\tnewOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;\n\t\t\t\tif ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.top + within.scrollTop,\n\t\t\t\touterHeight = within.height,\n\t\t\t\toffsetTop = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = collisionPosTop - offsetTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,\n\t\t\t\ttop = data.my[ 1 ] === \"top\",\n\t\t\t\tmyOffset = top ?\n\t\t\t\t\t-data.elemHeight :\n\t\t\t\t\tdata.my[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\tdata.elemHeight :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 1 ] === \"top\" ?\n\t\t\t\t\tdata.targetHeight :\n\t\t\t\t\tdata.at[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\t-data.targetHeight :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 1 ],\n\t\t\t\tnewOverTop,\n\t\t\t\tnewOverBottom;\n\t\t\tif ( overTop < 0 ) {\n\t\t\t\tnewOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\tif ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( overBottom > 0 ) {\n\t\t\t\tnewOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;\n\t\t\t\tif ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tflipfit: {\n\t\tleft: function() {\n\t\t\t$.ui.position.flip.left.apply( this, arguments );\n\t\t\t$.ui.position.fit.left.apply( this, arguments );\n\t\t},\n\t\ttop: function() {\n\t\t\t$.ui.position.flip.top.apply( this, arguments );\n\t\t\t$.ui.position.fit.top.apply( this, arguments );\n\t\t}\n\t}\n};\n\n// fraction support test\n(function () {\n\tvar testElement, testElementParent, testElementStyle, offsetLeft, i,\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ],\n\t\tdiv = document.createElement( \"div\" );\n\n\t//Create a \"fake body\" for testing based on method used in jQuery.support\n\ttestElement = document.createElement( body ? \"div\" : \"body\" );\n\ttestElementStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0,\n\t\tbackground: \"none\"\n\t};\n\tif ( body ) {\n\t\t$.extend( testElementStyle, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-1000px\",\n\t\t\ttop: \"-1000px\"\n\t\t});\n\t}\n\tfor ( i in testElementStyle ) {\n\t\ttestElement.style[ i ] = testElementStyle[ i ];\n\t}\n\ttestElement.appendChild( div );\n\ttestElementParent = body || document.documentElement;\n\ttestElementParent.insertBefore( testElement, testElementParent.firstChild );\n\n\tdiv.style.cssText = \"position: absolute; left: 10.7432222px;\";\n\n\toffsetLeft = $( div ).offset().left;\n\t$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;\n\n\ttestElement.innerHTML = \"\";\n\ttestElementParent.removeChild( testElement );\n})();\n\n}( jQuery ) );\n(function( $, undefined ) {\n\nvar uid = 0,\n\thideProps = {},\n\tshowProps = {};\n\nhideProps.height = hideProps.paddingTop = hideProps.paddingBottom =\n\thideProps.borderTopWidth = hideProps.borderBottomWidth = \"hide\";\nshowProps.height = showProps.paddingTop = showProps.paddingBottom =\n\tshowProps.borderTopWidth = showProps.borderBottomWidth = \"show\";\n\n$.widget( \"ui.accordion\", {\n\tversion: \"1.10.4\",\n\toptions: {\n\t\tactive: 0,\n\t\tanimate: {},\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theader: \"> li > :first-child,> :not(li):even\",\n\t\theightStyle: \"auto\",\n\t\ticons: {\n\t\t\tactiveHeader: \"ui-icon-triangle-1-s\",\n\t\t\theader: \"ui-icon-triangle-1-e\"\n\t\t},\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null\n\t},\n\n\t_create: function() {\n\t\tvar options = this.options;\n\t\tthis.prevShow = this.prevHide = $();\n\t\tthis.element.addClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t// ARIA\n\t\t\t.attr( \"role\", \"tablist\" );\n\n\t\t// don't allow collapsible: false and active: false / null\n\t\tif ( !options.collapsible && (options.active === false || options.active == null) ) {\n\t\t\toptions.active = 0;\n\t\t}\n\n\t\tthis._processPanels();\n\t\t// handle negative values\n\t\tif ( options.active < 0 ) {\n\t\t\toptions.active += this.headers.length;\n\t\t}\n\t\tthis._refresh();\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\theader: this.active,\n\t\t\tpanel: !this.active.length ? $() : this.active.next(),\n\t\t\tcontent: !this.active.length ? $() : this.active.next()\n\t\t};\n\t},\n\n\t_createIcons: function() {\n\t\tvar icons = this.options.icons;\n\t\tif ( icons ) {\n\t\t\t$( \"<span>\" )\n\t\t\t\t.addClass( \"ui-accordion-header-icon ui-icon \" + icons.header )\n\t\t\t\t.prependTo( this.headers );\n\t\t\tthis.active.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( icons.header )\n\t\t\t\t.addClass( icons.activeHeader );\n\t\t\tthis.headers.addClass( \"ui-accordion-icons\" );\n\t\t}\n\t},\n\n\t_destroyIcons: function() {\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-icons\" )\n\t\t\t.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.remove();\n\t},\n\n\t_destroy: function() {\n\t\tvar contents;\n\n\t\t// clean up main element\n\t\tthis.element\n\t\t\t.removeClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\t// clean up headers\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t.removeAttr( \"aria-controls\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.each(function() {\n\t\t\t\tif ( /^ui-accordion/.test( this.id ) ) {\n\t\t\t\t\tthis.removeAttribute( \"id\" );\n\t\t\t\t}\n\t\t\t});\n\t\tthis._destroyIcons();\n\n\t\t// clean up content panels\n\t\tcontents = this.headers.next()\n\t\t\t.css( \"display\", \"\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t.removeClass( \"ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled\" )\n\t\t\t.each(function() {\n\t\t\t\tif ( /^ui-accordion/.test( this.id ) ) {\n\t\t\t\t\tthis.removeAttribute( \"id\" );\n\t\t\t\t}\n\t\t\t});\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tcontents.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tif ( this.options.event ) {\n\t\t\t\tthis._off( this.headers, this.options.event );\n\t\t\t}\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\t// setting collapsible: false while collapsed; open first panel\n\t\tif ( key === \"collapsible\" && !value && this.options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t}\n\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis._destroyIcons();\n\t\t\tif ( value ) {\n\t\t\t\tthis._createIcons();\n\t\t\t}\n\t\t}\n\n\t\t// #5332 - opacity doesn't cascade to positioned elements in IE\n\t\t// so we need to add the disabled class to the headers and panels\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.headers.add( this.headers.next() )\n\t\t\t\t.toggleClass( \"ui-state-disabled\", !!value );\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\tif ( event.altKey || event.ctrlKey ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar keyCode = $.ui.keyCode,\n\t\t\tlength = this.headers.length,\n\t\t\tcurrentIndex = this.headers.index( event.target ),\n\t\t\ttoFocus = false;\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase keyCode.RIGHT:\n\t\t\tcase keyCode.DOWN:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex + 1 ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.LEFT:\n\t\t\tcase keyCode.UP:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex - 1 + length ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.SPACE:\n\t\t\tcase keyCode.ENTER:\n\t\t\t\tthis._eventHandler( event );\n\t\t\t\tbreak;\n\t\t\tcase keyCode.HOME:\n\t\t\t\ttoFocus = this.headers[ 0 ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.END:\n\t\t\t\ttoFocus = this.headers[ length - 1 ];\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( toFocus ) {\n\t\t\t$( event.target ).attr( \"tabIndex\", -1 );\n\t\t\t$( toFocus ).attr( \"tabIndex\", 0 );\n\t\t\ttoFocus.focus();\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_panelKeyDown : function( event ) {\n\t\tif ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {\n\t\t\t$( event.currentTarget ).prev().focus();\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options;\n\t\tthis._processPanels();\n\n\t\t// was collapsed or no panel\n\t\tif ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// active false only when collapsible is true\n\t\t} else if ( options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t// was active, but active panel is gone\n\t\t} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining panel are disabled\n\t\t\tif ( this.headers.length === this.headers.find(\".ui-state-disabled\").length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous panel\n\t\t\t} else {\n\t\t\t\tthis._activate( Math.max( 0, options.active - 1 ) );\n\t\t\t}\n\t\t// was active, active panel still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.headers.index( this.active );\n\t\t}\n\n\t\tthis._destroyIcons();\n\n\t\tthis._refresh();\n\t},\n\n\t_processPanels: function() {\n\t\tthis.headers = this.element.find( this.options.header )\n\t\t\t.addClass( \"ui-accordion-header ui-helper-reset ui-state-default ui-corner-all\" );\n\n\t\tthis.headers.next()\n\t\t\t.addClass( \"ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom\" )\n\t\t\t.filter(\":not(.ui-accordion-content-active)\")\n\t\t\t.hide();\n\t},\n\n\t_refresh: function() {\n\t\tvar maxHeight,\n\t\t\toptions = this.options,\n\t\t\theightStyle = options.heightStyle,\n\t\t\tparent = this.element.parent(),\n\t\t\taccordionId = this.accordionId = \"ui-accordion-\" +\n\t\t\t\t(this.element.attr( \"id\" ) || ++uid);\n\n\t\tthis.active = this._findActive( options.active )\n\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" )\n\t\t\t.removeClass( \"ui-corner-all\" );\n\t\tthis.active.next()\n\t\t\t.addClass( \"ui-accordion-content-active\" )\n\t\t\t.show();\n\n\t\tthis.headers\n\t\t\t.attr( \"role\", \"tab\" )\n\t\t\t.each(function( i ) {\n\t\t\t\tvar header = $( this ),\n\t\t\t\t\theaderId = header.attr( \"id\" ),\n\t\t\t\t\tpanel = header.next(),\n\t\t\t\t\tpanelId = panel.attr( \"id\" );\n\t\t\t\tif ( !headerId ) {\n\t\t\t\t\theaderId = accordionId + \"-header-\" + i;\n\t\t\t\t\theader.attr( \"id\", headerId );\n\t\t\t\t}\n\t\t\t\tif ( !panelId ) {\n\t\t\t\t\tpanelId = accordionId + \"-panel-\" + i;\n\t\t\t\t\tpanel.attr( \"id\", panelId );\n\t\t\t\t}\n\t\t\t\theader.attr( \"aria-controls\", panelId );\n\t\t\t\tpanel.attr( \"aria-labelledby\", headerId );\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr( \"role\", \"tabpanel\" );\n\n\t\tthis.headers\n\t\t\t.not( this.active )\n\t\t\t.attr({\n\t\t\t\t\"aria-selected\": \"false\",\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\ttabIndex: -1\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t\t})\n\t\t\t\t.hide();\n\n\t\t// make sure at least one header is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.headers.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active.attr({\n\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\ttabIndex: 0\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\n\t\tthis._createIcons();\n\n\t\tthis._setupEvents( options.event );\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t\t})\n\t\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).css( \"height\", \"\" ).height() );\n\t\t\t\t})\n\t\t\t\t.height( maxHeight );\n\t\t}\n\t},\n\n\t_activate: function( index ) {\n\t\tvar active = this._findActive( index )[ 0 ];\n\n\t\t// trying to activate the already active panel\n\t\tif ( active === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the currently active header\n\t\tactive = active || this.active[ 0 ];\n\n\t\tthis._eventHandler({\n\t\t\ttarget: active,\n\t\t\tcurrentTarget: active,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( selector ) {\n\t\treturn typeof selector === \"number\" ? this.headers.eq( selector ) : $();\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {\n\t\t\tkeydown: \"_keydown\"\n\t\t};\n\t\tif ( event ) {\n\t\t\t$.each( event.split(\" \"), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.headers.add( this.headers.next() ) );\n\t\tthis._on( this.headers, events );\n\t\tthis._on( this.headers.next(), { keydown: \"_panelKeyDown\" });\n\t\tthis._hoverable( this.headers );\n\t\tthis._focusable( this.headers );\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tclicked = $( event.currentTarget ),\n\t\t\tclickedIsActive = clicked[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive && options.collapsible,\n\t\t\ttoShow = collapsing ? $() : clicked.next(),\n\t\t\ttoHide = active.next(),\n\t\t\teventData = {\n\t\t\t\toldHeader: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewHeader: collapsing ? $() : clicked,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif (\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive && !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.headers.index( clicked );\n\n\t\t// when the call to ._toggle() comes after the class changes\n\t\t// it causes a very odd bug in IE 8 (see #6720)\n\t\tthis.active = clickedIsActive ? $() : clicked;\n\t\tthis._toggle( eventData );\n\n\t\t// switch classes\n\t\t// corner classes on the previously active header stay after the animation\n\t\tactive.removeClass( \"ui-accordion-header-active ui-state-active\" );\n\t\tif ( options.icons ) {\n\t\t\tactive.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( options.icons.activeHeader )\n\t\t\t\t.addClass( options.icons.header );\n\t\t}\n\n\t\tif ( !clickedIsActive ) {\n\t\t\tclicked\n\t\t\t\t.removeClass( \"ui-corner-all\" )\n\t\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" );\n\t\t\tif ( options.icons ) {\n\t\t\t\tclicked.children( \".ui-accordion-header-icon\" )\n\t\t\t\t\t.removeClass( options.icons.header )\n\t\t\t\t\t.addClass( options.icons.activeHeader );\n\t\t\t}\n\n\t\t\tclicked\n\t\t\t\t.next()\n\t\t\t\t.addClass( \"ui-accordion-content-active\" );\n\t\t}\n\t},\n\n\t_toggle: function( data ) {\n\t\tvar toShow = data.newPanel,\n\t\t\ttoHide = this.prevShow.length ? this.prevShow : data.oldPanel;\n\n\t\t// handle activating a panel during the animation for another activation\n\t\tthis.prevShow.add( this.prevHide ).stop( true, true );\n\t\tthis.prevShow = toShow;\n\t\tthis.prevHide = toHide;\n\n\t\tif ( this.options.animate ) {\n\t\t\tthis._animate( toShow, toHide, data );\n\t\t} else {\n\t\t\ttoHide.hide();\n\t\t\ttoShow.show();\n\t\t\tthis._toggleComplete( data );\n\t\t}\n\n\t\ttoHide.attr({\n\t\t\t\"aria-hidden\": \"true\"\n\t\t});\n\t\ttoHide.prev().attr( \"aria-selected\", \"false\" );\n\t\t// if we're switching panels, remove the old header from the tab order\n\t\t// if we're opening from collapsed state, remove the previous header from the tab order\n\t\t// if we're collapsing, then keep the collapsing header in the tab order\n\t\tif ( toShow.length && toHide.length ) {\n\t\t\ttoHide.prev().attr({\n\t\t\t\t\"tabIndex\": -1,\n\t\t\t\t\"aria-expanded\": \"false\"\n\t\t\t});\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.headers.filter(function() {\n\t\t\t\treturn $( this ).attr( \"tabIndex\" ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow\n\t\t\t.attr( \"aria-hidden\", \"false\" )\n\t\t\t.prev()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\ttabIndex: 0,\n\t\t\t\t\t\"aria-expanded\": \"true\"\n\t\t\t\t});\n\t},\n\n\t_animate: function( toShow, toHide, data ) {\n\t\tvar total, easing, duration,\n\t\t\tthat = this,\n\t\t\tadjust = 0,\n\t\t\tdown = toShow.length &&\n\t\t\t\t( !toHide.length || ( toShow.index() < toHide.index() ) ),\n\t\t\tanimate = this.options.animate || {},\n\t\t\toptions = down && animate.down || animate,\n\t\t\tcomplete = function() {\n\t\t\t\tthat._toggleComplete( data );\n\t\t\t};\n\n\t\tif ( typeof options === \"number\" ) {\n\t\t\tduration = options;\n\t\t}\n\t\tif ( typeof options === \"string\" ) {\n\t\t\teasing = options;\n\t\t}\n\t\t// fall back from options to animation in case of partial down settings\n\t\teasing = easing || options.easing || animate.easing;\n\t\tduration = duration || options.duration || animate.duration;\n\n\t\tif ( !toHide.length ) {\n\t\t\treturn toShow.animate( showProps, duration, easing, complete );\n\t\t}\n\t\tif ( !toShow.length ) {\n\t\t\treturn toHide.animate( hideProps, duration, easing, complete );\n\t\t}\n\n\t\ttotal = toShow.show().outerHeight();\n\t\ttoHide.animate( hideProps, {\n\t\t\tduration: duration,\n\t\t\teasing: easing,\n\t\t\tstep: function( now, fx ) {\n\t\t\t\tfx.now = Math.round( now );\n\t\t\t}\n\t\t});\n\t\ttoShow\n\t\t\t.hide()\n\t\t\t.animate( showProps, {\n\t\t\t\tduration: duration,\n\t\t\t\teasing: easing,\n\t\t\t\tcomplete: complete,\n\t\t\t\tstep: function( now, fx ) {\n\t\t\t\t\tfx.now = Math.round( now );\n\t\t\t\t\tif ( fx.prop !== \"height\" ) {\n\t\t\t\t\t\tadjust += fx.now;\n\t\t\t\t\t} else if ( that.options.heightStyle !== \"content\" ) {\n\t\t\t\t\t\tfx.now = Math.round( total - toHide.outerHeight() - adjust );\n\t\t\t\t\t\tadjust = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t},\n\n\t_toggleComplete: function( data ) {\n\t\tvar toHide = data.oldPanel;\n\n\t\ttoHide\n\t\t\t.removeClass( \"ui-accordion-content-active\" )\n\t\t\t.prev()\n\t\t\t\t.removeClass( \"ui-corner-top\" )\n\t\t\t\t.addClass( \"ui-corner-all\" );\n\n\t\t// Work around for rendering bug in IE (#5421)\n\t\tif ( toHide.length ) {\n\t\t\ttoHide.parent()[0].className = toHide.parent()[0].className;\n\t\t}\n\t\tthis._trigger( \"activate\", null, data );\n\t}\n});\n\n})( jQuery );\n(function( $, undefined ) {\n\n$.widget( \"ui.autocomplete\", {\n\tversion: \"1.10.4\",\n\tdefaultElement: \"<input>\",\n\toptions: {\n\t\tappendTo: null,\n\t\tautoFocus: false,\n\t\tdelay: 300,\n\t\tminLength: 1,\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"none\"\n\t\t},\n\t\tsource: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tclose: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresponse: null,\n\t\tsearch: null,\n\t\tselect: null\n\t},\n\n\trequestIndex: 0,\n\tpending: 0,\n\n\t_create: function() {\n\t\t// Some browsers only repeat keydown events, not keypress events,\n\t\t// so we use the suppressKeyPress flag to determine if we've already\n\t\t// handled the keydown event. #7269\n\t\t// Unfortunately the code for & in keypress is the same as the up arrow,\n\t\t// so we use the suppressKeyPressRepeat flag to avoid handling keypress\n\t\t// events when we know the keydown event was used to modify the\n\t\t// search term. #7799\n\t\tvar suppressKeyPress, suppressKeyPressRepeat, suppressInput,\n\t\t\tnodeName = this.element[0].nodeName.toLowerCase(),\n\t\t\tisTextarea = nodeName === \"textarea\",\n\t\t\tisInput = nodeName === \"input\";\n\n\t\tthis.isMultiLine =\n\t\t\t// Textareas are always multi-line\n\t\t\tisTextarea ? true :\n\t\t\t// Inputs are always single-line, even if inside a contentEditable element\n\t\t\t// IE also treats inputs as contentEditable\n\t\t\tisInput ? false :\n\t\t\t// All other element types are determined by whether or not they're contentEditable\n\t\t\tthis.element.prop( \"isContentEditable\" );\n\n\t\tthis.valueMethod = this.element[ isTextarea || isInput ? \"val\" : \"text\" ];\n\t\tthis.isNewMenu = true;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-autocomplete-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" );\n\n\t\tthis._on( this.element, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\tif ( this.element.prop( \"readOnly\" ) ) {\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tsuppressInput = true;\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsuppressKeyPress = false;\n\t\t\t\tsuppressInput = false;\n\t\t\t\tsuppressKeyPressRepeat = false;\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ENTER:\n\t\t\t\tcase keyCode.NUMPAD_ENTER:\n\t\t\t\t\t// when menu is open and has focus\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\t// #6055 - Opera still allows the keypress to occur\n\t\t\t\t\t\t// which causes forms to submit\n\t\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.TAB:\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ESCAPE:\n\t\t\t\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tthis._value( this.term );\n\t\t\t\t\t\tthis.close( event );\n\t\t\t\t\t\t// Different browsers have different default behavior for escape\n\t\t\t\t\t\t// Single press can mean undo or clear\n\t\t\t\t\t\t// Double press in IE means clear the whole form\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\t// search timeout should be triggered before the input value is changed\n\t\t\t\t\tthis._searchTimeout( event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tkeypress: function( event ) {\n\t\t\t\tif ( suppressKeyPress ) {\n\t\t\t\t\tsuppressKeyPress = false;\n\t\t\t\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( suppressKeyPressRepeat ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// replicate some key handlers to allow them to repeat in Firefox and Opera\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tinput: function( event ) {\n\t\t\t\tif ( suppressInput ) {\n\t\t\t\t\tsuppressInput = false;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._searchTimeout( event );\n\t\t\t},\n\t\t\tfocus: function() {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.previous = this._value();\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tif ( this.cancelBlur ) {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tclearTimeout( this.searching );\n\t\t\t\tthis.close( event );\n\t\t\t\tthis._change( event );\n\t\t\t}\n\t\t});\n\n\t\tthis._initSource();\n\t\tthis.menu = $( \"<ul>\" )\n\t\t\t.addClass( \"ui-autocomplete ui-front\" )\n\t\t\t.appendTo( this._appendTo() )\n\t\t\t.menu({\n\t\t\t\t// disable ARIA support, the live region takes care of that\n\t\t\t\trole: null\n\t\t\t})\n\t\t\t.hide()\n\t\t\t.data( \"ui-menu\" );\n\n\t\tthis._on( this.menu.element, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// prevent moving focus out of the text field\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// IE doesn't prevent moving focus even with event.preventDefault()\n\t\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t\tthis.cancelBlur = true;\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t});\n\n\t\t\t\t// clicking on the scrollbar causes focus to shift to the body\n\t\t\t\t// but we can't detect a mouseup or a click immediately afterward\n\t\t\t\t// so we have to track the next mousedown and close the menu if\n\t\t\t\t// the user clicks somewhere outside of the autocomplete\n\t\t\t\tvar menuElement = this.menu.element[ 0 ];\n\t\t\t\tif ( !$( event.target ).closest( \".ui-menu-item\" ).length ) {\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tvar that = this;\n\t\t\t\t\t\tthis.document.one( \"mousedown\", function( event ) {\n\t\t\t\t\t\t\tif ( event.target !== that.element[ 0 ] &&\n\t\t\t\t\t\t\t\t\tevent.target !== menuElement &&\n\t\t\t\t\t\t\t\t\t!$.contains( menuElement, event.target ) ) {\n\t\t\t\t\t\t\t\tthat.close();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenufocus: function( event, ui ) {\n\t\t\t\t// support: Firefox\n\t\t\t\t// Prevent accidental activation of menu items in Firefox (#7024 #9118)\n\t\t\t\tif ( this.isNewMenu ) {\n\t\t\t\t\tthis.isNewMenu = false;\n\t\t\t\t\tif ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis.menu.blur();\n\n\t\t\t\t\t\tthis.document.one( \"mousemove\", function() {\n\t\t\t\t\t\t\t$( event.target ).trigger( event.originalEvent );\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" );\n\t\t\t\tif ( false !== this._trigger( \"focus\", event, { item: item } ) ) {\n\t\t\t\t\t// use value to match what will end up in the input, if it was a key event\n\t\t\t\t\tif ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis._value( item.value );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Normally the input is populated with the item's value as the\n\t\t\t\t\t// menu is navigated, causing screen readers to notice a change and\n\t\t\t\t\t// announce the item. Since the focus event was canceled, this doesn't\n\t\t\t\t\t// happen, so we update the live region so that screen readers can\n\t\t\t\t\t// still notice the change and announce it.\n\t\t\t\t\tthis.liveRegion.text( item.value );\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenuselect: function( event, ui ) {\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" ),\n\t\t\t\t\tprevious = this.previous;\n\n\t\t\t\t// only trigger when focus was lost (click on menu)\n\t\t\t\tif ( this.element[0] !== this.document[0].activeElement ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// #6109 - IE triggers two focus events and the second\n\t\t\t\t\t// is asynchronous, so we need to reset the previous\n\t\t\t\t\t// term synchronously and asynchronously :-(\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t\tthis.selectedItem = item;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif ( false !== this._trigger( \"select\", event, { item: item } ) ) {\n\t\t\t\t\tthis._value( item.value );\n\t\t\t\t}\n\t\t\t\t// reset the term after the select event\n\t\t\t\t// this allows custom select handling to work properly\n\t\t\t\tthis.term = this._value();\n\n\t\t\t\tthis.close( event );\n\t\t\t\tthis.selectedItem = item;\n\t\t\t}\n\t\t});\n\n\t\tthis.liveRegion = $( \"<span>\", {\n\t\t\t\trole: \"status\",\n\t\t\t\t\"aria-live\": \"polite\"\n\t\t\t})\n\t\t\t.addClass( \"ui-helper-hidden-accessible\" )\n\t\t\t.insertBefore( this.element );\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\tclearTimeout( this.searching );\n\t\tthis.element\n\t\t\t.removeClass( \"ui-autocomplete-input\" )\n\t\t\t.removeAttr( \"autocomplete\" );\n\t\tthis.menu.element.remove();\n\t\tthis.liveRegion.remove();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"source\" ) {\n\t\t\tthis._initSource();\n\t\t}\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.menu.element.appendTo( this._appendTo() );\n\t\t}\n\t\tif ( key === \"disabled\" && value && this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\n\t\tif ( element ) {\n\t\t\telement = element.jquery || element.nodeType ?\n\t\t\t\t$( element ) :\n\t\t\t\tthis.document.find( element ).eq( 0 );\n\t\t}\n\n\t\tif ( !element ) {\n\t\t\telement = this.element.closest( \".ui-front\" );\n\t\t}\n\n\t\tif ( !element.length ) {\n\t\t\telement = this.document[0].body;\n\t\t}\n\n\t\treturn element;\n\t},\n\n\t_initSource: function() {\n\t\tvar array, url,\n\t\t\tthat = this;\n\t\tif ( $.isArray(this.options.source) ) {\n\t\t\tarray = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tresponse( $.ui.autocomplete.filter( array, request.term ) );\n\t\t\t};\n\t\t} else if ( typeof this.options.source === \"string\" ) {\n\t\t\turl = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tif ( that.xhr ) {\n\t\t\t\t\tthat.xhr.abort();\n\t\t\t\t}\n\t\t\t\tthat.xhr = $.ajax({\n\t\t\t\t\turl: url,\n\t\t\t\t\tdata: request,\n\t\t\t\t\tdataType: \"json\",\n\t\t\t\t\tsuccess: function( data ) {\n\t\t\t\t\t\tresponse( data );\n\t\t\t\t\t},\n\t\t\t\t\terror: function() {\n\t\t\t\t\t\tresponse( [] );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t};\n\t\t} else {\n\t\t\tthis.source = this.options.source;\n\t\t}\n\t},\n\n\t_searchTimeout: function( event ) {\n\t\tclearTimeout( this.searching );\n\t\tthis.searching = this._delay(function() {\n\t\t\t// only search if the value has changed\n\t\t\tif ( this.term !== this._value() ) {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.search( null, event );\n\t\t\t}\n\t\t}, this.options.delay );\n\t},\n\n\tsearch: function( value, event ) {\n\t\tvalue = value != null ? value : this._value();\n\n\t\t// always save the actual value, not the one passed as an argument\n\t\tthis.term = this._value();\n\n\t\tif ( value.length < this.options.minLength ) {\n\t\t\treturn this.close( event );\n\t\t}\n\n\t\tif ( this._trigger( \"search\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._search( value );\n\t},\n\n\t_search: function( value ) {\n\t\tthis.pending++;\n\t\tthis.element.addClass( \"ui-autocomplete-loading\" );\n\t\tthis.cancelSearch = false;\n\n\t\tthis.source( { term: value }, this._response() );\n\t},\n\n\t_response: function() {\n\t\tvar index = ++this.requestIndex;\n\n\t\treturn $.proxy(function( content ) {\n\t\t\tif ( index === this.requestIndex ) {\n\t\t\t\tthis.__response( content );\n\t\t\t}\n\n\t\t\tthis.pending--;\n\t\t\tif ( !this.pending ) {\n\t\t\t\tthis.element.removeClass( \"ui-autocomplete-loading\" );\n\t\t\t}\n\t\t}, this );\n\t},\n\n\t__response: function( content ) {\n\t\tif ( content ) {\n\t\t\tcontent = this._normalize( content );\n\t\t}\n\t\tthis._trigger( \"response\", null, { content: content } );\n\t\tif ( !this.options.disabled && content && content.length && !this.cancelSearch ) {\n\t\t\tthis._suggest( content );\n\t\t\tthis._trigger( \"open\" );\n\t\t} else {\n\t\t\t// use ._close() instead of .close() so we don't cancel future searches\n\t\t\tthis._close();\n\t\t}\n\t},\n\n\tclose: function( event ) {\n\t\tthis.cancelSearch = true;\n\t\tthis._close( event );\n\t},\n\n\t_close: function( event ) {\n\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.menu.element.hide();\n\t\t\tthis.menu.blur();\n\t\t\tthis.isNewMenu = true;\n\t\t\tthis._trigger( \"close\", event );\n\t\t}\n\t},\n\n\t_change: function( event ) {\n\t\tif ( this.previous !== this._value() ) {\n\t\t\tthis._trigger( \"change\", event, { item: this.selectedItem } );\n\t\t}\n\t},\n\n\t_normalize: function( items ) {\n\t\t// assume all items have the right format when the first item is complete\n\t\tif ( items.length && items[0].label && items[0].value ) {\n\t\t\treturn items;\n\t\t}\n\t\treturn $.map( items, function( item ) {\n\t\t\tif ( typeof item === \"string\" ) {\n\t\t\t\treturn {\n\t\t\t\t\tlabel: item,\n\t\t\t\t\tvalue: item\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn $.extend({\n\t\t\t\tlabel: item.label || item.value,\n\t\t\t\tvalue: item.value || item.label\n\t\t\t}, item );\n\t\t});\n\t},\n\n\t_suggest: function( items ) {\n\t\tvar ul = this.menu.element.empty();\n\t\tthis._renderMenu( ul, items );\n\t\tthis.isNewMenu = true;\n\t\tthis.menu.refresh();\n\n\t\t// size and position menu\n\t\tul.show();\n\t\tthis._resizeMenu();\n\t\tul.position( $.extend({\n\t\t\tof: this.element\n\t\t}, this.options.position ));\n\n\t\tif ( this.options.autoFocus ) {\n\t\t\tthis.menu.next();\n\t\t}\n\t},\n\n\t_resizeMenu: function() {\n\t\tvar ul = this.menu.element;\n\t\tul.outerWidth( Math.max(\n\t\t\t// Firefox wraps long text (possibly a rounding bug)\n\t\t\t// so we add 1px to avoid the wrapping (#7513)\n\t\t\tul.width( \"\" ).outerWidth() + 1,\n\t\t\tthis.element.outerWidth()\n\t\t) );\n\t},\n\n\t_renderMenu: function( ul, items ) {\n\t\tvar that = this;\n\t\t$.each( items, function( index, item ) {\n\t\t\tthat._renderItemData( ul, item );\n\t\t});\n\t},\n\n\t_renderItemData: function( ul, item ) {\n\t\treturn this._renderItem( ul, item ).data( \"ui-autocomplete-item\", item );\n\t},\n\n\t_renderItem: function( ul, item ) {\n\t\treturn $( \"<li>\" )\n\t\t\t.append( $( \"<a>\" ).text( item.label ) )\n\t\t\t.appendTo( ul );\n\t},\n\n\t_move: function( direction, event ) {\n\t\tif ( !this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.search( null, event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.menu.isFirstItem() && /^previous/.test( direction ) ||\n\t\t\t\tthis.menu.isLastItem() && /^next/.test( direction ) ) {\n\t\t\tthis._value( this.term );\n\t\t\tthis.menu.blur();\n\t\t\treturn;\n\t\t}\n\t\tthis.menu[ direction ]( event );\n\t},\n\n\twidget: function() {\n\t\treturn this.menu.element;\n\t},\n\n\t_value: function() {\n\t\treturn this.valueMethod.apply( this.element, arguments );\n\t},\n\n\t_keyEvent: function( keyEvent, event ) {\n\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis._move( keyEvent, event );\n\n\t\t\t// prevents moving cursor to beginning/end of the text field in some browsers\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n});\n\n$.extend( $.ui.autocomplete, {\n\tescapeRegex: function( value ) {\n\t\treturn value.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\");\n\t},\n\tfilter: function(array, term) {\n\t\tvar matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), \"i\" );\n\t\treturn $.grep( array, function(value) {\n\t\t\treturn matcher.test( value.label || value.value || value );\n\t\t});\n\t}\n});\n\n\n// live region extension, adding a `messages` option\n// NOTE: This is an experimental API. We are still investigating\n// a full solution for string manipulation and internationalization.\n$.widget( \"ui.autocomplete\", $.ui.autocomplete, {\n\toptions: {\n\t\tmessages: {\n\t\t\tnoResults: \"No search results.\",\n\t\t\tresults: function( amount ) {\n\t\t\t\treturn amount + ( amount > 1 ? \" results are\" : \" result is\" ) +\n\t\t\t\t\t\" available, use up and down arrow keys to navigate.\";\n\t\t\t}\n\t\t}\n\t},\n\n\t__response: function( content ) {\n\t\tvar message;\n\t\tthis._superApply( arguments );\n\t\tif ( this.options.disabled || this.cancelSearch ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( content && content.length ) {\n\t\t\tmessage = this.options.messages.results( content.length );\n\t\t} else {\n\t\t\tmessage = this.options.messages.noResults;\n\t\t}\n\t\tthis.liveRegion.text( message );\n\t}\n});\n\n}( jQuery ));\n(function( $, undefined ) {\n\nvar lastActive,\n\tbaseClasses = \"ui-button ui-widget ui-state-default ui-corner-all\",\n\ttypeClasses = \"ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only\",\n\tformResetHandler = function() {\n\t\tvar form = $( this );\n\t\tsetTimeout(function() {\n\t\t\tform.find( \":ui-button\" ).button( \"refresh\" );\n\t\t}, 1 );\n\t},\n\tradioGroup = function( radio ) {\n\t\tvar name = radio.name,\n\t\t\tform = radio.form,\n\t\t\tradios = $( [] );\n\t\tif ( name ) {\n\t\t\tname = name.replace( /'/g, \"\\\\'\" );\n\t\t\tif ( form ) {\n\t\t\t\tradios = $( form ).find( \"[name='\" + name + \"']\" );\n\t\t\t} else {\n\t\t\t\tradios = $( \"[name='\" + name + \"']\", radio.ownerDocument )\n\t\t\t\t\t.filter(function() {\n\t\t\t\t\t\treturn !this.form;\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn radios;\n\t};\n\n$.widget( \"ui.button\", {\n\tversion: \"1.10.4\",\n\tdefaultElement: \"<button>\",\n\toptions: {\n\t\tdisabled: null,\n\t\ttext: true,\n\t\tlabel: null,\n\t\ticons: {\n\t\t\tprimary: null,\n\t\t\tsecondary: null\n\t\t}\n\t},\n\t_create: function() {\n\t\tthis.element.closest( \"form\" )\n\t\t\t.unbind( \"reset\" + this.eventNamespace )\n\t\t\t.bind( \"reset\" + this.eventNamespace, formResetHandler );\n\n\t\tif ( typeof this.options.disabled !== \"boolean\" ) {\n\t\t\tthis.options.disabled = !!this.element.prop( \"disabled\" );\n\t\t} else {\n\t\t\tthis.element.prop( \"disabled\", this.options.disabled );\n\t\t}\n\n\t\tthis._determineButtonType();\n\t\tthis.hasTitle = !!this.buttonElement.attr( \"title\" );\n\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\ttoggleButton = this.type === \"checkbox\" || this.type === \"radio\",\n\t\t\tactiveClass = !toggleButton ? \"ui-state-active\" : \"\";\n\n\t\tif ( options.label === null ) {\n\t\t\toptions.label = (this.type === \"input\" ? this.buttonElement.val() : this.buttonElement.html());\n\t\t}\n\n\t\tthis._hoverable( this.buttonElement );\n\n\t\tthis.buttonElement\n\t\t\t.addClass( baseClasses )\n\t\t\t.attr( \"role\", \"button\" )\n\t\t\t.bind( \"mouseenter\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( this === lastActive ) {\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t}\n\t\t\t})\n\t\t\t.bind( \"mouseleave\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$( this ).removeClass( activeClass );\n\t\t\t})\n\t\t\t.bind( \"click\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t}\n\t\t\t});\n\n\t\t// Can't use _focusable() because the element that receives focus\n\t\t// and the element that gets the ui-state-focus class are different\n\t\tthis._on({\n\t\t\tfocus: function() {\n\t\t\t\tthis.buttonElement.addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tblur: function() {\n\t\t\t\tthis.buttonElement.removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\n\t\tif ( toggleButton ) {\n\t\t\tthis.element.bind( \"change\" + this.eventNamespace, function() {\n\t\t\t\tthat.refresh();\n\t\t\t});\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"radio\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\tthat.buttonElement.attr( \"aria-pressed\", \"true\" );\n\n\t\t\t\tvar radio = that.element[ 0 ];\n\t\t\t\tradioGroup( radio )\n\t\t\t\t\t.not( radio )\n\t\t\t\t\t.map(function() {\n\t\t\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t\t\t})\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t});\n\t\t} else {\n\t\t\tthis.buttonElement\n\t\t\t\t.bind( \"mousedown\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\tlastActive = this;\n\t\t\t\t\tthat.document.one( \"mouseup\", function() {\n\t\t\t\t\t\tlastActive = null;\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.bind( \"mouseup\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t})\n\t\t\t\t.bind( \"keydown\" + this.eventNamespace, function(event) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {\n\t\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t// see #8559, we bind to blur here in case the button element loses\n\t\t\t\t// focus between keydown and keyup, it would be left in an \"active\" state\n\t\t\t\t.bind( \"keyup\" + this.eventNamespace + \" blur\" + this.eventNamespace, function() {\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t});\n\n\t\t\tif ( this.buttonElement.is(\"a\") ) {\n\t\t\t\tthis.buttonElement.keyup(function(event) {\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE ) {\n\t\t\t\t\t\t// TODO pass through original event correctly (just as 2nd argument doesn't work)\n\t\t\t\t\t\t$( this ).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// TODO: pull out $.Widget's handling for the disabled option into\n\t\t// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can\n\t\t// be overridden by individual plugins\n\t\tthis._setOption( \"disabled\", options.disabled );\n\t\tthis._resetButton();\n\t},\n\n\t_determineButtonType: function() {\n\t\tvar ancestor, labelSelector, checked;\n\n\t\tif ( this.element.is(\"[type=checkbox]\") ) {\n\t\t\tthis.type = \"checkbox\";\n\t\t} else if ( this.element.is(\"[type=radio]\") ) {\n\t\t\tthis.type = \"radio\";\n\t\t} else if ( this.element.is(\"input\") ) {\n\t\t\tthis.type = \"input\";\n\t\t} else {\n\t\t\tthis.type = \"button\";\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t// we don't search against the document in case the element\n\t\t\t// is disconnected from the DOM\n\t\t\tancestor = this.element.parents().last();\n\t\t\tlabelSelector = \"label[for='\" + this.element.attr(\"id\") + \"']\";\n\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\tancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();\n\t\t\t\tthis.buttonElement = ancestor.filter( labelSelector );\n\t\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.element.addClass( \"ui-helper-hidden-accessible\" );\n\n\t\t\tchecked = this.element.is( \":checked\" );\n\t\t\tif ( checked ) {\n\t\t\t\tthis.buttonElement.addClass( \"ui-state-active\" );\n\t\t\t}\n\t\t\tthis.buttonElement.prop( \"aria-pressed\", checked );\n\t\t} else {\n\t\t\tthis.buttonElement = this.element;\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.buttonElement;\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-helper-hidden-accessible\" );\n\t\tthis.buttonElement\n\t\t\t.removeClass( baseClasses + \" ui-state-active \" + typeClasses )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-pressed\" )\n\t\t\t.html( this.buttonElement.find(\".ui-button-text\").html() );\n\n\t\tif ( !this.hasTitle ) {\n\t\t\tthis.buttonElement.removeAttr( \"title\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.element.prop( \"disabled\", !!value );\n\t\t\tif ( value ) {\n\t\t\t\tthis.buttonElement.removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._resetButton();\n\t},\n\n\trefresh: function() {\n\t\t//See #8237 & #8828\n\t\tvar isDisabled = this.element.is( \"input, button\" ) ? this.element.is( \":disabled\" ) : this.element.hasClass( \"ui-button-disabled\" );\n\n\t\tif ( isDisabled !== this.options.disabled ) {\n\t\t\tthis._setOption( \"disabled\", isDisabled );\n\t\t}\n\t\tif ( this.type === \"radio\" ) {\n\t\t\tradioGroup( this.element[0] ).each(function() {\n\t\t\t\tif ( $( this ).is( \":checked\" ) ) {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t\t} else {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"checkbox\" ) {\n\t\t\tif ( this.element.is( \":checked\" ) ) {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t} else {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t}\n\t\t}\n\t},\n\n\t_resetButton: function() {\n\t\tif ( this.type === \"input\" ) {\n\t\t\tif ( this.options.label ) {\n\t\t\t\tthis.element.val( this.options.label );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tvar buttonElement = this.buttonElement.removeClass( typeClasses ),\n\t\t\tbuttonText = $( \"<span></span>\", this.document[0] )\n\t\t\t\t.addClass( \"ui-button-text\" )\n\t\t\t\t.html( this.options.label )\n\t\t\t\t.appendTo( buttonElement.empty() )\n\t\t\t\t.text(),\n\t\t\ticons = this.options.icons,\n\t\t\tmultipleIcons = icons.primary && icons.secondary,\n\t\t\tbuttonClasses = [];\n\n\t\tif ( icons.primary || icons.secondary ) {\n\t\t\tif ( this.options.text ) {\n\t\t\t\tbuttonClasses.push( \"ui-button-text-icon\" + ( multipleIcons ? \"s\" : ( icons.primary ? \"-primary\" : \"-secondary\" ) ) );\n\t\t\t}\n\n\t\t\tif ( icons.primary ) {\n\t\t\t\tbuttonElement.prepend( \"<span class='ui-button-icon-primary ui-icon \" + icons.primary + \"'></span>\" );\n\t\t\t}\n\n\t\t\tif ( icons.secondary ) {\n\t\t\t\tbuttonElement.append( \"<span class='ui-button-icon-secondary ui-icon \" + icons.secondary + \"'></span>\" );\n\t\t\t}\n\n\t\t\tif ( !this.options.text ) {\n\t\t\t\tbuttonClasses.push( multipleIcons ? \"ui-button-icons-only\" : \"ui-button-icon-only\" );\n\n\t\t\t\tif ( !this.hasTitle ) {\n\t\t\t\t\tbuttonElement.attr( \"title\", $.trim( buttonText ) );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbuttonClasses.push( \"ui-button-text-only\" );\n\t\t}\n\t\tbuttonElement.addClass( buttonClasses.join( \" \" ) );\n\t}\n});\n\n$.widget( \"ui.buttonset\", {\n\tversion: \"1.10.4\",\n\toptions: {\n\t\titems: \"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)\"\n\t},\n\n\t_create: function() {\n\t\tthis.element.addClass( \"ui-buttonset\" );\n\t},\n\n\t_init: function() {\n\t\tthis.refresh();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.buttons.button( \"option\", key, value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\trefresh: function() {\n\t\tvar rtl = this.element.css( \"direction\" ) === \"rtl\";\n\n\t\tthis.buttons = this.element.find( this.options.items )\n\t\t\t.filter( \":ui-button\" )\n\t\t\t\t.button( \"refresh\" )\n\t\t\t.end()\n\t\t\t.not( \":ui-button\" )\n\t\t\t\t.button()\n\t\t\t.end()\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-all ui-corner-left ui-corner-right\" )\n\t\t\t\t.filter( \":first\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-right\" : \"ui-corner-left\" )\n\t\t\t\t.end()\n\t\t\t\t.filter( \":last\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-left\" : \"ui-corner-right\" )\n\t\t\t\t.end()\n\t\t\t.end();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element.removeClass( \"ui-buttonset\" );\n\t\tthis.buttons\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-left ui-corner-right\" )\n\t\t\t.end()\n\t\t\t.button( \"destroy\" );\n\t}\n});\n\n}( jQuery ) );\n(function( $, undefined ) {\n\n$.extend($.ui, { datepicker: { version: \"1.10.4\" } });\n\nvar PROP_NAME = \"datepicker\",\n\tinstActive;\n\n/* Date picker manager.\n   Use the singleton instance of this class, $.datepicker, to interact with the date picker.\n   Settings for (groups of) date pickers are maintained in an instance object,\n   allowing multiple different settings on the same page. */\n\nfunction Datepicker() {\n\tthis._curInst = null; // The current instance in use\n\tthis._keyEvent = false; // If the last event was a key event\n\tthis._disabledInputs = []; // List of date picker inputs that have been disabled\n\tthis._datepickerShowing = false; // True if the popup picker is showing , false if not\n\tthis._inDialog = false; // True if showing within a \"dialog\", false if not\n\tthis._mainDivId = \"ui-datepicker-div\"; // The ID of the main datepicker division\n\tthis._inlineClass = \"ui-datepicker-inline\"; // The name of the inline marker class\n\tthis._appendClass = \"ui-datepicker-append\"; // The name of the append marker class\n\tthis._triggerClass = \"ui-datepicker-trigger\"; // The name of the trigger marker class\n\tthis._dialogClass = \"ui-datepicker-dialog\"; // The name of the dialog marker class\n\tthis._disableClass = \"ui-datepicker-disabled\"; // The name of the disabled covering marker class\n\tthis._unselectableClass = \"ui-datepicker-unselectable\"; // The name of the unselectable cell marker class\n\tthis._currentClass = \"ui-datepicker-current-day\"; // The name of the current day marker class\n\tthis._dayOverClass = \"ui-datepicker-days-cell-over\"; // The name of the day hover marker class\n\tthis.regional = []; // Available regional settings, indexed by language code\n\tthis.regional[\"\"] = { // Default regional settings\n\t\tcloseText: \"Done\", // Display text for close link\n\t\tprevText: \"Prev\", // Display text for previous month link\n\t\tnextText: \"Next\", // Display text for next month link\n\t\tcurrentText: \"Today\", // Display text for current month link\n\t\tmonthNames: [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\n\t\t\t\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"], // Names of months for drop-down and formatting\n\t\tmonthNamesShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"], // For formatting\n\t\tdayNames: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"], // For formatting\n\t\tdayNamesShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"], // For formatting\n\t\tdayNamesMin: [\"Su\",\"Mo\",\"Tu\",\"We\",\"Th\",\"Fr\",\"Sa\"], // Column headings for days starting at Sunday\n\t\tweekHeader: \"Wk\", // Column header for week of the year\n\t\tdateFormat: \"mm/dd/yy\", // See format options on parseDate\n\t\tfirstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...\n\t\tisRTL: false, // True if right-to-left language, false if left-to-right\n\t\tshowMonthAfterYear: false, // True if the year select precedes month, false for month then year\n\t\tyearSuffix: \"\" // Additional text to append to the year in the month headers\n\t};\n\tthis._defaults = { // Global defaults for all the date picker instances\n\t\tshowOn: \"focus\", // \"focus\" for popup on focus,\n\t\t\t// \"button\" for trigger button, or \"both\" for either\n\t\tshowAnim: \"fadeIn\", // Name of jQuery animation for popup\n\t\tshowOptions: {}, // Options for enhanced animations\n\t\tdefaultDate: null, // Used when field is blank: actual date,\n\t\t\t// +/-number for offset from today, null for today\n\t\tappendText: \"\", // Display text following the input box, e.g. showing the format\n\t\tbuttonText: \"...\", // Text for trigger button\n\t\tbuttonImage: \"\", // URL for trigger button image\n\t\tbuttonImageOnly: false, // True if the image appears alone, false if it appears on a button\n\t\thideIfNoPrevNext: false, // True to hide next/previous month links\n\t\t\t// if not applicable, false to just disable them\n\t\tnavigationAsDateFormat: false, // True if date formatting applied to prev/today/next links\n\t\tgotoCurrent: false, // True if today link goes back to current selection instead\n\t\tchangeMonth: false, // True if month can be selected directly, false if only prev/next\n\t\tchangeYear: false, // True if year can be selected directly, false if only prev/next\n\t\tyearRange: \"c-10:c+10\", // Range of years to display in drop-down,\n\t\t\t// either relative to today's year (-nn:+nn), relative to currently displayed year\n\t\t\t// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)\n\t\tshowOtherMonths: false, // True to show dates in other months, false to leave blank\n\t\tselectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable\n\t\tshowWeek: false, // True to show week of the year, false to not show it\n\t\tcalculateWeek: this.iso8601Week, // How to calculate the week of the year,\n\t\t\t// takes a Date and returns the number of the week for it\n\t\tshortYearCutoff: \"+10\", // Short year values < this are in the current century,\n\t\t\t// > this are in the previous century,\n\t\t\t// string value starting with \"+\" for current year + value\n\t\tminDate: null, // The earliest selectable date, or null for no limit\n\t\tmaxDate: null, // The latest selectable date, or null for no limit\n\t\tduration: \"fast\", // Duration of display/closure\n\t\tbeforeShowDay: null, // Function that takes a date and returns an array with\n\t\t\t// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or \"\",\n\t\t\t// [2] = cell title (optional), e.g. $.datepicker.noWeekends\n\t\tbeforeShow: null, // Function that takes an input field and\n\t\t\t// returns a set of custom settings for the date picker\n\t\tonSelect: null, // Define a callback function when a date is selected\n\t\tonChangeMonthYear: null, // Define a callback function when the month or year is changed\n\t\tonClose: null, // Define a callback function when the datepicker is closed\n\t\tnumberOfMonths: 1, // Number of months to show at a time\n\t\tshowCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)\n\t\tstepMonths: 1, // Number of months to step back/forward\n\t\tstepBigMonths: 12, // Number of months to step back/forward for the big links\n\t\taltField: \"\", // Selector for an alternate field to store selected dates into\n\t\taltFormat: \"\", // The date format to use for the alternate field\n\t\tconstrainInput: true, // The input is constrained by the current date format\n\t\tshowButtonPanel: false, // True to show button panel, false to not show it\n\t\tautoSize: false, // True to size the input for the date format, false to leave as is\n\t\tdisabled: false // The initial disabled state\n\t};\n\t$.extend(this._defaults, this.regional[\"\"]);\n\tthis.dpDiv = bindHover($(\"<div id='\" + this._mainDivId + \"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>\"));\n}\n\n$.extend(Datepicker.prototype, {\n\t/* Class name added to elements to indicate already configured with a date picker. */\n\tmarkerClassName: \"hasDatepicker\",\n\n\t//Keep track of the maximum number of rows displayed (see #7043)\n\tmaxRows: 4,\n\n\t// TODO rename to \"widget\" when switching to widget factory\n\t_widgetDatepicker: function() {\n\t\treturn this.dpDiv;\n\t},\n\n\t/* Override the default settings for all instances of the date picker.\n\t * @param  settings  object - the new settings to use as defaults (anonymous object)\n\t * @return the manager object\n\t */\n\tsetDefaults: function(settings) {\n\t\textendRemove(this._defaults, settings || {});\n\t\treturn this;\n\t},\n\n\t/* Attach the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t * @param  settings  object - the new settings to use for this date picker instance (anonymous)\n\t */\n\t_attachDatepicker: function(target, settings) {\n\t\tvar nodeName, inline, inst;\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tinline = (nodeName === \"div\" || nodeName === \"span\");\n\t\tif (!target.id) {\n\t\t\tthis.uuid += 1;\n\t\t\ttarget.id = \"dp\" + this.uuid;\n\t\t}\n\t\tinst = this._newInst($(target), inline);\n\t\tinst.settings = $.extend({}, settings || {});\n\t\tif (nodeName === \"input\") {\n\t\t\tthis._connectDatepicker(target, inst);\n\t\t} else if (inline) {\n\t\t\tthis._inlineDatepicker(target, inst);\n\t\t}\n\t},\n\n\t/* Create a new instance object. */\n\t_newInst: function(target, inline) {\n\t\tvar id = target[0].id.replace(/([^A-Za-z0-9_\\-])/g, \"\\\\\\\\$1\"); // escape jQuery meta chars\n\t\treturn {id: id, input: target, // associated target\n\t\t\tselectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection\n\t\t\tdrawMonth: 0, drawYear: 0, // month being drawn\n\t\t\tinline: inline, // is datepicker inline or not\n\t\t\tdpDiv: (!inline ? this.dpDiv : // presentation div\n\t\t\tbindHover($(\"<div class='\" + this._inlineClass + \" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>\")))};\n\t},\n\n\t/* Attach the date picker to an input field. */\n\t_connectDatepicker: function(target, inst) {\n\t\tvar input = $(target);\n\t\tinst.append = $([]);\n\t\tinst.trigger = $([]);\n\t\tif (input.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tthis._attachments(input, inst);\n\t\tinput.addClass(this.markerClassName).keydown(this._doKeyDown).\n\t\t\tkeypress(this._doKeyPress).keyup(this._doKeyUp);\n\t\tthis._autoSize(inst);\n\t\t$.data(target, PROP_NAME, inst);\n\t\t//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t},\n\n\t/* Make attachments based on settings. */\n\t_attachments: function(input, inst) {\n\t\tvar showOn, buttonText, buttonImage,\n\t\t\tappendText = this._get(inst, \"appendText\"),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\tif (inst.append) {\n\t\t\tinst.append.remove();\n\t\t}\n\t\tif (appendText) {\n\t\t\tinst.append = $(\"<span class='\" + this._appendClass + \"'>\" + appendText + \"</span>\");\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.append);\n\t\t}\n\n\t\tinput.unbind(\"focus\", this._showDatepicker);\n\n\t\tif (inst.trigger) {\n\t\t\tinst.trigger.remove();\n\t\t}\n\n\t\tshowOn = this._get(inst, \"showOn\");\n\t\tif (showOn === \"focus\" || showOn === \"both\") { // pop-up date picker when in the marked field\n\t\t\tinput.focus(this._showDatepicker);\n\t\t}\n\t\tif (showOn === \"button\" || showOn === \"both\") { // pop-up date picker when button clicked\n\t\t\tbuttonText = this._get(inst, \"buttonText\");\n\t\t\tbuttonImage = this._get(inst, \"buttonImage\");\n\t\t\tinst.trigger = $(this._get(inst, \"buttonImageOnly\") ?\n\t\t\t\t$(\"<img/>\").addClass(this._triggerClass).\n\t\t\t\t\tattr({ src: buttonImage, alt: buttonText, title: buttonText }) :\n\t\t\t\t$(\"<button type='button'></button>\").addClass(this._triggerClass).\n\t\t\t\t\thtml(!buttonImage ? buttonText : $(\"<img/>\").attr(\n\t\t\t\t\t{ src:buttonImage, alt:buttonText, title:buttonText })));\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.trigger);\n\t\t\tinst.trigger.click(function() {\n\t\t\t\tif ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t} else {\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\t},\n\n\t/* Apply the maximum length for the date format. */\n\t_autoSize: function(inst) {\n\t\tif (this._get(inst, \"autoSize\") && !inst.inline) {\n\t\t\tvar findMax, max, maxI, i,\n\t\t\t\tdate = new Date(2009, 12 - 1, 20), // Ensure double digits\n\t\t\t\tdateFormat = this._get(inst, \"dateFormat\");\n\n\t\t\tif (dateFormat.match(/[DM]/)) {\n\t\t\t\tfindMax = function(names) {\n\t\t\t\t\tmax = 0;\n\t\t\t\t\tmaxI = 0;\n\t\t\t\t\tfor (i = 0; i < names.length; i++) {\n\t\t\t\t\t\tif (names[i].length > max) {\n\t\t\t\t\t\t\tmax = names[i].length;\n\t\t\t\t\t\t\tmaxI = i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn maxI;\n\t\t\t\t};\n\t\t\t\tdate.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?\n\t\t\t\t\t\"monthNames\" : \"monthNamesShort\"))));\n\t\t\t\tdate.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?\n\t\t\t\t\t\"dayNames\" : \"dayNamesShort\"))) + 20 - date.getDay());\n\t\t\t}\n\t\t\tinst.input.attr(\"size\", this._formatDate(inst, date).length);\n\t\t}\n\t},\n\n\t/* Attach an inline date picker to a div. */\n\t_inlineDatepicker: function(target, inst) {\n\t\tvar divSpan = $(target);\n\t\tif (divSpan.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tdivSpan.addClass(this.markerClassName).append(inst.dpDiv);\n\t\t$.data(target, PROP_NAME, inst);\n\t\tthis._setDate(inst, this._getDefaultDate(inst), true);\n\t\tthis._updateDatepicker(inst);\n\t\tthis._updateAlternate(inst);\n\t\t//If disabled option is true, disable the datepicker before showing it (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t\t// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements\n\t\t// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height\n\t\tinst.dpDiv.css( \"display\", \"block\" );\n\t},\n\n\t/* Pop-up the date picker in a \"dialog\" box.\n\t * @param  input element - ignored\n\t * @param  date\tstring or Date - the initial date to display\n\t * @param  onSelect  function - the function to call when a date is selected\n\t * @param  settings  object - update the dialog date picker instance's settings (anonymous object)\n\t * @param  pos int[2] - coordinates for the dialog's position within the screen or\n\t *\t\t\t\t\tevent - with x/y coordinates or\n\t *\t\t\t\t\tleave empty for default (screen centre)\n\t * @return the manager object\n\t */\n\t_dialogDatepicker: function(input, date, onSelect, settings, pos) {\n\t\tvar id, browserWidth, browserHeight, scrollX, scrollY,\n\t\t\tinst = this._dialogInst; // internal instance\n\n\t\tif (!inst) {\n\t\t\tthis.uuid += 1;\n\t\t\tid = \"dp\" + this.uuid;\n\t\t\tthis._dialogInput = $(\"<input type='text' id='\" + id +\n\t\t\t\t\"' style='position: absolute; top: -100px; width: 0px;'/>\");\n\t\t\tthis._dialogInput.keydown(this._doKeyDown);\n\t\t\t$(\"body\").append(this._dialogInput);\n\t\t\tinst = this._dialogInst = this._newInst(this._dialogInput, false);\n\t\t\tinst.settings = {};\n\t\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\n\t\t}\n\t\textendRemove(inst.settings, settings || {});\n\t\tdate = (date && date.constructor === Date ? this._formatDate(inst, date) : date);\n\t\tthis._dialogInput.val(date);\n\n\t\tthis._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);\n\t\tif (!this._pos) {\n\t\t\tbrowserWidth = document.documentElement.clientWidth;\n\t\t\tbrowserHeight = document.documentElement.clientHeight;\n\t\t\tscrollX = document.documentElement.scrollLeft || document.body.scrollLeft;\n\t\t\tscrollY = document.documentElement.scrollTop || document.body.scrollTop;\n\t\t\tthis._pos = // should use actual width/height below\n\t\t\t\t[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];\n\t\t}\n\n\t\t// move input on screen for focus, but hidden behind dialog\n\t\tthis._dialogInput.css(\"left\", (this._pos[0] + 20) + \"px\").css(\"top\", this._pos[1] + \"px\");\n\t\tinst.settings.onSelect = onSelect;\n\t\tthis._inDialog = true;\n\t\tthis.dpDiv.addClass(this._dialogClass);\n\t\tthis._showDatepicker(this._dialogInput[0]);\n\t\tif ($.blockUI) {\n\t\t\t$.blockUI(this.dpDiv);\n\t\t}\n\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\n\t\treturn this;\n\t},\n\n\t/* Detach a datepicker from its control.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_destroyDatepicker: function(target) {\n\t\tvar nodeName,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\t$.removeData(target, PROP_NAME);\n\t\tif (nodeName === \"input\") {\n\t\t\tinst.append.remove();\n\t\t\tinst.trigger.remove();\n\t\t\t$target.removeClass(this.markerClassName).\n\t\t\t\tunbind(\"focus\", this._showDatepicker).\n\t\t\t\tunbind(\"keydown\", this._doKeyDown).\n\t\t\t\tunbind(\"keypress\", this._doKeyPress).\n\t\t\t\tunbind(\"keyup\", this._doKeyUp);\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\t$target.removeClass(this.markerClassName).empty();\n\t\t}\n\t},\n\n\t/* Enable the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_enableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = false;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = false; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"1.0\", cursor: \"\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().removeClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", false);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t},\n\n\t/* Disable the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_disableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = true;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = true; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"0.5\", cursor: \"default\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().addClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", true);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t\tthis._disabledInputs[this._disabledInputs.length] = target;\n\t},\n\n\t/* Is the first field in a jQuery collection disabled as a datepicker?\n\t * @param  target\telement - the target input field or division or span\n\t * @return boolean - true if disabled, false if enabled\n\t */\n\t_isDisabledDatepicker: function(target) {\n\t\tif (!target) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (var i = 0; i < this._disabledInputs.length; i++) {\n\t\t\tif (this._disabledInputs[i] === target) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t},\n\n\t/* Retrieve the instance data for the target control.\n\t * @param  target  element - the target input field or division or span\n\t * @return  object - the associated instance data\n\t * @throws  error if a jQuery problem getting data\n\t */\n\t_getInst: function(target) {\n\t\ttry {\n\t\t\treturn $.data(target, PROP_NAME);\n\t\t}\n\t\tcatch (err) {\n\t\t\tthrow \"Missing instance data for this datepicker\";\n\t\t}\n\t},\n\n\t/* Update or retrieve the settings for a date picker attached to an input field or division.\n\t * @param  target  element - the target input field or division or span\n\t * @param  name\tobject - the new settings to update or\n\t *\t\t\t\tstring - the name of the setting to change or retrieve,\n\t *\t\t\t\twhen retrieving also \"all\" for all instance settings or\n\t *\t\t\t\t\"defaults\" for all global defaults\n\t * @param  value   any - the new value for the setting\n\t *\t\t\t\t(omit if above is an object or to retrieve a value)\n\t */\n\t_optionDatepicker: function(target, name, value) {\n\t\tvar settings, date, minDate, maxDate,\n\t\t\tinst = this._getInst(target);\n\n\t\tif (arguments.length === 2 && typeof name === \"string\") {\n\t\t\treturn (name === \"defaults\" ? $.extend({}, $.datepicker._defaults) :\n\t\t\t\t(inst ? (name === \"all\" ? $.extend({}, inst.settings) :\n\t\t\t\tthis._get(inst, name)) : null));\n\t\t}\n\n\t\tsettings = name || {};\n\t\tif (typeof name === \"string\") {\n\t\t\tsettings = {};\n\t\t\tsettings[name] = value;\n\t\t}\n\n\t\tif (inst) {\n\t\t\tif (this._curInst === inst) {\n\t\t\t\tthis._hideDatepicker();\n\t\t\t}\n\n\t\t\tdate = this._getDateDatepicker(target, true);\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\");\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\");\n\t\t\textendRemove(inst.settings, settings);\n\t\t\t// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided\n\t\t\tif (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {\n\t\t\t\tinst.settings.minDate = this._formatDate(inst, minDate);\n\t\t\t}\n\t\t\tif (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {\n\t\t\t\tinst.settings.maxDate = this._formatDate(inst, maxDate);\n\t\t\t}\n\t\t\tif ( \"disabled\" in settings ) {\n\t\t\t\tif ( settings.disabled ) {\n\t\t\t\t\tthis._disableDatepicker(target);\n\t\t\t\t} else {\n\t\t\t\t\tthis._enableDatepicker(target);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._attachments($(target), inst);\n\t\t\tthis._autoSize(inst);\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateAlternate(inst);\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t// change method deprecated\n\t_changeDatepicker: function(target, name, value) {\n\t\tthis._optionDatepicker(target, name, value);\n\t},\n\n\t/* Redraw the date picker attached to an input field or division.\n\t * @param  target  element - the target input field or division or span\n\t */\n\t_refreshDatepicker: function(target) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t/* Set the dates for a jQuery selection.\n\t * @param  target element - the target input field or division or span\n\t * @param  date\tDate - the new date\n\t */\n\t_setDateDatepicker: function(target, date) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateDatepicker(inst);\n\t\t\tthis._updateAlternate(inst);\n\t\t}\n\t},\n\n\t/* Get the date(s) for the first entry in a jQuery selection.\n\t * @param  target element - the target input field or division or span\n\t * @param  noDefault boolean - true if no default date is to be used\n\t * @return Date - the current date\n\t */\n\t_getDateDatepicker: function(target, noDefault) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst && !inst.inline) {\n\t\t\tthis._setDateFromField(inst, noDefault);\n\t\t}\n\t\treturn (inst ? this._getDate(inst) : null);\n\t},\n\n\t/* Handle keystrokes. */\n\t_doKeyDown: function(event) {\n\t\tvar onSelect, dateStr, sel,\n\t\t\tinst = $.datepicker._getInst(event.target),\n\t\t\thandled = true,\n\t\t\tisRTL = inst.dpDiv.is(\".ui-datepicker-rtl\");\n\n\t\tinst._keyEvent = true;\n\t\tif ($.datepicker._datepickerShowing) {\n\t\t\tswitch (event.keyCode) {\n\t\t\t\tcase 9: $.datepicker._hideDatepicker();\n\t\t\t\t\t\thandled = false;\n\t\t\t\t\t\tbreak; // hide on tab out\n\t\t\t\tcase 13: sel = $(\"td.\" + $.datepicker._dayOverClass + \":not(.\" +\n\t\t\t\t\t\t\t\t\t$.datepicker._currentClass + \")\", inst.dpDiv);\n\t\t\t\t\t\tif (sel[0]) {\n\t\t\t\t\t\t\t$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tonSelect = $.datepicker._get(inst, \"onSelect\");\n\t\t\t\t\t\tif (onSelect) {\n\t\t\t\t\t\t\tdateStr = $.datepicker._formatDate(inst);\n\n\t\t\t\t\t\t\t// trigger custom callback\n\t\t\t\t\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false; // don't submit the form\n\t\t\t\tcase 27: $.datepicker._hideDatepicker();\n\t\t\t\t\t\tbreak; // hide on escape\n\t\t\t\tcase 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // previous month/year on page up/+ ctrl\n\t\t\t\tcase 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // next month/year on page down/+ ctrl\n\t\t\t\tcase 35: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._clearDate(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // clear on ctrl or command +end\n\t\t\t\tcase 36: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._gotoToday(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // current on ctrl or command +home\n\t\t\t\tcase 37: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// -1 day on ctrl or command +left\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +left on Mac\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 38: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, -7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // -1 week on ctrl or command +up\n\t\t\t\tcase 39: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// +1 day on ctrl or command +right\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +right\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 40: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, +7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // +1 week on ctrl or command +down\n\t\t\t\tdefault: handled = false;\n\t\t\t}\n\t\t} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home\n\t\t\t$.datepicker._showDatepicker(this);\n\t\t} else {\n\t\t\thandled = false;\n\t\t}\n\n\t\tif (handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t},\n\n\t/* Filter entered characters - based on date format. */\n\t_doKeyPress: function(event) {\n\t\tvar chars, chr,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif ($.datepicker._get(inst, \"constrainInput\")) {\n\t\t\tchars = $.datepicker._possibleChars($.datepicker._get(inst, \"dateFormat\"));\n\t\t\tchr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);\n\t\t\treturn event.ctrlKey || event.metaKey || (chr < \" \" || !chars || chars.indexOf(chr) > -1);\n\t\t}\n\t},\n\n\t/* Synchronise manual entry and field/alternate field. */\n\t_doKeyUp: function(event) {\n\t\tvar date,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif (inst.input.val() !== inst.lastVal) {\n\t\t\ttry {\n\t\t\t\tdate = $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t(inst.input ? inst.input.val() : null),\n\t\t\t\t\t$.datepicker._getFormatConfig(inst));\n\n\t\t\t\tif (date) { // only if valid\n\t\t\t\t\t$.datepicker._setDateFromField(inst);\n\t\t\t\t\t$.datepicker._updateAlternate(inst);\n\t\t\t\t\t$.datepicker._updateDatepicker(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t},\n\n\t/* Pop-up the date picker for a given input field.\n\t * If false returned from beforeShow event handler do not show.\n\t * @param  input  element - the input field attached to the date picker or\n\t *\t\t\t\t\tevent - if triggered by focus\n\t */\n\t_showDatepicker: function(input) {\n\t\tinput = input.target || input;\n\t\tif (input.nodeName.toLowerCase() !== \"input\") { // find from button/image trigger\n\t\t\tinput = $(\"input\", input.parentNode)[0];\n\t\t}\n\n\t\tif ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here\n\t\t\treturn;\n\t\t}\n\n\t\tvar inst, beforeShow, beforeShowSettings, isFixed,\n\t\t\toffset, showAnim, duration;\n\n\t\tinst = $.datepicker._getInst(input);\n\t\tif ($.datepicker._curInst && $.datepicker._curInst !== inst) {\n\t\t\t$.datepicker._curInst.dpDiv.stop(true, true);\n\t\t\tif ( inst && $.datepicker._datepickerShowing ) {\n\t\t\t\t$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );\n\t\t\t}\n\t\t}\n\n\t\tbeforeShow = $.datepicker._get(inst, \"beforeShow\");\n\t\tbeforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};\n\t\tif(beforeShowSettings === false){\n\t\t\treturn;\n\t\t}\n\t\textendRemove(inst.settings, beforeShowSettings);\n\n\t\tinst.lastVal = null;\n\t\t$.datepicker._lastInput = input;\n\t\t$.datepicker._setDateFromField(inst);\n\n\t\tif ($.datepicker._inDialog) { // hide cursor\n\t\t\tinput.value = \"\";\n\t\t}\n\t\tif (!$.datepicker._pos) { // position below input\n\t\t\t$.datepicker._pos = $.datepicker._findPos(input);\n\t\t\t$.datepicker._pos[1] += input.offsetHeight; // add the height\n\t\t}\n\n\t\tisFixed = false;\n\t\t$(input).parents().each(function() {\n\t\t\tisFixed |= $(this).css(\"position\") === \"fixed\";\n\t\t\treturn !isFixed;\n\t\t});\n\n\t\toffset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};\n\t\t$.datepicker._pos = null;\n\t\t//to avoid flashes on Firefox\n\t\tinst.dpDiv.empty();\n\t\t// determine sizing offscreen\n\t\tinst.dpDiv.css({position: \"absolute\", display: \"block\", top: \"-1000px\"});\n\t\t$.datepicker._updateDatepicker(inst);\n\t\t// fix width for dynamic number of date pickers\n\t\t// and adjust position before showing\n\t\toffset = $.datepicker._checkOffset(inst, offset, isFixed);\n\t\tinst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?\n\t\t\t\"static\" : (isFixed ? \"fixed\" : \"absolute\")), display: \"none\",\n\t\t\tleft: offset.left + \"px\", top: offset.top + \"px\"});\n\n\t\tif (!inst.inline) {\n\t\t\tshowAnim = $.datepicker._get(inst, \"showAnim\");\n\t\t\tduration = $.datepicker._get(inst, \"duration\");\n\t\t\tinst.dpDiv.zIndex($(input).zIndex()+1);\n\t\t\t$.datepicker._datepickerShowing = true;\n\n\t\t\tif ( $.effects && $.effects.effect[ showAnim ] ) {\n\t\t\t\tinst.dpDiv.show(showAnim, $.datepicker._get(inst, \"showOptions\"), duration);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[showAnim || \"show\"](showAnim ? duration : null);\n\t\t\t}\n\n\t\t\tif ( $.datepicker._shouldFocusInput( inst ) ) {\n\t\t\t\tinst.input.focus();\n\t\t\t}\n\n\t\t\t$.datepicker._curInst = inst;\n\t\t}\n\t},\n\n\t/* Generate the date picker content. */\n\t_updateDatepicker: function(inst) {\n\t\tthis.maxRows = 4; //Reset the max number of rows being displayed (see #7043)\n\t\tinstActive = inst; // for delegate hover events\n\t\tinst.dpDiv.empty().append(this._generateHTML(inst));\n\t\tthis._attachHandlers(inst);\n\t\tinst.dpDiv.find(\".\" + this._dayOverClass + \" a\").mouseover();\n\n\t\tvar origyearshtml,\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tcols = numMonths[1],\n\t\t\twidth = 17;\n\n\t\tinst.dpDiv.removeClass(\"ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4\").width(\"\");\n\t\tif (cols > 1) {\n\t\t\tinst.dpDiv.addClass(\"ui-datepicker-multi-\" + cols).css(\"width\", (width * cols) + \"em\");\n\t\t}\n\t\tinst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-multi\");\n\t\tinst.dpDiv[(this._get(inst, \"isRTL\") ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-rtl\");\n\n\t\tif (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {\n\t\t\tinst.input.focus();\n\t\t}\n\n\t\t// deffered render of the years select (to avoid flashes on Firefox)\n\t\tif( inst.yearshtml ){\n\t\t\torigyearshtml = inst.yearshtml;\n\t\t\tsetTimeout(function(){\n\t\t\t\t//assure that inst.yearshtml didn't change.\n\t\t\t\tif( origyearshtml === inst.yearshtml && inst.yearshtml ){\n\t\t\t\t\tinst.dpDiv.find(\"select.ui-datepicker-year:first\").replaceWith(inst.yearshtml);\n\t\t\t\t}\n\t\t\t\torigyearshtml = inst.yearshtml = null;\n\t\t\t}, 0);\n\t\t}\n\t},\n\n\t// #6694 - don't focus the input if it's already focused\n\t// this breaks the change event in IE\n\t// Support: IE and jQuery <1.9\n\t_shouldFocusInput: function( inst ) {\n\t\treturn inst.input && inst.input.is( \":visible\" ) && !inst.input.is( \":disabled\" ) && !inst.input.is( \":focus\" );\n\t},\n\n\t/* Check positioning to remain on screen. */\n\t_checkOffset: function(inst, offset, isFixed) {\n\t\tvar dpWidth = inst.dpDiv.outerWidth(),\n\t\t\tdpHeight = inst.dpDiv.outerHeight(),\n\t\t\tinputWidth = inst.input ? inst.input.outerWidth() : 0,\n\t\t\tinputHeight = inst.input ? inst.input.outerHeight() : 0,\n\t\t\tviewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),\n\t\t\tviewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());\n\n\t\toffset.left -= (this._get(inst, \"isRTL\") ? (dpWidth - inputWidth) : 0);\n\t\toffset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;\n\t\toffset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;\n\n\t\t// now check if datepicker is showing outside window viewport - move to a better place if so.\n\t\toffset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?\n\t\t\tMath.abs(offset.left + dpWidth - viewWidth) : 0);\n\t\toffset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?\n\t\t\tMath.abs(dpHeight + inputHeight) : 0);\n\n\t\treturn offset;\n\t},\n\n\t/* Find an object's position on the screen. */\n\t_findPos: function(obj) {\n\t\tvar position,\n\t\t\tinst = this._getInst(obj),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\twhile (obj && (obj.type === \"hidden\" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {\n\t\t\tobj = obj[isRTL ? \"previousSibling\" : \"nextSibling\"];\n\t\t}\n\n\t\tposition = $(obj).offset();\n\t\treturn [position.left, position.top];\n\t},\n\n\t/* Hide the date picker from view.\n\t * @param  input  element - the input field attached to the date picker\n\t */\n\t_hideDatepicker: function(input) {\n\t\tvar showAnim, duration, postProcess, onClose,\n\t\t\tinst = this._curInst;\n\n\t\tif (!inst || (input && inst !== $.data(input, PROP_NAME))) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this._datepickerShowing) {\n\t\t\tshowAnim = this._get(inst, \"showAnim\");\n\t\t\tduration = this._get(inst, \"duration\");\n\t\t\tpostProcess = function() {\n\t\t\t\t$.datepicker._tidyDialog(inst);\n\t\t\t};\n\n\t\t\t// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed\n\t\t\tif ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {\n\t\t\t\tinst.dpDiv.hide(showAnim, $.datepicker._get(inst, \"showOptions\"), duration, postProcess);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[(showAnim === \"slideDown\" ? \"slideUp\" :\n\t\t\t\t\t(showAnim === \"fadeIn\" ? \"fadeOut\" : \"hide\"))]((showAnim ? duration : null), postProcess);\n\t\t\t}\n\n\t\t\tif (!showAnim) {\n\t\t\t\tpostProcess();\n\t\t\t}\n\t\t\tthis._datepickerShowing = false;\n\n\t\t\tonClose = this._get(inst, \"onClose\");\n\t\t\tif (onClose) {\n\t\t\t\tonClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : \"\"), inst]);\n\t\t\t}\n\n\t\t\tthis._lastInput = null;\n\t\t\tif (this._inDialog) {\n\t\t\t\tthis._dialogInput.css({ position: \"absolute\", left: \"0\", top: \"-100px\" });\n\t\t\t\tif ($.blockUI) {\n\t\t\t\t\t$.unblockUI();\n\t\t\t\t\t$(\"body\").append(this.dpDiv);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._inDialog = false;\n\t\t}\n\t},\n\n\t/* Tidy up after a dialog display. */\n\t_tidyDialog: function(inst) {\n\t\tinst.dpDiv.removeClass(this._dialogClass).unbind(\".ui-datepicker-calendar\");\n\t},\n\n\t/* Close date picker if clicked elsewhere. */\n\t_checkExternalClick: function(event) {\n\t\tif (!$.datepicker._curInst) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar $target = $(event.target),\n\t\t\tinst = $.datepicker._getInst($target[0]);\n\n\t\tif ( ( ( $target[0].id !== $.datepicker._mainDivId &&\n\t\t\t\t$target.parents(\"#\" + $.datepicker._mainDivId).length === 0 &&\n\t\t\t\t!$target.hasClass($.datepicker.markerClassName) &&\n\t\t\t\t!$target.closest(\".\" + $.datepicker._triggerClass).length &&\n\t\t\t\t$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||\n\t\t\t( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {\n\t\t\t\t$.datepicker._hideDatepicker();\n\t\t}\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustDate: function(id, offset, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\t\tthis._adjustInstDate(inst, offset +\n\t\t\t(period === \"M\" ? this._get(inst, \"showCurrentAtPos\") : 0), // undo positioning\n\t\t\tperiod);\n\t\tthis._updateDatepicker(inst);\n\t},\n\n\t/* Action for current link. */\n\t_gotoToday: function(id) {\n\t\tvar date,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._get(inst, \"gotoCurrent\") && inst.currentDay) {\n\t\t\tinst.selectedDay = inst.currentDay;\n\t\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth;\n\t\t\tinst.drawYear = inst.selectedYear = inst.currentYear;\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t\tinst.selectedDay = date.getDate();\n\t\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\t}\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a new month/year. */\n\t_selectMonthYear: function(id, select, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tinst[\"selected\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\tinst[\"draw\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\t\tparseInt(select.options[select.selectedIndex].value,10);\n\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a day. */\n\t_selectDay: function(id, month, year, td) {\n\t\tvar inst,\n\t\t\ttarget = $(id);\n\n\t\tif ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tinst = this._getInst(target[0]);\n\t\tinst.selectedDay = inst.currentDay = $(\"a\", td).html();\n\t\tinst.selectedMonth = inst.currentMonth = month;\n\t\tinst.selectedYear = inst.currentYear = year;\n\t\tthis._selectDate(id, this._formatDate(inst,\n\t\t\tinst.currentDay, inst.currentMonth, inst.currentYear));\n\t},\n\n\t/* Erase the input field and hide the date picker. */\n\t_clearDate: function(id) {\n\t\tvar target = $(id);\n\t\tthis._selectDate(target, \"\");\n\t},\n\n\t/* Update the input field with the selected date. */\n\t_selectDate: function(id, dateStr) {\n\t\tvar onSelect,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tdateStr = (dateStr != null ? dateStr : this._formatDate(inst));\n\t\tif (inst.input) {\n\t\t\tinst.input.val(dateStr);\n\t\t}\n\t\tthis._updateAlternate(inst);\n\n\t\tonSelect = this._get(inst, \"onSelect\");\n\t\tif (onSelect) {\n\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback\n\t\t} else if (inst.input) {\n\t\t\tinst.input.trigger(\"change\"); // fire the change event\n\t\t}\n\n\t\tif (inst.inline){\n\t\t\tthis._updateDatepicker(inst);\n\t\t} else {\n\t\t\tthis._hideDatepicker();\n\t\t\tthis._lastInput = inst.input[0];\n\t\t\tif (typeof(inst.input[0]) !== \"object\") {\n\t\t\t\tinst.input.focus(); // restore focus\n\t\t\t}\n\t\t\tthis._lastInput = null;\n\t\t}\n\t},\n\n\t/* Update any alternate field to synchronise with the main field. */\n\t_updateAlternate: function(inst) {\n\t\tvar altFormat, date, dateStr,\n\t\t\taltField = this._get(inst, \"altField\");\n\n\t\tif (altField) { // update alternate field too\n\t\t\taltFormat = this._get(inst, \"altFormat\") || this._get(inst, \"dateFormat\");\n\t\t\tdate = this._getDate(inst);\n\t\t\tdateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));\n\t\t\t$(altField).each(function() { $(this).val(dateStr); });\n\t\t}\n\t},\n\n\t/* Set as beforeShowDay function to prevent selection of weekends.\n\t * @param  date  Date - the date to customise\n\t * @return [boolean, string] - is this date selectable?, what is its CSS class?\n\t */\n\tnoWeekends: function(date) {\n\t\tvar day = date.getDay();\n\t\treturn [(day > 0 && day < 6), \"\"];\n\t},\n\n\t/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.\n\t * @param  date  Date - the date to get the week for\n\t * @return  number - the number of the week within the year that contains this date\n\t */\n\tiso8601Week: function(date) {\n\t\tvar time,\n\t\t\tcheckDate = new Date(date.getTime());\n\n\t\t// Find Thursday of this week starting on Monday\n\t\tcheckDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));\n\n\t\ttime = checkDate.getTime();\n\t\tcheckDate.setMonth(0); // Compare with Jan 1\n\t\tcheckDate.setDate(1);\n\t\treturn Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;\n\t},\n\n\t/* Parse a string value into a date object.\n\t * See formatDate below for the possible formats.\n\t *\n\t * @param  format string - the expected format of the date\n\t * @param  value string - the date in the above format\n\t * @param  settings Object - attributes include:\n\t *\t\t\t\t\tshortYearCutoff  number - the cutoff year for determining the century (optional)\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return  Date - the extracted date value or null if value is blank\n\t */\n\tparseDate: function (format, value, settings) {\n\t\tif (format == null || value == null) {\n\t\t\tthrow \"Invalid arguments\";\n\t\t}\n\n\t\tvalue = (typeof value === \"object\" ? value.toString() : value + \"\");\n\t\tif (value === \"\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar iFormat, dim, extra,\n\t\t\tiValue = 0,\n\t\t\tshortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,\n\t\t\tshortYearCutoff = (typeof shortYearCutoffTemp !== \"string\" ? shortYearCutoffTemp :\n\t\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\tyear = -1,\n\t\t\tmonth = -1,\n\t\t\tday = -1,\n\t\t\tdoy = -1,\n\t\t\tliteral = false,\n\t\t\tdate,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Extract a number from the string value\n\t\t\tgetNumber = function(match) {\n\t\t\t\tvar isDoubled = lookAhead(match),\n\t\t\t\t\tsize = (match === \"@\" ? 14 : (match === \"!\" ? 20 :\n\t\t\t\t\t(match === \"y\" && isDoubled ? 4 : (match === \"o\" ? 3 : 2)))),\n\t\t\t\t\tdigits = new RegExp(\"^\\\\d{1,\" + size + \"}\"),\n\t\t\t\t\tnum = value.substring(iValue).match(digits);\n\t\t\t\tif (!num) {\n\t\t\t\t\tthrow \"Missing number at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue += num[0].length;\n\t\t\t\treturn parseInt(num[0], 10);\n\t\t\t},\n\t\t\t// Extract a name from the string value and convert to an index\n\t\t\tgetName = function(match, shortNames, longNames) {\n\t\t\t\tvar index = -1,\n\t\t\t\t\tnames = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {\n\t\t\t\t\t\treturn [ [k, v] ];\n\t\t\t\t\t}).sort(function (a, b) {\n\t\t\t\t\t\treturn -(a[1].length - b[1].length);\n\t\t\t\t\t});\n\n\t\t\t\t$.each(names, function (i, pair) {\n\t\t\t\t\tvar name = pair[1];\n\t\t\t\t\tif (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {\n\t\t\t\t\t\tindex = pair[0];\n\t\t\t\t\t\tiValue += name.length;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\treturn index + 1;\n\t\t\t\t} else {\n\t\t\t\t\tthrow \"Unknown name at position \" + iValue;\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Confirm that a literal character matches the string value\n\t\t\tcheckLiteral = function() {\n\t\t\t\tif (value.charAt(iValue) !== format.charAt(iFormat)) {\n\t\t\t\t\tthrow \"Unexpected literal at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue++;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\tday = getNumber(\"d\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\tgetName(\"D\", dayNamesShort, dayNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\tdoy = getNumber(\"o\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\tmonth = getNumber(\"m\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\tmonth = getName(\"M\", monthNamesShort, monthNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\tyear = getNumber(\"y\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\tdate = new Date(getNumber(\"@\"));\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\tdate = new Date((getNumber(\"!\") - this._ticksTo1970) / 10000);\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\tif (lookAhead(\"'\")){\n\t\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (iValue < value.length){\n\t\t\textra = value.substr(iValue);\n\t\t\tif (!/^\\s+/.test(extra)) {\n\t\t\t\tthrow \"Extra/unparsed characters found in date: \" + extra;\n\t\t\t}\n\t\t}\n\n\t\tif (year === -1) {\n\t\t\tyear = new Date().getFullYear();\n\t\t} else if (year < 100) {\n\t\t\tyear += new Date().getFullYear() - new Date().getFullYear() % 100 +\n\t\t\t\t(year <= shortYearCutoff ? 0 : -100);\n\t\t}\n\n\t\tif (doy > -1) {\n\t\t\tmonth = 1;\n\t\t\tday = doy;\n\t\t\tdo {\n\t\t\t\tdim = this._getDaysInMonth(year, month - 1);\n\t\t\t\tif (day <= dim) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmonth++;\n\t\t\t\tday -= dim;\n\t\t\t} while (true);\n\t\t}\n\n\t\tdate = this._daylightSavingAdjust(new Date(year, month - 1, day));\n\t\tif (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {\n\t\t\tthrow \"Invalid date\"; // E.g. 31/02/00\n\t\t}\n\t\treturn date;\n\t},\n\n\t/* Standard date formats. */\n\tATOM: \"yy-mm-dd\", // RFC 3339 (ISO 8601)\n\tCOOKIE: \"D, dd M yy\",\n\tISO_8601: \"yy-mm-dd\",\n\tRFC_822: \"D, d M y\",\n\tRFC_850: \"DD, dd-M-y\",\n\tRFC_1036: \"D, d M y\",\n\tRFC_1123: \"D, d M yy\",\n\tRFC_2822: \"D, d M yy\",\n\tRSS: \"D, d M y\", // RFC 822\n\tTICKS: \"!\",\n\tTIMESTAMP: \"@\",\n\tW3C: \"yy-mm-dd\", // ISO 8601\n\n\t_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +\n\t\tMath.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),\n\n\t/* Format a date object into a string value.\n\t * The format can be combinations of the following:\n\t * d  - day of month (no leading zero)\n\t * dd - day of month (two digit)\n\t * o  - day of year (no leading zeros)\n\t * oo - day of year (three digit)\n\t * D  - day name short\n\t * DD - day name long\n\t * m  - month of year (no leading zero)\n\t * mm - month of year (two digit)\n\t * M  - month name short\n\t * MM - month name long\n\t * y  - year (two digit)\n\t * yy - year (four digit)\n\t * @ - Unix timestamp (ms since 01/01/1970)\n\t * ! - Windows ticks (100ns since 01/01/0001)\n\t * \"...\" - literal text\n\t * '' - single quote\n\t *\n\t * @param  format string - the desired format of the date\n\t * @param  date Date - the date value to format\n\t * @param  settings Object - attributes include:\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return  string - the date in the above format\n\t */\n\tformatDate: function (format, date, settings) {\n\t\tif (!date) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar iFormat,\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Format a number, with leading zero if necessary\n\t\t\tformatNumber = function(match, value, len) {\n\t\t\t\tvar num = \"\" + value;\n\t\t\t\tif (lookAhead(match)) {\n\t\t\t\t\twhile (num.length < len) {\n\t\t\t\t\t\tnum = \"0\" + num;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn num;\n\t\t\t},\n\t\t\t// Format a name, short or long as requested\n\t\t\tformatName = function(match, value, shortNames, longNames) {\n\t\t\t\treturn (lookAhead(match) ? longNames[value] : shortNames[value]);\n\t\t\t},\n\t\t\toutput = \"\",\n\t\t\tliteral = false;\n\n\t\tif (date) {\n\t\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\t\tif (literal) {\n\t\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\t\tliteral = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\t\toutput += formatNumber(\"d\", date.getDate(), 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\t\toutput += formatName(\"D\", date.getDay(), dayNamesShort, dayNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\t\toutput += formatNumber(\"o\",\n\t\t\t\t\t\t\t\tMath.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\t\toutput += formatNumber(\"m\", date.getMonth() + 1, 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\t\toutput += formatName(\"M\", date.getMonth(), monthNamesShort, monthNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\t\toutput += (lookAhead(\"y\") ? date.getFullYear() :\n\t\t\t\t\t\t\t\t(date.getYear() % 100 < 10 ? \"0\" : \"\") + date.getYear() % 100);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\t\toutput += date.getTime();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\t\toutput += date.getTime() * 10000 + this._ticksTo1970;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\t\tif (lookAhead(\"'\")) {\n\t\t\t\t\t\t\t\toutput += \"'\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t},\n\n\t/* Extract all possible characters from the date format. */\n\t_possibleChars: function (format) {\n\t\tvar iFormat,\n\t\t\tchars = \"\",\n\t\t\tliteral = false,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\": case \"m\": case \"y\": case \"@\":\n\t\t\t\t\t\tchars += \"0123456789\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\": case \"M\":\n\t\t\t\t\t\treturn null; // Accept anything\n\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\tif (lookAhead(\"'\")) {\n\t\t\t\t\t\t\tchars += \"'\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn chars;\n\t},\n\n\t/* Get a setting value, defaulting if necessary. */\n\t_get: function(inst, name) {\n\t\treturn inst.settings[name] !== undefined ?\n\t\t\tinst.settings[name] : this._defaults[name];\n\t},\n\n\t/* Parse existing date and initialise date picker. */\n\t_setDateFromField: function(inst, noDefault) {\n\t\tif (inst.input.val() === inst.lastVal) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar dateFormat = this._get(inst, \"dateFormat\"),\n\t\t\tdates = inst.lastVal = inst.input ? inst.input.val() : null,\n\t\t\tdefaultDate = this._getDefaultDate(inst),\n\t\t\tdate = defaultDate,\n\t\t\tsettings = this._getFormatConfig(inst);\n\n\t\ttry {\n\t\t\tdate = this.parseDate(dateFormat, dates, settings) || defaultDate;\n\t\t} catch (event) {\n\t\t\tdates = (noDefault ? \"\" : dates);\n\t\t}\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tinst.currentDay = (dates ? date.getDate() : 0);\n\t\tinst.currentMonth = (dates ? date.getMonth() : 0);\n\t\tinst.currentYear = (dates ? date.getFullYear() : 0);\n\t\tthis._adjustInstDate(inst);\n\t},\n\n\t/* Retrieve the default date shown on opening. */\n\t_getDefaultDate: function(inst) {\n\t\treturn this._restrictMinMax(inst,\n\t\t\tthis._determineDate(inst, this._get(inst, \"defaultDate\"), new Date()));\n\t},\n\n\t/* A date may be specified as an exact value or a relative one. */\n\t_determineDate: function(inst, date, defaultDate) {\n\t\tvar offsetNumeric = function(offset) {\n\t\t\t\tvar date = new Date();\n\t\t\t\tdate.setDate(date.getDate() + offset);\n\t\t\t\treturn date;\n\t\t\t},\n\t\t\toffsetString = function(offset) {\n\t\t\t\ttry {\n\t\t\t\t\treturn $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t\toffset, $.datepicker._getFormatConfig(inst));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// Ignore\n\t\t\t\t}\n\n\t\t\t\tvar date = (offset.toLowerCase().match(/^c/) ?\n\t\t\t\t\t$.datepicker._getDate(inst) : null) || new Date(),\n\t\t\t\t\tyear = date.getFullYear(),\n\t\t\t\t\tmonth = date.getMonth(),\n\t\t\t\t\tday = date.getDate(),\n\t\t\t\t\tpattern = /([+\\-]?[0-9]+)\\s*(d|D|w|W|m|M|y|Y)?/g,\n\t\t\t\t\tmatches = pattern.exec(offset);\n\n\t\t\t\twhile (matches) {\n\t\t\t\t\tswitch (matches[2] || \"d\") {\n\t\t\t\t\t\tcase \"d\" : case \"D\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10); break;\n\t\t\t\t\t\tcase \"w\" : case \"W\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10) * 7; break;\n\t\t\t\t\t\tcase \"m\" : case \"M\" :\n\t\t\t\t\t\t\tmonth += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\": case \"Y\" :\n\t\t\t\t\t\t\tyear += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tmatches = pattern.exec(offset);\n\t\t\t\t}\n\t\t\t\treturn new Date(year, month, day);\n\t\t\t},\n\t\t\tnewDate = (date == null || date === \"\" ? defaultDate : (typeof date === \"string\" ? offsetString(date) :\n\t\t\t\t(typeof date === \"number\" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));\n\n\t\tnewDate = (newDate && newDate.toString() === \"Invalid Date\" ? defaultDate : newDate);\n\t\tif (newDate) {\n\t\t\tnewDate.setHours(0);\n\t\t\tnewDate.setMinutes(0);\n\t\t\tnewDate.setSeconds(0);\n\t\t\tnewDate.setMilliseconds(0);\n\t\t}\n\t\treturn this._daylightSavingAdjust(newDate);\n\t},\n\n\t/* Handle switch to/from daylight saving.\n\t * Hours may be non-zero on daylight saving cut-over:\n\t * > 12 when midnight changeover, but then cannot generate\n\t * midnight datetime, so jump to 1AM, otherwise reset.\n\t * @param  date  (Date) the date to check\n\t * @return  (Date) the corrected date\n\t */\n\t_daylightSavingAdjust: function(date) {\n\t\tif (!date) {\n\t\t\treturn null;\n\t\t}\n\t\tdate.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n\t\treturn date;\n\t},\n\n\t/* Set the date(s) directly. */\n\t_setDate: function(inst, date, noChange) {\n\t\tvar clear = !date,\n\t\t\torigMonth = inst.selectedMonth,\n\t\t\torigYear = inst.selectedYear,\n\t\t\tnewDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));\n\n\t\tinst.selectedDay = inst.currentDay = newDate.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();\n\t\tinst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();\n\t\tif ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t\tthis._adjustInstDate(inst);\n\t\tif (inst.input) {\n\t\t\tinst.input.val(clear ? \"\" : this._formatDate(inst));\n\t\t}\n\t},\n\n\t/* Retrieve the date(s) directly. */\n\t_getDate: function(inst) {\n\t\tvar startDate = (!inst.currentYear || (inst.input && inst.input.val() === \"\") ? null :\n\t\t\tthis._daylightSavingAdjust(new Date(\n\t\t\tinst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\t\treturn startDate;\n\t},\n\n\t/* Attach the onxxx handlers.  These are declared statically so\n\t * they work with static code transformers like Caja.\n\t */\n\t_attachHandlers: function(inst) {\n\t\tvar stepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tid = \"#\" + inst.id.replace( /\\\\\\\\/g, \"\\\\\" );\n\t\tinst.dpDiv.find(\"[data-handler]\").map(function () {\n\t\t\tvar handler = {\n\t\t\t\tprev: function () {\n\t\t\t\t\t$.datepicker._adjustDate(id, -stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\tnext: function () {\n\t\t\t\t\t$.datepicker._adjustDate(id, +stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\thide: function () {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t},\n\t\t\t\ttoday: function () {\n\t\t\t\t\t$.datepicker._gotoToday(id);\n\t\t\t\t},\n\t\t\t\tselectDay: function () {\n\t\t\t\t\t$.datepicker._selectDay(id, +this.getAttribute(\"data-month\"), +this.getAttribute(\"data-year\"), this);\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectMonth: function () {\n\t\t\t\t\t$.datepicker._selectMonthYear(id, this, \"M\");\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectYear: function () {\n\t\t\t\t\t$.datepicker._selectMonthYear(id, this, \"Y\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t};\n\t\t\t$(this).bind(this.getAttribute(\"data-event\"), handler[this.getAttribute(\"data-handler\")]);\n\t\t});\n\t},\n\n\t/* Generate the HTML for the current state of the date picker. */\n\t_generateHTML: function(inst) {\n\t\tvar maxDraw, prevText, prev, nextText, next, currentText, gotoDate,\n\t\t\tcontrols, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,\n\t\t\tmonthNames, monthNamesShort, beforeShowDay, showOtherMonths,\n\t\t\tselectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,\n\t\t\tcornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,\n\t\t\tprintDate, dRow, tbody, daySettings, otherMonth, unselectable,\n\t\t\ttempDate = new Date(),\n\t\t\ttoday = this._daylightSavingAdjust(\n\t\t\t\tnew Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time\n\t\t\tisRTL = this._get(inst, \"isRTL\"),\n\t\t\tshowButtonPanel = this._get(inst, \"showButtonPanel\"),\n\t\t\thideIfNoPrevNext = this._get(inst, \"hideIfNoPrevNext\"),\n\t\t\tnavigationAsDateFormat = this._get(inst, \"navigationAsDateFormat\"),\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tshowCurrentAtPos = this._get(inst, \"showCurrentAtPos\"),\n\t\t\tstepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tisMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),\n\t\t\tcurrentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :\n\t\t\t\tnew Date(inst.currentYear, inst.currentMonth, inst.currentDay))),\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tdrawMonth = inst.drawMonth - showCurrentAtPos,\n\t\t\tdrawYear = inst.drawYear;\n\n\t\tif (drawMonth < 0) {\n\t\t\tdrawMonth += 12;\n\t\t\tdrawYear--;\n\t\t}\n\t\tif (maxDate) {\n\t\t\tmaxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),\n\t\t\t\tmaxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));\n\t\t\tmaxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);\n\t\t\twhile (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {\n\t\t\t\tdrawMonth--;\n\t\t\t\tif (drawMonth < 0) {\n\t\t\t\t\tdrawMonth = 11;\n\t\t\t\t\tdrawYear--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tinst.drawMonth = drawMonth;\n\t\tinst.drawYear = drawYear;\n\n\t\tprevText = this._get(inst, \"prevText\");\n\t\tprevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tprev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?\n\t\t\t\"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'\" +\n\t\t\t\" title='\" + prevText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"'>\" + prevText + \"</span></a>\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='\"+ prevText +\"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"'>\" + prevText + \"</span></a>\"));\n\n\t\tnextText = this._get(inst, \"nextText\");\n\t\tnextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tnext = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?\n\t\t\t\"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'\" +\n\t\t\t\" title='\" + nextText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"'>\" + nextText + \"</span></a>\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='\"+ nextText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"'>\" + nextText + \"</span></a>\"));\n\n\t\tcurrentText = this._get(inst, \"currentText\");\n\t\tgotoDate = (this._get(inst, \"gotoCurrent\") && inst.currentDay ? currentDate : today);\n\t\tcurrentText = (!navigationAsDateFormat ? currentText :\n\t\t\tthis.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));\n\n\t\tcontrols = (!inst.inline ? \"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>\" +\n\t\t\tthis._get(inst, \"closeText\") + \"</button>\" : \"\");\n\n\t\tbuttonPanel = (showButtonPanel) ? \"<div class='ui-datepicker-buttonpane ui-widget-content'>\" + (isRTL ? controls : \"\") +\n\t\t\t(this._isInRange(inst, gotoDate) ? \"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'\" +\n\t\t\t\">\" + currentText + \"</button>\" : \"\") + (isRTL ? \"\" : controls) + \"</div>\" : \"\";\n\n\t\tfirstDay = parseInt(this._get(inst, \"firstDay\"),10);\n\t\tfirstDay = (isNaN(firstDay) ? 0 : firstDay);\n\n\t\tshowWeek = this._get(inst, \"showWeek\");\n\t\tdayNames = this._get(inst, \"dayNames\");\n\t\tdayNamesMin = this._get(inst, \"dayNamesMin\");\n\t\tmonthNames = this._get(inst, \"monthNames\");\n\t\tmonthNamesShort = this._get(inst, \"monthNamesShort\");\n\t\tbeforeShowDay = this._get(inst, \"beforeShowDay\");\n\t\tshowOtherMonths = this._get(inst, \"showOtherMonths\");\n\t\tselectOtherMonths = this._get(inst, \"selectOtherMonths\");\n\t\tdefaultDate = this._getDefaultDate(inst);\n\t\thtml = \"\";\n\t\tdow;\n\t\tfor (row = 0; row < numMonths[0]; row++) {\n\t\t\tgroup = \"\";\n\t\t\tthis.maxRows = 4;\n\t\t\tfor (col = 0; col < numMonths[1]; col++) {\n\t\t\t\tselectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));\n\t\t\t\tcornerClass = \" ui-corner-all\";\n\t\t\t\tcalender = \"\";\n\t\t\t\tif (isMultiMonth) {\n\t\t\t\t\tcalender += \"<div class='ui-datepicker-group\";\n\t\t\t\t\tif (numMonths[1] > 1) {\n\t\t\t\t\t\tswitch (col) {\n\t\t\t\t\t\t\tcase 0: calender += \" ui-datepicker-group-first\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"right\" : \"left\"); break;\n\t\t\t\t\t\t\tcase numMonths[1]-1: calender += \" ui-datepicker-group-last\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"left\" : \"right\"); break;\n\t\t\t\t\t\t\tdefault: calender += \" ui-datepicker-group-middle\"; cornerClass = \"\"; break;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcalender += \"'>\";\n\t\t\t\t}\n\t\t\t\tcalender += \"<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix\" + cornerClass + \"'>\" +\n\t\t\t\t\t(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : \"\") +\n\t\t\t\t\t(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : \"\") +\n\t\t\t\t\tthis._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\t\t\trow > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers\n\t\t\t\t\t\"</div><table class='ui-datepicker-calendar'><thead>\" +\n\t\t\t\t\t\"<tr>\";\n\t\t\t\tthead = (showWeek ? \"<th class='ui-datepicker-week-col'>\" + this._get(inst, \"weekHeader\") + \"</th>\" : \"\");\n\t\t\t\tfor (dow = 0; dow < 7; dow++) { // days of the week\n\t\t\t\t\tday = (dow + firstDay) % 7;\n\t\t\t\t\tthead += \"<th\" + ((dow + firstDay + 6) % 7 >= 5 ? \" class='ui-datepicker-week-end'\" : \"\") + \">\" +\n\t\t\t\t\t\t\"<span title='\" + dayNames[day] + \"'>\" + dayNamesMin[day] + \"</span></th>\";\n\t\t\t\t}\n\t\t\t\tcalender += thead + \"</tr></thead><tbody>\";\n\t\t\t\tdaysInMonth = this._getDaysInMonth(drawYear, drawMonth);\n\t\t\t\tif (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {\n\t\t\t\t\tinst.selectedDay = Math.min(inst.selectedDay, daysInMonth);\n\t\t\t\t}\n\t\t\t\tleadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;\n\t\t\t\tcurRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate\n\t\t\t\tnumRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)\n\t\t\t\tthis.maxRows = numRows;\n\t\t\t\tprintDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));\n\t\t\t\tfor (dRow = 0; dRow < numRows; dRow++) { // create date picker rows\n\t\t\t\t\tcalender += \"<tr>\";\n\t\t\t\t\ttbody = (!showWeek ? \"\" : \"<td class='ui-datepicker-week-col'>\" +\n\t\t\t\t\t\tthis._get(inst, \"calculateWeek\")(printDate) + \"</td>\");\n\t\t\t\t\tfor (dow = 0; dow < 7; dow++) { // create date picker days\n\t\t\t\t\t\tdaySettings = (beforeShowDay ?\n\t\t\t\t\t\t\tbeforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, \"\"]);\n\t\t\t\t\t\totherMonth = (printDate.getMonth() !== drawMonth);\n\t\t\t\t\t\tunselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||\n\t\t\t\t\t\t\t(minDate && printDate < minDate) || (maxDate && printDate > maxDate);\n\t\t\t\t\t\ttbody += \"<td class='\" +\n\t\t\t\t\t\t\t((dow + firstDay + 6) % 7 >= 5 ? \" ui-datepicker-week-end\" : \"\") + // highlight weekends\n\t\t\t\t\t\t\t(otherMonth ? \" ui-datepicker-other-month\" : \"\") + // highlight days from other months\n\t\t\t\t\t\t\t((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key\n\t\t\t\t\t\t\t(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?\n\t\t\t\t\t\t\t// or defaultDate is current printedDate and defaultDate is selectedDate\n\t\t\t\t\t\t\t\" \" + this._dayOverClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(unselectable ? \" \" + this._unselectableClass + \" ui-state-disabled\": \"\") +  // highlight unselectable days\n\t\t\t\t\t\t\t(otherMonth && !showOtherMonths ? \"\" : \" \" + daySettings[1] + // highlight custom dates\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" \" + this._currentClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-datepicker-today\" : \"\")) + \"'\" + // highlight today (if different)\n\t\t\t\t\t\t\t((!otherMonth || showOtherMonths) && daySettings[2] ? \" title='\" + daySettings[2].replace(/'/g, \"&#39;\") + \"'\" : \"\") + // cell title\n\t\t\t\t\t\t\t(unselectable ? \"\" : \" data-handler='selectDay' data-event='click' data-month='\" + printDate.getMonth() + \"' data-year='\" + printDate.getFullYear() + \"'\") + \">\" + // actions\n\t\t\t\t\t\t\t(otherMonth && !showOtherMonths ? \"&#xa0;\" : // display for other months\n\t\t\t\t\t\t\t(unselectable ? \"<span class='ui-state-default'>\" + printDate.getDate() + \"</span>\" : \"<a class='ui-state-default\" +\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-state-highlight\" : \"\") +\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" ui-state-active\" : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(otherMonth ? \" ui-priority-secondary\" : \"\") + // distinguish dates from other months\n\t\t\t\t\t\t\t\"' href='#'>\" + printDate.getDate() + \"</a>\")) + \"</td>\"; // display selectable date\n\t\t\t\t\t\tprintDate.setDate(printDate.getDate() + 1);\n\t\t\t\t\t\tprintDate = this._daylightSavingAdjust(printDate);\n\t\t\t\t\t}\n\t\t\t\t\tcalender += tbody + \"</tr>\";\n\t\t\t\t}\n\t\t\t\tdrawMonth++;\n\t\t\t\tif (drawMonth > 11) {\n\t\t\t\t\tdrawMonth = 0;\n\t\t\t\t\tdrawYear++;\n\t\t\t\t}\n\t\t\t\tcalender += \"</tbody></table>\" + (isMultiMonth ? \"</div>\" +\n\t\t\t\t\t\t\t((numMonths[0] > 0 && col === numMonths[1]-1) ? \"<div class='ui-datepicker-row-break'></div>\" : \"\") : \"\");\n\t\t\t\tgroup += calender;\n\t\t\t}\n\t\t\thtml += group;\n\t\t}\n\t\thtml += buttonPanel;\n\t\tinst._keyEvent = false;\n\t\treturn html;\n\t},\n\n\t/* Generate the month and year header. */\n\t_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\tsecondary, monthNames, monthNamesShort) {\n\n\t\tvar inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,\n\t\t\tchangeMonth = this._get(inst, \"changeMonth\"),\n\t\t\tchangeYear = this._get(inst, \"changeYear\"),\n\t\t\tshowMonthAfterYear = this._get(inst, \"showMonthAfterYear\"),\n\t\t\thtml = \"<div class='ui-datepicker-title'>\",\n\t\t\tmonthHtml = \"\";\n\n\t\t// month selection\n\t\tif (secondary || !changeMonth) {\n\t\t\tmonthHtml += \"<span class='ui-datepicker-month'>\" + monthNames[drawMonth] + \"</span>\";\n\t\t} else {\n\t\t\tinMinYear = (minDate && minDate.getFullYear() === drawYear);\n\t\t\tinMaxYear = (maxDate && maxDate.getFullYear() === drawYear);\n\t\t\tmonthHtml += \"<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>\";\n\t\t\tfor ( month = 0; month < 12; month++) {\n\t\t\t\tif ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {\n\t\t\t\t\tmonthHtml += \"<option value='\" + month + \"'\" +\n\t\t\t\t\t\t(month === drawMonth ? \" selected='selected'\" : \"\") +\n\t\t\t\t\t\t\">\" + monthNamesShort[month] + \"</option>\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tmonthHtml += \"</select>\";\n\t\t}\n\n\t\tif (!showMonthAfterYear) {\n\t\t\thtml += monthHtml + (secondary || !(changeMonth && changeYear) ? \"&#xa0;\" : \"\");\n\t\t}\n\n\t\t// year selection\n\t\tif ( !inst.yearshtml ) {\n\t\t\tinst.yearshtml = \"\";\n\t\t\tif (secondary || !changeYear) {\n\t\t\t\thtml += \"<span class='ui-datepicker-year'>\" + drawYear + \"</span>\";\n\t\t\t} else {\n\t\t\t\t// determine range of years to display\n\t\t\t\tyears = this._get(inst, \"yearRange\").split(\":\");\n\t\t\t\tthisYear = new Date().getFullYear();\n\t\t\t\tdetermineYear = function(value) {\n\t\t\t\t\tvar year = (value.match(/c[+\\-].*/) ? drawYear + parseInt(value.substring(1), 10) :\n\t\t\t\t\t\t(value.match(/[+\\-].*/) ? thisYear + parseInt(value, 10) :\n\t\t\t\t\t\tparseInt(value, 10)));\n\t\t\t\t\treturn (isNaN(year) ? thisYear : year);\n\t\t\t\t};\n\t\t\t\tyear = determineYear(years[0]);\n\t\t\t\tendYear = Math.max(year, determineYear(years[1] || \"\"));\n\t\t\t\tyear = (minDate ? Math.max(year, minDate.getFullYear()) : year);\n\t\t\t\tendYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);\n\t\t\t\tinst.yearshtml += \"<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>\";\n\t\t\t\tfor (; year <= endYear; year++) {\n\t\t\t\t\tinst.yearshtml += \"<option value='\" + year + \"'\" +\n\t\t\t\t\t\t(year === drawYear ? \" selected='selected'\" : \"\") +\n\t\t\t\t\t\t\">\" + year + \"</option>\";\n\t\t\t\t}\n\t\t\t\tinst.yearshtml += \"</select>\";\n\n\t\t\t\thtml += inst.yearshtml;\n\t\t\t\tinst.yearshtml = null;\n\t\t\t}\n\t\t}\n\n\t\thtml += this._get(inst, \"yearSuffix\");\n\t\tif (showMonthAfterYear) {\n\t\t\thtml += (secondary || !(changeMonth && changeYear) ? \"&#xa0;\" : \"\") + monthHtml;\n\t\t}\n\t\thtml += \"</div>\"; // Close datepicker_header\n\t\treturn html;\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustInstDate: function(inst, offset, period) {\n\t\tvar year = inst.drawYear + (period === \"Y\" ? offset : 0),\n\t\t\tmonth = inst.drawMonth + (period === \"M\" ? offset : 0),\n\t\t\tday = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === \"D\" ? offset : 0),\n\t\t\tdate = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));\n\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tif (period === \"M\" || period === \"Y\") {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t},\n\n\t/* Ensure a date is within any min/max bounds. */\n\t_restrictMinMax: function(inst, date) {\n\t\tvar minDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tnewDate = (minDate && date < minDate ? minDate : date);\n\t\treturn (maxDate && newDate > maxDate ? maxDate : newDate);\n\t},\n\n\t/* Notify change of month/year. */\n\t_notifyChange: function(inst) {\n\t\tvar onChange = this._get(inst, \"onChangeMonthYear\");\n\t\tif (onChange) {\n\t\t\tonChange.apply((inst.input ? inst.input[0] : null),\n\t\t\t\t[inst.selectedYear, inst.selectedMonth + 1, inst]);\n\t\t}\n\t},\n\n\t/* Determine the number of months to show. */\n\t_getNumberOfMonths: function(inst) {\n\t\tvar numMonths = this._get(inst, \"numberOfMonths\");\n\t\treturn (numMonths == null ? [1, 1] : (typeof numMonths === \"number\" ? [1, numMonths] : numMonths));\n\t},\n\n\t/* Determine the current maximum date - ensure no time components are set. */\n\t_getMinMaxDate: function(inst, minMax) {\n\t\treturn this._determineDate(inst, this._get(inst, minMax + \"Date\"), null);\n\t},\n\n\t/* Find the number of days in a given month. */\n\t_getDaysInMonth: function(year, month) {\n\t\treturn 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();\n\t},\n\n\t/* Find the day of the week of the first of a month. */\n\t_getFirstDayOfMonth: function(year, month) {\n\t\treturn new Date(year, month, 1).getDay();\n\t},\n\n\t/* Determines if we should allow a \"next/prev\" month display change. */\n\t_canAdjustMonth: function(inst, offset, curYear, curMonth) {\n\t\tvar numMonths = this._getNumberOfMonths(inst),\n\t\t\tdate = this._daylightSavingAdjust(new Date(curYear,\n\t\t\tcurMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));\n\n\t\tif (offset < 0) {\n\t\t\tdate.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));\n\t\t}\n\t\treturn this._isInRange(inst, date);\n\t},\n\n\t/* Is the given date in the accepted range? */\n\t_isInRange: function(inst, date) {\n\t\tvar yearSplit, currentYear,\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tminYear = null,\n\t\t\tmaxYear = null,\n\t\t\tyears = this._get(inst, \"yearRange\");\n\t\t\tif (years){\n\t\t\t\tyearSplit = years.split(\":\");\n\t\t\t\tcurrentYear = new Date().getFullYear();\n\t\t\t\tminYear = parseInt(yearSplit[0], 10);\n\t\t\t\tmaxYear = parseInt(yearSplit[1], 10);\n\t\t\t\tif ( yearSplit[0].match(/[+\\-].*/) ) {\n\t\t\t\t\tminYear += currentYear;\n\t\t\t\t}\n\t\t\t\tif ( yearSplit[1].match(/[+\\-].*/) ) {\n\t\t\t\t\tmaxYear += currentYear;\n\t\t\t\t}\n\t\t\t}\n\n\t\treturn ((!minDate || date.getTime() >= minDate.getTime()) &&\n\t\t\t(!maxDate || date.getTime() <= maxDate.getTime()) &&\n\t\t\t(!minYear || date.getFullYear() >= minYear) &&\n\t\t\t(!maxYear || date.getFullYear() <= maxYear));\n\t},\n\n\t/* Provide the configuration settings for formatting/parsing. */\n\t_getFormatConfig: function(inst) {\n\t\tvar shortYearCutoff = this._get(inst, \"shortYearCutoff\");\n\t\tshortYearCutoff = (typeof shortYearCutoff !== \"string\" ? shortYearCutoff :\n\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));\n\t\treturn {shortYearCutoff: shortYearCutoff,\n\t\t\tdayNamesShort: this._get(inst, \"dayNamesShort\"), dayNames: this._get(inst, \"dayNames\"),\n\t\t\tmonthNamesShort: this._get(inst, \"monthNamesShort\"), monthNames: this._get(inst, \"monthNames\")};\n\t},\n\n\t/* Format the given date for display. */\n\t_formatDate: function(inst, day, month, year) {\n\t\tif (!day) {\n\t\t\tinst.currentDay = inst.selectedDay;\n\t\t\tinst.currentMonth = inst.selectedMonth;\n\t\t\tinst.currentYear = inst.selectedYear;\n\t\t}\n\t\tvar date = (day ? (typeof day === \"object\" ? day :\n\t\t\tthis._daylightSavingAdjust(new Date(year, month, day))) :\n\t\t\tthis._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\treturn this.formatDate(this._get(inst, \"dateFormat\"), date, this._getFormatConfig(inst));\n\t}\n});\n\n/*\n * Bind hover events for datepicker elements.\n * Done via delegate so the binding only occurs once in the lifetime of the parent div.\n * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.\n */\nfunction bindHover(dpDiv) {\n\tvar selector = \"button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a\";\n\treturn dpDiv.delegate(selector, \"mouseout\", function() {\n\t\t\t$(this).removeClass(\"ui-state-hover\");\n\t\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-prev-hover\");\n\t\t\t}\n\t\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-next-hover\");\n\t\t\t}\n\t\t})\n\t\t.delegate(selector, \"mouseover\", function(){\n\t\t\tif (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {\n\t\t\t\t$(this).parents(\".ui-datepicker-calendar\").find(\"a\").removeClass(\"ui-state-hover\");\n\t\t\t\t$(this).addClass(\"ui-state-hover\");\n\t\t\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t\t\t$(this).addClass(\"ui-datepicker-prev-hover\");\n\t\t\t\t}\n\t\t\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t\t\t$(this).addClass(\"ui-datepicker-next-hover\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n}\n\n/* jQuery extend now ignores nulls! */\nfunction extendRemove(target, props) {\n\t$.extend(target, props);\n\tfor (var name in props) {\n\t\tif (props[name] == null) {\n\t\t\ttarget[name] = props[name];\n\t\t}\n\t}\n\treturn target;\n}\n\n/* Invoke the datepicker functionality.\n   @param  options  string - a command, optionally followed by additional parameters or\n\t\t\t\t\tObject - settings for attaching new datepicker functionality\n   @return  jQuery object */\n$.fn.datepicker = function(options){\n\n\t/* Verify an empty collection wasn't passed - Fixes #6976 */\n\tif ( !this.length ) {\n\t\treturn this;\n\t}\n\n\t/* Initialise the date picker. */\n\tif (!$.datepicker.initialized) {\n\t\t$(document).mousedown($.datepicker._checkExternalClick);\n\t\t$.datepicker.initialized = true;\n\t}\n\n\t/* Append datepicker main container to body if not exist. */\n\tif ($(\"#\"+$.datepicker._mainDivId).length === 0) {\n\t\t$(\"body\").append($.datepicker.dpDiv);\n\t}\n\n\tvar otherArgs = Array.prototype.slice.call(arguments, 1);\n\tif (typeof options === \"string\" && (options === \"isDisabled\" || options === \"getDate\" || options === \"widget\")) {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\tif (options === \"option\" && arguments.length === 2 && typeof arguments[1] === \"string\") {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\treturn this.each(function() {\n\t\ttypeof options === \"string\" ?\n\t\t\t$.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\t\tapply($.datepicker, [this].concat(otherArgs)) :\n\t\t\t$.datepicker._attachDatepicker(this, options);\n\t});\n};\n\n$.datepicker = new Datepicker(); // singleton instance\n$.datepicker.initialized = false;\n$.datepicker.uuid = new Date().getTime();\n$.datepicker.version = \"1.10.4\";\n\n})(jQuery);\n(function( $, undefined ) {\n\nvar sizeRelatedOptions = {\n\t\tbuttons: true,\n\t\theight: true,\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true,\n\t\twidth: true\n\t},\n\tresizableRelatedOptions = {\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true\n\t};\n\n$.widget( \"ui.dialog\", {\n\tversion: \"1.10.4\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoOpen: true,\n\t\tbuttons: [],\n\t\tcloseOnEscape: true,\n\t\tcloseText: \"close\",\n\t\tdialogClass: \"\",\n\t\tdraggable: true,\n\t\thide: null,\n\t\theight: \"auto\",\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 150,\n\t\tminWidth: 150,\n\t\tmodal: false,\n\t\tposition: {\n\t\t\tmy: \"center\",\n\t\t\tat: \"center\",\n\t\t\tof: window,\n\t\t\tcollision: \"fit\",\n\t\t\t// Ensure the titlebar is always visible\n\t\t\tusing: function( pos ) {\n\t\t\t\tvar topOffset = $( this ).css( pos ).offset().top;\n\t\t\t\tif ( topOffset < 0 ) {\n\t\t\t\t\t$( this ).css( \"top\", pos.top - topOffset );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tresizable: true,\n\t\tshow: null,\n\t\ttitle: null,\n\t\twidth: 300,\n\n\t\t// callbacks\n\t\tbeforeClose: null,\n\t\tclose: null,\n\t\tdrag: null,\n\t\tdragStart: null,\n\t\tdragStop: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresize: null,\n\t\tresizeStart: null,\n\t\tresizeStop: null\n\t},\n\n\t_create: function() {\n\t\tthis.originalCss = {\n\t\t\tdisplay: this.element[0].style.display,\n\t\t\twidth: this.element[0].style.width,\n\t\t\tminHeight: this.element[0].style.minHeight,\n\t\t\tmaxHeight: this.element[0].style.maxHeight,\n\t\t\theight: this.element[0].style.height\n\t\t};\n\t\tthis.originalPosition = {\n\t\t\tparent: this.element.parent(),\n\t\t\tindex: this.element.parent().children().index( this.element )\n\t\t};\n\t\tthis.originalTitle = this.element.attr(\"title\");\n\t\tthis.options.title = this.options.title || this.originalTitle;\n\n\t\tthis._createWrapper();\n\n\t\tthis.element\n\t\t\t.show()\n\t\t\t.removeAttr(\"title\")\n\t\t\t.addClass(\"ui-dialog-content ui-widget-content\")\n\t\t\t.appendTo( this.uiDialog );\n\n\t\tthis._createTitlebar();\n\t\tthis._createButtonPane();\n\n\t\tif ( this.options.draggable && $.fn.draggable ) {\n\t\t\tthis._makeDraggable();\n\t\t}\n\t\tif ( this.options.resizable && $.fn.resizable ) {\n\t\t\tthis._makeResizable();\n\t\t}\n\n\t\tthis._isOpen = false;\n\t},\n\n\t_init: function() {\n\t\tif ( this.options.autoOpen ) {\n\t\t\tthis.open();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\t\tif ( element && (element.jquery || element.nodeType) ) {\n\t\t\treturn $( element );\n\t\t}\n\t\treturn this.document.find( element || \"body\" ).eq( 0 );\n\t},\n\n\t_destroy: function() {\n\t\tvar next,\n\t\t\toriginalPosition = this.originalPosition;\n\n\t\tthis._destroyOverlay();\n\n\t\tthis.element\n\t\t\t.removeUniqueId()\n\t\t\t.removeClass(\"ui-dialog-content ui-widget-content\")\n\t\t\t.css( this.originalCss )\n\t\t\t// Without detaching first, the following becomes really slow\n\t\t\t.detach();\n\n\t\tthis.uiDialog.stop( true, true ).remove();\n\n\t\tif ( this.originalTitle ) {\n\t\t\tthis.element.attr( \"title\", this.originalTitle );\n\t\t}\n\n\t\tnext = originalPosition.parent.children().eq( originalPosition.index );\n\t\t// Don't try to place the dialog next to itself (#8613)\n\t\tif ( next.length && next[0] !== this.element[0] ) {\n\t\t\tnext.before( this.element );\n\t\t} else {\n\t\t\toriginalPosition.parent.append( this.element );\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.uiDialog;\n\t},\n\n\tdisable: $.noop,\n\tenable: $.noop,\n\n\tclose: function( event ) {\n\t\tvar activeElement,\n\t\t\tthat = this;\n\n\t\tif ( !this._isOpen || this._trigger( \"beforeClose\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = false;\n\t\tthis._destroyOverlay();\n\n\t\tif ( !this.opener.filter(\":focusable\").focus().length ) {\n\n\t\t\t// support: IE9\n\t\t\t// IE9 throws an \"Unspecified error\" accessing document.activeElement from an <iframe>\n\t\t\ttry {\n\t\t\t\tactiveElement = this.document[ 0 ].activeElement;\n\n\t\t\t\t// Support: IE9, IE10\n\t\t\t\t// If the <body> is blurred, IE will switch windows, see #4520\n\t\t\t\tif ( activeElement && activeElement.nodeName.toLowerCase() !== \"body\" ) {\n\n\t\t\t\t\t// Hiding a focused element doesn't trigger blur in WebKit\n\t\t\t\t\t// so in case we have nothing to focus on, explicitly blur the active element\n\t\t\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=47182\n\t\t\t\t\t$( activeElement ).blur();\n\t\t\t\t}\n\t\t\t} catch ( error ) {}\n\t\t}\n\n\t\tthis._hide( this.uiDialog, this.options.hide, function() {\n\t\t\tthat._trigger( \"close\", event );\n\t\t});\n\t},\n\n\tisOpen: function() {\n\t\treturn this._isOpen;\n\t},\n\n\tmoveToTop: function() {\n\t\tthis._moveToTop();\n\t},\n\n\t_moveToTop: function( event, silent ) {\n\t\tvar moved = !!this.uiDialog.nextAll(\":visible\").insertBefore( this.uiDialog ).length;\n\t\tif ( moved && !silent ) {\n\t\t\tthis._trigger( \"focus\", event );\n\t\t}\n\t\treturn moved;\n\t},\n\n\topen: function() {\n\t\tvar that = this;\n\t\tif ( this._isOpen ) {\n\t\t\tif ( this._moveToTop() ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = true;\n\t\tthis.opener = $( this.document[0].activeElement );\n\n\t\tthis._size();\n\t\tthis._position();\n\t\tthis._createOverlay();\n\t\tthis._moveToTop( null, true );\n\t\tthis._show( this.uiDialog, this.options.show, function() {\n\t\t\tthat._focusTabbable();\n\t\t\tthat._trigger(\"focus\");\n\t\t});\n\n\t\tthis._trigger(\"open\");\n\t},\n\n\t_focusTabbable: function() {\n\t\t// Set focus to the first match:\n\t\t// 1. First element inside the dialog matching [autofocus]\n\t\t// 2. Tabbable element inside the content element\n\t\t// 3. Tabbable element inside the buttonpane\n\t\t// 4. The close button\n\t\t// 5. The dialog itself\n\t\tvar hasFocus = this.element.find(\"[autofocus]\");\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.element.find(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogButtonPane.find(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogTitlebarClose.filter(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialog;\n\t\t}\n\t\thasFocus.eq( 0 ).focus();\n\t},\n\n\t_keepFocus: function( event ) {\n\t\tfunction checkFocus() {\n\t\t\tvar activeElement = this.document[0].activeElement,\n\t\t\t\tisActive = this.uiDialog[0] === activeElement ||\n\t\t\t\t\t$.contains( this.uiDialog[0], activeElement );\n\t\t\tif ( !isActive ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t}\n\t\tevent.preventDefault();\n\t\tcheckFocus.call( this );\n\t\t// support: IE\n\t\t// IE <= 8 doesn't prevent moving focus even with event.preventDefault()\n\t\t// so we check again later\n\t\tthis._delay( checkFocus );\n\t},\n\n\t_createWrapper: function() {\n\t\tthis.uiDialog = $(\"<div>\")\n\t\t\t.addClass( \"ui-dialog ui-widget ui-widget-content ui-corner-all ui-front \" +\n\t\t\t\tthis.options.dialogClass )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t// Setting tabIndex makes the div focusable\n\t\t\t\ttabIndex: -1,\n\t\t\t\trole: \"dialog\"\n\t\t\t})\n\t\t\t.appendTo( this._appendTo() );\n\n\t\tthis._on( this.uiDialog, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\tif ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&\n\t\t\t\t\t\tevent.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tthis.close( event );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// prevent tabbing out of dialogs\n\t\t\t\tif ( event.keyCode !== $.ui.keyCode.TAB ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar tabbables = this.uiDialog.find(\":tabbable\"),\n\t\t\t\t\tfirst = tabbables.filter(\":first\"),\n\t\t\t\t\tlast  = tabbables.filter(\":last\");\n\n\t\t\t\tif ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {\n\t\t\t\t\tfirst.focus( 1 );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {\n\t\t\t\t\tlast.focus( 1 );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t},\n\t\t\tmousedown: function( event ) {\n\t\t\t\tif ( this._moveToTop( event ) ) {\n\t\t\t\t\tthis._focusTabbable();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// We assume that any existing aria-describedby attribute means\n\t\t// that the dialog content is marked up properly\n\t\t// otherwise we brute force the content as the description\n\t\tif ( !this.element.find(\"[aria-describedby]\").length ) {\n\t\t\tthis.uiDialog.attr({\n\t\t\t\t\"aria-describedby\": this.element.uniqueId().attr(\"id\")\n\t\t\t});\n\t\t}\n\t},\n\n\t_createTitlebar: function() {\n\t\tvar uiDialogTitle;\n\n\t\tthis.uiDialogTitlebar = $(\"<div>\")\n\t\t\t.addClass(\"ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix\")\n\t\t\t.prependTo( this.uiDialog );\n\t\tthis._on( this.uiDialogTitlebar, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// Don't prevent click on close button (#8838)\n\t\t\t\t// Focusing a dialog that is partially scrolled out of view\n\t\t\t\t// causes the browser to scroll it into view, preventing the click event\n\t\t\t\tif ( !$( event.target ).closest(\".ui-dialog-titlebar-close\") ) {\n\t\t\t\t\t// Dialog isn't getting focus when dragging (#8063)\n\t\t\t\t\tthis.uiDialog.focus();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// support: IE\n\t\t// Use type=\"button\" to prevent enter keypresses in textboxes from closing the\n\t\t// dialog in IE (#9312)\n\t\tthis.uiDialogTitlebarClose = $( \"<button type='button'></button>\" )\n\t\t\t.button({\n\t\t\t\tlabel: this.options.closeText,\n\t\t\t\ticons: {\n\t\t\t\t\tprimary: \"ui-icon-closethick\"\n\t\t\t\t},\n\t\t\t\ttext: false\n\t\t\t})\n\t\t\t.addClass(\"ui-dialog-titlebar-close\")\n\t\t\t.appendTo( this.uiDialogTitlebar );\n\t\tthis._on( this.uiDialogTitlebarClose, {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.close( event );\n\t\t\t}\n\t\t});\n\n\t\tuiDialogTitle = $(\"<span>\")\n\t\t\t.uniqueId()\n\t\t\t.addClass(\"ui-dialog-title\")\n\t\t\t.prependTo( this.uiDialogTitlebar );\n\t\tthis._title( uiDialogTitle );\n\n\t\tthis.uiDialog.attr({\n\t\t\t\"aria-labelledby\": uiDialogTitle.attr(\"id\")\n\t\t});\n\t},\n\n\t_title: function( title ) {\n\t\tif ( !this.options.title ) {\n\t\t\ttitle.html(\"&#160;\");\n\t\t}\n\t\ttitle.text( this.options.title );\n\t},\n\n\t_createButtonPane: function() {\n\t\tthis.uiDialogButtonPane = $(\"<div>\")\n\t\t\t.addClass(\"ui-dialog-buttonpane ui-widget-content ui-helper-clearfix\");\n\n\t\tthis.uiButtonSet = $(\"<div>\")\n\t\t\t.addClass(\"ui-dialog-buttonset\")\n\t\t\t.appendTo( this.uiDialogButtonPane );\n\n\t\tthis._createButtons();\n\t},\n\n\t_createButtons: function() {\n\t\tvar that = this,\n\t\t\tbuttons = this.options.buttons;\n\n\t\t// if we already have a button pane, remove it\n\t\tthis.uiDialogButtonPane.remove();\n\t\tthis.uiButtonSet.empty();\n\n\t\tif ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {\n\t\t\tthis.uiDialog.removeClass(\"ui-dialog-buttons\");\n\t\t\treturn;\n\t\t}\n\n\t\t$.each( buttons, function( name, props ) {\n\t\t\tvar click, buttonOptions;\n\t\t\tprops = $.isFunction( props ) ?\n\t\t\t\t{ click: props, text: name } :\n\t\t\t\tprops;\n\t\t\t// Default to a non-submitting button\n\t\t\tprops = $.extend( { type: \"button\" }, props );\n\t\t\t// Change the context for the click callback to be the main element\n\t\t\tclick = props.click;\n\t\t\tprops.click = function() {\n\t\t\t\tclick.apply( that.element[0], arguments );\n\t\t\t};\n\t\t\tbuttonOptions = {\n\t\t\t\ticons: props.icons,\n\t\t\t\ttext: props.showText\n\t\t\t};\n\t\t\tdelete props.icons;\n\t\t\tdelete props.showText;\n\t\t\t$( \"<button></button>\", props )\n\t\t\t\t.button( buttonOptions )\n\t\t\t\t.appendTo( that.uiButtonSet );\n\t\t});\n\t\tthis.uiDialog.addClass(\"ui-dialog-buttons\");\n\t\tthis.uiDialogButtonPane.appendTo( this.uiDialog );\n\t},\n\n\t_makeDraggable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\tposition: ui.position,\n\t\t\t\toffset: ui.offset\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.draggable({\n\t\t\tcancel: \".ui-dialog-content, .ui-dialog-titlebar-close\",\n\t\t\thandle: \".ui-dialog-titlebar\",\n\t\t\tcontainment: \"document\",\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass(\"ui-dialog-dragging\");\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"dragStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tdrag: function( event, ui ) {\n\t\t\t\tthat._trigger( \"drag\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\toptions.position = [\n\t\t\t\t\tui.position.left - that.document.scrollLeft(),\n\t\t\t\t\tui.position.top - that.document.scrollTop()\n\t\t\t\t];\n\t\t\t\t$( this ).removeClass(\"ui-dialog-dragging\");\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"dragStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t});\n\t},\n\n\t_makeResizable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\thandles = options.resizable,\n\t\t\t// .ui-resizable has position: relative defined in the stylesheet\n\t\t\t// but dialogs have to use absolute or fixed positioning\n\t\t\tposition = this.uiDialog.css(\"position\"),\n\t\t\tresizeHandles = typeof handles === \"string\" ?\n\t\t\t\thandles\t:\n\t\t\t\t\"n,e,s,w,se,sw,ne,nw\";\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\toriginalPosition: ui.originalPosition,\n\t\t\t\toriginalSize: ui.originalSize,\n\t\t\t\tposition: ui.position,\n\t\t\t\tsize: ui.size\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.resizable({\n\t\t\tcancel: \".ui-dialog-content\",\n\t\t\tcontainment: \"document\",\n\t\t\talsoResize: this.element,\n\t\t\tmaxWidth: options.maxWidth,\n\t\t\tmaxHeight: options.maxHeight,\n\t\t\tminWidth: options.minWidth,\n\t\t\tminHeight: this._minHeight(),\n\t\t\thandles: resizeHandles,\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass(\"ui-dialog-resizing\");\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"resizeStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tresize: function( event, ui ) {\n\t\t\t\tthat._trigger( \"resize\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\toptions.height = $( this ).height();\n\t\t\t\toptions.width = $( this ).width();\n\t\t\t\t$( this ).removeClass(\"ui-dialog-resizing\");\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"resizeStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t})\n\t\t.css( \"position\", position );\n\t},\n\n\t_minHeight: function() {\n\t\tvar options = this.options;\n\n\t\treturn options.height === \"auto\" ?\n\t\t\toptions.minHeight :\n\t\t\tMath.min( options.minHeight, options.height );\n\t},\n\n\t_position: function() {\n\t\t// Need to show the dialog to get the actual offset in the position plugin\n\t\tvar isVisible = this.uiDialog.is(\":visible\");\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.show();\n\t\t}\n\t\tthis.uiDialog.position( this.options.position );\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.hide();\n\t\t}\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar that = this,\n\t\t\tresize = false,\n\t\t\tresizableOptions = {};\n\n\t\t$.each( options, function( key, value ) {\n\t\t\tthat._setOption( key, value );\n\n\t\t\tif ( key in sizeRelatedOptions ) {\n\t\t\t\tresize = true;\n\t\t\t}\n\t\t\tif ( key in resizableRelatedOptions ) {\n\t\t\t\tresizableOptions[ key ] = value;\n\t\t\t}\n\t\t});\n\n\t\tif ( resize ) {\n\t\t\tthis._size();\n\t\t\tthis._position();\n\t\t}\n\t\tif ( this.uiDialog.is(\":data(ui-resizable)\") ) {\n\t\t\tthis.uiDialog.resizable( \"option\", resizableOptions );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar isDraggable, isResizable,\n\t\t\tuiDialog = this.uiDialog;\n\n\t\tif ( key === \"dialogClass\" ) {\n\t\t\tuiDialog\n\t\t\t\t.removeClass( this.options.dialogClass )\n\t\t\t\t.addClass( value );\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.uiDialog.appendTo( this._appendTo() );\n\t\t}\n\n\t\tif ( key === \"buttons\" ) {\n\t\t\tthis._createButtons();\n\t\t}\n\n\t\tif ( key === \"closeText\" ) {\n\t\t\tthis.uiDialogTitlebarClose.button({\n\t\t\t\t// Ensure that we always pass a string\n\t\t\t\tlabel: \"\" + value\n\t\t\t});\n\t\t}\n\n\t\tif ( key === \"draggable\" ) {\n\t\t\tisDraggable = uiDialog.is(\":data(ui-draggable)\");\n\t\t\tif ( isDraggable && !value ) {\n\t\t\t\tuiDialog.draggable(\"destroy\");\n\t\t\t}\n\n\t\t\tif ( !isDraggable && value ) {\n\t\t\t\tthis._makeDraggable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"position\" ) {\n\t\t\tthis._position();\n\t\t}\n\n\t\tif ( key === \"resizable\" ) {\n\t\t\t// currently resizable, becoming non-resizable\n\t\t\tisResizable = uiDialog.is(\":data(ui-resizable)\");\n\t\t\tif ( isResizable && !value ) {\n\t\t\t\tuiDialog.resizable(\"destroy\");\n\t\t\t}\n\n\t\t\t// currently resizable, changing handles\n\t\t\tif ( isResizable && typeof value === \"string\" ) {\n\t\t\t\tuiDialog.resizable( \"option\", \"handles\", value );\n\t\t\t}\n\n\t\t\t// currently non-resizable, becoming resizable\n\t\t\tif ( !isResizable && value !== false ) {\n\t\t\t\tthis._makeResizable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"title\" ) {\n\t\t\tthis._title( this.uiDialogTitlebar.find(\".ui-dialog-title\") );\n\t\t}\n\t},\n\n\t_size: function() {\n\t\t// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content\n\t\t// divs will both have width and height set, so we need to reset them\n\t\tvar nonContentHeight, minContentHeight, maxContentHeight,\n\t\t\toptions = this.options;\n\n\t\t// Reset content sizing\n\t\tthis.element.show().css({\n\t\t\twidth: \"auto\",\n\t\t\tminHeight: 0,\n\t\t\tmaxHeight: \"none\",\n\t\t\theight: 0\n\t\t});\n\n\t\tif ( options.minWidth > options.width ) {\n\t\t\toptions.width = options.minWidth;\n\t\t}\n\n\t\t// reset wrapper sizing\n\t\t// determine the height of all the non-content elements\n\t\tnonContentHeight = this.uiDialog.css({\n\t\t\t\theight: \"auto\",\n\t\t\t\twidth: options.width\n\t\t\t})\n\t\t\t.outerHeight();\n\t\tminContentHeight = Math.max( 0, options.minHeight - nonContentHeight );\n\t\tmaxContentHeight = typeof options.maxHeight === \"number\" ?\n\t\t\tMath.max( 0, options.maxHeight - nonContentHeight ) :\n\t\t\t\"none\";\n\n\t\tif ( options.height === \"auto\" ) {\n\t\t\tthis.element.css({\n\t\t\t\tminHeight: minContentHeight,\n\t\t\t\tmaxHeight: maxContentHeight,\n\t\t\t\theight: \"auto\"\n\t\t\t});\n\t\t} else {\n\t\t\tthis.element.height( Math.max( 0, options.height - nonContentHeight ) );\n\t\t}\n\n\t\tif (this.uiDialog.is(\":data(ui-resizable)\") ) {\n\t\t\tthis.uiDialog.resizable( \"option\", \"minHeight\", this._minHeight() );\n\t\t}\n\t},\n\n\t_blockFrames: function() {\n\t\tthis.iframeBlocks = this.document.find( \"iframe\" ).map(function() {\n\t\t\tvar iframe = $( this );\n\n\t\t\treturn $( \"<div>\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\twidth: iframe.outerWidth(),\n\t\t\t\t\theight: iframe.outerHeight()\n\t\t\t\t})\n\t\t\t\t.appendTo( iframe.parent() )\n\t\t\t\t.offset( iframe.offset() )[0];\n\t\t});\n\t},\n\n\t_unblockFrames: function() {\n\t\tif ( this.iframeBlocks ) {\n\t\t\tthis.iframeBlocks.remove();\n\t\t\tdelete this.iframeBlocks;\n\t\t}\n\t},\n\n\t_allowInteraction: function( event ) {\n\t\tif ( $( event.target ).closest(\".ui-dialog\").length ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: Remove hack when datepicker implements\n\t\t// the .ui-front logic (#8989)\n\t\treturn !!$( event.target ).closest(\".ui-datepicker\").length;\n\t},\n\n\t_createOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar that = this,\n\t\t\twidgetFullName = this.widgetFullName;\n\t\tif ( !$.ui.dialog.overlayInstances ) {\n\t\t\t// Prevent use of anchors and inputs.\n\t\t\t// We use a delay in case the overlay is created from an\n\t\t\t// event that we're going to be cancelling. (#2804)\n\t\t\tthis._delay(function() {\n\t\t\t\t// Handle .dialog().dialog(\"close\") (#4065)\n\t\t\t\tif ( $.ui.dialog.overlayInstances ) {\n\t\t\t\t\tthis.document.bind( \"focusin.dialog\", function( event ) {\n\t\t\t\t\t\tif ( !that._allowInteraction( event ) ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t$(\".ui-dialog:visible:last .ui-dialog-content\")\n\t\t\t\t\t\t\t\t.data( widgetFullName )._focusTabbable();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.overlay = $(\"<div>\")\n\t\t\t.addClass(\"ui-widget-overlay ui-front\")\n\t\t\t.appendTo( this._appendTo() );\n\t\tthis._on( this.overlay, {\n\t\t\tmousedown: \"_keepFocus\"\n\t\t});\n\t\t$.ui.dialog.overlayInstances++;\n\t},\n\n\t_destroyOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.overlay ) {\n\t\t\t$.ui.dialog.overlayInstances--;\n\n\t\t\tif ( !$.ui.dialog.overlayInstances ) {\n\t\t\t\tthis.document.unbind( \"focusin.dialog\" );\n\t\t\t}\n\t\t\tthis.overlay.remove();\n\t\t\tthis.overlay = null;\n\t\t}\n\t}\n});\n\n$.ui.dialog.overlayInstances = 0;\n\n// DEPRECATED\nif ( $.uiBackCompat !== false ) {\n\t// position option with array notation\n\t// just override with old implementation\n\t$.widget( \"ui.dialog\", $.ui.dialog, {\n\t\t_position: function() {\n\t\t\tvar position = this.options.position,\n\t\t\t\tmyAt = [],\n\t\t\t\toffset = [ 0, 0 ],\n\t\t\t\tisVisible;\n\n\t\t\tif ( position ) {\n\t\t\t\tif ( typeof position === \"string\" || (typeof position === \"object\" && \"0\" in position ) ) {\n\t\t\t\t\tmyAt = position.split ? position.split(\" \") : [ position[0], position[1] ];\n\t\t\t\t\tif ( myAt.length === 1 ) {\n\t\t\t\t\t\tmyAt[1] = myAt[0];\n\t\t\t\t\t}\n\n\t\t\t\t\t$.each( [ \"left\", \"top\" ], function( i, offsetPosition ) {\n\t\t\t\t\t\tif ( +myAt[ i ] === myAt[ i ] ) {\n\t\t\t\t\t\t\toffset[ i ] = myAt[ i ];\n\t\t\t\t\t\t\tmyAt[ i ] = offsetPosition;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tposition = {\n\t\t\t\t\t\tmy: myAt[0] + (offset[0] < 0 ? offset[0] : \"+\" + offset[0]) + \" \" +\n\t\t\t\t\t\t\tmyAt[1] + (offset[1] < 0 ? offset[1] : \"+\" + offset[1]),\n\t\t\t\t\t\tat: myAt.join(\" \")\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tposition = $.extend( {}, $.ui.dialog.prototype.options.position, position );\n\t\t\t} else {\n\t\t\t\tposition = $.ui.dialog.prototype.options.position;\n\t\t\t}\n\n\t\t\t// need to show the dialog to get the actual offset in the position plugin\n\t\t\tisVisible = this.uiDialog.is(\":visible\");\n\t\t\tif ( !isVisible ) {\n\t\t\t\tthis.uiDialog.show();\n\t\t\t}\n\t\t\tthis.uiDialog.position( position );\n\t\t\tif ( !isVisible ) {\n\t\t\t\tthis.uiDialog.hide();\n\t\t\t}\n\t\t}\n\t});\n}\n\n}( jQuery ) );\n(function( $, undefined ) {\n\n$.widget(\"ui.draggable\", $.ui.mouse, {\n\tversion: \"1.10.4\",\n\twidgetEventPrefix: \"drag\",\n\toptions: {\n\t\taddClasses: true,\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectToSortable: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\tiframeFix: false,\n\t\topacity: false,\n\t\trefreshPositions: false,\n\t\trevert: false,\n\t\trevertDuration: 500,\n\t\tscope: \"default\",\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tsnap: false,\n\t\tsnapMode: \"both\",\n\t\tsnapTolerance: 20,\n\t\tstack: false,\n\t\tzIndex: false,\n\n\t\t// callbacks\n\t\tdrag: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\t_create: function() {\n\n\t\tif (this.options.helper === \"original\" && !(/^(?:r|a|f)/).test(this.element.css(\"position\"))) {\n\t\t\tthis.element[0].style.position = \"relative\";\n\t\t}\n\t\tif (this.options.addClasses){\n\t\t\tthis.element.addClass(\"ui-draggable\");\n\t\t}\n\t\tif (this.options.disabled){\n\t\t\tthis.element.addClass(\"ui-draggable-disabled\");\n\t\t}\n\n\t\tthis._mouseInit();\n\n\t},\n\n\t_destroy: function() {\n\t\tthis.element.removeClass( \"ui-draggable ui-draggable-dragging ui-draggable-disabled\" );\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function(event) {\n\n\t\tvar o = this.options;\n\n\t\t// among others, prevent a drag on a resizable-handle\n\t\tif (this.helper || o.disabled || $(event.target).closest(\".ui-resizable-handle\").length > 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\t//Quit if we're not on a valid handle\n\t\tthis.handle = this._getHandle(event);\n\t\tif (!this.handle) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$(o.iframeFix === true ? \"iframe\" : o.iframeFix).each(function() {\n\t\t\t$(\"<div class='ui-draggable-iframeFix' style='background: #fff;'></div>\")\n\t\t\t.css({\n\t\t\t\twidth: this.offsetWidth+\"px\", height: this.offsetHeight+\"px\",\n\t\t\t\tposition: \"absolute\", opacity: \"0.001\", zIndex: 1000\n\t\t\t})\n\t\t\t.css($(this).offset())\n\t\t\t.appendTo(\"body\");\n\t\t});\n\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar o = this.options;\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\tthis.helper.addClass(\"ui-draggable-dragging\");\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//If ddmanager is used for droppables, set the global draggable\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it's the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Store the helper's css position\n\t\tthis.cssPosition = this.helper.css( \"position\" );\n\t\tthis.scrollParent = this.helper.scrollParent();\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tthis.offsetParentCssPosition = this.offsetParent.css( \"position\" );\n\n\t\t//The element's absolute position on the page minus margins\n\t\tthis.offset = this.positionAbs = this.element.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t//Reset scroll cache\n\t\tthis.offset.scroll = false;\n\n\t\t$.extend(this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper\n\t\t});\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this.position = this._generatePosition(event);\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Set a containment if given in the options\n\t\tthis._setContainment();\n\n\t\t//Trigger event + callbacks\n\t\tif(this._trigger(\"start\", event) === false) {\n\t\t\tthis._clear();\n\t\t\treturn false;\n\t\t}\n\n\t\t//Recache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//Prepare the droppable offsets\n\t\tif ($.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\n\t\tthis._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)\n\t\tif ( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStart(this, event);\n\t\t}\n\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function(event, noPropagation) {\n\t\t// reset any necessary cached properties (see #5009)\n\t\tif ( this.offsetParentCssPosition === \"fixed\" ) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition(event);\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Call plugins and callbacks and use the resulting position if something is returned\n\t\tif (!noPropagation) {\n\t\t\tvar ui = this._uiHash();\n\t\t\tif(this._trigger(\"drag\", event, ui) === false) {\n\t\t\t\tthis._mouseUp({});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.position = ui.position;\n\t\t}\n\n\t\tif(!this.options.axis || this.options.axis !== \"y\") {\n\t\t\tthis.helper[0].style.left = this.position.left+\"px\";\n\t\t}\n\t\tif(!this.options.axis || this.options.axis !== \"x\") {\n\t\t\tthis.helper[0].style.top = this.position.top+\"px\";\n\t\t}\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tvar that = this,\n\t\t\tdropped = false;\n\t\tif ($.ui.ddmanager && !this.options.dropBehaviour) {\n\t\t\tdropped = $.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\t//if a drop comes from outside (a sortable)\n\t\tif(this.dropped) {\n\t\t\tdropped = this.dropped;\n\t\t\tthis.dropped = false;\n\t\t}\n\n\t\t//if the original element is no longer in the DOM don't bother to continue (see #8269)\n\t\tif ( this.options.helper === \"original\" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif((this.options.revert === \"invalid\" && !dropped) || (this.options.revert === \"valid\" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {\n\t\t\t$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {\n\t\t\t\tif(that._trigger(\"stop\", event) !== false) {\n\t\t\t\t\tthat._clear();\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tif(this._trigger(\"stop\", event) !== false) {\n\t\t\t\tthis._clear();\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseUp: function(event) {\n\t\t//Remove frame helpers\n\t\t$(\"div.ui-draggable-iframeFix\").each(function() {\n\t\t\tthis.parentNode.removeChild(this);\n\t\t});\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)\n\t\tif( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStop(this, event);\n\t\t}\n\n\t\treturn $.ui.mouse.prototype._mouseUp.call(this, event);\n\t},\n\n\tcancel: function() {\n\n\t\tif(this.helper.is(\".ui-draggable-dragging\")) {\n\t\t\tthis._mouseUp({});\n\t\t} else {\n\t\t\tthis._clear();\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\t_getHandle: function(event) {\n\t\treturn this.options.handle ?\n\t\t\t!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :\n\t\t\ttrue;\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === \"clone\" ? this.element.clone().removeAttr(\"id\") : this.element);\n\n\t\tif(!helper.parents(\"body\").length) {\n\t\t\thelper.appendTo((o.appendTo === \"parent\" ? this.element[0].parentNode : o.appendTo));\n\t\t}\n\n\t\tif(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css(\"position\"))) {\n\t\t\thelper.css(\"position\", \"absolute\");\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = {left: +obj[0], top: +obj[1] || 0};\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\t\t//Get the offsetParent and cache its position\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that\n\t\t//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif(this.cssPosition === \"absolute\" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t//This needs to be actually done for all browsers, since pageX/pageY includes this information\n\t\t//Ugly IE fix\n\t\tif((this.offsetParent[0] === document.body) ||\n\t\t\t(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === \"html\" && $.ui.ie)) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"),10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"),10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif(this.cssPosition === \"relative\") {\n\t\t\tvar p = this.element.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - (parseInt(this.helper.css(\"top\"),10) || 0) + this.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - (parseInt(this.helper.css(\"left\"),10) || 0) + this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.element.css(\"marginLeft\"),10) || 0),\n\t\t\ttop: (parseInt(this.element.css(\"marginTop\"),10) || 0),\n\t\t\tright: (parseInt(this.element.css(\"marginRight\"),10) || 0),\n\t\t\tbottom: (parseInt(this.element.css(\"marginBottom\"),10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar over, c, ce,\n\t\t\to = this.options;\n\n\t\tif ( !o.containment ) {\n\t\t\tthis.containment = null;\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"window\" ) {\n\t\t\tthis.containment = [\n\t\t\t\t$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\t$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"document\") {\n\t\t\tthis.containment = [\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t$( document ).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment.constructor === Array ) {\n\t\t\tthis.containment = o.containment;\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"parent\" ) {\n\t\t\to.containment = this.helper[ 0 ].parentNode;\n\t\t}\n\n\t\tc = $( o.containment );\n\t\tce = c[ 0 ];\n\n\t\tif( !ce ) {\n\t\t\treturn;\n\t\t}\n\n\t\tover = c.css( \"overflow\" ) !== \"hidden\";\n\n\t\tthis.containment = [\n\t\t\t( parseInt( c.css( \"borderLeftWidth\" ), 10 ) || 0 ) + ( parseInt( c.css( \"paddingLeft\" ), 10 ) || 0 ),\n\t\t\t( parseInt( c.css( \"borderTopWidth\" ), 10 ) || 0 ) + ( parseInt( c.css( \"paddingTop\" ), 10 ) || 0 ) ,\n\t\t\t( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( \"borderRightWidth\" ), 10 ) || 0 ) - ( parseInt( c.css( \"paddingRight\" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,\n\t\t\t( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( \"borderBottomWidth\" ), 10 ) || 0 ) - ( parseInt( c.css( \"paddingBottom\" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom\n\t\t];\n\t\tthis.relative_container = c;\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif(!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;\n\n\t\t//Cache the scroll\n\t\tif (!this.offset.scroll) {\n\t\t\tthis.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function(event) {\n\n\t\tvar containment, co, top, left,\n\t\t\to = this.options,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY;\n\n\t\t//Cache the scroll\n\t\tif (!this.offset.scroll) {\n\t\t\tthis.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\t// If we are not dragging yet, we won't check for options\n\t\tif ( this.originalPosition ) {\n\t\t\tif ( this.containment ) {\n\t\t\t\tif ( this.relative_container ){\n\t\t\t\t\tco = this.relative_container.offset();\n\t\t\t\t\tcontainment = [\n\t\t\t\t\t\tthis.containment[ 0 ] + co.left,\n\t\t\t\t\t\tthis.containment[ 1 ] + co.top,\n\t\t\t\t\t\tthis.containment[ 2 ] + co.left,\n\t\t\t\t\t\tthis.containment[ 3 ] + co.top\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tcontainment = this.containment;\n\t\t\t\t}\n\n\t\t\t\tif(event.pageX - this.offset.click.left < containment[0]) {\n\t\t\t\t\tpageX = containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top < containment[1]) {\n\t\t\t\t\tpageY = containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif(event.pageX - this.offset.click.left > containment[2]) {\n\t\t\t\t\tpageX = containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top > containment[3]) {\n\t\t\t\t\tpageY = containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(o.grid) {\n\t\t\t\t//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)\n\t\t\t\ttop = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;\n\t\t\t\tpageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;\n\t\t\t\tpageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top\t-\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_clear: function() {\n\t\tthis.helper.removeClass(\"ui-draggable-dragging\");\n\t\tif(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {\n\t\t\tthis.helper.remove();\n\t\t}\n\t\tthis.helper = null;\n\t\tthis.cancelHelperRemoval = false;\n\t},\n\n\t// From now on bulk stuff - mainly helpers\n\n\t_trigger: function(type, event, ui) {\n\t\tui = ui || this._uiHash();\n\t\t$.ui.plugin.call(this, type, [event, ui]);\n\t\t//The absolute position has to be recalculated after plugins\n\t\tif(type === \"drag\") {\n\t\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\t\t}\n\t\treturn $.Widget.prototype._trigger.call(this, type, event, ui);\n\t},\n\n\tplugins: {},\n\n\t_uiHash: function() {\n\t\treturn {\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\toriginalPosition: this.originalPosition,\n\t\t\toffset: this.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.plugin.add(\"draggable\", \"connectToSortable\", {\n\tstart: function(event, ui) {\n\n\t\tvar inst = $(this).data(\"ui-draggable\"), o = inst.options,\n\t\t\tuiSortable = $.extend({}, ui, { item: inst.element });\n\t\tinst.sortables = [];\n\t\t$(o.connectToSortable).each(function() {\n\t\t\tvar sortable = $.data(this, \"ui-sortable\");\n\t\t\tif (sortable && !sortable.options.disabled) {\n\t\t\t\tinst.sortables.push({\n\t\t\t\t\tinstance: sortable,\n\t\t\t\t\tshouldRevert: sortable.options.revert\n\t\t\t\t});\n\t\t\t\tsortable.refreshPositions();\t// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).\n\t\t\t\tsortable._trigger(\"activate\", event, uiSortable);\n\t\t\t}\n\t\t});\n\n\t},\n\tstop: function(event, ui) {\n\n\t\t//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper\n\t\tvar inst = $(this).data(\"ui-draggable\"),\n\t\t\tuiSortable = $.extend({}, ui, { item: inst.element });\n\n\t\t$.each(inst.sortables, function() {\n\t\t\tif(this.instance.isOver) {\n\n\t\t\t\tthis.instance.isOver = 0;\n\n\t\t\t\tinst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance\n\t\t\t\tthis.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)\n\n\t\t\t\t//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: \"valid/invalid\"\n\t\t\t\tif(this.shouldRevert) {\n\t\t\t\t\tthis.instance.options.revert = this.shouldRevert;\n\t\t\t\t}\n\n\t\t\t\t//Trigger the stop of the sortable\n\t\t\t\tthis.instance._mouseStop(event);\n\n\t\t\t\tthis.instance.options.helper = this.instance.options._helper;\n\n\t\t\t\t//If the helper has been the original item, restore properties in the sortable\n\t\t\t\tif(inst.options.helper === \"original\") {\n\t\t\t\t\tthis.instance.currentItem.css({ top: \"auto\", left: \"auto\" });\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tthis.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance\n\t\t\t\tthis.instance._trigger(\"deactivate\", event, uiSortable);\n\t\t\t}\n\n\t\t});\n\n\t},\n\tdrag: function(event, ui) {\n\n\t\tvar inst = $(this).data(\"ui-draggable\"), that = this;\n\n\t\t$.each(inst.sortables, function() {\n\n\t\t\tvar innermostIntersecting = false,\n\t\t\t\tthisSortable = this;\n\n\t\t\t//Copy over some variables to allow calling the sortable's native _intersectsWith\n\t\t\tthis.instance.positionAbs = inst.positionAbs;\n\t\t\tthis.instance.helperProportions = inst.helperProportions;\n\t\t\tthis.instance.offset.click = inst.offset.click;\n\n\t\t\tif(this.instance._intersectsWith(this.instance.containerCache)) {\n\t\t\t\tinnermostIntersecting = true;\n\t\t\t\t$.each(inst.sortables, function () {\n\t\t\t\t\tthis.instance.positionAbs = inst.positionAbs;\n\t\t\t\t\tthis.instance.helperProportions = inst.helperProportions;\n\t\t\t\t\tthis.instance.offset.click = inst.offset.click;\n\t\t\t\t\tif (this !== thisSortable &&\n\t\t\t\t\t\tthis.instance._intersectsWith(this.instance.containerCache) &&\n\t\t\t\t\t\t$.contains(thisSortable.instance.element[0], this.instance.element[0])\n\t\t\t\t\t) {\n\t\t\t\t\t\tinnermostIntersecting = false;\n\t\t\t\t\t}\n\t\t\t\t\treturn innermostIntersecting;\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tif(innermostIntersecting) {\n\t\t\t\t//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once\n\t\t\t\tif(!this.instance.isOver) {\n\n\t\t\t\t\tthis.instance.isOver = 1;\n\t\t\t\t\t//Now we fake the start of dragging for the sortable instance,\n\t\t\t\t\t//by cloning the list group item, appending it to the sortable and using it as inst.currentItem\n\t\t\t\t\t//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)\n\t\t\t\t\tthis.instance.currentItem = $(that).clone().removeAttr(\"id\").appendTo(this.instance.element).data(\"ui-sortable-item\", true);\n\t\t\t\t\tthis.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it\n\t\t\t\t\tthis.instance.options.helper = function() { return ui.helper[0]; };\n\n\t\t\t\t\tevent.target = this.instance.currentItem[0];\n\t\t\t\t\tthis.instance._mouseCapture(event, true);\n\t\t\t\t\tthis.instance._mouseStart(event, true, true);\n\n\t\t\t\t\t//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes\n\t\t\t\t\tthis.instance.offset.click.top = inst.offset.click.top;\n\t\t\t\t\tthis.instance.offset.click.left = inst.offset.click.left;\n\t\t\t\t\tthis.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;\n\t\t\t\t\tthis.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;\n\n\t\t\t\t\tinst._trigger(\"toSortable\", event);\n\t\t\t\t\tinst.dropped = this.instance.element; //draggable revert needs that\n\t\t\t\t\t//hack so receive/update callbacks work (mostly)\n\t\t\t\t\tinst.currentItem = inst.element;\n\t\t\t\t\tthis.instance.fromOutside = inst;\n\n\t\t\t\t}\n\n\t\t\t\t//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable\n\t\t\t\tif(this.instance.currentItem) {\n\t\t\t\t\tthis.instance._mouseDrag(event);\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t//If it doesn't intersect with the sortable, and it intersected before,\n\t\t\t\t//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval\n\t\t\t\tif(this.instance.isOver) {\n\n\t\t\t\t\tthis.instance.isOver = 0;\n\t\t\t\t\tthis.instance.cancelHelperRemoval = true;\n\n\t\t\t\t\t//Prevent reverting on this forced stop\n\t\t\t\t\tthis.instance.options.revert = false;\n\n\t\t\t\t\t// The out event needs to be triggered independently\n\t\t\t\t\tthis.instance._trigger(\"out\", event, this.instance._uiHash(this.instance));\n\n\t\t\t\t\tthis.instance._mouseStop(event, true);\n\t\t\t\t\tthis.instance.options.helper = this.instance.options._helper;\n\n\t\t\t\t\t//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size\n\t\t\t\t\tthis.instance.currentItem.remove();\n\t\t\t\t\tif(this.instance.placeholder) {\n\t\t\t\t\t\tthis.instance.placeholder.remove();\n\t\t\t\t\t}\n\n\t\t\t\t\tinst._trigger(\"fromSortable\", event);\n\t\t\t\t\tinst.dropped = false; //draggable revert needs that\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t});\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"cursor\", {\n\tstart: function() {\n\t\tvar t = $(\"body\"), o = $(this).data(\"ui-draggable\").options;\n\t\tif (t.css(\"cursor\")) {\n\t\t\to._cursor = t.css(\"cursor\");\n\t\t}\n\t\tt.css(\"cursor\", o.cursor);\n\t},\n\tstop: function() {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif (o._cursor) {\n\t\t\t$(\"body\").css(\"cursor\", o._cursor);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"opacity\", {\n\tstart: function(event, ui) {\n\t\tvar t = $(ui.helper), o = $(this).data(\"ui-draggable\").options;\n\t\tif(t.css(\"opacity\")) {\n\t\t\to._opacity = t.css(\"opacity\");\n\t\t}\n\t\tt.css(\"opacity\", o.opacity);\n\t},\n\tstop: function(event, ui) {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif(o._opacity) {\n\t\t\t$(ui.helper).css(\"opacity\", o._opacity);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"scroll\", {\n\tstart: function() {\n\t\tvar i = $(this).data(\"ui-draggable\");\n\t\tif(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== \"HTML\") {\n\t\t\ti.overflowOffset = i.scrollParent.offset();\n\t\t}\n\t},\n\tdrag: function( event ) {\n\n\t\tvar i = $(this).data(\"ui-draggable\"), o = i.options, scrolled = false;\n\n\t\tif(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== \"HTML\") {\n\n\t\t\tif(!o.axis || o.axis !== \"x\") {\n\t\t\t\tif((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!o.axis || o.axis !== \"y\") {\n\t\t\t\tif((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif(!o.axis || o.axis !== \"x\") {\n\t\t\t\tif(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!o.axis || o.axis !== \"y\") {\n\t\t\t\tif(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(i, event);\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"snap\", {\n\tstart: function() {\n\n\t\tvar i = $(this).data(\"ui-draggable\"),\n\t\t\to = i.options;\n\n\t\ti.snapElements = [];\n\n\t\t$(o.snap.constructor !== String ? ( o.snap.items || \":data(ui-draggable)\" ) : o.snap).each(function() {\n\t\t\tvar $t = $(this),\n\t\t\t\t$o = $t.offset();\n\t\t\tif(this !== i.element[0]) {\n\t\t\t\ti.snapElements.push({\n\t\t\t\t\titem: this,\n\t\t\t\t\twidth: $t.outerWidth(), height: $t.outerHeight(),\n\t\t\t\t\ttop: $o.top, left: $o.left\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t},\n\tdrag: function(event, ui) {\n\n\t\tvar ts, bs, ls, rs, l, r, t, b, i, first,\n\t\t\tinst = $(this).data(\"ui-draggable\"),\n\t\t\to = inst.options,\n\t\t\td = o.snapTolerance,\n\t\t\tx1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,\n\t\t\ty1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;\n\n\t\tfor (i = inst.snapElements.length - 1; i >= 0; i--){\n\n\t\t\tl = inst.snapElements[i].left;\n\t\t\tr = l + inst.snapElements[i].width;\n\t\t\tt = inst.snapElements[i].top;\n\t\t\tb = t + inst.snapElements[i].height;\n\n\t\t\tif ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {\n\t\t\t\tif(inst.snapElements[i].snapping) {\n\t\t\t\t\t(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t\t}\n\t\t\t\tinst.snapElements[i].snapping = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(o.snapMode !== \"inner\") {\n\t\t\t\tts = Math.abs(t - y2) <= d;\n\t\t\t\tbs = Math.abs(b - y1) <= d;\n\t\t\t\tls = Math.abs(l - x2) <= d;\n\t\t\t\trs = Math.abs(r - x1) <= d;\n\t\t\t\tif(ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t\tif(rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfirst = (ts || bs || ls || rs);\n\n\t\t\tif(o.snapMode !== \"outer\") {\n\t\t\t\tts = Math.abs(t - y1) <= d;\n\t\t\t\tbs = Math.abs(b - y2) <= d;\n\t\t\t\tls = Math.abs(l - x1) <= d;\n\t\t\t\trs = Math.abs(r - x2) <= d;\n\t\t\t\tif(ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t\tif(rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {\n\t\t\t\t(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t}\n\t\t\tinst.snapElements[i].snapping = (ts || bs || ls || rs || first);\n\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"stack\", {\n\tstart: function() {\n\t\tvar min,\n\t\t\to = this.data(\"ui-draggable\").options,\n\t\t\tgroup = $.makeArray($(o.stack)).sort(function(a,b) {\n\t\t\t\treturn (parseInt($(a).css(\"zIndex\"),10) || 0) - (parseInt($(b).css(\"zIndex\"),10) || 0);\n\t\t\t});\n\n\t\tif (!group.length) { return; }\n\n\t\tmin = parseInt($(group[0]).css(\"zIndex\"), 10) || 0;\n\t\t$(group).each(function(i) {\n\t\t\t$(this).css(\"zIndex\", min + i);\n\t\t});\n\t\tthis.css(\"zIndex\", (min + group.length));\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"zIndex\", {\n\tstart: function(event, ui) {\n\t\tvar t = $(ui.helper), o = $(this).data(\"ui-draggable\").options;\n\t\tif(t.css(\"zIndex\")) {\n\t\t\to._zIndex = t.css(\"zIndex\");\n\t\t}\n\t\tt.css(\"zIndex\", o.zIndex);\n\t},\n\tstop: function(event, ui) {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif(o._zIndex) {\n\t\t\t$(ui.helper).css(\"zIndex\", o._zIndex);\n\t\t}\n\t}\n});\n\n})(jQuery);\n(function( $, undefined ) {\n\nfunction isOverAxis( x, reference, size ) {\n\treturn ( x > reference ) && ( x < ( reference + size ) );\n}\n\n$.widget(\"ui.droppable\", {\n\tversion: \"1.10.4\",\n\twidgetEventPrefix: \"drop\",\n\toptions: {\n\t\taccept: \"*\",\n\t\tactiveClass: false,\n\t\taddClasses: true,\n\t\tgreedy: false,\n\t\thoverClass: false,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tdeactivate: null,\n\t\tdrop: null,\n\t\tout: null,\n\t\tover: null\n\t},\n\t_create: function() {\n\n\t\tvar proportions,\n\t\t\to = this.options,\n\t\t\taccept = o.accept;\n\n\t\tthis.isover = false;\n\t\tthis.isout = true;\n\n\t\tthis.accept = $.isFunction(accept) ? accept : function(d) {\n\t\t\treturn d.is(accept);\n\t\t};\n\n\t\tthis.proportions = function( /* valueToWrite */ ) {\n\t\t\tif ( arguments.length ) {\n\t\t\t\t// Store the droppable's proportions\n\t\t\t\tproportions = arguments[ 0 ];\n\t\t\t} else {\n\t\t\t\t// Retrieve or derive the droppable's proportions\n\t\t\t\treturn proportions ?\n\t\t\t\t\tproportions :\n\t\t\t\t\tproportions = {\n\t\t\t\t\t\twidth: this.element[ 0 ].offsetWidth,\n\t\t\t\t\t\theight: this.element[ 0 ].offsetHeight\n\t\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t\t// Add the reference and positions to the manager\n\t\t$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];\n\t\t$.ui.ddmanager.droppables[o.scope].push(this);\n\n\t\t(o.addClasses && this.element.addClass(\"ui-droppable\"));\n\n\t},\n\n\t_destroy: function() {\n\t\tvar i = 0,\n\t\t\tdrop = $.ui.ddmanager.droppables[this.options.scope];\n\n\t\tfor ( ; i < drop.length; i++ ) {\n\t\t\tif ( drop[i] === this ) {\n\t\t\t\tdrop.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\tthis.element.removeClass(\"ui-droppable ui-droppable-disabled\");\n\t},\n\n\t_setOption: function(key, value) {\n\n\t\tif(key === \"accept\") {\n\t\t\tthis.accept = $.isFunction(value) ? value : function(d) {\n\t\t\t\treturn d.is(value);\n\t\t\t};\n\t\t}\n\t\t$.Widget.prototype._setOption.apply(this, arguments);\n\t},\n\n\t_activate: function(event) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif(this.options.activeClass) {\n\t\t\tthis.element.addClass(this.options.activeClass);\n\t\t}\n\t\tif(draggable){\n\t\t\tthis._trigger(\"activate\", event, this.ui(draggable));\n\t\t}\n\t},\n\n\t_deactivate: function(event) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif(this.options.activeClass) {\n\t\t\tthis.element.removeClass(this.options.activeClass);\n\t\t}\n\t\tif(draggable){\n\t\t\tthis._trigger(\"deactivate\", event, this.ui(draggable));\n\t\t}\n\t},\n\n\t_over: function(event) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.addClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"over\", event, this.ui(draggable));\n\t\t}\n\n\t},\n\n\t_out: function(event) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.removeClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"out\", event, this.ui(draggable));\n\t\t}\n\n\t},\n\n\t_drop: function(event,custom) {\n\n\t\tvar draggable = custom || $.ui.ddmanager.current,\n\t\t\tchildrenIntersection = false;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.element.find(\":data(ui-droppable)\").not(\".ui-draggable-dragging\").each(function() {\n\t\t\tvar inst = $.data(this, \"ui-droppable\");\n\t\t\tif(\n\t\t\t\tinst.options.greedy &&\n\t\t\t\t!inst.options.disabled &&\n\t\t\t\tinst.options.scope === draggable.options.scope &&\n\t\t\t\tinst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&\n\t\t\t\t$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)\n\t\t\t) { childrenIntersection = true; return false; }\n\t\t});\n\t\tif(childrenIntersection) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.activeClass) {\n\t\t\t\tthis.element.removeClass(this.options.activeClass);\n\t\t\t}\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.removeClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"drop\", event, this.ui(draggable));\n\t\t\treturn this.element;\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tui: function(c) {\n\t\treturn {\n\t\t\tdraggable: (c.currentItem || c.element),\n\t\t\thelper: c.helper,\n\t\t\tposition: c.position,\n\t\t\toffset: c.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.intersect = function(draggable, droppable, toleranceMode) {\n\n\tif (!droppable.offset) {\n\t\treturn false;\n\t}\n\n\tvar draggableLeft, draggableTop,\n\t\tx1 = (draggable.positionAbs || draggable.position.absolute).left,\n\t\ty1 = (draggable.positionAbs || draggable.position.absolute).top,\n\t\tx2 = x1 + draggable.helperProportions.width,\n\t\ty2 = y1 + draggable.helperProportions.height,\n\t\tl = droppable.offset.left,\n\t\tt = droppable.offset.top,\n\t\tr = l + droppable.proportions().width,\n\t\tb = t + droppable.proportions().height;\n\n\tswitch (toleranceMode) {\n\t\tcase \"fit\":\n\t\t\treturn (l <= x1 && x2 <= r && t <= y1 && y2 <= b);\n\t\tcase \"intersect\":\n\t\t\treturn (l < x1 + (draggable.helperProportions.width / 2) && // Right Half\n\t\t\t\tx2 - (draggable.helperProportions.width / 2) < r && // Left Half\n\t\t\t\tt < y1 + (draggable.helperProportions.height / 2) && // Bottom Half\n\t\t\t\ty2 - (draggable.helperProportions.height / 2) < b ); // Top Half\n\t\tcase \"pointer\":\n\t\t\tdraggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);\n\t\t\tdraggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);\n\t\t\treturn isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );\n\t\tcase \"touch\":\n\t\t\treturn (\n\t\t\t\t(y1 >= t && y1 <= b) ||\t// Top edge touching\n\t\t\t\t(y2 >= t && y2 <= b) ||\t// Bottom edge touching\n\t\t\t\t(y1 < t && y2 > b)\t\t// Surrounded vertically\n\t\t\t) && (\n\t\t\t\t(x1 >= l && x1 <= r) ||\t// Left edge touching\n\t\t\t\t(x2 >= l && x2 <= r) ||\t// Right edge touching\n\t\t\t\t(x1 < l && x2 > r)\t\t// Surrounded horizontally\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\n};\n\n/*\n\tThis manager tracks offsets of draggables and droppables\n*/\n$.ui.ddmanager = {\n\tcurrent: null,\n\tdroppables: { \"default\": [] },\n\tprepareOffsets: function(t, event) {\n\n\t\tvar i, j,\n\t\t\tm = $.ui.ddmanager.droppables[t.options.scope] || [],\n\t\t\ttype = event ? event.type : null, // workaround for #2317\n\t\t\tlist = (t.currentItem || t.element).find(\":data(ui-droppable)\").addBack();\n\n\t\tdroppablesLoop: for (i = 0; i < m.length; i++) {\n\n\t\t\t//No disabled and non-accepted\n\t\t\tif(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Filter out elements in the current dragged item\n\t\t\tfor (j=0; j < list.length; j++) {\n\t\t\t\tif(list[j] === m[i].element[0]) {\n\t\t\t\t\tm[i].proportions().height = 0;\n\t\t\t\t\tcontinue droppablesLoop;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tm[i].visible = m[i].element.css(\"display\") !== \"none\";\n\t\t\tif(!m[i].visible) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//Activate the droppable if used directly from draggables\n\t\t\tif(type === \"mousedown\") {\n\t\t\t\tm[i]._activate.call(m[i], event);\n\t\t\t}\n\n\t\t\tm[ i ].offset = m[ i ].element.offset();\n\t\t\tm[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });\n\n\t\t}\n\n\t},\n\tdrop: function(draggable, event) {\n\n\t\tvar dropped = false;\n\t\t// Create a copy of the droppables in case the list changes during the drop (#9116)\n\t\t$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {\n\n\t\t\tif(!this.options) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {\n\t\t\t\tdropped = this._drop.call(this, event) || dropped;\n\t\t\t}\n\n\t\t\tif (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\t\tthis.isout = true;\n\t\t\t\tthis.isover = false;\n\t\t\t\tthis._deactivate.call(this, event);\n\t\t\t}\n\n\t\t});\n\t\treturn dropped;\n\n\t},\n\tdragStart: function( draggable, event ) {\n\t\t//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)\n\t\tdraggable.element.parentsUntil( \"body\" ).bind( \"scroll.droppable\", function() {\n\t\t\tif( !draggable.options.refreshPositions ) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t\t}\n\t\t});\n\t},\n\tdrag: function(draggable, event) {\n\n\t\t//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.\n\t\tif(draggable.options.refreshPositions) {\n\t\t\t$.ui.ddmanager.prepareOffsets(draggable, event);\n\t\t}\n\n\t\t//Run through all droppables and check their positions based on specific tolerance options\n\t\t$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {\n\n\t\t\tif(this.options.disabled || this.greedyChild || !this.visible) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar parentInstance, scope, parent,\n\t\t\t\tintersects = $.ui.intersect(draggable, this, this.options.tolerance),\n\t\t\t\tc = !intersects && this.isover ? \"isout\" : (intersects && !this.isover ? \"isover\" : null);\n\t\t\tif(!c) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.options.greedy) {\n\t\t\t\t// find droppable parents with same scope\n\t\t\t\tscope = this.options.scope;\n\t\t\t\tparent = this.element.parents(\":data(ui-droppable)\").filter(function () {\n\t\t\t\t\treturn $.data(this, \"ui-droppable\").options.scope === scope;\n\t\t\t\t});\n\n\t\t\t\tif (parent.length) {\n\t\t\t\t\tparentInstance = $.data(parent[0], \"ui-droppable\");\n\t\t\t\t\tparentInstance.greedyChild = (c === \"isover\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// we just moved into a greedy child\n\t\t\tif (parentInstance && c === \"isover\") {\n\t\t\t\tparentInstance.isover = false;\n\t\t\t\tparentInstance.isout = true;\n\t\t\t\tparentInstance._out.call(parentInstance, event);\n\t\t\t}\n\n\t\t\tthis[c] = true;\n\t\t\tthis[c === \"isout\" ? \"isover\" : \"isout\"] = false;\n\t\t\tthis[c === \"isover\" ? \"_over\" : \"_out\"].call(this, event);\n\n\t\t\t// we just moved out of a greedy child\n\t\t\tif (parentInstance && c === \"isout\") {\n\t\t\t\tparentInstance.isout = false;\n\t\t\t\tparentInstance.isover = true;\n\t\t\t\tparentInstance._over.call(parentInstance, event);\n\t\t\t}\n\t\t});\n\n\t},\n\tdragStop: function( draggable, event ) {\n\t\tdraggable.element.parentsUntil( \"body\" ).unbind( \"scroll.droppable\" );\n\t\t//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)\n\t\tif( !draggable.options.refreshPositions ) {\n\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t}\n\t}\n};\n\n})(jQuery);\n(function($, undefined) {\n\nvar dataSpace = \"ui-effects-\";\n\n$.effects = {\n\teffect: {}\n};\n\n/*!\n * jQuery Color Animations v2.1.2\n * https://github.com/jquery/jquery-color\n *\n * Copyright 2013 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * Date: Wed Jan 16 08:47:09 2013 -0600\n */\n(function( jQuery, undefined ) {\n\n\tvar stepHooks = \"backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor\",\n\n\t// plusequals test for += 100 -= 100\n\trplusequals = /^([\\-+])=\\s*(\\d+\\.?\\d*)/,\n\t// a set of RE's that can match strings and generate color tuples.\n\tstringParsers = [{\n\t\t\tre: /rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ],\n\t\t\t\t\texecResult[ 3 ],\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /rgba?\\(\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ] * 2.55,\n\t\t\t\t\texecResult[ 2 ] * 2.55,\n\t\t\t\t\texecResult[ 3 ] * 2.55,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9])([a-f0-9])([a-f0-9])/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ] + execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /hsla?\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tspace: \"hsla\",\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ] / 100,\n\t\t\t\t\texecResult[ 3 ] / 100,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}],\n\n\t// jQuery.Color( )\n\tcolor = jQuery.Color = function( color, green, blue, alpha ) {\n\t\treturn new jQuery.Color.fn.parse( color, green, blue, alpha );\n\t},\n\tspaces = {\n\t\trgba: {\n\t\t\tprops: {\n\t\t\t\tred: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tgreen: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tblue: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\thsla: {\n\t\t\tprops: {\n\t\t\t\thue: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"degrees\"\n\t\t\t\t},\n\t\t\t\tsaturation: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t},\n\t\t\t\tlightness: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tpropTypes = {\n\t\t\"byte\": {\n\t\t\tfloor: true,\n\t\t\tmax: 255\n\t\t},\n\t\t\"percent\": {\n\t\t\tmax: 1\n\t\t},\n\t\t\"degrees\": {\n\t\t\tmod: 360,\n\t\t\tfloor: true\n\t\t}\n\t},\n\tsupport = color.support = {},\n\n\t// element for support tests\n\tsupportElem = jQuery( \"<p>\" )[ 0 ],\n\n\t// colors = jQuery.Color.names\n\tcolors,\n\n\t// local aliases of functions called often\n\teach = jQuery.each;\n\n// determine rgba support immediately\nsupportElem.style.cssText = \"background-color:rgba(1,1,1,.5)\";\nsupport.rgba = supportElem.style.backgroundColor.indexOf( \"rgba\" ) > -1;\n\n// define cache name and alpha properties\n// for rgba and hsla spaces\neach( spaces, function( spaceName, space ) {\n\tspace.cache = \"_\" + spaceName;\n\tspace.props.alpha = {\n\t\tidx: 3,\n\t\ttype: \"percent\",\n\t\tdef: 1\n\t};\n});\n\nfunction clamp( value, prop, allowEmpty ) {\n\tvar type = propTypes[ prop.type ] || {};\n\n\tif ( value == null ) {\n\t\treturn (allowEmpty || !prop.def) ? null : prop.def;\n\t}\n\n\t// ~~ is an short way of doing floor for positive numbers\n\tvalue = type.floor ? ~~value : parseFloat( value );\n\n\t// IE will pass in empty strings as value for alpha,\n\t// which will hit this case\n\tif ( isNaN( value ) ) {\n\t\treturn prop.def;\n\t}\n\n\tif ( type.mod ) {\n\t\t// we add mod before modding to make sure that negatives values\n\t\t// get converted properly: -10 -> 350\n\t\treturn (value + type.mod) % type.mod;\n\t}\n\n\t// for now all property types without mod have min and max\n\treturn 0 > value ? 0 : type.max < value ? type.max : value;\n}\n\nfunction stringParse( string ) {\n\tvar inst = color(),\n\t\trgba = inst._rgba = [];\n\n\tstring = string.toLowerCase();\n\n\teach( stringParsers, function( i, parser ) {\n\t\tvar parsed,\n\t\t\tmatch = parser.re.exec( string ),\n\t\t\tvalues = match && parser.parse( match ),\n\t\t\tspaceName = parser.space || \"rgba\";\n\n\t\tif ( values ) {\n\t\t\tparsed = inst[ spaceName ]( values );\n\n\t\t\t// if this was an rgba parse the assignment might happen twice\n\t\t\t// oh well....\n\t\t\tinst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];\n\t\t\trgba = inst._rgba = parsed._rgba;\n\n\t\t\t// exit each( stringParsers ) here because we matched\n\t\t\treturn false;\n\t\t}\n\t});\n\n\t// Found a stringParser that handled it\n\tif ( rgba.length ) {\n\n\t\t// if this came from a parsed string, force \"transparent\" when alpha is 0\n\t\t// chrome, (and maybe others) return \"transparent\" as rgba(0,0,0,0)\n\t\tif ( rgba.join() === \"0,0,0,0\" ) {\n\t\t\tjQuery.extend( rgba, colors.transparent );\n\t\t}\n\t\treturn inst;\n\t}\n\n\t// named colors\n\treturn colors[ string ];\n}\n\ncolor.fn = jQuery.extend( color.prototype, {\n\tparse: function( red, green, blue, alpha ) {\n\t\tif ( red === undefined ) {\n\t\t\tthis._rgba = [ null, null, null, null ];\n\t\t\treturn this;\n\t\t}\n\t\tif ( red.jquery || red.nodeType ) {\n\t\t\tred = jQuery( red ).css( green );\n\t\t\tgreen = undefined;\n\t\t}\n\n\t\tvar inst = this,\n\t\t\ttype = jQuery.type( red ),\n\t\t\trgba = this._rgba = [];\n\n\t\t// more than 1 argument specified - assume ( red, green, blue, alpha )\n\t\tif ( green !== undefined ) {\n\t\t\tred = [ red, green, blue, alpha ];\n\t\t\ttype = \"array\";\n\t\t}\n\n\t\tif ( type === \"string\" ) {\n\t\t\treturn this.parse( stringParse( red ) || colors._default );\n\t\t}\n\n\t\tif ( type === \"array\" ) {\n\t\t\teach( spaces.rgba.props, function( key, prop ) {\n\t\t\t\trgba[ prop.idx ] = clamp( red[ prop.idx ], prop );\n\t\t\t});\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( type === \"object\" ) {\n\t\t\tif ( red instanceof color ) {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tif ( red[ space.cache ] ) {\n\t\t\t\t\t\tinst[ space.cache ] = red[ space.cache ].slice();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tvar cache = space.cache;\n\t\t\t\t\teach( space.props, function( key, prop ) {\n\n\t\t\t\t\t\t// if the cache doesn't exist, and we know how to convert\n\t\t\t\t\t\tif ( !inst[ cache ] && space.to ) {\n\n\t\t\t\t\t\t\t// if the value was null, we don't need to copy it\n\t\t\t\t\t\t\t// if the key was alpha, we don't need to copy it either\n\t\t\t\t\t\t\tif ( key === \"alpha\" || red[ key ] == null ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinst[ cache ] = space.to( inst._rgba );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// this is the only case where we allow nulls for ALL properties.\n\t\t\t\t\t\t// call clamp with alwaysAllowEmpty\n\t\t\t\t\t\tinst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );\n\t\t\t\t\t});\n\n\t\t\t\t\t// everything defined but alpha?\n\t\t\t\t\tif ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {\n\t\t\t\t\t\t// use the default of 1\n\t\t\t\t\t\tinst[ cache ][ 3 ] = 1;\n\t\t\t\t\t\tif ( space.from ) {\n\t\t\t\t\t\t\tinst._rgba = space.from( inst[ cache ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t},\n\tis: function( compare ) {\n\t\tvar is = color( compare ),\n\t\t\tsame = true,\n\t\t\tinst = this;\n\n\t\teach( spaces, function( _, space ) {\n\t\t\tvar localCache,\n\t\t\t\tisCache = is[ space.cache ];\n\t\t\tif (isCache) {\n\t\t\t\tlocalCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];\n\t\t\t\teach( space.props, function( _, prop ) {\n\t\t\t\t\tif ( isCache[ prop.idx ] != null ) {\n\t\t\t\t\t\tsame = ( isCache[ prop.idx ] === localCache[ prop.idx ] );\n\t\t\t\t\t\treturn same;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn same;\n\t\t});\n\t\treturn same;\n\t},\n\t_space: function() {\n\t\tvar used = [],\n\t\t\tinst = this;\n\t\teach( spaces, function( spaceName, space ) {\n\t\t\tif ( inst[ space.cache ] ) {\n\t\t\t\tused.push( spaceName );\n\t\t\t}\n\t\t});\n\t\treturn used.pop();\n\t},\n\ttransition: function( other, distance ) {\n\t\tvar end = color( other ),\n\t\t\tspaceName = end._space(),\n\t\t\tspace = spaces[ spaceName ],\n\t\t\tstartColor = this.alpha() === 0 ? color( \"transparent\" ) : this,\n\t\t\tstart = startColor[ space.cache ] || space.to( startColor._rgba ),\n\t\t\tresult = start.slice();\n\n\t\tend = end[ space.cache ];\n\t\teach( space.props, function( key, prop ) {\n\t\t\tvar index = prop.idx,\n\t\t\t\tstartValue = start[ index ],\n\t\t\t\tendValue = end[ index ],\n\t\t\t\ttype = propTypes[ prop.type ] || {};\n\n\t\t\t// if null, don't override start value\n\t\t\tif ( endValue === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// if null - use end\n\t\t\tif ( startValue === null ) {\n\t\t\t\tresult[ index ] = endValue;\n\t\t\t} else {\n\t\t\t\tif ( type.mod ) {\n\t\t\t\t\tif ( endValue - startValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue += type.mod;\n\t\t\t\t\t} else if ( startValue - endValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue -= type.mod;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );\n\t\t\t}\n\t\t});\n\t\treturn this[ spaceName ]( result );\n\t},\n\tblend: function( opaque ) {\n\t\t// if we are already opaque - return ourself\n\t\tif ( this._rgba[ 3 ] === 1 ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar rgb = this._rgba.slice(),\n\t\t\ta = rgb.pop(),\n\t\t\tblend = color( opaque )._rgba;\n\n\t\treturn color( jQuery.map( rgb, function( v, i ) {\n\t\t\treturn ( 1 - a ) * blend[ i ] + a * v;\n\t\t}));\n\t},\n\ttoRgbaString: function() {\n\t\tvar prefix = \"rgba(\",\n\t\t\trgba = jQuery.map( this._rgba, function( v, i ) {\n\t\t\t\treturn v == null ? ( i > 2 ? 1 : 0 ) : v;\n\t\t\t});\n\n\t\tif ( rgba[ 3 ] === 1 ) {\n\t\t\trgba.pop();\n\t\t\tprefix = \"rgb(\";\n\t\t}\n\n\t\treturn prefix + rgba.join() + \")\";\n\t},\n\ttoHslaString: function() {\n\t\tvar prefix = \"hsla(\",\n\t\t\thsla = jQuery.map( this.hsla(), function( v, i ) {\n\t\t\t\tif ( v == null ) {\n\t\t\t\t\tv = i > 2 ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\t// catch 1 and 2\n\t\t\t\tif ( i && i < 3 ) {\n\t\t\t\t\tv = Math.round( v * 100 ) + \"%\";\n\t\t\t\t}\n\t\t\t\treturn v;\n\t\t\t});\n\n\t\tif ( hsla[ 3 ] === 1 ) {\n\t\t\thsla.pop();\n\t\t\tprefix = \"hsl(\";\n\t\t}\n\t\treturn prefix + hsla.join() + \")\";\n\t},\n\ttoHexString: function( includeAlpha ) {\n\t\tvar rgba = this._rgba.slice(),\n\t\t\talpha = rgba.pop();\n\n\t\tif ( includeAlpha ) {\n\t\t\trgba.push( ~~( alpha * 255 ) );\n\t\t}\n\n\t\treturn \"#\" + jQuery.map( rgba, function( v ) {\n\n\t\t\t// default to 0 when nulls exist\n\t\t\tv = ( v || 0 ).toString( 16 );\n\t\t\treturn v.length === 1 ? \"0\" + v : v;\n\t\t}).join(\"\");\n\t},\n\ttoString: function() {\n\t\treturn this._rgba[ 3 ] === 0 ? \"transparent\" : this.toRgbaString();\n\t}\n});\ncolor.fn.parse.prototype = color.fn;\n\n// hsla conversions adapted from:\n// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021\n\nfunction hue2rgb( p, q, h ) {\n\th = ( h + 1 ) % 1;\n\tif ( h * 6 < 1 ) {\n\t\treturn p + (q - p) * h * 6;\n\t}\n\tif ( h * 2 < 1) {\n\t\treturn q;\n\t}\n\tif ( h * 3 < 2 ) {\n\t\treturn p + (q - p) * ((2/3) - h) * 6;\n\t}\n\treturn p;\n}\n\nspaces.hsla.to = function ( rgba ) {\n\tif ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {\n\t\treturn [ null, null, null, rgba[ 3 ] ];\n\t}\n\tvar r = rgba[ 0 ] / 255,\n\t\tg = rgba[ 1 ] / 255,\n\t\tb = rgba[ 2 ] / 255,\n\t\ta = rgba[ 3 ],\n\t\tmax = Math.max( r, g, b ),\n\t\tmin = Math.min( r, g, b ),\n\t\tdiff = max - min,\n\t\tadd = max + min,\n\t\tl = add * 0.5,\n\t\th, s;\n\n\tif ( min === max ) {\n\t\th = 0;\n\t} else if ( r === max ) {\n\t\th = ( 60 * ( g - b ) / diff ) + 360;\n\t} else if ( g === max ) {\n\t\th = ( 60 * ( b - r ) / diff ) + 120;\n\t} else {\n\t\th = ( 60 * ( r - g ) / diff ) + 240;\n\t}\n\n\t// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%\n\t// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)\n\tif ( diff === 0 ) {\n\t\ts = 0;\n\t} else if ( l <= 0.5 ) {\n\t\ts = diff / add;\n\t} else {\n\t\ts = diff / ( 2 - add );\n\t}\n\treturn [ Math.round(h) % 360, s, l, a == null ? 1 : a ];\n};\n\nspaces.hsla.from = function ( hsla ) {\n\tif ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {\n\t\treturn [ null, null, null, hsla[ 3 ] ];\n\t}\n\tvar h = hsla[ 0 ] / 360,\n\t\ts = hsla[ 1 ],\n\t\tl = hsla[ 2 ],\n\t\ta = hsla[ 3 ],\n\t\tq = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,\n\t\tp = 2 * l - q;\n\n\treturn [\n\t\tMath.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),\n\t\ta\n\t];\n};\n\n\neach( spaces, function( spaceName, space ) {\n\tvar props = space.props,\n\t\tcache = space.cache,\n\t\tto = space.to,\n\t\tfrom = space.from;\n\n\t// makes rgba() and hsla()\n\tcolor.fn[ spaceName ] = function( value ) {\n\n\t\t// generate a cache for this space if it doesn't exist\n\t\tif ( to && !this[ cache ] ) {\n\t\t\tthis[ cache ] = to( this._rgba );\n\t\t}\n\t\tif ( value === undefined ) {\n\t\t\treturn this[ cache ].slice();\n\t\t}\n\n\t\tvar ret,\n\t\t\ttype = jQuery.type( value ),\n\t\t\tarr = ( type === \"array\" || type === \"object\" ) ? value : arguments,\n\t\t\tlocal = this[ cache ].slice();\n\n\t\teach( props, function( key, prop ) {\n\t\t\tvar val = arr[ type === \"object\" ? key : prop.idx ];\n\t\t\tif ( val == null ) {\n\t\t\t\tval = local[ prop.idx ];\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = clamp( val, prop );\n\t\t});\n\n\t\tif ( from ) {\n\t\t\tret = color( from( local ) );\n\t\t\tret[ cache ] = local;\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn color( local );\n\t\t}\n\t};\n\n\t// makes red() green() blue() alpha() hue() saturation() lightness()\n\teach( props, function( key, prop ) {\n\t\t// alpha is included in more than one space\n\t\tif ( color.fn[ key ] ) {\n\t\t\treturn;\n\t\t}\n\t\tcolor.fn[ key ] = function( value ) {\n\t\t\tvar vtype = jQuery.type( value ),\n\t\t\t\tfn = ( key === \"alpha\" ? ( this._hsla ? \"hsla\" : \"rgba\" ) : spaceName ),\n\t\t\t\tlocal = this[ fn ](),\n\t\t\t\tcur = local[ prop.idx ],\n\t\t\t\tmatch;\n\n\t\t\tif ( vtype === \"undefined\" ) {\n\t\t\t\treturn cur;\n\t\t\t}\n\n\t\t\tif ( vtype === \"function\" ) {\n\t\t\t\tvalue = value.call( this, cur );\n\t\t\t\tvtype = jQuery.type( value );\n\t\t\t}\n\t\t\tif ( value == null && prop.empty ) {\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tif ( vtype === \"string\" ) {\n\t\t\t\tmatch = rplusequals.exec( value );\n\t\t\t\tif ( match ) {\n\t\t\t\t\tvalue = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === \"+\" ? 1 : -1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = value;\n\t\t\treturn this[ fn ]( local );\n\t\t};\n\t});\n});\n\n// add cssHook and .fx.step function for each named hook.\n// accept a space separated string of properties\ncolor.hook = function( hook ) {\n\tvar hooks = hook.split( \" \" );\n\teach( hooks, function( i, hook ) {\n\t\tjQuery.cssHooks[ hook ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar parsed, curElem,\n\t\t\t\t\tbackgroundColor = \"\";\n\n\t\t\t\tif ( value !== \"transparent\" && ( jQuery.type( value ) !== \"string\" || ( parsed = stringParse( value ) ) ) ) {\n\t\t\t\t\tvalue = color( parsed || value );\n\t\t\t\t\tif ( !support.rgba && value._rgba[ 3 ] !== 1 ) {\n\t\t\t\t\t\tcurElem = hook === \"backgroundColor\" ? elem.parentNode : elem;\n\t\t\t\t\t\twhile (\n\t\t\t\t\t\t\t(backgroundColor === \"\" || backgroundColor === \"transparent\") &&\n\t\t\t\t\t\t\tcurElem && curElem.style\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tbackgroundColor = jQuery.css( curElem, \"backgroundColor\" );\n\t\t\t\t\t\t\t\tcurElem = curElem.parentNode;\n\t\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvalue = value.blend( backgroundColor && backgroundColor !== \"transparent\" ?\n\t\t\t\t\t\t\tbackgroundColor :\n\t\t\t\t\t\t\t\"_default\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tvalue = value.toRgbaString();\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\telem.style[ hook ] = value;\n\t\t\t\t} catch( e ) {\n\t\t\t\t\t// wrapped to prevent IE from throwing errors on \"invalid\" values like 'auto' or 'inherit'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tjQuery.fx.step[ hook ] = function( fx ) {\n\t\t\tif ( !fx.colorInit ) {\n\t\t\t\tfx.start = color( fx.elem, hook );\n\t\t\t\tfx.end = color( fx.end );\n\t\t\t\tfx.colorInit = true;\n\t\t\t}\n\t\t\tjQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );\n\t\t};\n\t});\n\n};\n\ncolor.hook( stepHooks );\n\njQuery.cssHooks.borderColor = {\n\texpand: function( value ) {\n\t\tvar expanded = {};\n\n\t\teach( [ \"Top\", \"Right\", \"Bottom\", \"Left\" ], function( i, part ) {\n\t\t\texpanded[ \"border\" + part + \"Color\" ] = value;\n\t\t});\n\t\treturn expanded;\n\t}\n};\n\n// Basic color names only.\n// Usage of any of the other color names requires adding yourself or including\n// jquery.color.svg-names.js.\ncolors = jQuery.Color.names = {\n\t// 4.1. Basic color keywords\n\taqua: \"#00ffff\",\n\tblack: \"#000000\",\n\tblue: \"#0000ff\",\n\tfuchsia: \"#ff00ff\",\n\tgray: \"#808080\",\n\tgreen: \"#008000\",\n\tlime: \"#00ff00\",\n\tmaroon: \"#800000\",\n\tnavy: \"#000080\",\n\tolive: \"#808000\",\n\tpurple: \"#800080\",\n\tred: \"#ff0000\",\n\tsilver: \"#c0c0c0\",\n\tteal: \"#008080\",\n\twhite: \"#ffffff\",\n\tyellow: \"#ffff00\",\n\n\t// 4.2.3. \"transparent\" color keyword\n\ttransparent: [ null, null, null, 0 ],\n\n\t_default: \"#ffffff\"\n};\n\n})( jQuery );\n\n\n/******************************************************************************/\n/****************************** CLASS ANIMATIONS ******************************/\n/******************************************************************************/\n(function() {\n\nvar classAnimationActions = [ \"add\", \"remove\", \"toggle\" ],\n\tshorthandStyles = {\n\t\tborder: 1,\n\t\tborderBottom: 1,\n\t\tborderColor: 1,\n\t\tborderLeft: 1,\n\t\tborderRight: 1,\n\t\tborderTop: 1,\n\t\tborderWidth: 1,\n\t\tmargin: 1,\n\t\tpadding: 1\n\t};\n\n$.each([ \"borderLeftStyle\", \"borderRightStyle\", \"borderBottomStyle\", \"borderTopStyle\" ], function( _, prop ) {\n\t$.fx.step[ prop ] = function( fx ) {\n\t\tif ( fx.end !== \"none\" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {\n\t\t\tjQuery.style( fx.elem, prop, fx.end );\n\t\t\tfx.setAttr = true;\n\t\t}\n\t};\n});\n\nfunction getElementStyles( elem ) {\n\tvar key, len,\n\t\tstyle = elem.ownerDocument.defaultView ?\n\t\t\telem.ownerDocument.defaultView.getComputedStyle( elem, null ) :\n\t\t\telem.currentStyle,\n\t\tstyles = {};\n\n\tif ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {\n\t\tlen = style.length;\n\t\twhile ( len-- ) {\n\t\t\tkey = style[ len ];\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ $.camelCase( key ) ] = style[ key ];\n\t\t\t}\n\t\t}\n\t// support: Opera, IE <9\n\t} else {\n\t\tfor ( key in style ) {\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ key ] = style[ key ];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn styles;\n}\n\n\nfunction styleDifference( oldStyle, newStyle ) {\n\tvar diff = {},\n\t\tname, value;\n\n\tfor ( name in newStyle ) {\n\t\tvalue = newStyle[ name ];\n\t\tif ( oldStyle[ name ] !== value ) {\n\t\t\tif ( !shorthandStyles[ name ] ) {\n\t\t\t\tif ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {\n\t\t\t\t\tdiff[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn diff;\n}\n\n// support: jQuery <1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n$.effects.animateClass = function( value, duration, easing, callback ) {\n\tvar o = $.speed( duration, easing, callback );\n\n\treturn this.queue( function() {\n\t\tvar animated = $( this ),\n\t\t\tbaseClass = animated.attr( \"class\" ) || \"\",\n\t\t\tapplyClassChange,\n\t\t\tallAnimations = o.children ? animated.find( \"*\" ).addBack() : animated;\n\n\t\t// map the animated objects to store the original styles.\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar el = $( this );\n\t\t\treturn {\n\t\t\t\tel: el,\n\t\t\t\tstart: getElementStyles( this )\n\t\t\t};\n\t\t});\n\n\t\t// apply class change\n\t\tapplyClassChange = function() {\n\t\t\t$.each( classAnimationActions, function(i, action) {\n\t\t\t\tif ( value[ action ] ) {\n\t\t\t\t\tanimated[ action + \"Class\" ]( value[ action ] );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t\tapplyClassChange();\n\n\t\t// map all animated objects again - calculate new styles and diff\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tthis.end = getElementStyles( this.el[ 0 ] );\n\t\t\tthis.diff = styleDifference( this.start, this.end );\n\t\t\treturn this;\n\t\t});\n\n\t\t// apply original class\n\t\tanimated.attr( \"class\", baseClass );\n\n\t\t// map all animated objects again - this time collecting a promise\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar styleInfo = this,\n\t\t\t\tdfd = $.Deferred(),\n\t\t\t\topts = $.extend({}, o, {\n\t\t\t\t\tqueue: false,\n\t\t\t\t\tcomplete: function() {\n\t\t\t\t\t\tdfd.resolve( styleInfo );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\tthis.el.animate( this.diff, opts );\n\t\t\treturn dfd.promise();\n\t\t});\n\n\t\t// once all animations have completed:\n\t\t$.when.apply( $, allAnimations.get() ).done(function() {\n\n\t\t\t// set the final class\n\t\t\tapplyClassChange();\n\n\t\t\t// for each animated element,\n\t\t\t// clear all css properties that were animated\n\t\t\t$.each( arguments, function() {\n\t\t\t\tvar el = this.el;\n\t\t\t\t$.each( this.diff, function(key) {\n\t\t\t\t\tel.css( key, \"\" );\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// this is guarnteed to be there if you use jQuery.speed()\n\t\t\t// it also handles dequeuing the next anim...\n\t\t\to.complete.call( animated[ 0 ] );\n\t\t});\n\t});\n};\n\n$.fn.extend({\n\taddClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn speed ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ add: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.addClass ),\n\n\tremoveClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn arguments.length > 1 ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ remove: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.removeClass ),\n\n\ttoggleClass: (function( orig ) {\n\t\treturn function( classNames, force, speed, easing, callback ) {\n\t\t\tif ( typeof force === \"boolean\" || force === undefined ) {\n\t\t\t\tif ( !speed ) {\n\t\t\t\t\t// without speed parameter\n\t\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t\t} else {\n\t\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t\t(force ? { add: classNames } : { remove: classNames }),\n\t\t\t\t\t\tspeed, easing, callback );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// without force parameter\n\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t{ toggle: classNames }, force, speed, easing );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggleClass ),\n\n\tswitchClass: function( remove, add, speed, easing, callback) {\n\t\treturn $.effects.animateClass.call( this, {\n\t\t\tadd: add,\n\t\t\tremove: remove\n\t\t}, speed, easing, callback );\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EFFECTS **********************************/\n/******************************************************************************/\n\n(function() {\n\n$.extend( $.effects, {\n\tversion: \"1.10.4\",\n\n\t// Saves a set of properties in a data storage\n\tsave: function( element, set ) {\n\t\tfor( var i=0; i < set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\telement.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Restores a set of previously saved properties from a data storage\n\trestore: function( element, set ) {\n\t\tvar val, i;\n\t\tfor( i=0; i < set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\tval = element.data( dataSpace + set[ i ] );\n\t\t\t\t// support: jQuery 1.6.2\n\t\t\t\t// http://bugs.jquery.com/ticket/9917\n\t\t\t\t// jQuery 1.6.2 incorrectly returns undefined for any falsy value.\n\t\t\t\t// We can't differentiate between \"\" and 0 here, so we just assume\n\t\t\t\t// empty string since it's likely to be a more common value...\n\t\t\t\tif ( val === undefined ) {\n\t\t\t\t\tval = \"\";\n\t\t\t\t}\n\t\t\t\telement.css( set[ i ], val );\n\t\t\t}\n\t\t}\n\t},\n\n\tsetMode: function( el, mode ) {\n\t\tif (mode === \"toggle\") {\n\t\t\tmode = el.is( \":hidden\" ) ? \"show\" : \"hide\";\n\t\t}\n\t\treturn mode;\n\t},\n\n\t// Translates a [top,left] array into a baseline value\n\t// this should be a little more flexible in the future to handle a string & hash\n\tgetBaseline: function( origin, original ) {\n\t\tvar y, x;\n\t\tswitch ( origin[ 0 ] ) {\n\t\t\tcase \"top\": y = 0; break;\n\t\t\tcase \"middle\": y = 0.5; break;\n\t\t\tcase \"bottom\": y = 1; break;\n\t\t\tdefault: y = origin[ 0 ] / original.height;\n\t\t}\n\t\tswitch ( origin[ 1 ] ) {\n\t\t\tcase \"left\": x = 0; break;\n\t\t\tcase \"center\": x = 0.5; break;\n\t\t\tcase \"right\": x = 1; break;\n\t\t\tdefault: x = origin[ 1 ] / original.width;\n\t\t}\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t},\n\n\t// Wraps the element around a wrapper that copies position properties\n\tcreateWrapper: function( element ) {\n\n\t\t// if the element is already wrapped, return it\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" )) {\n\t\t\treturn element.parent();\n\t\t}\n\n\t\t// wrap the element\n\t\tvar props = {\n\t\t\t\twidth: element.outerWidth(true),\n\t\t\t\theight: element.outerHeight(true),\n\t\t\t\t\"float\": element.css( \"float\" )\n\t\t\t},\n\t\t\twrapper = $( \"<div></div>\" )\n\t\t\t\t.addClass( \"ui-effects-wrapper\" )\n\t\t\t\t.css({\n\t\t\t\t\tfontSize: \"100%\",\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tborder: \"none\",\n\t\t\t\t\tmargin: 0,\n\t\t\t\t\tpadding: 0\n\t\t\t\t}),\n\t\t\t// Store the size in case width/height are defined in % - Fixes #5245\n\t\t\tsize = {\n\t\t\t\twidth: element.width(),\n\t\t\t\theight: element.height()\n\t\t\t},\n\t\t\tactive = document.activeElement;\n\n\t\t// support: Firefox\n\t\t// Firefox incorrectly exposes anonymous content\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=561664\n\t\ttry {\n\t\t\tactive.id;\n\t\t} catch( e ) {\n\t\t\tactive = document.body;\n\t\t}\n\n\t\telement.wrap( wrapper );\n\n\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t$( active ).focus();\n\t\t}\n\n\t\twrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element\n\n\t\t// transfer positioning properties to the wrapper\n\t\tif ( element.css( \"position\" ) === \"static\" ) {\n\t\t\twrapper.css({ position: \"relative\" });\n\t\t\telement.css({ position: \"relative\" });\n\t\t} else {\n\t\t\t$.extend( props, {\n\t\t\t\tposition: element.css( \"position\" ),\n\t\t\t\tzIndex: element.css( \"z-index\" )\n\t\t\t});\n\t\t\t$.each([ \"top\", \"left\", \"bottom\", \"right\" ], function(i, pos) {\n\t\t\t\tprops[ pos ] = element.css( pos );\n\t\t\t\tif ( isNaN( parseInt( props[ pos ], 10 ) ) ) {\n\t\t\t\t\tprops[ pos ] = \"auto\";\n\t\t\t\t}\n\t\t\t});\n\t\t\telement.css({\n\t\t\t\tposition: \"relative\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tright: \"auto\",\n\t\t\t\tbottom: \"auto\"\n\t\t\t});\n\t\t}\n\t\telement.css(size);\n\n\t\treturn wrapper.css( props ).show();\n\t},\n\n\tremoveWrapper: function( element ) {\n\t\tvar active = document.activeElement;\n\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t\telement.parent().replaceWith( element );\n\n\t\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t\t$( active ).focus();\n\t\t\t}\n\t\t}\n\n\n\t\treturn element;\n\t},\n\n\tsetTransition: function( element, list, factor, value ) {\n\t\tvalue = value || {};\n\t\t$.each( list, function( i, x ) {\n\t\t\tvar unit = element.cssUnit( x );\n\t\t\tif ( unit[ 0 ] > 0 ) {\n\t\t\t\tvalue[ x ] = unit[ 0 ] * factor + unit[ 1 ];\n\t\t\t}\n\t\t});\n\t\treturn value;\n\t}\n});\n\n// return an effect options object for the given parameters:\nfunction _normalizeArguments( effect, options, speed, callback ) {\n\n\t// allow passing all options as the first parameter\n\tif ( $.isPlainObject( effect ) ) {\n\t\toptions = effect;\n\t\teffect = effect.effect;\n\t}\n\n\t// convert to an object\n\teffect = { effect: effect };\n\n\t// catch (effect, null, ...)\n\tif ( options == null ) {\n\t\toptions = {};\n\t}\n\n\t// catch (effect, callback)\n\tif ( $.isFunction( options ) ) {\n\t\tcallback = options;\n\t\tspeed = null;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, speed, ?)\n\tif ( typeof options === \"number\" || $.fx.speeds[ options ] ) {\n\t\tcallback = speed;\n\t\tspeed = options;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, options, callback)\n\tif ( $.isFunction( speed ) ) {\n\t\tcallback = speed;\n\t\tspeed = null;\n\t}\n\n\t// add options to effect\n\tif ( options ) {\n\t\t$.extend( effect, options );\n\t}\n\n\tspeed = speed || options.duration;\n\teffect.duration = $.fx.off ? 0 :\n\t\ttypeof speed === \"number\" ? speed :\n\t\tspeed in $.fx.speeds ? $.fx.speeds[ speed ] :\n\t\t$.fx.speeds._default;\n\n\teffect.complete = callback || options.complete;\n\n\treturn effect;\n}\n\nfunction standardAnimationOption( option ) {\n\t// Valid standard speeds (nothing, number, named speed)\n\tif ( !option || typeof option === \"number\" || $.fx.speeds[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Invalid strings - treat as \"normal\" speed\n\tif ( typeof option === \"string\" && !$.effects.effect[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Complete callback\n\tif ( $.isFunction( option ) ) {\n\t\treturn true;\n\t}\n\n\t// Options hash (but not naming an effect)\n\tif ( typeof option === \"object\" && !option.effect ) {\n\t\treturn true;\n\t}\n\n\t// Didn't match any standard API\n\treturn false;\n}\n\n$.fn.extend({\n\teffect: function( /* effect, options, speed, callback */ ) {\n\t\tvar args = _normalizeArguments.apply( this, arguments ),\n\t\t\tmode = args.mode,\n\t\t\tqueue = args.queue,\n\t\t\teffectMethod = $.effects.effect[ args.effect ];\n\n\t\tif ( $.fx.off || !effectMethod ) {\n\t\t\t// delegate to the original method (e.g., .show()) if possible\n\t\t\tif ( mode ) {\n\t\t\t\treturn this[ mode ]( args.duration, args.complete );\n\t\t\t} else {\n\t\t\t\treturn this.each( function() {\n\t\t\t\t\tif ( args.complete ) {\n\t\t\t\t\t\targs.complete.call( this );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction run( next ) {\n\t\t\tvar elem = $( this ),\n\t\t\t\tcomplete = args.complete,\n\t\t\t\tmode = args.mode;\n\n\t\t\tfunction done() {\n\t\t\t\tif ( $.isFunction( complete ) ) {\n\t\t\t\t\tcomplete.call( elem[0] );\n\t\t\t\t}\n\t\t\t\tif ( $.isFunction( next ) ) {\n\t\t\t\t\tnext();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the element already has the correct final state, delegate to\n\t\t\t// the core methods so the internal tracking of \"olddisplay\" works.\n\t\t\tif ( elem.is( \":hidden\" ) ? mode === \"hide\" : mode === \"show\" ) {\n\t\t\t\telem[ mode ]();\n\t\t\t\tdone();\n\t\t\t} else {\n\t\t\t\teffectMethod.call( elem[0], args, done );\n\t\t\t}\n\t\t}\n\n\t\treturn queue === false ? this.each( run ) : this.queue( queue || \"fx\", run );\n\t},\n\n\tshow: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"show\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.show ),\n\n\thide: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"hide\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.hide ),\n\n\ttoggle: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) || typeof option === \"boolean\" ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"toggle\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggle ),\n\n\t// helper functions\n\tcssUnit: function(key) {\n\t\tvar style = this.css( key ),\n\t\t\tval = [];\n\n\t\t$.each( [ \"em\", \"px\", \"%\", \"pt\" ], function( i, unit ) {\n\t\t\tif ( style.indexOf( unit ) > 0 ) {\n\t\t\t\tval = [ parseFloat( style ), unit ];\n\t\t\t}\n\t\t});\n\t\treturn val;\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EASING ***********************************/\n/******************************************************************************/\n\n(function() {\n\n// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)\n\nvar baseEasings = {};\n\n$.each( [ \"Quad\", \"Cubic\", \"Quart\", \"Quint\", \"Expo\" ], function( i, name ) {\n\tbaseEasings[ name ] = function( p ) {\n\t\treturn Math.pow( p, i + 2 );\n\t};\n});\n\n$.extend( baseEasings, {\n\tSine: function ( p ) {\n\t\treturn 1 - Math.cos( p * Math.PI / 2 );\n\t},\n\tCirc: function ( p ) {\n\t\treturn 1 - Math.sqrt( 1 - p * p );\n\t},\n\tElastic: function( p ) {\n\t\treturn p === 0 || p === 1 ? p :\n\t\t\t-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );\n\t},\n\tBack: function( p ) {\n\t\treturn p * p * ( 3 * p - 2 );\n\t},\n\tBounce: function ( p ) {\n\t\tvar pow2,\n\t\t\tbounce = 4;\n\n\t\twhile ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}\n\t\treturn 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );\n\t}\n});\n\n$.each( baseEasings, function( name, easeIn ) {\n\t$.easing[ \"easeIn\" + name ] = easeIn;\n\t$.easing[ \"easeOut\" + name ] = function( p ) {\n\t\treturn 1 - easeIn( 1 - p );\n\t};\n\t$.easing[ \"easeInOut\" + name ] = function( p ) {\n\t\treturn p < 0.5 ?\n\t\t\teaseIn( p * 2 ) / 2 :\n\t\t\t1 - easeIn( p * -2 + 2 ) / 2;\n\t};\n});\n\n})();\n\n})(jQuery);\n(function( $, undefined ) {\n\nvar rvertical = /up|down|vertical/,\n\trpositivemotion = /up|left|vertical|horizontal/;\n\n$.effects.effect.blind = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tdirection = o.direction || \"up\",\n\t\tvertical = rvertical.test( direction ),\n\t\tref = vertical ? \"height\" : \"width\",\n\t\tref2 = vertical ? \"top\" : \"left\",\n\t\tmotion = rpositivemotion.test( direction ),\n\t\tanimation = {},\n\t\tshow = mode === \"show\",\n\t\twrapper, distance, margin;\n\n\t// if already wrapped, the wrapper's properties are my property. #6245\n\tif ( el.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t$.effects.save( el.parent(), props );\n\t} else {\n\t\t$.effects.save( el, props );\n\t}\n\tel.show();\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tdistance = wrapper[ ref ]();\n\tmargin = parseFloat( wrapper.css( ref2 ) ) || 0;\n\n\tanimation[ ref ] = show ? distance : 0;\n\tif ( !motion ) {\n\t\tel\n\t\t\t.css( vertical ? \"bottom\" : \"right\", 0 )\n\t\t\t.css( vertical ? \"top\" : \"left\", \"auto\" )\n\t\t\t.css({ position: \"absolute\" });\n\n\t\tanimation[ ref2 ] = show ? margin : distance + margin;\n\t}\n\n\t// start at 0 if we are showing\n\tif ( show ) {\n\t\twrapper.css( ref, 0 );\n\t\tif ( ! motion ) {\n\t\t\twrapper.css( ref2, margin + distance );\n\t\t}\n\t}\n\n\t// Animate\n\twrapper.animate( animation, {\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tqueue: false,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.bounce = function( o, done ) {\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\n\t\t// defaults:\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\thide = mode === \"hide\",\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"up\",\n\t\tdistance = o.distance,\n\t\ttimes = o.times || 5,\n\n\t\t// number of internal animations\n\t\tanims = times * 2 + ( show || hide ? 1 : 0 ),\n\t\tspeed = o.duration / anims,\n\t\teasing = o.easing,\n\n\t\t// utility:\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ),\n\t\ti,\n\t\tupAnim,\n\t\tdownAnim,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t// Avoid touching opacity to prevent clearType and PNG issues in IE\n\tif ( show || hide ) {\n\t\tprops.push( \"opacity\" );\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el ); // Create Wrapper\n\n\t// default distance for the BIGGEST bounce is the outer Distance / 3\n\tif ( !distance ) {\n\t\tdistance = el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]() / 3;\n\t}\n\n\tif ( show ) {\n\t\tdownAnim = { opacity: 1 };\n\t\tdownAnim[ ref ] = 0;\n\n\t\t// if we are showing, force opacity 0 and set the initial position\n\t\t// then do the \"first\" animation\n\t\tel.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion ? -distance * 2 : distance * 2 )\n\t\t\t.animate( downAnim, speed, easing );\n\t}\n\n\t// start at the smallest distance if we are hiding\n\tif ( hide ) {\n\t\tdistance = distance / Math.pow( 2, times - 1 );\n\t}\n\n\tdownAnim = {};\n\tdownAnim[ ref ] = 0;\n\t// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here\n\tfor ( i = 0; i < times; i++ ) {\n\t\tupAnim = {};\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing )\n\t\t\t.animate( downAnim, speed, easing );\n\n\t\tdistance = hide ? distance * 2 : distance / 2;\n\t}\n\n\t// Last Bounce when Hiding\n\tif ( hide ) {\n\t\tupAnim = { opacity: 0 };\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing );\n\t}\n\n\tel.queue(function() {\n\t\tif ( hide ) {\n\t\t\tel.hide();\n\t\t}\n\t\t$.effects.restore( el, props );\n\t\t$.effects.removeWrapper( el );\n\t\tdone();\n\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen > 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.clip = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"vertical\",\n\t\tvert = direction === \"vertical\",\n\t\tsize = vert ? \"height\" : \"width\",\n\t\tposition = vert ? \"top\" : \"left\",\n\t\tanimation = {},\n\t\twrapper, animate, distance;\n\n\t// Save & Show\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tanimate = ( el[0].tagName === \"IMG\" ) ? wrapper : el;\n\tdistance = animate[ size ]();\n\n\t// Shift\n\tif ( show ) {\n\t\tanimate.css( size, 0 );\n\t\tanimate.css( position, distance / 2 );\n\t}\n\n\t// Create Animation Object:\n\tanimation[ size ] = show ? distance : 0;\n\tanimation[ position ] = show ? 0 : distance / 2;\n\n\t// Animate\n\tanimate.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( !show ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.drop = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"opacity\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ) ? \"pos\" : \"neg\",\n\t\tanimation = {\n\t\t\topacity: show ? 1 : 0\n\t\t},\n\t\tdistance;\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\": \"outerWidth\" ]( true ) / 2;\n\n\tif ( show ) {\n\t\tel\n\t\t\t.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion === \"pos\" ? -distance : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( motion === \"pos\" ? \"+=\" : \"-=\" ) :\n\t\t( motion === \"pos\" ? \"-=\" : \"+=\" ) ) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.explode = function( o, done ) {\n\n\tvar rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,\n\t\tcells = rows,\n\t\tel = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\n\t\t// show and then visibility:hidden the element before calculating offset\n\t\toffset = el.show().css( \"visibility\", \"hidden\" ).offset(),\n\n\t\t// width and height of a piece\n\t\twidth = Math.ceil( el.outerWidth() / cells ),\n\t\theight = Math.ceil( el.outerHeight() / rows ),\n\t\tpieces = [],\n\n\t\t// loop\n\t\ti, j, left, top, mx, my;\n\n\t// children animate complete:\n\tfunction childComplete() {\n\t\tpieces.push( this );\n\t\tif ( pieces.length === rows * cells ) {\n\t\t\tanimComplete();\n\t\t}\n\t}\n\n\t// clone the element for each row and cell.\n\tfor( i = 0; i < rows ; i++ ) { // ===>\n\t\ttop = offset.top + i * height;\n\t\tmy = i - ( rows - 1 ) / 2 ;\n\n\t\tfor( j = 0; j < cells ; j++ ) { // |||\n\t\t\tleft = offset.left + j * width;\n\t\t\tmx = j - ( cells - 1 ) / 2 ;\n\n\t\t\t// Create a clone of the now hidden main element that will be absolute positioned\n\t\t\t// within a wrapper div off the -left and -top equal to size of our pieces\n\t\t\tel\n\t\t\t\t.clone()\n\t\t\t\t.appendTo( \"body\" )\n\t\t\t\t.wrap( \"<div></div>\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tvisibility: \"visible\",\n\t\t\t\t\tleft: -j * width,\n\t\t\t\t\ttop: -i * height\n\t\t\t\t})\n\n\t\t\t// select the wrapper - make it overflow: hidden and absolute positioned based on\n\t\t\t// where the original was located +left and +top equal to the size of pieces\n\t\t\t\t.parent()\n\t\t\t\t.addClass( \"ui-effects-explode\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\twidth: width,\n\t\t\t\t\theight: height,\n\t\t\t\t\tleft: left + ( show ? mx * width : 0 ),\n\t\t\t\t\ttop: top + ( show ? my * height : 0 ),\n\t\t\t\t\topacity: show ? 0 : 1\n\t\t\t\t}).animate({\n\t\t\t\t\tleft: left + ( show ? 0 : mx * width ),\n\t\t\t\t\ttop: top + ( show ? 0 : my * height ),\n\t\t\t\t\topacity: show ? 1 : 0\n\t\t\t\t}, o.duration || 500, o.easing, childComplete );\n\t\t}\n\t}\n\n\tfunction animComplete() {\n\t\tel.css({\n\t\t\tvisibility: \"visible\"\n\t\t});\n\t\t$( pieces ).remove();\n\t\tif ( !show ) {\n\t\t\tel.hide();\n\t\t}\n\t\tdone();\n\t}\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.fade = function( o, done ) {\n\tvar el = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"toggle\" );\n\n\tel.animate({\n\t\topacity: mode\n\t}, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: done\n\t});\n};\n\n})( jQuery );\n(function( $, undefined ) {\n\n$.effects.effect.fold = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tsize = o.size || 15,\n\t\tpercent = /([0-9]+)%/.exec( size ),\n\t\thorizFirst = !!o.horizFirst,\n\t\twidthFirst = show !== horizFirst,\n\t\tref = widthFirst ? [ \"width\", \"height\" ] : [ \"height\", \"width\" ],\n\t\tduration = o.duration / 2,\n\t\twrapper, distance,\n\t\tanimation1 = {},\n\t\tanimation2 = {};\n\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tdistance = widthFirst ?\n\t\t[ wrapper.width(), wrapper.height() ] :\n\t\t[ wrapper.height(), wrapper.width() ];\n\n\tif ( percent ) {\n\t\tsize = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];\n\t}\n\tif ( show ) {\n\t\twrapper.css( horizFirst ? {\n\t\t\theight: 0,\n\t\t\twidth: size\n\t\t} : {\n\t\t\theight: size,\n\t\t\twidth: 0\n\t\t});\n\t}\n\n\t// Animation\n\tanimation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;\n\tanimation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;\n\n\t// Animate\n\twrapper\n\t\t.animate( animation1, duration, o.easing )\n\t\t.animate( animation2, duration, o.easing, function() {\n\t\t\tif ( hide ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.highlight = function( o, done ) {\n\tvar elem = $( this ),\n\t\tprops = [ \"backgroundImage\", \"backgroundColor\", \"opacity\" ],\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tanimation = {\n\t\t\tbackgroundColor: elem.css( \"backgroundColor\" )\n\t\t};\n\n\tif (mode === \"hide\") {\n\t\tanimation.opacity = 0;\n\t}\n\n\t$.effects.save( elem, props );\n\n\telem\n\t\t.show()\n\t\t.css({\n\t\t\tbackgroundImage: \"none\",\n\t\t\tbackgroundColor: o.color || \"#ffff99\"\n\t\t})\n\t\t.animate( animation, {\n\t\t\tqueue: false,\n\t\t\tduration: o.duration,\n\t\t\teasing: o.easing,\n\t\t\tcomplete: function() {\n\t\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\t\telem.hide();\n\t\t\t\t}\n\t\t\t\t$.effects.restore( elem, props );\n\t\t\t\tdone();\n\t\t\t}\n\t\t});\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.pulsate = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tshowhide = ( show || mode === \"hide\" ),\n\n\t\t// showing or hiding leaves of the \"last\" animation\n\t\tanims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),\n\t\tduration = o.duration / anims,\n\t\tanimateTo = 0,\n\t\tqueue = elem.queue(),\n\t\tqueuelen = queue.length,\n\t\ti;\n\n\tif ( show || !elem.is(\":visible\")) {\n\t\telem.css( \"opacity\", 0 ).show();\n\t\tanimateTo = 1;\n\t}\n\n\t// anims - 1 opacity \"toggles\"\n\tfor ( i = 1; i < anims; i++ ) {\n\t\telem.animate({\n\t\t\topacity: animateTo\n\t\t}, duration, o.easing );\n\t\tanimateTo = 1 - animateTo;\n\t}\n\n\telem.animate({\n\t\topacity: animateTo\n\t}, duration, o.easing);\n\n\telem.queue(function() {\n\t\tif ( hide ) {\n\t\t\telem.hide();\n\t\t}\n\t\tdone();\n\t});\n\n\t// We just queued up \"anims\" animations, we need to put them next in the queue\n\tif ( queuelen > 1 ) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\telem.dequeue();\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.puff = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"hide\" ),\n\t\thide = mode === \"hide\",\n\t\tpercent = parseInt( o.percent, 10 ) || 150,\n\t\tfactor = percent / 100,\n\t\toriginal = {\n\t\t\theight: elem.height(),\n\t\t\twidth: elem.width(),\n\t\t\touterHeight: elem.outerHeight(),\n\t\t\touterWidth: elem.outerWidth()\n\t\t};\n\n\t$.extend( o, {\n\t\teffect: \"scale\",\n\t\tqueue: false,\n\t\tfade: true,\n\t\tmode: mode,\n\t\tcomplete: done,\n\t\tpercent: hide ? percent : 100,\n\t\tfrom: hide ?\n\t\t\toriginal :\n\t\t\t{\n\t\t\t\theight: original.height * factor,\n\t\t\t\twidth: original.width * factor,\n\t\t\t\touterHeight: original.outerHeight * factor,\n\t\t\t\touterWidth: original.outerWidth * factor\n\t\t\t}\n\t});\n\n\telem.effect( o );\n};\n\n$.effects.effect.scale = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\toptions = $.extend( true, {}, o ),\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tpercent = parseInt( o.percent, 10 ) ||\n\t\t\t( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === \"hide\" ? 0 : 100 ) ),\n\t\tdirection = o.direction || \"both\",\n\t\torigin = o.origin,\n\t\toriginal = {\n\t\t\theight: el.height(),\n\t\t\twidth: el.width(),\n\t\t\touterHeight: el.outerHeight(),\n\t\t\touterWidth: el.outerWidth()\n\t\t},\n\t\tfactor = {\n\t\t\ty: direction !== \"horizontal\" ? (percent / 100) : 1,\n\t\t\tx: direction !== \"vertical\" ? (percent / 100) : 1\n\t\t};\n\n\t// We are going to pass this effect to the size effect:\n\toptions.effect = \"size\";\n\toptions.queue = false;\n\toptions.complete = done;\n\n\t// Set default origin and restore for show/hide\n\tif ( mode !== \"effect\" ) {\n\t\toptions.origin = origin || [\"middle\",\"center\"];\n\t\toptions.restore = true;\n\t}\n\n\toptions.from = o.from || ( mode === \"show\" ? {\n\t\theight: 0,\n\t\twidth: 0,\n\t\touterHeight: 0,\n\t\touterWidth: 0\n\t} : original );\n\toptions.to = {\n\t\theight: original.height * factor.y,\n\t\twidth: original.width * factor.x,\n\t\touterHeight: original.outerHeight * factor.y,\n\t\touterWidth: original.outerWidth * factor.x\n\t};\n\n\t// Fade option to support puff\n\tif ( options.fade ) {\n\t\tif ( mode === \"show\" ) {\n\t\t\toptions.from.opacity = 0;\n\t\t\toptions.to.opacity = 1;\n\t\t}\n\t\tif ( mode === \"hide\" ) {\n\t\t\toptions.from.opacity = 1;\n\t\t\toptions.to.opacity = 0;\n\t\t}\n\t}\n\n\t// Animate\n\tel.effect( options );\n\n};\n\n$.effects.effect.size = function( o, done ) {\n\n\t// Create element\n\tvar original, baseline, factor,\n\t\tel = $( this ),\n\t\tprops0 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\", \"overflow\", \"opacity\" ],\n\n\t\t// Always restore\n\t\tprops1 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"overflow\", \"opacity\" ],\n\n\t\t// Copy for children\n\t\tprops2 = [ \"width\", \"height\", \"overflow\" ],\n\t\tcProps = [ \"fontSize\" ],\n\t\tvProps = [ \"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\" ],\n\t\thProps = [ \"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\" ],\n\n\t\t// Set options\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\trestore = o.restore || mode !== \"effect\",\n\t\tscale = o.scale || \"both\",\n\t\torigin = o.origin || [ \"middle\", \"center\" ],\n\t\tposition = el.css( \"position\" ),\n\t\tprops = restore ? props0 : props1,\n\t\tzero = {\n\t\t\theight: 0,\n\t\t\twidth: 0,\n\t\t\touterHeight: 0,\n\t\t\touterWidth: 0\n\t\t};\n\n\tif ( mode === \"show\" ) {\n\t\tel.show();\n\t}\n\toriginal = {\n\t\theight: el.height(),\n\t\twidth: el.width(),\n\t\touterHeight: el.outerHeight(),\n\t\touterWidth: el.outerWidth()\n\t};\n\n\tif ( o.mode === \"toggle\" && mode === \"show\" ) {\n\t\tel.from = o.to || zero;\n\t\tel.to = o.from || original;\n\t} else {\n\t\tel.from = o.from || ( mode === \"show\" ? zero : original );\n\t\tel.to = o.to || ( mode === \"hide\" ? zero : original );\n\t}\n\n\t// Set scaling factor\n\tfactor = {\n\t\tfrom: {\n\t\t\ty: el.from.height / original.height,\n\t\t\tx: el.from.width / original.width\n\t\t},\n\t\tto: {\n\t\t\ty: el.to.height / original.height,\n\t\t\tx: el.to.width / original.width\n\t\t}\n\t};\n\n\t// Scale the css box\n\tif ( scale === \"box\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( vProps );\n\t\t\tel.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );\n\t\t}\n\n\t\t// Horizontal props scaling\n\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\tprops = props.concat( hProps );\n\t\t\tel.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );\n\t\t\tel.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );\n\t\t}\n\t}\n\n\t// Scale the content\n\tif ( scale === \"content\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( cProps ).concat( props2 );\n\t\t\tel.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );\n\t\t}\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\tel.css( \"overflow\", \"hidden\" ).css( el.from );\n\n\t// Adjust\n\tif (origin) { // Calculate baseline shifts\n\t\tbaseline = $.effects.getBaseline( origin, original );\n\t\tel.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;\n\t\tel.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;\n\t\tel.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;\n\t\tel.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;\n\t}\n\tel.css( el.from ); // set top & left\n\n\t// Animate\n\tif ( scale === \"content\" || scale === \"both\" ) { // Scale the children\n\n\t\t// Add margins/font-size\n\t\tvProps = vProps.concat([ \"marginTop\", \"marginBottom\" ]).concat(cProps);\n\t\thProps = hProps.concat([ \"marginLeft\", \"marginRight\" ]);\n\t\tprops2 = props0.concat(vProps).concat(hProps);\n\n\t\tel.find( \"*[width]\" ).each( function(){\n\t\t\tvar child = $( this ),\n\t\t\t\tc_original = {\n\t\t\t\t\theight: child.height(),\n\t\t\t\t\twidth: child.width(),\n\t\t\t\t\touterHeight: child.outerHeight(),\n\t\t\t\t\touterWidth: child.outerWidth()\n\t\t\t\t};\n\t\t\tif (restore) {\n\t\t\t\t$.effects.save(child, props2);\n\t\t\t}\n\n\t\t\tchild.from = {\n\t\t\t\theight: c_original.height * factor.from.y,\n\t\t\t\twidth: c_original.width * factor.from.x,\n\t\t\t\touterHeight: c_original.outerHeight * factor.from.y,\n\t\t\t\touterWidth: c_original.outerWidth * factor.from.x\n\t\t\t};\n\t\t\tchild.to = {\n\t\t\t\theight: c_original.height * factor.to.y,\n\t\t\t\twidth: c_original.width * factor.to.x,\n\t\t\t\touterHeight: c_original.height * factor.to.y,\n\t\t\t\touterWidth: c_original.width * factor.to.x\n\t\t\t};\n\n\t\t\t// Vertical props scaling\n\t\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );\n\t\t\t}\n\n\t\t\t// Horizontal props scaling\n\t\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );\n\t\t\t}\n\n\t\t\t// Animate children\n\t\t\tchild.css( child.from );\n\t\t\tchild.animate( child.to, o.duration, o.easing, function() {\n\n\t\t\t\t// Restore children\n\t\t\t\tif ( restore ) {\n\t\t\t\t\t$.effects.restore( child, props2 );\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// Animate\n\tel.animate( el.to, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( el.to.opacity === 0 ) {\n\t\t\t\tel.css( \"opacity\", el.from.opacity );\n\t\t\t}\n\t\t\tif( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\tif ( !restore ) {\n\n\t\t\t\t// we need to calculate our new positioning based on the scaling\n\t\t\t\tif ( position === \"static\" ) {\n\t\t\t\t\tel.css({\n\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\ttop: el.to.top,\n\t\t\t\t\t\tleft: el.to.left\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t$.each([ \"top\", \"left\" ], function( idx, pos ) {\n\t\t\t\t\t\tel.css( pos, function( _, str ) {\n\t\t\t\t\t\t\tvar val = parseInt( str, 10 ),\n\t\t\t\t\t\t\t\ttoRef = idx ? el.to.left : el.to.top;\n\n\t\t\t\t\t\t\t// if original was \"auto\", recalculate the new value from wrapper\n\t\t\t\t\t\t\tif ( str === \"auto\" ) {\n\t\t\t\t\t\t\t\treturn toRef + \"px\";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn val + toRef + \"px\";\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.shake = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tdirection = o.direction || \"left\",\n\t\tdistance = o.distance || 20,\n\t\ttimes = o.times || 3,\n\t\tanims = times * 2 + 1,\n\t\tspeed = Math.round(o.duration/anims),\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tanimation = {},\n\t\tanimation1 = {},\n\t\tanimation2 = {},\n\t\ti,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\t// Animation\n\tanimation[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance;\n\tanimation1[ ref ] = ( positiveMotion ? \"+=\" : \"-=\" ) + distance * 2;\n\tanimation2[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance * 2;\n\n\t// Animate\n\tel.animate( animation, speed, o.easing );\n\n\t// Shakes\n\tfor ( i = 1; i < times; i++ ) {\n\t\tel.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );\n\t}\n\tel\n\t\t.animate( animation1, speed, o.easing )\n\t\t.animate( animation, speed / 2, o.easing )\n\t\t.queue(function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen > 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.slide = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tdistance,\n\t\tanimation = {};\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]( true );\n\n\t$.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tif ( show ) {\n\t\tel.css( ref, positiveMotion ? (isNaN(distance) ? \"-\" + distance : -distance) : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( positiveMotion ? \"+=\" : \"-=\") :\n\t\t( positiveMotion ? \"-=\" : \"+=\")) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.effects.effect.transfer = function( o, done ) {\n\tvar elem = $( this ),\n\t\ttarget = $( o.to ),\n\t\ttargetFixed = target.css( \"position\" ) === \"fixed\",\n\t\tbody = $(\"body\"),\n\t\tfixTop = targetFixed ? body.scrollTop() : 0,\n\t\tfixLeft = targetFixed ? body.scrollLeft() : 0,\n\t\tendPosition = target.offset(),\n\t\tanimation = {\n\t\t\ttop: endPosition.top - fixTop ,\n\t\t\tleft: endPosition.left - fixLeft ,\n\t\t\theight: target.innerHeight(),\n\t\t\twidth: target.innerWidth()\n\t\t},\n\t\tstartPosition = elem.offset(),\n\t\ttransfer = $( \"<div class='ui-effects-transfer'></div>\" )\n\t\t\t.appendTo( document.body )\n\t\t\t.addClass( o.className )\n\t\t\t.css({\n\t\t\t\ttop: startPosition.top - fixTop ,\n\t\t\t\tleft: startPosition.left - fixLeft ,\n\t\t\t\theight: elem.innerHeight(),\n\t\t\t\twidth: elem.innerWidth(),\n\t\t\t\tposition: targetFixed ? \"fixed\" : \"absolute\"\n\t\t\t})\n\t\t\t.animate( animation, o.duration, o.easing, function() {\n\t\t\t\ttransfer.remove();\n\t\t\t\tdone();\n\t\t\t});\n};\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.widget( \"ui.menu\", {\n\tversion: \"1.10.4\",\n\tdefaultElement: \"<ul>\",\n\tdelay: 300,\n\toptions: {\n\t\ticons: {\n\t\t\tsubmenu: \"ui-icon-carat-1-e\"\n\t\t},\n\t\tmenus: \"ul\",\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"right top\"\n\t\t},\n\t\trole: \"menu\",\n\n\t\t// callbacks\n\t\tblur: null,\n\t\tfocus: null,\n\t\tselect: null\n\t},\n\n\t_create: function() {\n\t\tthis.activeMenu = this.element;\n\t\t// flag used to prevent firing of the click handler\n\t\t// as the event bubbles up through nested menus\n\t\tthis.mouseHandled = false;\n\t\tthis.element\n\t\t\t.uniqueId()\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.toggleClass( \"ui-menu-icons\", !!this.element.find( \".ui-icon\" ).length )\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\ttabIndex: 0\n\t\t\t})\n\t\t\t// need to catch all clicks on disabled menu\n\t\t\t// not possible through _on\n\t\t\t.bind( \"click\" + this.eventNamespace, $.proxy(function( event ) {\n\t\t\t\tif ( this.options.disabled ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}, this ));\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.element\n\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t}\n\n\t\tthis._on({\n\t\t\t// Prevent focus from sticking to links inside menu after clicking\n\t\t\t// them (focus should always stay on UL during navigation).\n\t\t\t\"mousedown .ui-menu-item > a\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-state-disabled > a\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-menu-item:has(a)\": function( event ) {\n\t\t\t\tvar target = $( event.target ).closest( \".ui-menu-item\" );\n\t\t\t\tif ( !this.mouseHandled && target.not( \".ui-state-disabled\" ).length ) {\n\t\t\t\t\tthis.select( event );\n\n\t\t\t\t\t// Only set the mouseHandled flag if the event will bubble, see #9469.\n\t\t\t\t\tif ( !event.isPropagationStopped() ) {\n\t\t\t\t\t\tthis.mouseHandled = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Open submenu on click\n\t\t\t\t\tif ( target.has( \".ui-menu\" ).length ) {\n\t\t\t\t\t\tthis.expand( event );\n\t\t\t\t\t} else if ( !this.element.is( \":focus\" ) && $( this.document[ 0 ].activeElement ).closest( \".ui-menu\" ).length ) {\n\n\t\t\t\t\t\t// Redirect focus to the menu\n\t\t\t\t\t\tthis.element.trigger( \"focus\", [ true ] );\n\n\t\t\t\t\t\t// If the active item is on the top level, let it stay active.\n\t\t\t\t\t\t// Otherwise, blur the active item since it is no longer visible.\n\t\t\t\t\t\tif ( this.active && this.active.parents( \".ui-menu\" ).length === 1 ) {\n\t\t\t\t\t\t\tclearTimeout( this.timer );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"mouseenter .ui-menu-item\": function( event ) {\n\t\t\t\tvar target = $( event.currentTarget );\n\t\t\t\t// Remove ui-state-active class from siblings of the newly focused menu item\n\t\t\t\t// to avoid a jump caused by adjacent elements both having a class with a border\n\t\t\t\ttarget.siblings().children( \".ui-state-active\" ).removeClass( \"ui-state-active\" );\n\t\t\t\tthis.focus( event, target );\n\t\t\t},\n\t\t\tmouseleave: \"collapseAll\",\n\t\t\t\"mouseleave .ui-menu\": \"collapseAll\",\n\t\t\tfocus: function( event, keepActiveItem ) {\n\t\t\t\t// If there's already an active item, keep it active\n\t\t\t\t// If not, activate the first item\n\t\t\t\tvar item = this.active || this.element.children( \".ui-menu-item\" ).eq( 0 );\n\n\t\t\t\tif ( !keepActiveItem ) {\n\t\t\t\t\tthis.focus( event, item );\n\t\t\t\t}\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tif ( !$.contains( this.element[0], this.document[0].activeElement ) ) {\n\t\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tkeydown: \"_keydown\"\n\t\t});\n\n\t\tthis.refresh();\n\n\t\t// Clicks outside of a menu collapse any open menus\n\t\tthis._on( this.document, {\n\t\t\tclick: function( event ) {\n\t\t\t\tif ( !$( event.target ).closest( \".ui-menu\" ).length ) {\n\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t}\n\n\t\t\t\t// Reset the mouseHandled flag\n\t\t\t\tthis.mouseHandled = false;\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\t// Destroy (sub)menus\n\t\tthis.element\n\t\t\t.removeAttr( \"aria-activedescendant\" )\n\t\t\t.find( \".ui-menu\" ).addBack()\n\t\t\t\t.removeClass( \"ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons\" )\n\t\t\t\t.removeAttr( \"role\" )\n\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.show();\n\n\t\t// Destroy menu items\n\t\tthis.element.find( \".ui-menu-item\" )\n\t\t\t.removeClass( \"ui-menu-item\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.children( \"a\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.removeClass( \"ui-corner-all ui-state-hover\" )\n\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t.removeAttr( \"role\" )\n\t\t\t\t.removeAttr( \"aria-haspopup\" )\n\t\t\t\t.children().each( function() {\n\t\t\t\t\tvar elem = $( this );\n\t\t\t\t\tif ( elem.data( \"ui-menu-submenu-carat\" ) ) {\n\t\t\t\t\t\telem.remove();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t// Destroy menu dividers\n\t\tthis.element.find( \".ui-menu-divider\" ).removeClass( \"ui-menu-divider ui-widget-content\" );\n\t},\n\n\t_keydown: function( event ) {\n\t\tvar match, prev, character, skip, regex,\n\t\t\tpreventDefault = true;\n\n\t\tfunction escape( value ) {\n\t\t\treturn value.replace( /[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\" );\n\t\t}\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\tthis.previousPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\tthis.nextPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.HOME:\n\t\t\tthis._move( \"first\", \"first\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.END:\n\t\t\tthis._move( \"last\", \"last\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.UP:\n\t\t\tthis.previous( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.DOWN:\n\t\t\tthis.next( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.LEFT:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tif ( this.active && !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\t\tthis.expand( event );\n\t\t\t}\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ENTER:\n\t\tcase $.ui.keyCode.SPACE:\n\t\t\tthis._activate( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ESCAPE:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpreventDefault = false;\n\t\t\tprev = this.previousFilter || \"\";\n\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\tskip = false;\n\n\t\t\tclearTimeout( this.filterTimer );\n\n\t\t\tif ( character === prev ) {\n\t\t\t\tskip = true;\n\t\t\t} else {\n\t\t\t\tcharacter = prev + character;\n\t\t\t}\n\n\t\t\tregex = new RegExp( \"^\" + escape( character ), \"i\" );\n\t\t\tmatch = this.activeMenu.children( \".ui-menu-item\" ).filter(function() {\n\t\t\t\treturn regex.test( $( this ).children( \"a\" ).text() );\n\t\t\t});\n\t\t\tmatch = skip && match.index( this.active.next() ) !== -1 ?\n\t\t\t\tthis.active.nextAll( \".ui-menu-item\" ) :\n\t\t\t\tmatch;\n\n\t\t\t// If no matches on the current filter, reset to the last character pressed\n\t\t\t// to move down the menu to the first item that starts with that character\n\t\t\tif ( !match.length ) {\n\t\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\t\tregex = new RegExp( \"^\" + escape( character ), \"i\" );\n\t\t\t\tmatch = this.activeMenu.children( \".ui-menu-item\" ).filter(function() {\n\t\t\t\t\treturn regex.test( $( this ).children( \"a\" ).text() );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( match.length ) {\n\t\t\t\tthis.focus( event, match );\n\t\t\t\tif ( match.length > 1 ) {\n\t\t\t\t\tthis.previousFilter = character;\n\t\t\t\t\tthis.filterTimer = this._delay(function() {\n\t\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t\t}, 1000 );\n\t\t\t\t} else {\n\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdelete this.previousFilter;\n\t\t\t}\n\t\t}\n\n\t\tif ( preventDefault ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_activate: function( event ) {\n\t\tif ( !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\tif ( this.active.children( \"a[aria-haspopup='true']\" ).length ) {\n\t\t\t\tthis.expand( event );\n\t\t\t} else {\n\t\t\t\tthis.select( event );\n\t\t\t}\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar menus,\n\t\t\ticon = this.options.icons.submenu,\n\t\t\tsubmenus = this.element.find( this.options.menus );\n\n\t\tthis.element.toggleClass( \"ui-menu-icons\", !!this.element.find( \".ui-icon\" ).length );\n\n\t\t// Initialize nested menus\n\t\tsubmenus.filter( \":not(.ui-menu)\" )\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\"\n\t\t\t})\n\t\t\t.each(function() {\n\t\t\t\tvar menu = $( this ),\n\t\t\t\t\titem = menu.prev( \"a\" ),\n\t\t\t\t\tsubmenuCarat = $( \"<span>\" )\n\t\t\t\t\t\t.addClass( \"ui-menu-icon ui-icon \" + icon )\n\t\t\t\t\t\t.data( \"ui-menu-submenu-carat\", true );\n\n\t\t\t\titem\n\t\t\t\t\t.attr( \"aria-haspopup\", \"true\" )\n\t\t\t\t\t.prepend( submenuCarat );\n\t\t\t\tmenu.attr( \"aria-labelledby\", item.attr( \"id\" ) );\n\t\t\t});\n\n\t\tmenus = submenus.add( this.element );\n\n\t\t// Don't refresh list items that are already adapted\n\t\tmenus.children( \":not(.ui-menu-item):has(a)\" )\n\t\t\t.addClass( \"ui-menu-item\" )\n\t\t\t.attr( \"role\", \"presentation\" )\n\t\t\t.children( \"a\" )\n\t\t\t\t.uniqueId()\n\t\t\t\t.addClass( \"ui-corner-all\" )\n\t\t\t\t.attr({\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t\trole: this._itemRole()\n\t\t\t\t});\n\n\t\t// Initialize unlinked menu-items containing spaces and/or dashes only as dividers\n\t\tmenus.children( \":not(.ui-menu-item)\" ).each(function() {\n\t\t\tvar item = $( this );\n\t\t\t// hyphen, em dash, en dash\n\t\t\tif ( !/[^\\-\\u2014\\u2013\\s]/.test( item.text() ) ) {\n\t\t\t\titem.addClass( \"ui-widget-content ui-menu-divider\" );\n\t\t\t}\n\t\t});\n\n\t\t// Add aria-disabled attribute to any disabled menu item\n\t\tmenus.children( \".ui-state-disabled\" ).attr( \"aria-disabled\", \"true\" );\n\n\t\t// If the active item has been removed, blur the menu\n\t\tif ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\tthis.blur();\n\t\t}\n\t},\n\n\t_itemRole: function() {\n\t\treturn {\n\t\t\tmenu: \"menuitem\",\n\t\t\tlistbox: \"option\"\n\t\t}[ this.options.role ];\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.element.find( \".ui-menu-icon\" )\n\t\t\t\t.removeClass( this.options.icons.submenu )\n\t\t\t\t.addClass( value.submenu );\n\t\t}\n\t\tthis._super( key, value );\n\t},\n\n\tfocus: function( event, item ) {\n\t\tvar nested, focused;\n\t\tthis.blur( event, event && event.type === \"focus\" );\n\n\t\tthis._scrollIntoView( item );\n\n\t\tthis.active = item.first();\n\t\tfocused = this.active.children( \"a\" ).addClass( \"ui-state-focus\" );\n\t\t// Only update aria-activedescendant if there's a role\n\t\t// otherwise we assume focus is managed elsewhere\n\t\tif ( this.options.role ) {\n\t\t\tthis.element.attr( \"aria-activedescendant\", focused.attr( \"id\" ) );\n\t\t}\n\n\t\t// Highlight active parent menu item, if any\n\t\tthis.active\n\t\t\t.parent()\n\t\t\t.closest( \".ui-menu-item\" )\n\t\t\t.children( \"a:first\" )\n\t\t\t.addClass( \"ui-state-active\" );\n\n\t\tif ( event && event.type === \"keydown\" ) {\n\t\t\tthis._close();\n\t\t} else {\n\t\t\tthis.timer = this._delay(function() {\n\t\t\t\tthis._close();\n\t\t\t}, this.delay );\n\t\t}\n\n\t\tnested = item.children( \".ui-menu\" );\n\t\tif ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {\n\t\t\tthis._startOpening(nested);\n\t\t}\n\t\tthis.activeMenu = item.parent();\n\n\t\tthis._trigger( \"focus\", event, { item: item } );\n\t},\n\n\t_scrollIntoView: function( item ) {\n\t\tvar borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;\n\t\tif ( this._hasScroll() ) {\n\t\t\tborderTop = parseFloat( $.css( this.activeMenu[0], \"borderTopWidth\" ) ) || 0;\n\t\t\tpaddingTop = parseFloat( $.css( this.activeMenu[0], \"paddingTop\" ) ) || 0;\n\t\t\toffset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;\n\t\t\tscroll = this.activeMenu.scrollTop();\n\t\t\telementHeight = this.activeMenu.height();\n\t\t\titemHeight = item.height();\n\n\t\t\tif ( offset < 0 ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset );\n\t\t\t} else if ( offset + itemHeight > elementHeight ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );\n\t\t\t}\n\t\t}\n\t},\n\n\tblur: function( event, fromFocus ) {\n\t\tif ( !fromFocus ) {\n\t\t\tclearTimeout( this.timer );\n\t\t}\n\n\t\tif ( !this.active ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.active.children( \"a\" ).removeClass( \"ui-state-focus\" );\n\t\tthis.active = null;\n\n\t\tthis._trigger( \"blur\", event, { item: this.active } );\n\t},\n\n\t_startOpening: function( submenu ) {\n\t\tclearTimeout( this.timer );\n\n\t\t// Don't open if already open fixes a Firefox bug that caused a .5 pixel\n\t\t// shift in the submenu position when mousing over the carat icon\n\t\tif ( submenu.attr( \"aria-hidden\" ) !== \"true\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._close();\n\t\t\tthis._open( submenu );\n\t\t}, this.delay );\n\t},\n\n\t_open: function( submenu ) {\n\t\tvar position = $.extend({\n\t\t\tof: this.active\n\t\t}, this.options.position );\n\n\t\tclearTimeout( this.timer );\n\t\tthis.element.find( \".ui-menu\" ).not( submenu.parents( \".ui-menu\" ) )\n\t\t\t.hide()\n\t\t\t.attr( \"aria-hidden\", \"true\" );\n\n\t\tsubmenu\n\t\t\t.show()\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.attr( \"aria-expanded\", \"true\" )\n\t\t\t.position( position );\n\t},\n\n\tcollapseAll: function( event, all ) {\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\t// If we were passed an event, look for the submenu that contains the event\n\t\t\tvar currentMenu = all ? this.element :\n\t\t\t\t$( event && event.target ).closest( this.element.find( \".ui-menu\" ) );\n\n\t\t\t// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway\n\t\t\tif ( !currentMenu.length ) {\n\t\t\t\tcurrentMenu = this.element;\n\t\t\t}\n\n\t\t\tthis._close( currentMenu );\n\n\t\t\tthis.blur( event );\n\t\t\tthis.activeMenu = currentMenu;\n\t\t}, this.delay );\n\t},\n\n\t// With no arguments, closes the currently active menu - if nothing is active\n\t// it closes all menus.  If passed an argument, it will search for menus BELOW\n\t_close: function( startMenu ) {\n\t\tif ( !startMenu ) {\n\t\t\tstartMenu = this.active ? this.active.parent() : this.element;\n\t\t}\n\n\t\tstartMenu\n\t\t\t.find( \".ui-menu\" )\n\t\t\t\t.hide()\n\t\t\t\t.attr( \"aria-hidden\", \"true\" )\n\t\t\t\t.attr( \"aria-expanded\", \"false\" )\n\t\t\t.end()\n\t\t\t.find( \"a.ui-state-active\" )\n\t\t\t\t.removeClass( \"ui-state-active\" );\n\t},\n\n\tcollapse: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active.parent().closest( \".ui-menu-item\", this.element );\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._close();\n\t\t\tthis.focus( event, newItem );\n\t\t}\n\t},\n\n\texpand: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active\n\t\t\t\t.children( \".ui-menu \" )\n\t\t\t\t.children( \".ui-menu-item\" )\n\t\t\t\t.first();\n\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._open( newItem.parent() );\n\n\t\t\t// Delay so Firefox will not hide activedescendant change in expanding submenu from AT\n\t\t\tthis._delay(function() {\n\t\t\t\tthis.focus( event, newItem );\n\t\t\t});\n\t\t}\n\t},\n\n\tnext: function( event ) {\n\t\tthis._move( \"next\", \"first\", event );\n\t},\n\n\tprevious: function( event ) {\n\t\tthis._move( \"prev\", \"last\", event );\n\t},\n\n\tisFirstItem: function() {\n\t\treturn this.active && !this.active.prevAll( \".ui-menu-item\" ).length;\n\t},\n\n\tisLastItem: function() {\n\t\treturn this.active && !this.active.nextAll( \".ui-menu-item\" ).length;\n\t},\n\n\t_move: function( direction, filter, event ) {\n\t\tvar next;\n\t\tif ( this.active ) {\n\t\t\tif ( direction === \"first\" || direction === \"last\" ) {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction === \"first\" ? \"prevAll\" : \"nextAll\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( -1 );\n\t\t\t} else {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction + \"All\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( 0 );\n\t\t\t}\n\t\t}\n\t\tif ( !next || !next.length || !this.active ) {\n\t\t\tnext = this.activeMenu.children( \".ui-menu-item\" )[ filter ]();\n\t\t}\n\n\t\tthis.focus( event, next );\n\t},\n\n\tnextPage: function( event ) {\n\t\tvar item, base, height;\n\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isLastItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.nextAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base - height < 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.children( \".ui-menu-item\" )\n\t\t\t\t[ !this.active ? \"first\" : \"last\" ]() );\n\t\t}\n\t},\n\n\tpreviousPage: function( event ) {\n\t\tvar item, base, height;\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isFirstItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.prevAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base + height > 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.children( \".ui-menu-item\" ).first() );\n\t\t}\n\t},\n\n\t_hasScroll: function() {\n\t\treturn this.element.outerHeight() < this.element.prop( \"scrollHeight\" );\n\t},\n\n\tselect: function( event ) {\n\t\t// TODO: It should never be possible to not have an active item at this\n\t\t// point, but the tests don't trigger mouseenter before click.\n\t\tthis.active = this.active || $( event.target ).closest( \".ui-menu-item\" );\n\t\tvar ui = { item: this.active };\n\t\tif ( !this.active.has( \".ui-menu\" ).length ) {\n\t\t\tthis.collapseAll( event, true );\n\t\t}\n\t\tthis._trigger( \"select\", event, ui );\n\t}\n});\n\n}( jQuery ));\n(function( $, undefined ) {\n\n$.widget( \"ui.progressbar\", {\n\tversion: \"1.10.4\",\n\toptions: {\n\t\tmax: 100,\n\t\tvalue: 0,\n\n\t\tchange: null,\n\t\tcomplete: null\n\t},\n\n\tmin: 0,\n\n\t_create: function() {\n\t\t// Constrain initial value\n\t\tthis.oldValue = this.options.value = this._constrainedValue();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.attr({\n\t\t\t\t// Only set static values, aria-valuenow and aria-valuemax are\n\t\t\t\t// set inside _refreshValue()\n\t\t\t\trole: \"progressbar\",\n\t\t\t\t\"aria-valuemin\": this.min\n\t\t\t});\n\n\t\tthis.valueDiv = $( \"<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>\" )\n\t\t\t.appendTo( this.element );\n\n\t\tthis._refreshValue();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\n\t\tthis.valueDiv.remove();\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\treturn this.options.value;\n\t\t}\n\n\t\tthis.options.value = this._constrainedValue( newValue );\n\t\tthis._refreshValue();\n\t},\n\n\t_constrainedValue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\tnewValue = this.options.value;\n\t\t}\n\n\t\tthis.indeterminate = newValue === false;\n\n\t\t// sanitize value\n\t\tif ( typeof newValue !== \"number\" ) {\n\t\t\tnewValue = 0;\n\t\t}\n\n\t\treturn this.indeterminate ? false :\n\t\t\tMath.min( this.options.max, Math.max( this.min, newValue ) );\n\t},\n\n\t_setOptions: function( options ) {\n\t\t// Ensure \"value\" option is set after other values (like max)\n\t\tvar value = options.value;\n\t\tdelete options.value;\n\n\t\tthis._super( options );\n\n\t\tthis.options.value = this._constrainedValue( value );\n\t\tthis._refreshValue();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"max\" ) {\n\t\t\t// Don't allow a max less than min\n\t\t\tvalue = Math.max( this.min, value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\t_percentage: function() {\n\t\treturn this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );\n\t},\n\n\t_refreshValue: function() {\n\t\tvar value = this.options.value,\n\t\t\tpercentage = this._percentage();\n\n\t\tthis.valueDiv\n\t\t\t.toggle( this.indeterminate || value > this.min )\n\t\t\t.toggleClass( \"ui-corner-right\", value === this.options.max )\n\t\t\t.width( percentage.toFixed(0) + \"%\" );\n\n\t\tthis.element.toggleClass( \"ui-progressbar-indeterminate\", this.indeterminate );\n\n\t\tif ( this.indeterminate ) {\n\t\t\tthis.element.removeAttr( \"aria-valuenow\" );\n\t\t\tif ( !this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv = $( \"<div class='ui-progressbar-overlay'></div>\" ).appendTo( this.valueDiv );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.element.attr({\n\t\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t\t\"aria-valuenow\": value\n\t\t\t});\n\t\t\tif ( this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv.remove();\n\t\t\t\tthis.overlayDiv = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( this.oldValue !== value ) {\n\t\t\tthis.oldValue = value;\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t\tif ( value === this.options.max ) {\n\t\t\tthis._trigger( \"complete\" );\n\t\t}\n\t}\n});\n\n})( jQuery );\n(function( $, undefined ) {\n\nfunction num(v) {\n\treturn parseInt(v, 10) || 0;\n}\n\nfunction isNumber(value) {\n\treturn !isNaN(parseInt(value, 10));\n}\n\n$.widget(\"ui.resizable\", $.ui.mouse, {\n\tversion: \"1.10.4\",\n\twidgetEventPrefix: \"resize\",\n\toptions: {\n\t\talsoResize: false,\n\t\tanimate: false,\n\t\tanimateDuration: \"slow\",\n\t\tanimateEasing: \"swing\",\n\t\taspectRatio: false,\n\t\tautoHide: false,\n\t\tcontainment: false,\n\t\tghost: false,\n\t\tgrid: false,\n\t\thandles: \"e,s,se\",\n\t\thelper: false,\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 10,\n\t\tminWidth: 10,\n\t\t// See #7960\n\t\tzIndex: 90,\n\n\t\t// callbacks\n\t\tresize: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\t_create: function() {\n\n\t\tvar n, i, handle, axis, hname,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\t\tthis.element.addClass(\"ui-resizable\");\n\n\t\t$.extend(this, {\n\t\t\t_aspectRatio: !!(o.aspectRatio),\n\t\t\taspectRatio: o.aspectRatio,\n\t\t\toriginalElement: this.element,\n\t\t\t_proportionallyResizeElements: [],\n\t\t\t_helper: o.helper || o.ghost || o.animate ? o.helper || \"ui-resizable-helper\" : null\n\t\t});\n\n\t\t//Wrap the element if it cannot hold child nodes\n\t\tif(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {\n\n\t\t\t//Create a wrapper element and set the wrapper to the new current internal element\n\t\t\tthis.element.wrap(\n\t\t\t\t$(\"<div class='ui-wrapper' style='overflow: hidden;'></div>\").css({\n\t\t\t\t\tposition: this.element.css(\"position\"),\n\t\t\t\t\twidth: this.element.outerWidth(),\n\t\t\t\t\theight: this.element.outerHeight(),\n\t\t\t\t\ttop: this.element.css(\"top\"),\n\t\t\t\t\tleft: this.element.css(\"left\")\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t//Overwrite the original this.element\n\t\t\tthis.element = this.element.parent().data(\n\t\t\t\t\"ui-resizable\", this.element.data(\"ui-resizable\")\n\t\t\t);\n\n\t\t\tthis.elementIsWrapper = true;\n\n\t\t\t//Move margins to the wrapper\n\t\t\tthis.element.css({ marginLeft: this.originalElement.css(\"marginLeft\"), marginTop: this.originalElement.css(\"marginTop\"), marginRight: this.originalElement.css(\"marginRight\"), marginBottom: this.originalElement.css(\"marginBottom\") });\n\t\t\tthis.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});\n\n\t\t\t//Prevent Safari textarea resize\n\t\t\tthis.originalResizeStyle = this.originalElement.css(\"resize\");\n\t\t\tthis.originalElement.css(\"resize\", \"none\");\n\n\t\t\t//Push the actual element to our proportionallyResize internal array\n\t\t\tthis._proportionallyResizeElements.push(this.originalElement.css({ position: \"static\", zoom: 1, display: \"block\" }));\n\n\t\t\t// avoid IE jump (hard set the margin)\n\t\t\tthis.originalElement.css({ margin: this.originalElement.css(\"margin\") });\n\n\t\t\t// fix handlers offset\n\t\t\tthis._proportionallyResize();\n\n\t\t}\n\n\t\tthis.handles = o.handles || (!$(\".ui-resizable-handle\", this.element).length ? \"e,s,se\" : { n: \".ui-resizable-n\", e: \".ui-resizable-e\", s: \".ui-resizable-s\", w: \".ui-resizable-w\", se: \".ui-resizable-se\", sw: \".ui-resizable-sw\", ne: \".ui-resizable-ne\", nw: \".ui-resizable-nw\" });\n\t\tif(this.handles.constructor === String) {\n\n\t\t\tif ( this.handles === \"all\") {\n\t\t\t\tthis.handles = \"n,e,s,w,se,sw,ne,nw\";\n\t\t\t}\n\n\t\t\tn = this.handles.split(\",\");\n\t\t\tthis.handles = {};\n\n\t\t\tfor(i = 0; i < n.length; i++) {\n\n\t\t\t\thandle = $.trim(n[i]);\n\t\t\t\thname = \"ui-resizable-\"+handle;\n\t\t\t\taxis = $(\"<div class='ui-resizable-handle \" + hname + \"'></div>\");\n\n\t\t\t\t// Apply zIndex to all handles - see #7960\n\t\t\t\taxis.css({ zIndex: o.zIndex });\n\n\t\t\t\t//TODO : What's going on here?\n\t\t\t\tif (\"se\" === handle) {\n\t\t\t\t\taxis.addClass(\"ui-icon ui-icon-gripsmall-diagonal-se\");\n\t\t\t\t}\n\n\t\t\t\t//Insert into internal handles object and append to element\n\t\t\t\tthis.handles[handle] = \".ui-resizable-\"+handle;\n\t\t\t\tthis.element.append(axis);\n\t\t\t}\n\n\t\t}\n\n\t\tthis._renderAxis = function(target) {\n\n\t\t\tvar i, axis, padPos, padWrapper;\n\n\t\t\ttarget = target || this.element;\n\n\t\t\tfor(i in this.handles) {\n\n\t\t\t\tif(this.handles[i].constructor === String) {\n\t\t\t\t\tthis.handles[i] = $(this.handles[i], this.element).show();\n\t\t\t\t}\n\n\t\t\t\t//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)\n\t\t\t\tif (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {\n\n\t\t\t\t\taxis = $(this.handles[i], this.element);\n\n\t\t\t\t\t//Checking the correct pad and border\n\t\t\t\t\tpadWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();\n\n\t\t\t\t\t//The padding type i have to apply...\n\t\t\t\t\tpadPos = [ \"padding\",\n\t\t\t\t\t\t/ne|nw|n/.test(i) ? \"Top\" :\n\t\t\t\t\t\t/se|sw|s/.test(i) ? \"Bottom\" :\n\t\t\t\t\t\t/^e$/.test(i) ? \"Right\" : \"Left\" ].join(\"\");\n\n\t\t\t\t\ttarget.css(padPos, padWrapper);\n\n\t\t\t\t\tthis._proportionallyResize();\n\n\t\t\t\t}\n\n\t\t\t\t//TODO: What's that good for? There's not anything to be executed left\n\t\t\t\tif(!$(this.handles[i]).length) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t//TODO: make renderAxis a prototype function\n\t\tthis._renderAxis(this.element);\n\n\t\tthis._handles = $(\".ui-resizable-handle\", this.element)\n\t\t\t.disableSelection();\n\n\t\t//Matching axis name\n\t\tthis._handles.mouseover(function() {\n\t\t\tif (!that.resizing) {\n\t\t\t\tif (this.className) {\n\t\t\t\t\taxis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);\n\t\t\t\t}\n\t\t\t\t//Axis, default = se\n\t\t\t\tthat.axis = axis && axis[1] ? axis[1] : \"se\";\n\t\t\t}\n\t\t});\n\n\t\t//If we want to auto hide the elements\n\t\tif (o.autoHide) {\n\t\t\tthis._handles.hide();\n\t\t\t$(this.element)\n\t\t\t\t.addClass(\"ui-resizable-autohide\")\n\t\t\t\t.mouseenter(function() {\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t$(this).removeClass(\"ui-resizable-autohide\");\n\t\t\t\t\tthat._handles.show();\n\t\t\t\t})\n\t\t\t\t.mouseleave(function(){\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!that.resizing) {\n\t\t\t\t\t\t$(this).addClass(\"ui-resizable-autohide\");\n\t\t\t\t\t\tthat._handles.hide();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}\n\n\t\t//Initialize the mouse interaction\n\t\tthis._mouseInit();\n\n\t},\n\n\t_destroy: function() {\n\n\t\tthis._mouseDestroy();\n\n\t\tvar wrapper,\n\t\t\t_destroy = function(exp) {\n\t\t\t\t$(exp).removeClass(\"ui-resizable ui-resizable-disabled ui-resizable-resizing\")\n\t\t\t\t\t.removeData(\"resizable\").removeData(\"ui-resizable\").unbind(\".resizable\").find(\".ui-resizable-handle\").remove();\n\t\t\t};\n\n\t\t//TODO: Unwrap at same DOM position\n\t\tif (this.elementIsWrapper) {\n\t\t\t_destroy(this.element);\n\t\t\twrapper = this.element;\n\t\t\tthis.originalElement.css({\n\t\t\t\tposition: wrapper.css(\"position\"),\n\t\t\t\twidth: wrapper.outerWidth(),\n\t\t\t\theight: wrapper.outerHeight(),\n\t\t\t\ttop: wrapper.css(\"top\"),\n\t\t\t\tleft: wrapper.css(\"left\")\n\t\t\t}).insertAfter( wrapper );\n\t\t\twrapper.remove();\n\t\t}\n\n\t\tthis.originalElement.css(\"resize\", this.originalResizeStyle);\n\t\t_destroy(this.originalElement);\n\n\t\treturn this;\n\t},\n\n\t_mouseCapture: function(event) {\n\t\tvar i, handle,\n\t\t\tcapture = false;\n\n\t\tfor (i in this.handles) {\n\t\t\thandle = $(this.handles[i])[0];\n\t\t\tif (handle === event.target || $.contains(handle, event.target)) {\n\t\t\t\tcapture = true;\n\t\t\t}\n\t\t}\n\n\t\treturn !this.options.disabled && capture;\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar curleft, curtop, cursor,\n\t\t\to = this.options,\n\t\t\tiniPos = this.element.position(),\n\t\t\tel = this.element;\n\n\t\tthis.resizing = true;\n\n\t\t// bugfix for http://dev.jquery.com/ticket/1749\n\t\tif ( (/absolute/).test( el.css(\"position\") ) ) {\n\t\t\tel.css({ position: \"absolute\", top: el.css(\"top\"), left: el.css(\"left\") });\n\t\t} else if (el.is(\".ui-draggable\")) {\n\t\t\tel.css({ position: \"absolute\", top: iniPos.top, left: iniPos.left });\n\t\t}\n\n\t\tthis._renderProxy();\n\n\t\tcurleft = num(this.helper.css(\"left\"));\n\t\tcurtop = num(this.helper.css(\"top\"));\n\n\t\tif (o.containment) {\n\t\t\tcurleft += $(o.containment).scrollLeft() || 0;\n\t\t\tcurtop += $(o.containment).scrollTop() || 0;\n\t\t}\n\n\t\t//Store needed variables\n\t\tthis.offset = this.helper.offset();\n\t\tthis.position = { left: curleft, top: curtop };\n\t\tthis.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };\n\t\tthis.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };\n\t\tthis.originalPosition = { left: curleft, top: curtop };\n\t\tthis.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };\n\t\tthis.originalMousePosition = { left: event.pageX, top: event.pageY };\n\n\t\t//Aspect Ratio\n\t\tthis.aspectRatio = (typeof o.aspectRatio === \"number\") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);\n\n\t\tcursor = $(\".ui-resizable-\" + this.axis).css(\"cursor\");\n\t\t$(\"body\").css(\"cursor\", cursor === \"auto\" ? this.axis + \"-resize\" : cursor);\n\n\t\tel.addClass(\"ui-resizable-resizing\");\n\t\tthis._propagate(\"start\", event);\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\t//Increase performance, avoid regex\n\t\tvar data,\n\t\t\tel = this.helper, props = {},\n\t\t\tsmp = this.originalMousePosition,\n\t\t\ta = this.axis,\n\t\t\tprevTop = this.position.top,\n\t\t\tprevLeft = this.position.left,\n\t\t\tprevWidth = this.size.width,\n\t\t\tprevHeight = this.size.height,\n\t\t\tdx = (event.pageX-smp.left)||0,\n\t\t\tdy = (event.pageY-smp.top)||0,\n\t\t\ttrigger = this._change[a];\n\n\t\tif (!trigger) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Calculate the attrs that will be change\n\t\tdata = trigger.apply(this, [event, dx, dy]);\n\n\t\t// Put this in the mouseDrag handler since the user can start pressing shift while resizing\n\t\tthis._updateVirtualBoundaries(event.shiftKey);\n\t\tif (this._aspectRatio || event.shiftKey) {\n\t\t\tdata = this._updateRatio(data, event);\n\t\t}\n\n\t\tdata = this._respectSize(data, event);\n\n\t\tthis._updateCache(data);\n\n\t\t// plugins callbacks need to be called first\n\t\tthis._propagate(\"resize\", event);\n\n\t\tif (this.position.top !== prevTop) {\n\t\t\tprops.top = this.position.top + \"px\";\n\t\t}\n\t\tif (this.position.left !== prevLeft) {\n\t\t\tprops.left = this.position.left + \"px\";\n\t\t}\n\t\tif (this.size.width !== prevWidth) {\n\t\t\tprops.width = this.size.width + \"px\";\n\t\t}\n\t\tif (this.size.height !== prevHeight) {\n\t\t\tprops.height = this.size.height + \"px\";\n\t\t}\n\t\tel.css(props);\n\n\t\tif (!this._helper && this._proportionallyResizeElements.length) {\n\t\t\tthis._proportionallyResize();\n\t\t}\n\n\t\t// Call the user callback if the element was resized\n\t\tif ( ! $.isEmptyObject(props) ) {\n\t\t\tthis._trigger(\"resize\", event, this.ui());\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\tthis.resizing = false;\n\t\tvar pr, ista, soffseth, soffsetw, s, left, top,\n\t\t\to = this.options, that = this;\n\n\t\tif(this._helper) {\n\n\t\t\tpr = this._proportionallyResizeElements;\n\t\t\tista = pr.length && (/textarea/i).test(pr[0].nodeName);\n\t\t\tsoffseth = ista && $.ui.hasScroll(pr[0], \"left\") /* TODO - jump height */ ? 0 : that.sizeDiff.height;\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width;\n\n\t\t\ts = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) + (that.position.left - that.originalPosition.left)) || null;\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) + (that.position.top - that.originalPosition.top)) || null;\n\n\t\t\tif (!o.animate) {\n\t\t\t\tthis.element.css($.extend(s, { top: top, left: left }));\n\t\t\t}\n\n\t\t\tthat.helper.height(that.size.height);\n\t\t\tthat.helper.width(that.size.width);\n\n\t\t\tif (this._helper && !o.animate) {\n\t\t\t\tthis._proportionallyResize();\n\t\t\t}\n\t\t}\n\n\t\t$(\"body\").css(\"cursor\", \"auto\");\n\n\t\tthis.element.removeClass(\"ui-resizable-resizing\");\n\n\t\tthis._propagate(\"stop\", event);\n\n\t\tif (this._helper) {\n\t\t\tthis.helper.remove();\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\t_updateVirtualBoundaries: function(forceAspectRatio) {\n\t\tvar pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,\n\t\t\to = this.options;\n\n\t\tb = {\n\t\t\tminWidth: isNumber(o.minWidth) ? o.minWidth : 0,\n\t\t\tmaxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,\n\t\t\tminHeight: isNumber(o.minHeight) ? o.minHeight : 0,\n\t\t\tmaxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity\n\t\t};\n\n\t\tif(this._aspectRatio || forceAspectRatio) {\n\t\t\t// We want to create an enclosing box whose aspect ration is the requested one\n\t\t\t// First, compute the \"projected\" size for each dimension based on the aspect ratio and other dimension\n\t\t\tpMinWidth = b.minHeight * this.aspectRatio;\n\t\t\tpMinHeight = b.minWidth / this.aspectRatio;\n\t\t\tpMaxWidth = b.maxHeight * this.aspectRatio;\n\t\t\tpMaxHeight = b.maxWidth / this.aspectRatio;\n\n\t\t\tif(pMinWidth > b.minWidth) {\n\t\t\t\tb.minWidth = pMinWidth;\n\t\t\t}\n\t\t\tif(pMinHeight > b.minHeight) {\n\t\t\t\tb.minHeight = pMinHeight;\n\t\t\t}\n\t\t\tif(pMaxWidth < b.maxWidth) {\n\t\t\t\tb.maxWidth = pMaxWidth;\n\t\t\t}\n\t\t\tif(pMaxHeight < b.maxHeight) {\n\t\t\t\tb.maxHeight = pMaxHeight;\n\t\t\t}\n\t\t}\n\t\tthis._vBoundaries = b;\n\t},\n\n\t_updateCache: function(data) {\n\t\tthis.offset = this.helper.offset();\n\t\tif (isNumber(data.left)) {\n\t\t\tthis.position.left = data.left;\n\t\t}\n\t\tif (isNumber(data.top)) {\n\t\t\tthis.position.top = data.top;\n\t\t}\n\t\tif (isNumber(data.height)) {\n\t\t\tthis.size.height = data.height;\n\t\t}\n\t\tif (isNumber(data.width)) {\n\t\t\tthis.size.width = data.width;\n\t\t}\n\t},\n\n\t_updateRatio: function( data ) {\n\n\t\tvar cpos = this.position,\n\t\t\tcsize = this.size,\n\t\t\ta = this.axis;\n\n\t\tif (isNumber(data.height)) {\n\t\t\tdata.width = (data.height * this.aspectRatio);\n\t\t} else if (isNumber(data.width)) {\n\t\t\tdata.height = (data.width / this.aspectRatio);\n\t\t}\n\n\t\tif (a === \"sw\") {\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t\tdata.top = null;\n\t\t}\n\t\tif (a === \"nw\") {\n\t\t\tdata.top = cpos.top + (csize.height - data.height);\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_respectSize: function( data ) {\n\n\t\tvar o = this._vBoundaries,\n\t\t\ta = this.axis,\n\t\t\tismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),\n\t\t\tisminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),\n\t\t\tdw = this.originalPosition.left + this.originalSize.width,\n\t\t\tdh = this.position.top + this.size.height,\n\t\t\tcw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);\n\t\tif (isminw) {\n\t\t\tdata.width = o.minWidth;\n\t\t}\n\t\tif (isminh) {\n\t\t\tdata.height = o.minHeight;\n\t\t}\n\t\tif (ismaxw) {\n\t\t\tdata.width = o.maxWidth;\n\t\t}\n\t\tif (ismaxh) {\n\t\t\tdata.height = o.maxHeight;\n\t\t}\n\n\t\tif (isminw && cw) {\n\t\t\tdata.left = dw - o.minWidth;\n\t\t}\n\t\tif (ismaxw && cw) {\n\t\t\tdata.left = dw - o.maxWidth;\n\t\t}\n\t\tif (isminh && ch) {\n\t\t\tdata.top = dh - o.minHeight;\n\t\t}\n\t\tif (ismaxh && ch) {\n\t\t\tdata.top = dh - o.maxHeight;\n\t\t}\n\n\t\t// fixing jump error on top/left - bug #2330\n\t\tif (!data.width && !data.height && !data.left && data.top) {\n\t\t\tdata.top = null;\n\t\t} else if (!data.width && !data.height && !data.top && data.left) {\n\t\t\tdata.left = null;\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_proportionallyResize: function() {\n\n\t\tif (!this._proportionallyResizeElements.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar i, j, borders, paddings, prel,\n\t\t\telement = this.helper || this.element;\n\n\t\tfor ( i=0; i < this._proportionallyResizeElements.length; i++) {\n\n\t\t\tprel = this._proportionallyResizeElements[i];\n\n\t\t\tif (!this.borderDif) {\n\t\t\t\tthis.borderDif = [];\n\t\t\t\tborders = [prel.css(\"borderTopWidth\"), prel.css(\"borderRightWidth\"), prel.css(\"borderBottomWidth\"), prel.css(\"borderLeftWidth\")];\n\t\t\t\tpaddings = [prel.css(\"paddingTop\"), prel.css(\"paddingRight\"), prel.css(\"paddingBottom\"), prel.css(\"paddingLeft\")];\n\n\t\t\t\tfor ( j = 0; j < borders.length; j++ ) {\n\t\t\t\t\tthis.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprel.css({\n\t\t\t\theight: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,\n\t\t\t\twidth: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0\n\t\t\t});\n\n\t\t}\n\n\t},\n\n\t_renderProxy: function() {\n\n\t\tvar el = this.element, o = this.options;\n\t\tthis.elementOffset = el.offset();\n\n\t\tif(this._helper) {\n\n\t\t\tthis.helper = this.helper || $(\"<div style='overflow:hidden;'></div>\");\n\n\t\t\tthis.helper.addClass(this._helper).css({\n\t\t\t\twidth: this.element.outerWidth() - 1,\n\t\t\t\theight: this.element.outerHeight() - 1,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: this.elementOffset.left +\"px\",\n\t\t\t\ttop: this.elementOffset.top +\"px\",\n\t\t\t\tzIndex: ++o.zIndex //TODO: Don't modify option\n\t\t\t});\n\n\t\t\tthis.helper\n\t\t\t\t.appendTo(\"body\")\n\t\t\t\t.disableSelection();\n\n\t\t} else {\n\t\t\tthis.helper = this.element;\n\t\t}\n\n\t},\n\n\t_change: {\n\t\te: function(event, dx) {\n\t\t\treturn { width: this.originalSize.width + dx };\n\t\t},\n\t\tw: function(event, dx) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { left: sp.left + dx, width: cs.width - dx };\n\t\t},\n\t\tn: function(event, dx, dy) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { top: sp.top + dy, height: cs.height - dy };\n\t\t},\n\t\ts: function(event, dx, dy) {\n\t\t\treturn { height: this.originalSize.height + dy };\n\t\t},\n\t\tse: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));\n\t\t},\n\t\tsw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));\n\t\t},\n\t\tne: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));\n\t\t},\n\t\tnw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));\n\t\t}\n\t},\n\n\t_propagate: function(n, event) {\n\t\t$.ui.plugin.call(this, n, [event, this.ui()]);\n\t\t(n !== \"resize\" && this._trigger(n, event, this.ui()));\n\t},\n\n\tplugins: {},\n\n\tui: function() {\n\t\treturn {\n\t\t\toriginalElement: this.originalElement,\n\t\t\telement: this.element,\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\tsize: this.size,\n\t\t\toriginalSize: this.originalSize,\n\t\t\toriginalPosition: this.originalPosition\n\t\t};\n\t}\n\n});\n\n/*\n * Resizable Extensions\n */\n\n$.ui.plugin.add(\"resizable\", \"animate\", {\n\n\tstop: function( event ) {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tpr = that._proportionallyResizeElements,\n\t\t\tista = pr.length && (/textarea/i).test(pr[0].nodeName),\n\t\t\tsoffseth = ista && $.ui.hasScroll(pr[0], \"left\") /* TODO - jump height */ ? 0 : that.sizeDiff.height,\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width,\n\t\t\tstyle = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) + (that.position.left - that.originalPosition.left)) || null,\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) + (that.position.top - that.originalPosition.top)) || null;\n\n\t\tthat.element.animate(\n\t\t\t$.extend(style, top && left ? { top: top, left: left } : {}), {\n\t\t\t\tduration: o.animateDuration,\n\t\t\t\teasing: o.animateEasing,\n\t\t\t\tstep: function() {\n\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\twidth: parseInt(that.element.css(\"width\"), 10),\n\t\t\t\t\t\theight: parseInt(that.element.css(\"height\"), 10),\n\t\t\t\t\t\ttop: parseInt(that.element.css(\"top\"), 10),\n\t\t\t\t\t\tleft: parseInt(that.element.css(\"left\"), 10)\n\t\t\t\t\t};\n\n\t\t\t\t\tif (pr && pr.length) {\n\t\t\t\t\t\t$(pr[0]).css({ width: data.width, height: data.height });\n\t\t\t\t\t}\n\n\t\t\t\t\t// propagating resize, and updating values for each animation step\n\t\t\t\t\tthat._updateCache(data);\n\t\t\t\t\tthat._propagate(\"resize\", event);\n\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n});\n\n$.ui.plugin.add(\"resizable\", \"containment\", {\n\n\tstart: function() {\n\t\tvar element, p, co, ch, cw, width, height,\n\t\t\tthat = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tel = that.element,\n\t\t\toc = o.containment,\n\t\t\tce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;\n\n\t\tif (!ce) {\n\t\t\treturn;\n\t\t}\n\n\t\tthat.containerElement = $(ce);\n\n\t\tif (/document/.test(oc) || oc === document) {\n\t\t\tthat.containerOffset = { left: 0, top: 0 };\n\t\t\tthat.containerPosition = { left: 0, top: 0 };\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: $(document), left: 0, top: 0,\n\t\t\t\twidth: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight\n\t\t\t};\n\t\t}\n\n\t\t// i'm a node, so compute top, left, right, bottom\n\t\telse {\n\t\t\telement = $(ce);\n\t\t\tp = [];\n\t\t\t$([ \"Top\", \"Right\", \"Left\", \"Bottom\" ]).each(function(i, name) { p[i] = num(element.css(\"padding\" + name)); });\n\n\t\t\tthat.containerOffset = element.offset();\n\t\t\tthat.containerPosition = element.position();\n\t\t\tthat.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };\n\n\t\t\tco = that.containerOffset;\n\t\t\tch = that.containerSize.height;\n\t\t\tcw = that.containerSize.width;\n\t\t\twidth = ($.ui.hasScroll(ce, \"left\") ? ce.scrollWidth : cw );\n\t\t\theight = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: ce, left: co.left, top: co.top, width: width, height: height\n\t\t\t};\n\t\t}\n\t},\n\n\tresize: function( event ) {\n\t\tvar woset, hoset, isParent, isOffsetRelative,\n\t\t\tthat = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset, cp = that.position,\n\t\t\tpRatio = that._aspectRatio || event.shiftKey,\n\t\t\tcop = { top:0, left:0 }, ce = that.containerElement;\n\n\t\tif (ce[0] !== document && (/static/).test(ce.css(\"position\"))) {\n\t\t\tcop = co;\n\t\t}\n\n\t\tif (cp.left < (that._helper ? co.left : 0)) {\n\t\t\tthat.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t}\n\t\t\tthat.position.left = o.helper ? co.left : 0;\n\t\t}\n\n\t\tif (cp.top < (that._helper ? co.top : 0)) {\n\t\t\tthat.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t}\n\t\t\tthat.position.top = that._helper ? co.top : 0;\n\t\t}\n\n\t\tthat.offset.left = that.parentData.left+that.position.left;\n\t\tthat.offset.top = that.parentData.top+that.position.top;\n\n\t\twoset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );\n\t\thoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );\n\n\t\tisParent = that.containerElement.get(0) === that.element.parent().get(0);\n\t\tisOffsetRelative = /relative|absolute/.test(that.containerElement.css(\"position\"));\n\n\t\tif ( isParent && isOffsetRelative ) {\n\t\t\twoset -= Math.abs( that.parentData.left );\n\t\t}\n\n\t\tif (woset + that.size.width >= that.parentData.width) {\n\t\t\tthat.size.width = that.parentData.width - woset;\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t}\n\t\t}\n\n\t\tif (hoset + that.size.height >= that.parentData.height) {\n\t\t\tthat.size.height = that.parentData.height - hoset;\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t}\n\t\t}\n\t},\n\n\tstop: function(){\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset,\n\t\t\tcop = that.containerPosition,\n\t\t\tce = that.containerElement,\n\t\t\thelper = $(that.helper),\n\t\t\tho = helper.offset(),\n\t\t\tw = helper.outerWidth() - that.sizeDiff.width,\n\t\t\th = helper.outerHeight() - that.sizeDiff.height;\n\n\t\tif (that._helper && !o.animate && (/relative/).test(ce.css(\"position\"))) {\n\t\t\t$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });\n\t\t}\n\n\t\tif (that._helper && !o.animate && (/static/).test(ce.css(\"position\"))) {\n\t\t\t$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"alsoResize\", {\n\n\tstart: function () {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\t_store = function (exp) {\n\t\t\t\t$(exp).each(function() {\n\t\t\t\t\tvar el = $(this);\n\t\t\t\t\tel.data(\"ui-resizable-alsoresize\", {\n\t\t\t\t\t\twidth: parseInt(el.width(), 10), height: parseInt(el.height(), 10),\n\t\t\t\t\t\tleft: parseInt(el.css(\"left\"), 10), top: parseInt(el.css(\"top\"), 10)\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t};\n\n\t\tif (typeof(o.alsoResize) === \"object\" && !o.alsoResize.parentNode) {\n\t\t\tif (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }\n\t\t\telse { $.each(o.alsoResize, function (exp) { _store(exp); }); }\n\t\t}else{\n\t\t\t_store(o.alsoResize);\n\t\t}\n\t},\n\n\tresize: function (event, ui) {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\tdelta = {\n\t\t\t\theight: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,\n\t\t\t\ttop: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0\n\t\t\t},\n\n\t\t\t_alsoResize = function (exp, c) {\n\t\t\t\t$(exp).each(function() {\n\t\t\t\t\tvar el = $(this), start = $(this).data(\"ui-resizable-alsoresize\"), style = {},\n\t\t\t\t\t\tcss = c && c.length ? c : el.parents(ui.originalElement[0]).length ? [\"width\", \"height\"] : [\"width\", \"height\", \"top\", \"left\"];\n\n\t\t\t\t\t$.each(css, function (i, prop) {\n\t\t\t\t\t\tvar sum = (start[prop]||0) + (delta[prop]||0);\n\t\t\t\t\t\tif (sum && sum >= 0) {\n\t\t\t\t\t\t\tstyle[prop] = sum || null;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tel.css(style);\n\t\t\t\t});\n\t\t\t};\n\n\t\tif (typeof(o.alsoResize) === \"object\" && !o.alsoResize.nodeType) {\n\t\t\t$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });\n\t\t}else{\n\t\t\t_alsoResize(o.alsoResize);\n\t\t}\n\t},\n\n\tstop: function () {\n\t\t$(this).removeData(\"resizable-alsoresize\");\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"ghost\", {\n\n\tstart: function() {\n\n\t\tvar that = $(this).data(\"ui-resizable\"), o = that.options, cs = that.size;\n\n\t\tthat.ghost = that.originalElement.clone();\n\t\tthat.ghost\n\t\t\t.css({ opacity: 0.25, display: \"block\", position: \"relative\", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })\n\t\t\t.addClass(\"ui-resizable-ghost\")\n\t\t\t.addClass(typeof o.ghost === \"string\" ? o.ghost : \"\");\n\n\t\tthat.ghost.appendTo(that.helper);\n\n\t},\n\n\tresize: function(){\n\t\tvar that = $(this).data(\"ui-resizable\");\n\t\tif (that.ghost) {\n\t\t\tthat.ghost.css({ position: \"relative\", height: that.size.height, width: that.size.width });\n\t\t}\n\t},\n\n\tstop: function() {\n\t\tvar that = $(this).data(\"ui-resizable\");\n\t\tif (that.ghost && that.helper) {\n\t\t\tthat.helper.get(0).removeChild(that.ghost.get(0));\n\t\t}\n\t}\n\n});\n\n$.ui.plugin.add(\"resizable\", \"grid\", {\n\n\tresize: function() {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tcs = that.size,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\ta = that.axis,\n\t\t\tgrid = typeof o.grid === \"number\" ? [o.grid, o.grid] : o.grid,\n\t\t\tgridX = (grid[0]||1),\n\t\t\tgridY = (grid[1]||1),\n\t\t\tox = Math.round((cs.width - os.width) / gridX) * gridX,\n\t\t\toy = Math.round((cs.height - os.height) / gridY) * gridY,\n\t\t\tnewWidth = os.width + ox,\n\t\t\tnewHeight = os.height + oy,\n\t\t\tisMaxWidth = o.maxWidth && (o.maxWidth < newWidth),\n\t\t\tisMaxHeight = o.maxHeight && (o.maxHeight < newHeight),\n\t\t\tisMinWidth = o.minWidth && (o.minWidth > newWidth),\n\t\t\tisMinHeight = o.minHeight && (o.minHeight > newHeight);\n\n\t\to.grid = grid;\n\n\t\tif (isMinWidth) {\n\t\t\tnewWidth = newWidth + gridX;\n\t\t}\n\t\tif (isMinHeight) {\n\t\t\tnewHeight = newHeight + gridY;\n\t\t}\n\t\tif (isMaxWidth) {\n\t\t\tnewWidth = newWidth - gridX;\n\t\t}\n\t\tif (isMaxHeight) {\n\t\t\tnewHeight = newHeight - gridY;\n\t\t}\n\n\t\tif (/^(se|s|e)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t} else if (/^(ne)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.top = op.top - oy;\n\t\t} else if (/^(sw)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.left = op.left - ox;\n\t\t} else {\n\t\t\tif ( newHeight - gridY > 0 ) {\n\t\t\t\tthat.size.height = newHeight;\n\t\t\t\tthat.position.top = op.top - oy;\n\t\t\t} else {\n\t\t\t\tthat.size.height = gridY;\n\t\t\t\tthat.position.top = op.top + os.height - gridY;\n\t\t\t}\n\t\t\tif ( newWidth - gridX > 0 ) {\n\t\t\t\tthat.size.width = newWidth;\n\t\t\t\tthat.position.left = op.left - ox;\n\t\t\t} else {\n\t\t\t\tthat.size.width = gridX;\n\t\t\t\tthat.position.left = op.left + os.width - gridX;\n\t\t\t}\n\t\t}\n\t}\n\n});\n\n})(jQuery);\n(function( $, undefined ) {\n\n$.widget(\"ui.selectable\", $.ui.mouse, {\n\tversion: \"1.10.4\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoRefresh: true,\n\t\tdistance: 0,\n\t\tfilter: \"*\",\n\t\ttolerance: \"touch\",\n\n\t\t// callbacks\n\t\tselected: null,\n\t\tselecting: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tunselected: null,\n\t\tunselecting: null\n\t},\n\t_create: function() {\n\t\tvar selectees,\n\t\t\tthat = this;\n\n\t\tthis.element.addClass(\"ui-selectable\");\n\n\t\tthis.dragged = false;\n\n\t\t// cache selectee children based on filter\n\t\tthis.refresh = function() {\n\t\t\tselectees = $(that.options.filter, that.element[0]);\n\t\t\tselectees.addClass(\"ui-selectee\");\n\t\t\tselectees.each(function() {\n\t\t\t\tvar $this = $(this),\n\t\t\t\t\tpos = $this.offset();\n\t\t\t\t$.data(this, \"selectable-item\", {\n\t\t\t\t\telement: this,\n\t\t\t\t\t$element: $this,\n\t\t\t\t\tleft: pos.left,\n\t\t\t\t\ttop: pos.top,\n\t\t\t\t\tright: pos.left + $this.outerWidth(),\n\t\t\t\t\tbottom: pos.top + $this.outerHeight(),\n\t\t\t\t\tstartselected: false,\n\t\t\t\t\tselected: $this.hasClass(\"ui-selected\"),\n\t\t\t\t\tselecting: $this.hasClass(\"ui-selecting\"),\n\t\t\t\t\tunselecting: $this.hasClass(\"ui-unselecting\")\n\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tthis.refresh();\n\n\t\tthis.selectees = selectees.addClass(\"ui-selectee\");\n\n\t\tthis._mouseInit();\n\n\t\tthis.helper = $(\"<div class='ui-selectable-helper'></div>\");\n\t},\n\n\t_destroy: function() {\n\t\tthis.selectees\n\t\t\t.removeClass(\"ui-selectee\")\n\t\t\t.removeData(\"selectable-item\");\n\t\tthis.element\n\t\t\t.removeClass(\"ui-selectable ui-selectable-disabled\");\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseStart: function(event) {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.opos = [event.pageX, event.pageY];\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.selectees = $(options.filter, this.element[0]);\n\n\t\tthis._trigger(\"start\", event);\n\n\t\t$(options.appendTo).append(this.helper);\n\t\t// position helper (lasso)\n\t\tthis.helper.css({\n\t\t\t\"left\": event.pageX,\n\t\t\t\"top\": event.pageY,\n\t\t\t\"width\": 0,\n\t\t\t\"height\": 0\n\t\t});\n\n\t\tif (options.autoRefresh) {\n\t\t\tthis.refresh();\n\t\t}\n\n\t\tthis.selectees.filter(\".ui-selected\").each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.startselected = true;\n\t\t\tif (!event.metaKey && !event.ctrlKey) {\n\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\tselectee.selected = false;\n\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\tselectee.unselecting = true;\n\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t$(event.target).parents().addBack().each(function() {\n\t\t\tvar doSelect,\n\t\t\t\tselectee = $.data(this, \"selectable-item\");\n\t\t\tif (selectee) {\n\t\t\t\tdoSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass(\"ui-selected\");\n\t\t\t\tselectee.$element\n\t\t\t\t\t.removeClass(doSelect ? \"ui-unselecting\" : \"ui-selected\")\n\t\t\t\t\t.addClass(doSelect ? \"ui-selecting\" : \"ui-unselecting\");\n\t\t\t\tselectee.unselecting = !doSelect;\n\t\t\t\tselectee.selecting = doSelect;\n\t\t\t\tselectee.selected = doSelect;\n\t\t\t\t// selectable (UN)SELECTING callback\n\t\t\t\tif (doSelect) {\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\tthis.dragged = true;\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar tmp,\n\t\t\tthat = this,\n\t\t\toptions = this.options,\n\t\t\tx1 = this.opos[0],\n\t\t\ty1 = this.opos[1],\n\t\t\tx2 = event.pageX,\n\t\t\ty2 = event.pageY;\n\n\t\tif (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }\n\t\tif (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }\n\t\tthis.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});\n\n\t\tthis.selectees.each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\"),\n\t\t\t\thit = false;\n\n\t\t\t//prevent helper from being selected if appendTo: selectable\n\t\t\tif (!selectee || selectee.element === that.element[0]) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (options.tolerance === \"touch\") {\n\t\t\t\thit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );\n\t\t\t} else if (options.tolerance === \"fit\") {\n\t\t\t\thit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);\n\t\t\t}\n\n\t\t\tif (hit) {\n\t\t\t\t// SELECT\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\tselectee.selected = false;\n\t\t\t\t}\n\t\t\t\tif (selectee.unselecting) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\t\t\tselectee.unselecting = false;\n\t\t\t\t}\n\t\t\t\tif (!selectee.selecting) {\n\t\t\t\t\tselectee.$element.addClass(\"ui-selecting\");\n\t\t\t\t\tselectee.selecting = true;\n\t\t\t\t\t// selectable SELECTING callback\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// UNSELECT\n\t\t\t\tif (selectee.selecting) {\n\t\t\t\t\tif ((event.metaKey || event.ctrlKey) && selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tif (selectee.startselected) {\n\t\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tif (!event.metaKey && !event.ctrlKey && !selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = false;\n\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\t\tvar that = this;\n\n\t\tthis.dragged = false;\n\n\t\t$(\".ui-unselecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\tselectee.unselecting = false;\n\t\t\tselectee.startselected = false;\n\t\t\tthat._trigger(\"unselected\", event, {\n\t\t\t\tunselected: selectee.element\n\t\t\t});\n\t\t});\n\t\t$(\".ui-selecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-selecting\").addClass(\"ui-selected\");\n\t\t\tselectee.selecting = false;\n\t\t\tselectee.selected = true;\n\t\t\tselectee.startselected = true;\n\t\t\tthat._trigger(\"selected\", event, {\n\t\t\t\tselected: selectee.element\n\t\t\t});\n\t\t});\n\t\tthis._trigger(\"stop\", event);\n\n\t\tthis.helper.remove();\n\n\t\treturn false;\n\t}\n\n});\n\n})(jQuery);\n(function( $, undefined ) {\n\n// number of pages in a slider\n// (how many times can you page up/down to go through the whole range)\nvar numPages = 5;\n\n$.widget( \"ui.slider\", $.ui.mouse, {\n\tversion: \"1.10.4\",\n\twidgetEventPrefix: \"slide\",\n\n\toptions: {\n\t\tanimate: false,\n\t\tdistance: 0,\n\t\tmax: 100,\n\t\tmin: 0,\n\t\torientation: \"horizontal\",\n\t\trange: false,\n\t\tstep: 1,\n\t\tvalue: 0,\n\t\tvalues: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tslide: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_create: function() {\n\t\tthis._keySliding = false;\n\t\tthis._mouseSliding = false;\n\t\tthis._animateOff = true;\n\t\tthis._handleIndex = null;\n\t\tthis._detectOrientation();\n\t\tthis._mouseInit();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-\" + this.orientation +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\");\n\n\t\tthis._refresh();\n\t\tthis._setOption( \"disabled\", this.options.disabled );\n\n\t\tthis._animateOff = false;\n\t},\n\n\t_refresh: function() {\n\t\tthis._createRange();\n\t\tthis._createHandles();\n\t\tthis._setupEvents();\n\t\tthis._refreshValue();\n\t},\n\n\t_createHandles: function() {\n\t\tvar i, handleCount,\n\t\t\toptions = this.options,\n\t\t\texistingHandles = this.element.find( \".ui-slider-handle\" ).addClass( \"ui-state-default ui-corner-all\" ),\n\t\t\thandle = \"<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>\",\n\t\t\thandles = [];\n\n\t\thandleCount = ( options.values && options.values.length ) || 1;\n\n\t\tif ( existingHandles.length > handleCount ) {\n\t\t\texistingHandles.slice( handleCount ).remove();\n\t\t\texistingHandles = existingHandles.slice( 0, handleCount );\n\t\t}\n\n\t\tfor ( i = existingHandles.length; i < handleCount; i++ ) {\n\t\t\thandles.push( handle );\n\t\t}\n\n\t\tthis.handles = existingHandles.add( $( handles.join( \"\" ) ).appendTo( this.element ) );\n\n\t\tthis.handle = this.handles.eq( 0 );\n\n\t\tthis.handles.each(function( i ) {\n\t\t\t$( this ).data( \"ui-slider-handle-index\", i );\n\t\t});\n\t},\n\n\t_createRange: function() {\n\t\tvar options = this.options,\n\t\t\tclasses = \"\";\n\n\t\tif ( options.range ) {\n\t\t\tif ( options.range === true ) {\n\t\t\t\tif ( !options.values ) {\n\t\t\t\t\toptions.values = [ this._valueMin(), this._valueMin() ];\n\t\t\t\t} else if ( options.values.length && options.values.length !== 2 ) {\n\t\t\t\t\toptions.values = [ options.values[0], options.values[0] ];\n\t\t\t\t} else if ( $.isArray( options.values ) ) {\n\t\t\t\t\toptions.values = options.values.slice(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !this.range || !this.range.length ) {\n\t\t\t\tthis.range = $( \"<div></div>\" )\n\t\t\t\t\t.appendTo( this.element );\n\n\t\t\t\tclasses = \"ui-slider-range\" +\n\t\t\t\t// note: this isn't the most fittingly semantic framework class for this element,\n\t\t\t\t// but worked best visually with a variety of themes\n\t\t\t\t\" ui-widget-header ui-corner-all\";\n\t\t\t} else {\n\t\t\t\tthis.range.removeClass( \"ui-slider-range-min ui-slider-range-max\" )\n\t\t\t\t\t// Handle range switching from true to min/max\n\t\t\t\t\t.css({\n\t\t\t\t\t\t\"left\": \"\",\n\t\t\t\t\t\t\"bottom\": \"\"\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.range.addClass( classes +\n\t\t\t\t( ( options.range === \"min\" || options.range === \"max\" ) ? \" ui-slider-range-\" + options.range : \"\" ) );\n\t\t} else {\n\t\t\tif ( this.range ) {\n\t\t\t\tthis.range.remove();\n\t\t\t}\n\t\t\tthis.range = null;\n\t\t}\n\t},\n\n\t_setupEvents: function() {\n\t\tvar elements = this.handles.add( this.range ).filter( \"a\" );\n\t\tthis._off( elements );\n\t\tthis._on( elements, this._handleEvents );\n\t\tthis._hoverable( elements );\n\t\tthis._focusable( elements );\n\t},\n\n\t_destroy: function() {\n\t\tthis.handles.remove();\n\t\tif ( this.range ) {\n\t\t\tthis.range.remove();\n\t\t}\n\n\t\tthis.element\n\t\t\t.removeClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-horizontal\" +\n\t\t\t\t\" ui-slider-vertical\" +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\" );\n\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function( event ) {\n\t\tvar position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\n\t\tif ( o.disabled ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.elementSize = {\n\t\t\twidth: this.element.outerWidth(),\n\t\t\theight: this.element.outerHeight()\n\t\t};\n\t\tthis.elementOffset = this.element.offset();\n\n\t\tposition = { x: event.pageX, y: event.pageY };\n\t\tnormValue = this._normValueFromMouse( position );\n\t\tdistance = this._valueMax() - this._valueMin() + 1;\n\t\tthis.handles.each(function( i ) {\n\t\t\tvar thisDistance = Math.abs( normValue - that.values(i) );\n\t\t\tif (( distance > thisDistance ) ||\n\t\t\t\t( distance === thisDistance &&\n\t\t\t\t\t(i === that._lastChangedValue || that.values(i) === o.min ))) {\n\t\t\t\tdistance = thisDistance;\n\t\t\t\tclosestHandle = $( this );\n\t\t\t\tindex = i;\n\t\t\t}\n\t\t});\n\n\t\tallowed = this._start( event, index );\n\t\tif ( allowed === false ) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._mouseSliding = true;\n\n\t\tthis._handleIndex = index;\n\n\t\tclosestHandle\n\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t.focus();\n\n\t\toffset = closestHandle.offset();\n\t\tmouseOverHandle = !$( event.target ).parents().addBack().is( \".ui-slider-handle\" );\n\t\tthis._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {\n\t\t\tleft: event.pageX - offset.left - ( closestHandle.width() / 2 ),\n\t\t\ttop: event.pageY - offset.top -\n\t\t\t\t( closestHandle.height() / 2 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderTopWidth\"), 10 ) || 0 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderBottomWidth\"), 10 ) || 0) +\n\t\t\t\t( parseInt( closestHandle.css(\"marginTop\"), 10 ) || 0)\n\t\t};\n\n\t\tif ( !this.handles.hasClass( \"ui-state-hover\" ) ) {\n\t\t\tthis._slide( event, index, normValue );\n\t\t}\n\t\tthis._animateOff = true;\n\t\treturn true;\n\t},\n\n\t_mouseStart: function() {\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function( event ) {\n\t\tvar position = { x: event.pageX, y: event.pageY },\n\t\t\tnormValue = this._normValueFromMouse( position );\n\n\t\tthis._slide( event, this._handleIndex, normValue );\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function( event ) {\n\t\tthis.handles.removeClass( \"ui-state-active\" );\n\t\tthis._mouseSliding = false;\n\n\t\tthis._stop( event, this._handleIndex );\n\t\tthis._change( event, this._handleIndex );\n\n\t\tthis._handleIndex = null;\n\t\tthis._clickOffset = null;\n\t\tthis._animateOff = false;\n\n\t\treturn false;\n\t},\n\n\t_detectOrientation: function() {\n\t\tthis.orientation = ( this.options.orientation === \"vertical\" ) ? \"vertical\" : \"horizontal\";\n\t},\n\n\t_normValueFromMouse: function( position ) {\n\t\tvar pixelTotal,\n\t\t\tpixelMouse,\n\t\t\tpercentMouse,\n\t\t\tvalueTotal,\n\t\t\tvalueMouse;\n\n\t\tif ( this.orientation === \"horizontal\" ) {\n\t\t\tpixelTotal = this.elementSize.width;\n\t\t\tpixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );\n\t\t} else {\n\t\t\tpixelTotal = this.elementSize.height;\n\t\t\tpixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );\n\t\t}\n\n\t\tpercentMouse = ( pixelMouse / pixelTotal );\n\t\tif ( percentMouse > 1 ) {\n\t\t\tpercentMouse = 1;\n\t\t}\n\t\tif ( percentMouse < 0 ) {\n\t\t\tpercentMouse = 0;\n\t\t}\n\t\tif ( this.orientation === \"vertical\" ) {\n\t\t\tpercentMouse = 1 - percentMouse;\n\t\t}\n\n\t\tvalueTotal = this._valueMax() - this._valueMin();\n\t\tvalueMouse = this._valueMin() + percentMouse * valueTotal;\n\n\t\treturn this._trimAlignValue( valueMouse );\n\t},\n\n\t_start: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\t\treturn this._trigger( \"start\", event, uiHash );\n\t},\n\n\t_slide: function( event, index, newVal ) {\n\t\tvar otherVal,\n\t\t\tnewValues,\n\t\t\tallowed;\n\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\totherVal = this.values( index ? 0 : 1 );\n\n\t\t\tif ( ( this.options.values.length === 2 && this.options.range === true ) &&\n\t\t\t\t\t( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )\n\t\t\t\t) {\n\t\t\t\tnewVal = otherVal;\n\t\t\t}\n\n\t\t\tif ( newVal !== this.values( index ) ) {\n\t\t\t\tnewValues = this.values();\n\t\t\t\tnewValues[ index ] = newVal;\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal,\n\t\t\t\t\tvalues: newValues\n\t\t\t\t} );\n\t\t\t\totherVal = this.values( index ? 0 : 1 );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.values( index, newVal );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif ( newVal !== this.value() ) {\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal\n\t\t\t\t} );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.value( newVal );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t_stop: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\n\t\tthis._trigger( \"stop\", event, uiHash );\n\t},\n\n\t_change: function( event, index ) {\n\t\tif ( !this._keySliding && !this._mouseSliding ) {\n\t\t\tvar uiHash = {\n\t\t\t\thandle: this.handles[ index ],\n\t\t\t\tvalue: this.value()\n\t\t\t};\n\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\tuiHash.value = this.values( index );\n\t\t\t\tuiHash.values = this.values();\n\t\t\t}\n\n\t\t\t//store the last changed value index for reference when handles overlap\n\t\t\tthis._lastChangedValue = index;\n\n\t\t\tthis._trigger( \"change\", event, uiHash );\n\t\t}\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( arguments.length ) {\n\t\t\tthis.options.value = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, 0 );\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._value();\n\t},\n\n\tvalues: function( index, newValue ) {\n\t\tvar vals,\n\t\t\tnewValues,\n\t\t\ti;\n\n\t\tif ( arguments.length > 1 ) {\n\t\t\tthis.options.values[ index ] = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, index );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tif ( $.isArray( arguments[ 0 ] ) ) {\n\t\t\t\tvals = this.options.values;\n\t\t\t\tnewValues = arguments[ 0 ];\n\t\t\t\tfor ( i = 0; i < vals.length; i += 1 ) {\n\t\t\t\t\tvals[ i ] = this._trimAlignValue( newValues[ i ] );\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._refreshValue();\n\t\t\t} else {\n\t\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\t\treturn this._values( index );\n\t\t\t\t} else {\n\t\t\t\t\treturn this.value();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturn this._values();\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar i,\n\t\t\tvalsLength = 0;\n\n\t\tif ( key === \"range\" && this.options.range === true ) {\n\t\t\tif ( value === \"min\" ) {\n\t\t\t\tthis.options.value = this._values( 0 );\n\t\t\t\tthis.options.values = null;\n\t\t\t} else if ( value === \"max\" ) {\n\t\t\t\tthis.options.value = this._values( this.options.values.length-1 );\n\t\t\t\tthis.options.values = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( $.isArray( this.options.values ) ) {\n\t\t\tvalsLength = this.options.values.length;\n\t\t}\n\n\t\t$.Widget.prototype._setOption.apply( this, arguments );\n\n\t\tswitch ( key ) {\n\t\t\tcase \"orientation\":\n\t\t\t\tthis._detectOrientation();\n\t\t\t\tthis.element\n\t\t\t\t\t.removeClass( \"ui-slider-horizontal ui-slider-vertical\" )\n\t\t\t\t\t.addClass( \"ui-slider-\" + this.orientation );\n\t\t\t\tthis._refreshValue();\n\t\t\t\tbreak;\n\t\t\tcase \"value\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._change( null, 0 );\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"values\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tfor ( i = 0; i < valsLength; i += 1 ) {\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"min\":\n\t\t\tcase \"max\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"range\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refresh();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t}\n\t},\n\n\t//internal value getter\n\t// _value() returns value trimmed by min and max, aligned by step\n\t_value: function() {\n\t\tvar val = this.options.value;\n\t\tval = this._trimAlignValue( val );\n\n\t\treturn val;\n\t},\n\n\t//internal values getter\n\t// _values() returns array of values trimmed by min and max, aligned by step\n\t// _values( index ) returns single value trimmed by min and max, aligned by step\n\t_values: function( index ) {\n\t\tvar val,\n\t\t\tvals,\n\t\t\ti;\n\n\t\tif ( arguments.length ) {\n\t\t\tval = this.options.values[ index ];\n\t\t\tval = this._trimAlignValue( val );\n\n\t\t\treturn val;\n\t\t} else if ( this.options.values && this.options.values.length ) {\n\t\t\t// .slice() creates a copy of the array\n\t\t\t// this copy gets trimmed by min and max and then returned\n\t\t\tvals = this.options.values.slice();\n\t\t\tfor ( i = 0; i < vals.length; i+= 1) {\n\t\t\t\tvals[ i ] = this._trimAlignValue( vals[ i ] );\n\t\t\t}\n\n\t\t\treturn vals;\n\t\t} else {\n\t\t\treturn [];\n\t\t}\n\t},\n\n\t// returns the step-aligned value that val is closest to, between (inclusive) min and max\n\t_trimAlignValue: function( val ) {\n\t\tif ( val <= this._valueMin() ) {\n\t\t\treturn this._valueMin();\n\t\t}\n\t\tif ( val >= this._valueMax() ) {\n\t\t\treturn this._valueMax();\n\t\t}\n\t\tvar step = ( this.options.step > 0 ) ? this.options.step : 1,\n\t\t\tvalModStep = (val - this._valueMin()) % step,\n\t\t\talignValue = val - valModStep;\n\n\t\tif ( Math.abs(valModStep) * 2 >= step ) {\n\t\t\talignValue += ( valModStep > 0 ) ? step : ( -step );\n\t\t}\n\n\t\t// Since JavaScript has problems with large floats, round\n\t\t// the final value to 5 digits after the decimal point (see #4124)\n\t\treturn parseFloat( alignValue.toFixed(5) );\n\t},\n\n\t_valueMin: function() {\n\t\treturn this.options.min;\n\t},\n\n\t_valueMax: function() {\n\t\treturn this.options.max;\n\t},\n\n\t_refreshValue: function() {\n\t\tvar lastValPercent, valPercent, value, valueMin, valueMax,\n\t\t\toRange = this.options.range,\n\t\t\to = this.options,\n\t\t\tthat = this,\n\t\t\tanimate = ( !this._animateOff ) ? o.animate : false,\n\t\t\t_set = {};\n\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tthis.handles.each(function( i ) {\n\t\t\t\tvalPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;\n\t\t\t\t_set[ that.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\t\t$( this ).stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\t\t\t\tif ( that.options.range === true ) {\n\t\t\t\t\tif ( that.orientation === \"horizontal\" ) {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { left: valPercent + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { width: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { bottom: ( valPercent ) + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { height: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlastValPercent = valPercent;\n\t\t\t});\n\t\t} else {\n\t\t\tvalue = this.value();\n\t\t\tvalueMin = this._valueMin();\n\t\t\tvalueMax = this._valueMax();\n\t\t\tvalPercent = ( valueMax !== valueMin ) ?\n\t\t\t\t\t( value - valueMin ) / ( valueMax - valueMin ) * 100 :\n\t\t\t\t\t0;\n\t\t\t_set[ this.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\tthis.handle.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\n\t\t\tif ( oRange === \"min\" && this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { width: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" && this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { width: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t\tif ( oRange === \"min\" && this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { height: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" && this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { height: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t}\n\t},\n\n\t_handleEvents: {\n\t\tkeydown: function( event ) {\n\t\t\tvar allowed, curVal, newVal, step,\n\t\t\t\tindex = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tif ( !this._keySliding ) {\n\t\t\t\t\t\tthis._keySliding = true;\n\t\t\t\t\t\t$( event.target ).addClass( \"ui-state-active\" );\n\t\t\t\t\t\tallowed = this._start( event, index );\n\t\t\t\t\t\tif ( allowed === false ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tstep = this.options.step;\n\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\tcurVal = newVal = this.values( index );\n\t\t\t} else {\n\t\t\t\tcurVal = newVal = this.value();\n\t\t\t}\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\t\tnewVal = this._valueMin();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\t\tnewVal = this._valueMax();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\t\tif ( curVal === this._valueMax() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal + step );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tif ( curVal === this._valueMin() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal - step );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis._slide( event, index, newVal );\n\t\t},\n\t\tclick: function( event ) {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\tkeyup: function( event ) {\n\t\t\tvar index = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tif ( this._keySliding ) {\n\t\t\t\tthis._keySliding = false;\n\t\t\t\tthis._stop( event, index );\n\t\t\t\tthis._change( event, index );\n\t\t\t\t$( event.target ).removeClass( \"ui-state-active\" );\n\t\t\t}\n\t\t}\n\t}\n\n});\n\n}(jQuery));\n(function( $, undefined ) {\n\nfunction isOverAxis( x, reference, size ) {\n\treturn ( x > reference ) && ( x < ( reference + size ) );\n}\n\nfunction isFloating(item) {\n\treturn (/left|right/).test(item.css(\"float\")) || (/inline|table-cell/).test(item.css(\"display\"));\n}\n\n$.widget(\"ui.sortable\", $.ui.mouse, {\n\tversion: \"1.10.4\",\n\twidgetEventPrefix: \"sort\",\n\tready: false,\n\toptions: {\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectWith: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tdropOnEmpty: true,\n\t\tforcePlaceholderSize: false,\n\t\tforceHelperSize: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\titems: \"> *\",\n\t\topacity: false,\n\t\tplaceholder: false,\n\t\trevert: false,\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\t\tzIndex: 1000,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeStop: null,\n\t\tchange: null,\n\t\tdeactivate: null,\n\t\tout: null,\n\t\tover: null,\n\t\treceive: null,\n\t\tremove: null,\n\t\tsort: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tupdate: null\n\t},\n\t_create: function() {\n\n\t\tvar o = this.options;\n\t\tthis.containerCache = {};\n\t\tthis.element.addClass(\"ui-sortable\");\n\n\t\t//Get the items\n\t\tthis.refresh();\n\n\t\t//Let's determine if the items are being displayed horizontally\n\t\tthis.floating = this.items.length ? o.axis === \"x\" || isFloating(this.items[0].item) : false;\n\n\t\t//Let's determine the parent's offset\n\t\tthis.offset = this.element.offset();\n\n\t\t//Initialize mouse events for interaction\n\t\tthis._mouseInit();\n\n\t\t//We're ready to go\n\t\tthis.ready = true;\n\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass(\"ui-sortable ui-sortable-disabled\");\n\t\tthis._mouseDestroy();\n\n\t\tfor ( var i = this.items.length - 1; i >= 0; i-- ) {\n\t\t\tthis.items[i].item.removeData(this.widgetName + \"-item\");\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOption: function(key, value){\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.options[ key ] = value;\n\n\t\t\tthis.widget().toggleClass( \"ui-sortable-disabled\", !!value );\n\t\t} else {\n\t\t\t// Don't call widget base _setOption for disable as it adds ui-state-disabled class\n\t\t\t$.Widget.prototype._setOption.apply(this, arguments);\n\t\t}\n\t},\n\n\t_mouseCapture: function(event, overrideHandle) {\n\t\tvar currentItem = null,\n\t\t\tvalidHandle = false,\n\t\t\tthat = this;\n\n\t\tif (this.reverting) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.options.disabled || this.options.type === \"static\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t//We have to refresh the items data once first\n\t\tthis._refreshItems(event);\n\n\t\t//Find out if the clicked node (or one of its parents) is a actual item in this.items\n\t\t$(event.target).parents().each(function() {\n\t\t\tif($.data(this, that.widgetName + \"-item\") === that) {\n\t\t\t\tcurrentItem = $(this);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif($.data(event.target, that.widgetName + \"-item\") === that) {\n\t\t\tcurrentItem = $(event.target);\n\t\t}\n\n\t\tif(!currentItem) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.options.handle && !overrideHandle) {\n\t\t\t$(this.options.handle, currentItem).find(\"*\").addBack().each(function() {\n\t\t\t\tif(this === event.target) {\n\t\t\t\t\tvalidHandle = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(!validHandle) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.currentItem = currentItem;\n\t\tthis._removeCurrentsFromItems();\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function(event, overrideHandle, noActivation) {\n\n\t\tvar i, body,\n\t\t\to = this.options;\n\n\t\tthis.currentContainer = this;\n\n\t\t//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture\n\t\tthis.refreshPositions();\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it's the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Get the next scrolling parent\n\t\tthis.scrollParent = this.helper.scrollParent();\n\n\t\t//The element's absolute position on the page minus margins\n\t\tthis.offset = this.currentItem.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t$.extend(this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper\n\t\t});\n\n\t\t// Only after we got the offset, we can change the helper's position to absolute\n\t\t// TODO: Still need to figure out a way to make relative sorting possible\n\t\tthis.helper.css(\"position\", \"absolute\");\n\t\tthis.cssPosition = this.helper.css(\"position\");\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this._generatePosition(event);\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Cache the former DOM position\n\t\tthis.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };\n\n\t\t//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way\n\t\tif(this.helper[0] !== this.currentItem[0]) {\n\t\t\tthis.currentItem.hide();\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthis._createPlaceholder();\n\n\t\t//Set a containment if given in the options\n\t\tif(o.containment) {\n\t\t\tthis._setContainment();\n\t\t}\n\n\t\tif( o.cursor && o.cursor !== \"auto\" ) { // cursor option\n\t\t\tbody = this.document.find( \"body\" );\n\n\t\t\t// support: IE\n\t\t\tthis.storedCursor = body.css( \"cursor\" );\n\t\t\tbody.css( \"cursor\", o.cursor );\n\n\t\t\tthis.storedStylesheet = $( \"<style>*{ cursor: \"+o.cursor+\" !important; }</style>\" ).appendTo( body );\n\t\t}\n\n\t\tif(o.opacity) { // opacity option\n\t\t\tif (this.helper.css(\"opacity\")) {\n\t\t\t\tthis._storedOpacity = this.helper.css(\"opacity\");\n\t\t\t}\n\t\t\tthis.helper.css(\"opacity\", o.opacity);\n\t\t}\n\n\t\tif(o.zIndex) { // zIndex option\n\t\t\tif (this.helper.css(\"zIndex\")) {\n\t\t\t\tthis._storedZIndex = this.helper.css(\"zIndex\");\n\t\t\t}\n\t\t\tthis.helper.css(\"zIndex\", o.zIndex);\n\t\t}\n\n\t\t//Prepare scrolling\n\t\tif(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== \"HTML\") {\n\t\t\tthis.overflowOffset = this.scrollParent.offset();\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"start\", event, this._uiHash());\n\n\t\t//Recache the helper size\n\t\tif(!this._preserveHelperProportions) {\n\t\t\tthis._cacheHelperProportions();\n\t\t}\n\n\n\t\t//Post \"activate\" events to possible containers\n\t\tif( !noActivation ) {\n\t\t\tfor ( i = this.containers.length - 1; i >= 0; i-- ) {\n\t\t\t\tthis.containers[ i ]._trigger( \"activate\", event, this._uiHash( this ) );\n\t\t\t}\n\t\t}\n\n\t\t//Prepare possible droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\tif ($.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\t\tthis.dragging = true;\n\n\t\tthis.helper.addClass(\"ui-sortable-helper\");\n\t\tthis._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\t\treturn true;\n\n\t},\n\n\t_mouseDrag: function(event) {\n\t\tvar i, item, itemElement, intersection,\n\t\t\to = this.options,\n\t\t\tscrolled = false;\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition(event);\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\tif (!this.lastPositionAbs) {\n\t\t\tthis.lastPositionAbs = this.positionAbs;\n\t\t}\n\n\t\t//Do scrolling\n\t\tif(this.options.scroll) {\n\t\t\tif(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== \"HTML\") {\n\n\t\t\t\tif((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t\tif((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t\tif(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t\t}\n\t\t}\n\n\t\t//Regenerate the absolute position used for position checks\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Set the helper position\n\t\tif(!this.options.axis || this.options.axis !== \"y\") {\n\t\t\tthis.helper[0].style.left = this.position.left+\"px\";\n\t\t}\n\t\tif(!this.options.axis || this.options.axis !== \"x\") {\n\t\t\tthis.helper[0].style.top = this.position.top+\"px\";\n\t\t}\n\n\t\t//Rearrange\n\t\tfor (i = this.items.length - 1; i >= 0; i--) {\n\n\t\t\t//Cache variables and intersection, continue if no intersection\n\t\t\titem = this.items[i];\n\t\t\titemElement = item.item[0];\n\t\t\tintersection = this._intersectsWithPointer(item);\n\t\t\tif (!intersection) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Only put the placeholder inside the current Container, skip all\n\t\t\t// items from other containers. This works because when moving\n\t\t\t// an item from one container to another the\n\t\t\t// currentContainer is switched before the placeholder is moved.\n\t\t\t//\n\t\t\t// Without this, moving items in \"sub-sortables\" can cause\n\t\t\t// the placeholder to jitter beetween the outer and inner container.\n\t\t\tif (item.instance !== this.currentContainer) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// cannot intersect with itself\n\t\t\t// no useless actions that have been done before\n\t\t\t// no action if the item moved is the parent of the item checked\n\t\t\tif (itemElement !== this.currentItem[0] &&\n\t\t\t\tthis.placeholder[intersection === 1 ? \"next\" : \"prev\"]()[0] !== itemElement &&\n\t\t\t\t!$.contains(this.placeholder[0], itemElement) &&\n\t\t\t\t(this.options.type === \"semi-dynamic\" ? !$.contains(this.element[0], itemElement) : true)\n\t\t\t) {\n\n\t\t\t\tthis.direction = intersection === 1 ? \"down\" : \"up\";\n\n\t\t\t\tif (this.options.tolerance === \"pointer\" || this._intersectsWithSides(item)) {\n\t\t\t\t\tthis._rearrange(event, item);\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//Post events to containers\n\t\tthis._contactContainers(event);\n\n\t\t//Interconnect with droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"sort\", event, this._uiHash());\n\n\t\tthis.lastPositionAbs = this.positionAbs;\n\t\treturn false;\n\n\t},\n\n\t_mouseStop: function(event, noPropagation) {\n\n\t\tif(!event) {\n\t\t\treturn;\n\t\t}\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tif ($.ui.ddmanager && !this.options.dropBehaviour) {\n\t\t\t$.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\tif(this.options.revert) {\n\t\t\tvar that = this,\n\t\t\t\tcur = this.placeholder.offset(),\n\t\t\t\taxis = this.options.axis,\n\t\t\t\tanimation = {};\n\n\t\t\tif ( !axis || axis === \"x\" ) {\n\t\t\t\tanimation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);\n\t\t\t}\n\t\t\tif ( !axis || axis === \"y\" ) {\n\t\t\t\tanimation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);\n\t\t\t}\n\t\t\tthis.reverting = true;\n\t\t\t$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {\n\t\t\t\tthat._clear(event);\n\t\t\t});\n\t\t} else {\n\t\t\tthis._clear(event, noPropagation);\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tcancel: function() {\n\n\t\tif(this.dragging) {\n\n\t\t\tthis._mouseUp({ target: null });\n\n\t\t\tif(this.options.helper === \"original\") {\n\t\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t\t} else {\n\t\t\t\tthis.currentItem.show();\n\t\t\t}\n\n\t\t\t//Post deactivating events to containers\n\t\t\tfor (var i = this.containers.length - 1; i >= 0; i--){\n\t\t\t\tthis.containers[i]._trigger(\"deactivate\", null, this._uiHash(this));\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", null, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif (this.placeholder) {\n\t\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\t\tif(this.placeholder[0].parentNode) {\n\t\t\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\t\t\t}\n\t\t\tif(this.options.helper !== \"original\" && this.helper && this.helper[0].parentNode) {\n\t\t\t\tthis.helper.remove();\n\t\t\t}\n\n\t\t\t$.extend(this, {\n\t\t\t\thelper: null,\n\t\t\t\tdragging: false,\n\t\t\t\treverting: false,\n\t\t\t\t_noFinalSort: null\n\t\t\t});\n\n\t\t\tif(this.domPosition.prev) {\n\t\t\t\t$(this.domPosition.prev).after(this.currentItem);\n\t\t\t} else {\n\t\t\t\t$(this.domPosition.parent).prepend(this.currentItem);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\tserialize: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o && o.connected),\n\t\t\tstr = [];\n\t\to = o || {};\n\n\t\t$(items).each(function() {\n\t\t\tvar res = ($(o.item || this).attr(o.attribute || \"id\") || \"\").match(o.expression || (/(.+)[\\-=_](.+)/));\n\t\t\tif (res) {\n\t\t\t\tstr.push((o.key || res[1]+\"[]\")+\"=\"+(o.key && o.expression ? res[1] : res[2]));\n\t\t\t}\n\t\t});\n\n\t\tif(!str.length && o.key) {\n\t\t\tstr.push(o.key + \"=\");\n\t\t}\n\n\t\treturn str.join(\"&\");\n\n\t},\n\n\ttoArray: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o && o.connected),\n\t\t\tret = [];\n\n\t\to = o || {};\n\n\t\titems.each(function() { ret.push($(o.item || this).attr(o.attribute || \"id\") || \"\"); });\n\t\treturn ret;\n\n\t},\n\n\t/* Be careful with the following core functions */\n\t_intersectsWith: function(item) {\n\n\t\tvar x1 = this.positionAbs.left,\n\t\t\tx2 = x1 + this.helperProportions.width,\n\t\t\ty1 = this.positionAbs.top,\n\t\t\ty2 = y1 + this.helperProportions.height,\n\t\t\tl = item.left,\n\t\t\tr = l + item.width,\n\t\t\tt = item.top,\n\t\t\tb = t + item.height,\n\t\t\tdyClick = this.offset.click.top,\n\t\t\tdxClick = this.offset.click.left,\n\t\t\tisOverElementHeight = ( this.options.axis === \"x\" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),\n\t\t\tisOverElementWidth = ( this.options.axis === \"y\" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth;\n\n\t\tif ( this.options.tolerance === \"pointer\" ||\n\t\t\tthis.options.forcePointerForContainers ||\n\t\t\t(this.options.tolerance !== \"pointer\" && this.helperProportions[this.floating ? \"width\" : \"height\"] > item[this.floating ? \"width\" : \"height\"])\n\t\t) {\n\t\t\treturn isOverElement;\n\t\t} else {\n\n\t\t\treturn (l < x1 + (this.helperProportions.width / 2) && // Right Half\n\t\t\t\tx2 - (this.helperProportions.width / 2) < r && // Left Half\n\t\t\t\tt < y1 + (this.helperProportions.height / 2) && // Bottom Half\n\t\t\t\ty2 - (this.helperProportions.height / 2) < b ); // Top Half\n\n\t\t}\n\t},\n\n\t_intersectsWithPointer: function(item) {\n\n\t\tvar isOverElementHeight = (this.options.axis === \"x\") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),\n\t\t\tisOverElementWidth = (this.options.axis === \"y\") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth,\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (!isOverElement) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.floating ?\n\t\t\t( ((horizontalDirection && horizontalDirection === \"right\") || verticalDirection === \"down\") ? 2 : 1 )\n\t\t\t: ( verticalDirection && (verticalDirection === \"down\" ? 2 : 1) );\n\n\t},\n\n\t_intersectsWithSides: function(item) {\n\n\t\tvar isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),\n\t\t\tisOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (this.floating && horizontalDirection) {\n\t\t\treturn ((horizontalDirection === \"right\" && isOverRightHalf) || (horizontalDirection === \"left\" && !isOverRightHalf));\n\t\t} else {\n\t\t\treturn verticalDirection && ((verticalDirection === \"down\" && isOverBottomHalf) || (verticalDirection === \"up\" && !isOverBottomHalf));\n\t\t}\n\n\t},\n\n\t_getDragVerticalDirection: function() {\n\t\tvar delta = this.positionAbs.top - this.lastPositionAbs.top;\n\t\treturn delta !== 0 && (delta > 0 ? \"down\" : \"up\");\n\t},\n\n\t_getDragHorizontalDirection: function() {\n\t\tvar delta = this.positionAbs.left - this.lastPositionAbs.left;\n\t\treturn delta !== 0 && (delta > 0 ? \"right\" : \"left\");\n\t},\n\n\trefresh: function(event) {\n\t\tthis._refreshItems(event);\n\t\tthis.refreshPositions();\n\t\treturn this;\n\t},\n\n\t_connectWith: function() {\n\t\tvar options = this.options;\n\t\treturn options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;\n\t},\n\n\t_getItemsAsjQuery: function(connected) {\n\n\t\tvar i, j, cur, inst,\n\t\t\titems = [],\n\t\t\tqueries = [],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith && connected) {\n\t\t\tfor (i = connectWith.length - 1; i >= 0; i--){\n\t\t\t\tcur = $(connectWith[i]);\n\t\t\t\tfor ( j = cur.length - 1; j >= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst && inst !== this && !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), inst]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tqueries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), this]);\n\n\t\tfunction addItems() {\n\t\t\titems.push( this );\n\t\t}\n\t\tfor (i = queries.length - 1; i >= 0; i--){\n\t\t\tqueries[i][0].each( addItems );\n\t\t}\n\n\t\treturn $(items);\n\n\t},\n\n\t_removeCurrentsFromItems: function() {\n\n\t\tvar list = this.currentItem.find(\":data(\" + this.widgetName + \"-item)\");\n\n\t\tthis.items = $.grep(this.items, function (item) {\n\t\t\tfor (var j=0; j < list.length; j++) {\n\t\t\t\tif(list[j] === item.item[0]) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t},\n\n\t_refreshItems: function(event) {\n\n\t\tthis.items = [];\n\t\tthis.containers = [this];\n\n\t\tvar i, j, cur, inst, targetData, _queries, item, queriesLength,\n\t\t\titems = this.items,\n\t\t\tqueries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down\n\t\t\tfor (i = connectWith.length - 1; i >= 0; i--){\n\t\t\t\tcur = $(connectWith[i]);\n\t\t\t\tfor (j = cur.length - 1; j >= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst && inst !== this && !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);\n\t\t\t\t\t\tthis.containers.push(inst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (i = queries.length - 1; i >= 0; i--) {\n\t\t\ttargetData = queries[i][1];\n\t\t\t_queries = queries[i][0];\n\n\t\t\tfor (j=0, queriesLength = _queries.length; j < queriesLength; j++) {\n\t\t\t\titem = $(_queries[j]);\n\n\t\t\t\titem.data(this.widgetName + \"-item\", targetData); // Data for target checking (mouse manager)\n\n\t\t\t\titems.push({\n\t\t\t\t\titem: item,\n\t\t\t\t\tinstance: targetData,\n\t\t\t\t\twidth: 0, height: 0,\n\t\t\t\t\tleft: 0, top: 0\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t},\n\n\trefreshPositions: function(fast) {\n\n\t\t//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change\n\t\tif(this.offsetParent && this.helper) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\tvar i, item, t, p;\n\n\t\tfor (i = this.items.length - 1; i >= 0; i--){\n\t\t\titem = this.items[i];\n\n\t\t\t//We ignore calculating positions of all connected containers when we're not over them\n\t\t\tif(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tt = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;\n\n\t\t\tif (!fast) {\n\t\t\t\titem.width = t.outerWidth();\n\t\t\t\titem.height = t.outerHeight();\n\t\t\t}\n\n\t\t\tp = t.offset();\n\t\t\titem.left = p.left;\n\t\t\titem.top = p.top;\n\t\t}\n\n\t\tif(this.options.custom && this.options.custom.refreshContainers) {\n\t\t\tthis.options.custom.refreshContainers.call(this);\n\t\t} else {\n\t\t\tfor (i = this.containers.length - 1; i >= 0; i--){\n\t\t\t\tp = this.containers[i].element.offset();\n\t\t\t\tthis.containers[i].containerCache.left = p.left;\n\t\t\t\tthis.containers[i].containerCache.top = p.top;\n\t\t\t\tthis.containers[i].containerCache.width\t= this.containers[i].element.outerWidth();\n\t\t\t\tthis.containers[i].containerCache.height = this.containers[i].element.outerHeight();\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_createPlaceholder: function(that) {\n\t\tthat = that || this;\n\t\tvar className,\n\t\t\to = that.options;\n\n\t\tif(!o.placeholder || o.placeholder.constructor === String) {\n\t\t\tclassName = o.placeholder;\n\t\t\to.placeholder = {\n\t\t\t\telement: function() {\n\n\t\t\t\t\tvar nodeName = that.currentItem[0].nodeName.toLowerCase(),\n\t\t\t\t\t\telement = $( \"<\" + nodeName + \">\", that.document[0] )\n\t\t\t\t\t\t\t.addClass(className || that.currentItem[0].className+\" ui-sortable-placeholder\")\n\t\t\t\t\t\t\t.removeClass(\"ui-sortable-helper\");\n\n\t\t\t\t\tif ( nodeName === \"tr\" ) {\n\t\t\t\t\t\tthat.currentItem.children().each(function() {\n\t\t\t\t\t\t\t$( \"<td>&#160;</td>\", that.document[0] )\n\t\t\t\t\t\t\t\t.attr( \"colspan\", $( this ).attr( \"colspan\" ) || 1 )\n\t\t\t\t\t\t\t\t.appendTo( element );\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if ( nodeName === \"img\" ) {\n\t\t\t\t\t\telement.attr( \"src\", that.currentItem.attr( \"src\" ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !className ) {\n\t\t\t\t\t\telement.css( \"visibility\", \"hidden\" );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn element;\n\t\t\t\t},\n\t\t\t\tupdate: function(container, p) {\n\n\t\t\t\t\t// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that\n\t\t\t\t\t// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified\n\t\t\t\t\tif(className && !o.forcePlaceholderSize) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item\n\t\t\t\t\tif(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css(\"paddingTop\")||0, 10) - parseInt(that.currentItem.css(\"paddingBottom\")||0, 10)); }\n\t\t\t\t\tif(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css(\"paddingLeft\")||0, 10) - parseInt(that.currentItem.css(\"paddingRight\")||0, 10)); }\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthat.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));\n\n\t\t//Append it after the actual current item\n\t\tthat.currentItem.after(that.placeholder);\n\n\t\t//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)\n\t\to.placeholder.update(that, that.placeholder);\n\n\t},\n\n\t_contactContainers: function(event) {\n\t\tvar i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,\n\t\t\tinnermostContainer = null,\n\t\t\tinnermostIndex = null;\n\n\t\t// get innermost container that intersects with item\n\t\tfor (i = this.containers.length - 1; i >= 0; i--) {\n\n\t\t\t// never consider a container that's located within the item itself\n\t\t\tif($.contains(this.currentItem[0], this.containers[i].element[0])) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(this._intersectsWith(this.containers[i].containerCache)) {\n\n\t\t\t\t// if we've already found a container and it's more \"inner\" than this, then continue\n\t\t\t\tif(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tinnermostContainer = this.containers[i];\n\t\t\t\tinnermostIndex = i;\n\n\t\t\t} else {\n\t\t\t\t// container doesn't intersect. trigger \"out\" event if necessary\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", event, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t// if no intersecting containers found, return\n\t\tif(!innermostContainer) {\n\t\t\treturn;\n\t\t}\n\n\t\t// move the item into the container if it's not there already\n\t\tif(this.containers.length === 1) {\n\t\t\tif (!this.containers[innermostIndex].containerCache.over) {\n\t\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t\t}\n\t\t} else {\n\n\t\t\t//When entering a new container, we will find the item with the least distance and append our item near it\n\t\t\tdist = 10000;\n\t\t\titemWithLeastDistance = null;\n\t\t\tfloating = innermostContainer.floating || isFloating(this.currentItem);\n\t\t\tposProperty = floating ? \"left\" : \"top\";\n\t\t\tsizeProperty = floating ? \"width\" : \"height\";\n\t\t\tbase = this.positionAbs[posProperty] + this.offset.click[posProperty];\n\t\t\tfor (j = this.items.length - 1; j >= 0; j--) {\n\t\t\t\tif(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif(this.items[j].item[0] === this.currentItem[0]) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcur = this.items[j].item.offset()[posProperty];\n\t\t\t\tnearBottom = false;\n\t\t\t\tif(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){\n\t\t\t\t\tnearBottom = true;\n\t\t\t\t\tcur += this.items[j][sizeProperty];\n\t\t\t\t}\n\n\t\t\t\tif(Math.abs(cur - base) < dist) {\n\t\t\t\t\tdist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];\n\t\t\t\t\tthis.direction = nearBottom ? \"up\": \"down\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Check if dropOnEmpty is enabled\n\t\t\tif(!itemWithLeastDistance && !this.options.dropOnEmpty) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif(this.currentContainer === this.containers[innermostIndex]) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);\n\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\tthis.containers[innermostIndex]._trigger(\"change\", event, this._uiHash(this));\n\t\t\tthis.currentContainer = this.containers[innermostIndex];\n\n\t\t\t//Update the placeholder\n\t\t\tthis.options.placeholder.update(this.currentContainer, this.placeholder);\n\n\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t}\n\n\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === \"clone\" ? this.currentItem.clone() : this.currentItem);\n\n\t\t//Add the helper to the DOM if that didn't happen already\n\t\tif(!helper.parents(\"body\").length) {\n\t\t\t$(o.appendTo !== \"parent\" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);\n\t\t}\n\n\t\tif(helper[0] === this.currentItem[0]) {\n\t\t\tthis._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css(\"position\"), top: this.currentItem.css(\"top\"), left: this.currentItem.css(\"left\") };\n\t\t}\n\n\t\tif(!helper[0].style.width || o.forceHelperSize) {\n\t\t\thelper.width(this.currentItem.width());\n\t\t}\n\t\tif(!helper[0].style.height || o.forceHelperSize) {\n\t\t\thelper.height(this.currentItem.height());\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = {left: +obj[0], top: +obj[1] || 0};\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\n\t\t//Get the offsetParent and cache its position\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that\n\t\t//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif(this.cssPosition === \"absolute\" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t// This needs to be actually done for all browsers, since pageX/pageY includes this information\n\t\t// with an ugly IE fix\n\t\tif( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === \"html\" && $.ui.ie)) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"),10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"),10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif(this.cssPosition === \"relative\") {\n\t\t\tvar p = this.currentItem.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - (parseInt(this.helper.css(\"top\"),10) || 0) + this.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - (parseInt(this.helper.css(\"left\"),10) || 0) + this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.currentItem.css(\"marginLeft\"),10) || 0),\n\t\t\ttop: (parseInt(this.currentItem.css(\"marginTop\"),10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar ce, co, over,\n\t\t\to = this.options;\n\t\tif(o.containment === \"parent\") {\n\t\t\to.containment = this.helper[0].parentNode;\n\t\t}\n\t\tif(o.containment === \"document\" || o.containment === \"window\") {\n\t\t\tthis.containment = [\n\t\t\t\t0 - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t0 - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\t$(o.containment === \"document\" ? document : window).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t($(o.containment === \"document\" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t\tif(!(/^(document|window|parent)$/).test(o.containment)) {\n\t\t\tce = $(o.containment)[0];\n\t\t\tco = $(o.containment).offset();\n\t\t\tover = ($(ce).css(\"overflow\") !== \"hidden\");\n\n\t\t\tthis.containment = [\n\t\t\t\tco.left + (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingLeft\"),10) || 0) - this.margins.left,\n\t\t\t\tco.top + (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingTop\"),10) || 0) - this.margins.top,\n\t\t\t\tco.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingRight\"),10) || 0) - this.helperProportions.width - this.margins.left,\n\t\t\t\tco.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingBottom\"),10) || 0) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif(!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,\n\t\t\tscrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function(event) {\n\n\t\tvar top, left,\n\t\t\to = this.options,\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\t// This is another very weird special case that only happens for relative elements:\n\t\t// 1. If the css position is relative\n\t\t// 2. and the scroll parent is the document or similar to the offset parent\n\t\t// we have to refresh the relative offset during the scroll so there are no jumps\n\t\tif(this.cssPosition === \"relative\" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {\n\t\t\tthis.offset.relative = this._getRelativeOffset();\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\tif(this.originalPosition) { //If we are not dragging yet, we won't check for options\n\n\t\t\tif(this.containment) {\n\t\t\t\tif(event.pageX - this.offset.click.left < this.containment[0]) {\n\t\t\t\t\tpageX = this.containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top < this.containment[1]) {\n\t\t\t\t\tpageY = this.containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif(event.pageX - this.offset.click.left > this.containment[2]) {\n\t\t\t\t\tpageX = this.containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top > this.containment[3]) {\n\t\t\t\t\tpageY = this.containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(o.grid) {\n\t\t\t\ttop = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];\n\t\t\t\tpageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];\n\t\t\t\tpageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top -\t\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_rearrange: function(event, i, a, hardRefresh) {\n\n\t\ta ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === \"down\" ? i.item[0] : i.item[0].nextSibling));\n\n\t\t//Various things done here to improve the performance:\n\t\t// 1. we create a setTimeout, that calls refreshPositions\n\t\t// 2. on the instance, we have a counter variable, that get's higher after every append\n\t\t// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same\n\t\t// 4. this lets only the last addition to the timeout stack through\n\t\tthis.counter = this.counter ? ++this.counter : 1;\n\t\tvar counter = this.counter;\n\n\t\tthis._delay(function() {\n\t\t\tif(counter === this.counter) {\n\t\t\t\tthis.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_clear: function(event, noPropagation) {\n\n\t\tthis.reverting = false;\n\t\t// We delay all events that have to be triggered to after the point where the placeholder has been removed and\n\t\t// everything else normalized again\n\t\tvar i,\n\t\t\tdelayedTriggers = [];\n\n\t\t// We first have to update the dom position of the actual currentItem\n\t\t// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)\n\t\tif(!this._noFinalSort && this.currentItem.parent().length) {\n\t\t\tthis.placeholder.before(this.currentItem);\n\t\t}\n\t\tthis._noFinalSort = null;\n\n\t\tif(this.helper[0] === this.currentItem[0]) {\n\t\t\tfor(i in this._storedCSS) {\n\t\t\t\tif(this._storedCSS[i] === \"auto\" || this._storedCSS[i] === \"static\") {\n\t\t\t\t\tthis._storedCSS[i] = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t} else {\n\t\t\tthis.currentItem.show();\n\t\t}\n\n\t\tif(this.fromOutside && !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"receive\", event, this._uiHash(this.fromOutside)); });\n\t\t}\n\t\tif((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(\".ui-sortable-helper\")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"update\", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed\n\t\t}\n\n\t\t// Check if the items Container has Changed and trigger appropriate\n\t\t// events.\n\t\tif (this !== this.currentContainer) {\n\t\t\tif(!noPropagation) {\n\t\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"remove\", event, this._uiHash()); });\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"receive\", event, this._uiHash(this)); };  }).call(this, this.currentContainer));\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"update\", event, this._uiHash(this));  }; }).call(this, this.currentContainer));\n\t\t\t}\n\t\t}\n\n\n\t\t//Post events to containers\n\t\tfunction delayEvent( type, instance, container ) {\n\t\t\treturn function( event ) {\n\t\t\t\tcontainer._trigger( type, event, instance._uiHash( instance ) );\n\t\t\t};\n\t\t}\n\t\tfor (i = this.containers.length - 1; i >= 0; i--){\n\t\t\tif (!noPropagation) {\n\t\t\t\tdelayedTriggers.push( delayEvent( \"deactivate\", this, this.containers[ i ] ) );\n\t\t\t}\n\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\tdelayedTriggers.push( delayEvent( \"out\", this, this.containers[ i ] ) );\n\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t}\n\t\t}\n\n\t\t//Do what was originally in plugins\n\t\tif ( this.storedCursor ) {\n\t\t\tthis.document.find( \"body\" ).css( \"cursor\", this.storedCursor );\n\t\t\tthis.storedStylesheet.remove();\n\t\t}\n\t\tif(this._storedOpacity) {\n\t\t\tthis.helper.css(\"opacity\", this._storedOpacity);\n\t\t}\n\t\tif(this._storedZIndex) {\n\t\t\tthis.helper.css(\"zIndex\", this._storedZIndex === \"auto\" ? \"\" : this._storedZIndex);\n\t\t}\n\n\t\tthis.dragging = false;\n\t\tif(this.cancelHelperRemoval) {\n\t\t\tif(!noPropagation) {\n\t\t\t\tthis._trigger(\"beforeStop\", event, this._uiHash());\n\t\t\t\tfor (i=0; i < delayedTriggers.length; i++) {\n\t\t\t\t\tdelayedTriggers[i].call(this, event);\n\t\t\t\t} //Trigger all delayed events\n\t\t\t\tthis._trigger(\"stop\", event, this._uiHash());\n\t\t\t}\n\n\t\t\tthis.fromOutside = false;\n\t\t\treturn false;\n\t\t}\n\n\t\tif(!noPropagation) {\n\t\t\tthis._trigger(\"beforeStop\", event, this._uiHash());\n\t\t}\n\n\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\n\t\tif(this.helper[0] !== this.currentItem[0]) {\n\t\t\tthis.helper.remove();\n\t\t}\n\t\tthis.helper = null;\n\n\t\tif(!noPropagation) {\n\t\t\tfor (i=0; i < delayedTriggers.length; i++) {\n\t\t\t\tdelayedTriggers[i].call(this, event);\n\t\t\t} //Trigger all delayed events\n\t\t\tthis._trigger(\"stop\", event, this._uiHash());\n\t\t}\n\n\t\tthis.fromOutside = false;\n\t\treturn true;\n\n\t},\n\n\t_trigger: function() {\n\t\tif ($.Widget.prototype._trigger.apply(this, arguments) === false) {\n\t\t\tthis.cancel();\n\t\t}\n\t},\n\n\t_uiHash: function(_inst) {\n\t\tvar inst = _inst || this;\n\t\treturn {\n\t\t\thelper: inst.helper,\n\t\t\tplaceholder: inst.placeholder || $([]),\n\t\t\tposition: inst.position,\n\t\t\toriginalPosition: inst.originalPosition,\n\t\t\toffset: inst.positionAbs,\n\t\t\titem: inst.currentItem,\n\t\t\tsender: _inst ? _inst.element : null\n\t\t};\n\t}\n\n});\n\n})(jQuery);\n(function( $ ) {\n\nfunction modifier( fn ) {\n\treturn function() {\n\t\tvar previous = this.element.val();\n\t\tfn.apply( this, arguments );\n\t\tthis._refresh();\n\t\tif ( previous !== this.element.val() ) {\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t};\n}\n\n$.widget( \"ui.spinner\", {\n\tversion: \"1.10.4\",\n\tdefaultElement: \"<input>\",\n\twidgetEventPrefix: \"spin\",\n\toptions: {\n\t\tculture: null,\n\t\ticons: {\n\t\t\tdown: \"ui-icon-triangle-1-s\",\n\t\t\tup: \"ui-icon-triangle-1-n\"\n\t\t},\n\t\tincremental: true,\n\t\tmax: null,\n\t\tmin: null,\n\t\tnumberFormat: null,\n\t\tpage: 10,\n\t\tstep: 1,\n\n\t\tchange: null,\n\t\tspin: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_create: function() {\n\t\t// handle string values that need to be parsed\n\t\tthis._setOption( \"max\", this.options.max );\n\t\tthis._setOption( \"min\", this.options.min );\n\t\tthis._setOption( \"step\", this.options.step );\n\n\t\t// Only format if there is a value, prevents the field from being marked\n\t\t// as invalid in Firefox, see #9573.\n\t\tif ( this.value() !== \"\" ) {\n\t\t\t// Format the value, but don't constrain.\n\t\t\tthis._value( this.element.val(), true );\n\t\t}\n\n\t\tthis._draw();\n\t\tthis._on( this._events );\n\t\tthis._refresh();\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_getCreateOptions: function() {\n\t\tvar options = {},\n\t\t\telement = this.element;\n\n\t\t$.each( [ \"min\", \"max\", \"step\" ], function( i, option ) {\n\t\t\tvar value = element.attr( option );\n\t\t\tif ( value !== undefined && value.length ) {\n\t\t\t\toptions[ option ] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn options;\n\t},\n\n\t_events: {\n\t\tkeydown: function( event ) {\n\t\t\tif ( this._start( event ) && this._keydown( event ) ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t},\n\t\tkeyup: \"_stop\",\n\t\tfocus: function() {\n\t\t\tthis.previous = this.element.val();\n\t\t},\n\t\tblur: function( event ) {\n\t\t\tif ( this.cancelBlur ) {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._stop();\n\t\t\tthis._refresh();\n\t\t\tif ( this.previous !== this.element.val() ) {\n\t\t\t\tthis._trigger( \"change\", event );\n\t\t\t}\n\t\t},\n\t\tmousewheel: function( event, delta ) {\n\t\t\tif ( !delta ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( !this.spinning && !this._start( event ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._spin( (delta > 0 ? 1 : -1) * this.options.step, event );\n\t\t\tclearTimeout( this.mousewheelTimer );\n\t\t\tthis.mousewheelTimer = this._delay(function() {\n\t\t\t\tif ( this.spinning ) {\n\t\t\t\t\tthis._stop( event );\n\t\t\t\t}\n\t\t\t}, 100 );\n\t\t\tevent.preventDefault();\n\t\t},\n\t\t\"mousedown .ui-spinner-button\": function( event ) {\n\t\t\tvar previous;\n\n\t\t\t// We never want the buttons to have focus; whenever the user is\n\t\t\t// interacting with the spinner, the focus should be on the input.\n\t\t\t// If the input is focused then this.previous is properly set from\n\t\t\t// when the input first received focus. If the input is not focused\n\t\t\t// then we need to set this.previous based on the value before spinning.\n\t\t\tprevious = this.element[0] === this.document[0].activeElement ?\n\t\t\t\tthis.previous : this.element.val();\n\t\t\tfunction checkFocus() {\n\t\t\t\tvar isActive = this.element[0] === this.document[0].activeElement;\n\t\t\t\tif ( !isActive ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// support: IE\n\t\t\t\t\t// IE sets focus asynchronously, so we need to check if focus\n\t\t\t\t\t// moved off of the input because the user clicked on the button.\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// ensure focus is on (or stays on) the text field\n\t\t\tevent.preventDefault();\n\t\t\tcheckFocus.call( this );\n\n\t\t\t// support: IE\n\t\t\t// IE doesn't prevent moving focus even with event.preventDefault()\n\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t// and check (again) if focus moved off of the input.\n\t\t\tthis.cancelBlur = true;\n\t\t\tthis._delay(function() {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\tcheckFocus.call( this );\n\t\t\t});\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t\"mouseup .ui-spinner-button\": \"_stop\",\n\t\t\"mouseenter .ui-spinner-button\": function( event ) {\n\t\t\t// button will add ui-state-active if mouse was down while mouseleave and kept down\n\t\t\tif ( !$( event.currentTarget ).hasClass( \"ui-state-active\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t// TODO: do we really want to consider this a stop?\n\t\t// shouldn't we just stop the repeater and wait until mouseup before\n\t\t// we trigger the stop event?\n\t\t\"mouseleave .ui-spinner-button\": \"_stop\"\n\t},\n\n\t_draw: function() {\n\t\tvar uiSpinner = this.uiSpinner = this.element\n\t\t\t.addClass( \"ui-spinner-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" )\n\t\t\t.wrap( this._uiSpinnerHtml() )\n\t\t\t.parent()\n\t\t\t\t// add buttons\n\t\t\t\t.append( this._buttonHtml() );\n\n\t\tthis.element.attr( \"role\", \"spinbutton\" );\n\n\t\t// button bindings\n\t\tthis.buttons = uiSpinner.find( \".ui-spinner-button\" )\n\t\t\t.attr( \"tabIndex\", -1 )\n\t\t\t.button()\n\t\t\t.removeClass( \"ui-corner-all\" );\n\n\t\t// IE 6 doesn't understand height: 50% for the buttons\n\t\t// unless the wrapper has an explicit height\n\t\tif ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&\n\t\t\t\tuiSpinner.height() > 0 ) {\n\t\t\tuiSpinner.height( uiSpinner.height() );\n\t\t}\n\n\t\t// disable spinner if element was already disabled\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.disable();\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\tvar options = this.options,\n\t\t\tkeyCode = $.ui.keyCode;\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase keyCode.UP:\n\t\t\tthis._repeat( null, 1, event );\n\t\t\treturn true;\n\t\tcase keyCode.DOWN:\n\t\t\tthis._repeat( null, -1, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_UP:\n\t\t\tthis._repeat( null, options.page, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_DOWN:\n\t\t\tthis._repeat( null, -options.page, event );\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_uiSpinnerHtml: function() {\n\t\treturn \"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>\";\n\t},\n\n\t_buttonHtml: function() {\n\t\treturn \"\" +\n\t\t\t\"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>\" +\n\t\t\t\t\"<span class='ui-icon \" + this.options.icons.up + \"'>&#9650;</span>\" +\n\t\t\t\"</a>\" +\n\t\t\t\"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>\" +\n\t\t\t\t\"<span class='ui-icon \" + this.options.icons.down + \"'>&#9660;</span>\" +\n\t\t\t\"</a>\";\n\t},\n\n\t_start: function( event ) {\n\t\tif ( !this.spinning && this._trigger( \"start\", event ) === false ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\t\tthis.spinning = true;\n\t\treturn true;\n\t},\n\n\t_repeat: function( i, steps, event ) {\n\t\ti = i || 500;\n\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._repeat( 40, steps, event );\n\t\t}, i );\n\n\t\tthis._spin( steps * this.options.step, event );\n\t},\n\n\t_spin: function( step, event ) {\n\t\tvar value = this.value() || 0;\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\n\t\tvalue = this._adjustValue( value + step * this._increment( this.counter ) );\n\n\t\tif ( !this.spinning || this._trigger( \"spin\", event, { value: value } ) !== false) {\n\t\t\tthis._value( value );\n\t\t\tthis.counter++;\n\t\t}\n\t},\n\n\t_increment: function( i ) {\n\t\tvar incremental = this.options.incremental;\n\n\t\tif ( incremental ) {\n\t\t\treturn $.isFunction( incremental ) ?\n\t\t\t\tincremental( i ) :\n\t\t\t\tMath.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );\n\t\t}\n\n\t\treturn 1;\n\t},\n\n\t_precision: function() {\n\t\tvar precision = this._precisionOf( this.options.step );\n\t\tif ( this.options.min !== null ) {\n\t\t\tprecision = Math.max( precision, this._precisionOf( this.options.min ) );\n\t\t}\n\t\treturn precision;\n\t},\n\n\t_precisionOf: function( num ) {\n\t\tvar str = num.toString(),\n\t\t\tdecimal = str.indexOf( \".\" );\n\t\treturn decimal === -1 ? 0 : str.length - decimal - 1;\n\t},\n\n\t_adjustValue: function( value ) {\n\t\tvar base, aboveMin,\n\t\t\toptions = this.options;\n\n\t\t// make sure we're at a valid step\n\t\t// - find out where we are relative to the base (min or 0)\n\t\tbase = options.min !== null ? options.min : 0;\n\t\taboveMin = value - base;\n\t\t// - round to the nearest step\n\t\taboveMin = Math.round(aboveMin / options.step) * options.step;\n\t\t// - rounding is based on 0, so adjust back to our base\n\t\tvalue = base + aboveMin;\n\n\t\t// fix precision from bad JS floating point math\n\t\tvalue = parseFloat( value.toFixed( this._precision() ) );\n\n\t\t// clamp the value\n\t\tif ( options.max !== null && value > options.max) {\n\t\t\treturn options.max;\n\t\t}\n\t\tif ( options.min !== null && value < options.min ) {\n\t\t\treturn options.min;\n\t\t}\n\n\t\treturn value;\n\t},\n\n\t_stop: function( event ) {\n\t\tif ( !this.spinning ) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearTimeout( this.timer );\n\t\tclearTimeout( this.mousewheelTimer );\n\t\tthis.counter = 0;\n\t\tthis.spinning = false;\n\t\tthis._trigger( \"stop\", event );\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"culture\" || key === \"numberFormat\" ) {\n\t\t\tvar prevValue = this._parse( this.element.val() );\n\t\t\tthis.options[ key ] = value;\n\t\t\tthis.element.val( this._format( prevValue ) );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"max\" || key === \"min\" || key === \"step\" ) {\n\t\t\tif ( typeof value === \"string\" ) {\n\t\t\t\tvalue = this._parse( value );\n\t\t\t}\n\t\t}\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.buttons.first().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.up )\n\t\t\t\t.addClass( value.up );\n\t\t\tthis.buttons.last().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.down )\n\t\t\t\t.addClass( value.down );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tif ( value ) {\n\t\t\t\tthis.element.prop( \"disabled\", true );\n\t\t\t\tthis.buttons.button( \"disable\" );\n\t\t\t} else {\n\t\t\t\tthis.element.prop( \"disabled\", false );\n\t\t\t\tthis.buttons.button( \"enable\" );\n\t\t\t}\n\t\t}\n\t},\n\n\t_setOptions: modifier(function( options ) {\n\t\tthis._super( options );\n\t\tthis._value( this.element.val() );\n\t}),\n\n\t_parse: function( val ) {\n\t\tif ( typeof val === \"string\" && val !== \"\" ) {\n\t\t\tval = window.Globalize && this.options.numberFormat ?\n\t\t\t\tGlobalize.parseFloat( val, 10, this.options.culture ) : +val;\n\t\t}\n\t\treturn val === \"\" || isNaN( val ) ? null : val;\n\t},\n\n\t_format: function( value ) {\n\t\tif ( value === \"\" ) {\n\t\t\treturn \"\";\n\t\t}\n\t\treturn window.Globalize && this.options.numberFormat ?\n\t\t\tGlobalize.format( value, this.options.numberFormat, this.options.culture ) :\n\t\t\tvalue;\n\t},\n\n\t_refresh: function() {\n\t\tthis.element.attr({\n\t\t\t\"aria-valuemin\": this.options.min,\n\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t// TODO: what should we do with values that can't be parsed?\n\t\t\t\"aria-valuenow\": this._parse( this.element.val() )\n\t\t});\n\t},\n\n\t// update the value without triggering change\n\t_value: function( value, allowAny ) {\n\t\tvar parsed;\n\t\tif ( value !== \"\" ) {\n\t\t\tparsed = this._parse( value );\n\t\t\tif ( parsed !== null ) {\n\t\t\t\tif ( !allowAny ) {\n\t\t\t\t\tparsed = this._adjustValue( parsed );\n\t\t\t\t}\n\t\t\t\tvalue = this._format( parsed );\n\t\t\t}\n\t\t}\n\t\tthis.element.val( value );\n\t\tthis._refresh();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-spinner-input\" )\n\t\t\t.prop( \"disabled\", false )\n\t\t\t.removeAttr( \"autocomplete\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\t\tthis.uiSpinner.replaceWith( this.element );\n\t},\n\n\tstepUp: modifier(function( steps ) {\n\t\tthis._stepUp( steps );\n\t}),\n\t_stepUp: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tstepDown: modifier(function( steps ) {\n\t\tthis._stepDown( steps );\n\t}),\n\t_stepDown: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * -this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tpageUp: modifier(function( pages ) {\n\t\tthis._stepUp( (pages || 1) * this.options.page );\n\t}),\n\n\tpageDown: modifier(function( pages ) {\n\t\tthis._stepDown( (pages || 1) * this.options.page );\n\t}),\n\n\tvalue: function( newVal ) {\n\t\tif ( !arguments.length ) {\n\t\t\treturn this._parse( this.element.val() );\n\t\t}\n\t\tmodifier( this._value ).call( this, newVal );\n\t},\n\n\twidget: function() {\n\t\treturn this.uiSpinner;\n\t}\n});\n\n}( jQuery ) );\n(function( $, undefined ) {\n\nvar tabId = 0,\n\trhash = /#.*$/;\n\nfunction getNextTabId() {\n\treturn ++tabId;\n}\n\nfunction isLocal( anchor ) {\n\t// support: IE7\n\t// IE7 doesn't normalize the href property when set via script (#9317)\n\tanchor = anchor.cloneNode( false );\n\n\treturn anchor.hash.length > 1 &&\n\t\tdecodeURIComponent( anchor.href.replace( rhash, \"\" ) ) ===\n\t\t\tdecodeURIComponent( location.href.replace( rhash, \"\" ) );\n}\n\n$.widget( \"ui.tabs\", {\n\tversion: \"1.10.4\",\n\tdelay: 300,\n\toptions: {\n\t\tactive: null,\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theightStyle: \"content\",\n\t\thide: null,\n\t\tshow: null,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null,\n\t\tbeforeLoad: null,\n\t\tload: null\n\t},\n\n\t_create: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.running = false;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.toggleClass( \"ui-tabs-collapsible\", options.collapsible )\n\t\t\t// Prevent users from focusing disabled tabs via click\n\t\t\t.delegate( \".ui-tabs-nav > li\", \"mousedown\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( $( this ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t})\n\t\t\t// support: IE <9\n\t\t\t// Preventing the default action in mousedown doesn't prevent IE\n\t\t\t// from focusing the element, so if the anchor gets focused, blur.\n\t\t\t// We don't have to worry about focusing the previously focused\n\t\t\t// element since clicking on a non-focusable element should focus\n\t\t\t// the body anyway.\n\t\t\t.delegate( \".ui-tabs-anchor\", \"focus\" + this.eventNamespace, function() {\n\t\t\t\tif ( $( this ).closest( \"li\" ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis._processTabs();\n\t\toptions.active = this._initialActive();\n\n\t\t// Take disabling tabs via class attribute from HTML\n\t\t// into account and update option properly.\n\t\tif ( $.isArray( options.disabled ) ) {\n\t\t\toptions.disabled = $.unique( options.disabled.concat(\n\t\t\t\t$.map( this.tabs.filter( \".ui-state-disabled\" ), function( li ) {\n\t\t\t\t\treturn that.tabs.index( li );\n\t\t\t\t})\n\t\t\t) ).sort();\n\t\t}\n\n\t\t// check for length avoids error when initializing empty list\n\t\tif ( this.options.active !== false && this.anchors.length ) {\n\t\t\tthis.active = this._findActive( options.active );\n\t\t} else {\n\t\t\tthis.active = $();\n\t\t}\n\n\t\tthis._refresh();\n\n\t\tif ( this.active.length ) {\n\t\t\tthis.load( options.active );\n\t\t}\n\t},\n\n\t_initialActive: function() {\n\t\tvar active = this.options.active,\n\t\t\tcollapsible = this.options.collapsible,\n\t\t\tlocationHash = location.hash.substring( 1 );\n\n\t\tif ( active === null ) {\n\t\t\t// check the fragment identifier in the URL\n\t\t\tif ( locationHash ) {\n\t\t\t\tthis.tabs.each(function( i, tab ) {\n\t\t\t\t\tif ( $( tab ).attr( \"aria-controls\" ) === locationHash ) {\n\t\t\t\t\t\tactive = i;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// check for a tab marked active via a class\n\t\t\tif ( active === null ) {\n\t\t\t\tactive = this.tabs.index( this.tabs.filter( \".ui-tabs-active\" ) );\n\t\t\t}\n\n\t\t\t// no active tab, set to false\n\t\t\tif ( active === null || active === -1 ) {\n\t\t\t\tactive = this.tabs.length ? 0 : false;\n\t\t\t}\n\t\t}\n\n\t\t// handle numbers: negative, out of range\n\t\tif ( active !== false ) {\n\t\t\tactive = this.tabs.index( this.tabs.eq( active ) );\n\t\t\tif ( active === -1 ) {\n\t\t\t\tactive = collapsible ? false : 0;\n\t\t\t}\n\t\t}\n\n\t\t// don't allow collapsible: false and active: false\n\t\tif ( !collapsible && active === false && this.anchors.length ) {\n\t\t\tactive = 0;\n\t\t}\n\n\t\treturn active;\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\ttab: this.active,\n\t\t\tpanel: !this.active.length ? $() : this._getPanelForTab( this.active )\n\t\t};\n\t},\n\n\t_tabKeydown: function( event ) {\n\t\tvar focusedTab = $( this.document[0].activeElement ).closest( \"li\" ),\n\t\t\tselectedIndex = this.tabs.index( focusedTab ),\n\t\t\tgoingForward = true;\n\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tselectedIndex++;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.UP:\n\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\tgoingForward = false;\n\t\t\t\tselectedIndex--;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tselectedIndex = this.anchors.length - 1;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tselectedIndex = 0;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.SPACE:\n\t\t\t\t// Activate only, no collapsing\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\tthis._activate( selectedIndex );\n\t\t\t\treturn;\n\t\t\tcase $.ui.keyCode.ENTER:\n\t\t\t\t// Toggle (cancel delayed activation, allow collapsing)\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\t// Determine if we should collapse or activate\n\t\t\t\tthis._activate( selectedIndex === this.options.active ? false : selectedIndex );\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Focus the appropriate tab, based on which key was pressed\n\t\tevent.preventDefault();\n\t\tclearTimeout( this.activating );\n\t\tselectedIndex = this._focusNextTab( selectedIndex, goingForward );\n\n\t\t// Navigating with control key will prevent automatic activation\n\t\tif ( !event.ctrlKey ) {\n\t\t\t// Update aria-selected immediately so that AT think the tab is already selected.\n\t\t\t// Otherwise AT may confuse the user by stating that they need to activate the tab,\n\t\t\t// but the tab will already be activated by the time the announcement finishes.\n\t\t\tfocusedTab.attr( \"aria-selected\", \"false\" );\n\t\t\tthis.tabs.eq( selectedIndex ).attr( \"aria-selected\", \"true\" );\n\n\t\t\tthis.activating = this._delay(function() {\n\t\t\t\tthis.option( \"active\", selectedIndex );\n\t\t\t}, this.delay );\n\t\t}\n\t},\n\n\t_panelKeydown: function( event ) {\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ctrl+up moves focus to the current tab\n\t\tif ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {\n\t\t\tevent.preventDefault();\n\t\t\tthis.active.focus();\n\t\t}\n\t},\n\n\t// Alt+page up/down moves focus to the previous/next tab (and activates)\n\t_handlePageNav: function( event ) {\n\t\tif ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active - 1, false ) );\n\t\t\treturn true;\n\t\t}\n\t\tif ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active + 1, true ) );\n\t\t\treturn true;\n\t\t}\n\t},\n\n\t_findNextTab: function( index, goingForward ) {\n\t\tvar lastTabIndex = this.tabs.length - 1;\n\n\t\tfunction constrain() {\n\t\t\tif ( index > lastTabIndex ) {\n\t\t\t\tindex = 0;\n\t\t\t}\n\t\t\tif ( index < 0 ) {\n\t\t\t\tindex = lastTabIndex;\n\t\t\t}\n\t\t\treturn index;\n\t\t}\n\n\t\twhile ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {\n\t\t\tindex = goingForward ? index + 1 : index - 1;\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_focusNextTab: function( index, goingForward ) {\n\t\tindex = this._findNextTab( index, goingForward );\n\t\tthis.tabs.eq( index ).focus();\n\t\treturn index;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\t// don't use the widget factory's disabled handling\n\t\t\tthis._setupDisabled( value );\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value);\n\n\t\tif ( key === \"collapsible\" ) {\n\t\t\tthis.element.toggleClass( \"ui-tabs-collapsible\", value );\n\t\t\t// Setting collapsible: false while collapsed; open first panel\n\t\t\tif ( !value && this.options.active === false ) {\n\t\t\t\tthis._activate( 0 );\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tif ( key === \"heightStyle\" ) {\n\t\t\tthis._setupHeightStyle( value );\n\t\t}\n\t},\n\n\t_tabId: function( tab ) {\n\t\treturn tab.attr( \"aria-controls\" ) || \"ui-tabs-\" + getNextTabId();\n\t},\n\n\t_sanitizeSelector: function( hash ) {\n\t\treturn hash ? hash.replace( /[!\"$%&'()*+,.\\/:;<=>?@\\[\\]\\^`{|}~]/g, \"\\\\$&\" ) : \"\";\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options,\n\t\t\tlis = this.tablist.children( \":has(a[href])\" );\n\n\t\t// get disabled tabs from class attribute from HTML\n\t\t// this will get converted to a boolean if needed in _refresh()\n\t\toptions.disabled = $.map( lis.filter( \".ui-state-disabled\" ), function( tab ) {\n\t\t\treturn lis.index( tab );\n\t\t});\n\n\t\tthis._processTabs();\n\n\t\t// was collapsed or no tabs\n\t\tif ( options.active === false || !this.anchors.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// was active, but active tab is gone\n\t\t} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining tabs are disabled\n\t\t\tif ( this.tabs.length === options.disabled.length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous tab\n\t\t\t} else {\n\t\t\t\tthis._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );\n\t\t\t}\n\t\t// was active, active tab still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.tabs.index( this.active );\n\t\t}\n\n\t\tthis._refresh();\n\t},\n\n\t_refresh: function() {\n\t\tthis._setupDisabled( this.options.disabled );\n\t\tthis._setupEvents( this.options.event );\n\t\tthis._setupHeightStyle( this.options.heightStyle );\n\n\t\tthis.tabs.not( this.active ).attr({\n\t\t\t\"aria-selected\": \"false\",\n\t\t\ttabIndex: -1\n\t\t});\n\t\tthis.panels.not( this._getPanelForTab( this.active ) )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t});\n\n\t\t// Make sure one tab is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.tabs.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active\n\t\t\t\t.addClass( \"ui-tabs-active ui-state-active\" )\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\ttabIndex: 0\n\t\t\t\t});\n\t\t\tthis._getPanelForTab( this.active )\n\t\t\t\t.show()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_processTabs: function() {\n\t\tvar that = this;\n\n\t\tthis.tablist = this._getList()\n\t\t\t.addClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.attr( \"role\", \"tablist\" );\n\n\t\tthis.tabs = this.tablist.find( \"> li:has(a[href])\" )\n\t\t\t.addClass( \"ui-state-default ui-corner-top\" )\n\t\t\t.attr({\n\t\t\t\trole: \"tab\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.anchors = this.tabs.map(function() {\n\t\t\t\treturn $( \"a\", this )[ 0 ];\n\t\t\t})\n\t\t\t.addClass( \"ui-tabs-anchor\" )\n\t\t\t.attr({\n\t\t\t\trole: \"presentation\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.panels = $();\n\n\t\tthis.anchors.each(function( i, anchor ) {\n\t\t\tvar selector, panel, panelId,\n\t\t\t\tanchorId = $( anchor ).uniqueId().attr( \"id\" ),\n\t\t\t\ttab = $( anchor ).closest( \"li\" ),\n\t\t\t\toriginalAriaControls = tab.attr( \"aria-controls\" );\n\n\t\t\t// inline tab\n\t\t\tif ( isLocal( anchor ) ) {\n\t\t\t\tselector = anchor.hash;\n\t\t\t\tpanel = that.element.find( that._sanitizeSelector( selector ) );\n\t\t\t// remote tab\n\t\t\t} else {\n\t\t\t\tpanelId = that._tabId( tab );\n\t\t\t\tselector = \"#\" + panelId;\n\t\t\t\tpanel = that.element.find( selector );\n\t\t\t\tif ( !panel.length ) {\n\t\t\t\t\tpanel = that._createPanel( panelId );\n\t\t\t\t\tpanel.insertAfter( that.panels[ i - 1 ] || that.tablist );\n\t\t\t\t}\n\t\t\t\tpanel.attr( \"aria-live\", \"polite\" );\n\t\t\t}\n\n\t\t\tif ( panel.length) {\n\t\t\t\tthat.panels = that.panels.add( panel );\n\t\t\t}\n\t\t\tif ( originalAriaControls ) {\n\t\t\t\ttab.data( \"ui-tabs-aria-controls\", originalAriaControls );\n\t\t\t}\n\t\t\ttab.attr({\n\t\t\t\t\"aria-controls\": selector.substring( 1 ),\n\t\t\t\t\"aria-labelledby\": anchorId\n\t\t\t});\n\t\t\tpanel.attr( \"aria-labelledby\", anchorId );\n\t\t});\n\n\t\tthis.panels\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.attr( \"role\", \"tabpanel\" );\n\t},\n\n\t// allow overriding how to find the list for rare usage scenarios (#7715)\n\t_getList: function() {\n\t\treturn this.tablist || this.element.find( \"ol,ul\" ).eq( 0 );\n\t},\n\n\t_createPanel: function( id ) {\n\t\treturn $( \"<div>\" )\n\t\t\t.attr( \"id\", id )\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.data( \"ui-tabs-destroy\", true );\n\t},\n\n\t_setupDisabled: function( disabled ) {\n\t\tif ( $.isArray( disabled ) ) {\n\t\t\tif ( !disabled.length ) {\n\t\t\t\tdisabled = false;\n\t\t\t} else if ( disabled.length === this.anchors.length ) {\n\t\t\t\tdisabled = true;\n\t\t\t}\n\t\t}\n\n\t\t// disable tabs\n\t\tfor ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {\n\t\t\tif ( disabled === true || $.inArray( i, disabled ) !== -1 ) {\n\t\t\t\t$( li )\n\t\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t\t} else {\n\t\t\t\t$( li )\n\t\t\t\t\t.removeClass( \"ui-state-disabled\" )\n\t\t\t\t\t.removeAttr( \"aria-disabled\" );\n\t\t\t}\n\t\t}\n\n\t\tthis.options.disabled = disabled;\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t};\n\t\tif ( event ) {\n\t\t\t$.each( event.split(\" \"), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.anchors.add( this.tabs ).add( this.panels ) );\n\t\tthis._on( this.anchors, events );\n\t\tthis._on( this.tabs, { keydown: \"_tabKeydown\" } );\n\t\tthis._on( this.panels, { keydown: \"_panelKeydown\" } );\n\n\t\tthis._focusable( this.tabs );\n\t\tthis._hoverable( this.tabs );\n\t},\n\n\t_setupHeightStyle: function( heightStyle ) {\n\t\tvar maxHeight,\n\t\t\tparent = this.element.parent();\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tmaxHeight -= this.element.outerHeight() - this.element.height();\n\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.element.children().not( this.panels ).each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.panels.each(function() {\n\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t})\n\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.panels.each(function() {\n\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).height( \"\" ).height() );\n\t\t\t}).height( maxHeight );\n\t\t}\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tanchor = $( event.currentTarget ),\n\t\t\ttab = anchor.closest( \"li\" ),\n\t\t\tclickedIsActive = tab[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive && options.collapsible,\n\t\t\ttoShow = collapsing ? $() : this._getPanelForTab( tab ),\n\t\t\ttoHide = !active.length ? $() : this._getPanelForTab( active ),\n\t\t\teventData = {\n\t\t\t\toldTab: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewTab: collapsing ? $() : tab,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif ( tab.hasClass( \"ui-state-disabled\" ) ||\n\t\t\t\t// tab is already loading\n\t\t\t\ttab.hasClass( \"ui-tabs-loading\" ) ||\n\t\t\t\t// can't switch durning an animation\n\t\t\t\tthis.running ||\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive && !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.tabs.index( tab );\n\n\t\tthis.active = clickedIsActive ? $() : tab;\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tif ( !toHide.length && !toShow.length ) {\n\t\t\t$.error( \"jQuery UI Tabs: Mismatching fragment identifier.\" );\n\t\t}\n\n\t\tif ( toShow.length ) {\n\t\t\tthis.load( this.tabs.index( tab ), event );\n\t\t}\n\t\tthis._toggle( event, eventData );\n\t},\n\n\t// handles show/hide for selecting tabs\n\t_toggle: function( event, eventData ) {\n\t\tvar that = this,\n\t\t\ttoShow = eventData.newPanel,\n\t\t\ttoHide = eventData.oldPanel;\n\n\t\tthis.running = true;\n\n\t\tfunction complete() {\n\t\t\tthat.running = false;\n\t\t\tthat._trigger( \"activate\", event, eventData );\n\t\t}\n\n\t\tfunction show() {\n\t\t\teventData.newTab.closest( \"li\" ).addClass( \"ui-tabs-active ui-state-active\" );\n\n\t\t\tif ( toShow.length && that.options.show ) {\n\t\t\t\tthat._show( toShow, that.options.show, complete );\n\t\t\t} else {\n\t\t\t\ttoShow.show();\n\t\t\t\tcomplete();\n\t\t\t}\n\t\t}\n\n\t\t// start out by hiding, then showing, then completing\n\t\tif ( toHide.length && this.options.hide ) {\n\t\t\tthis._hide( toHide, this.options.hide, function() {\n\t\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\t\tshow();\n\t\t\t});\n\t\t} else {\n\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\ttoHide.hide();\n\t\t\tshow();\n\t\t}\n\n\t\ttoHide.attr({\n\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\"aria-hidden\": \"true\"\n\t\t});\n\t\teventData.oldTab.attr( \"aria-selected\", \"false\" );\n\t\t// If we're switching tabs, remove the old tab from the tab order.\n\t\t// If we're opening from collapsed state, remove the previous tab from the tab order.\n\t\t// If we're collapsing, then keep the collapsing tab in the tab order.\n\t\tif ( toShow.length && toHide.length ) {\n\t\t\teventData.oldTab.attr( \"tabIndex\", -1 );\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.tabs.filter(function() {\n\t\t\t\treturn $( this ).attr( \"tabIndex\" ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow.attr({\n\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\"aria-hidden\": \"false\"\n\t\t});\n\t\teventData.newTab.attr({\n\t\t\t\"aria-selected\": \"true\",\n\t\t\ttabIndex: 0\n\t\t});\n\t},\n\n\t_activate: function( index ) {\n\t\tvar anchor,\n\t\t\tactive = this._findActive( index );\n\n\t\t// trying to activate the already active panel\n\t\tif ( active[ 0 ] === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the current active header\n\t\tif ( !active.length ) {\n\t\t\tactive = this.active;\n\t\t}\n\n\t\tanchor = active.find( \".ui-tabs-anchor\" )[ 0 ];\n\t\tthis._eventHandler({\n\t\t\ttarget: anchor,\n\t\t\tcurrentTarget: anchor,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( index ) {\n\t\treturn index === false ? $() : this.tabs.eq( index );\n\t},\n\n\t_getIndex: function( index ) {\n\t\t// meta-function to give users option to provide a href string instead of a numerical index.\n\t\tif ( typeof index === \"string\" ) {\n\t\t\tindex = this.anchors.index( this.anchors.filter( \"[href$='\" + index + \"']\" ) );\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_destroy: function() {\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tthis.element.removeClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible\" );\n\n\t\tthis.tablist\n\t\t\t.removeClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\tthis.anchors\n\t\t\t.removeClass( \"ui-tabs-anchor\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.removeUniqueId();\n\n\t\tthis.tabs.add( this.panels ).each(function() {\n\t\t\tif ( $.data( this, \"ui-tabs-destroy\" ) ) {\n\t\t\t\t$( this ).remove();\n\t\t\t} else {\n\t\t\t\t$( this )\n\t\t\t\t\t.removeClass( \"ui-state-default ui-state-active ui-state-disabled \" +\n\t\t\t\t\t\t\"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel\" )\n\t\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t\t.removeAttr( \"aria-live\" )\n\t\t\t\t\t.removeAttr( \"aria-busy\" )\n\t\t\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t\t.removeAttr( \"role\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.tabs.each(function() {\n\t\t\tvar li = $( this ),\n\t\t\t\tprev = li.data( \"ui-tabs-aria-controls\" );\n\t\t\tif ( prev ) {\n\t\t\t\tli\n\t\t\t\t\t.attr( \"aria-controls\", prev )\n\t\t\t\t\t.removeData( \"ui-tabs-aria-controls\" );\n\t\t\t} else {\n\t\t\t\tli.removeAttr( \"aria-controls\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.panels.show();\n\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tthis.panels.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\tenable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = false;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.map( disabled, function( num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tdisabled = $.map( this.tabs, function( li, num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tdisable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === true ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = true;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.inArray( index, disabled ) !== -1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.merge( [ index ], disabled ).sort();\n\t\t\t} else {\n\t\t\t\tdisabled = [ index ];\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tload: function( index, event ) {\n\t\tindex = this._getIndex( index );\n\t\tvar that = this,\n\t\t\ttab = this.tabs.eq( index ),\n\t\t\tanchor = tab.find( \".ui-tabs-anchor\" ),\n\t\t\tpanel = this._getPanelForTab( tab ),\n\t\t\teventData = {\n\t\t\t\ttab: tab,\n\t\t\t\tpanel: panel\n\t\t\t};\n\n\t\t// not remote\n\t\tif ( isLocal( anchor[ 0 ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );\n\n\t\t// support: jQuery <1.8\n\t\t// jQuery <1.8 returns false if the request is canceled in beforeSend,\n\t\t// but as of 1.8, $.ajax() always returns a jqXHR object.\n\t\tif ( this.xhr && this.xhr.statusText !== \"canceled\" ) {\n\t\t\ttab.addClass( \"ui-tabs-loading\" );\n\t\t\tpanel.attr( \"aria-busy\", \"true\" );\n\n\t\t\tthis.xhr\n\t\t\t\t.success(function( response ) {\n\t\t\t\t\t// support: jQuery <1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tpanel.html( response );\n\t\t\t\t\t\tthat._trigger( \"load\", event, eventData );\n\t\t\t\t\t}, 1 );\n\t\t\t\t})\n\t\t\t\t.complete(function( jqXHR, status ) {\n\t\t\t\t\t// support: jQuery <1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tif ( status === \"abort\" ) {\n\t\t\t\t\t\t\tthat.panels.stop( false, true );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttab.removeClass( \"ui-tabs-loading\" );\n\t\t\t\t\t\tpanel.removeAttr( \"aria-busy\" );\n\n\t\t\t\t\t\tif ( jqXHR === that.xhr ) {\n\t\t\t\t\t\t\tdelete that.xhr;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 1 );\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_ajaxSettings: function( anchor, event, eventData ) {\n\t\tvar that = this;\n\t\treturn {\n\t\t\turl: anchor.attr( \"href\" ),\n\t\t\tbeforeSend: function( jqXHR, settings ) {\n\t\t\t\treturn that._trigger( \"beforeLoad\", event,\n\t\t\t\t\t$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );\n\t\t\t}\n\t\t};\n\t},\n\n\t_getPanelForTab: function( tab ) {\n\t\tvar id = $( tab ).attr( \"aria-controls\" );\n\t\treturn this.element.find( this._sanitizeSelector( \"#\" + id ) );\n\t}\n});\n\n})( jQuery );\n(function( $ ) {\n\nvar increments = 0;\n\nfunction addDescribedBy( elem, id ) {\n\tvar describedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ );\n\tdescribedby.push( id );\n\telem\n\t\t.data( \"ui-tooltip-id\", id )\n\t\t.attr( \"aria-describedby\", $.trim( describedby.join( \" \" ) ) );\n}\n\nfunction removeDescribedBy( elem ) {\n\tvar id = elem.data( \"ui-tooltip-id\" ),\n\t\tdescribedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ ),\n\t\tindex = $.inArray( id, describedby );\n\tif ( index !== -1 ) {\n\t\tdescribedby.splice( index, 1 );\n\t}\n\n\telem.removeData( \"ui-tooltip-id\" );\n\tdescribedby = $.trim( describedby.join( \" \" ) );\n\tif ( describedby ) {\n\t\telem.attr( \"aria-describedby\", describedby );\n\t} else {\n\t\telem.removeAttr( \"aria-describedby\" );\n\t}\n}\n\n$.widget( \"ui.tooltip\", {\n\tversion: \"1.10.4\",\n\toptions: {\n\t\tcontent: function() {\n\t\t\t// support: IE<9, Opera in jQuery <1.7\n\t\t\t// .text() can't accept undefined, so coerce to a string\n\t\t\tvar title = $( this ).attr( \"title\" ) || \"\";\n\t\t\t// Escape title, since we're going from an attribute to raw HTML\n\t\t\treturn $( \"<a>\" ).text( title ).html();\n\t\t},\n\t\thide: true,\n\t\t// Disabled elements have inconsistent behavior across browsers (#8661)\n\t\titems: \"[title]:not([disabled])\",\n\t\tposition: {\n\t\t\tmy: \"left top+15\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"flipfit flip\"\n\t\t},\n\t\tshow: true,\n\t\ttooltipClass: null,\n\t\ttrack: false,\n\n\t\t// callbacks\n\t\tclose: null,\n\t\topen: null\n\t},\n\n\t_create: function() {\n\t\tthis._on({\n\t\t\tmouseover: \"open\",\n\t\t\tfocusin: \"open\"\n\t\t});\n\n\t\t// IDs of generated tooltips, needed for destroy\n\t\tthis.tooltips = {};\n\t\t// IDs of parent tooltips where we removed the title attribute\n\t\tthis.parents = {};\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._disable();\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar that = this;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis[ value ? \"_disable\" : \"_enable\" ]();\n\t\t\tthis.options[ key ] = value;\n\t\t\t// disable element style changes\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"content\" ) {\n\t\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\t\tthat._updateContent( element );\n\t\t\t});\n\t\t}\n\t},\n\n\t_disable: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\tvar event = $.Event( \"blur\" );\n\t\t\tevent.target = event.currentTarget = element[0];\n\t\t\tthat.close( event, true );\n\t\t});\n\n\t\t// remove title attributes to prevent native tooltips\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.is( \"[title]\" ) ) {\n\t\t\t\telement\n\t\t\t\t\t.data( \"ui-tooltip-title\", element.attr( \"title\" ) )\n\t\t\t\t\t.attr( \"title\", \"\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_enable: function() {\n\t\t// restore title attributes\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t}\n\t\t});\n\t},\n\n\topen: function( event ) {\n\t\tvar that = this,\n\t\t\ttarget = $( event ? event.target : this.element )\n\t\t\t\t// we need closest here due to mouseover bubbling,\n\t\t\t\t// but always pointing at the same event target\n\t\t\t\t.closest( this.options.items );\n\n\t\t// No element to show a tooltip for or the tooltip is already open\n\t\tif ( !target.length || target.data( \"ui-tooltip-id\" ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( target.attr( \"title\" ) ) {\n\t\t\ttarget.data( \"ui-tooltip-title\", target.attr( \"title\" ) );\n\t\t}\n\n\t\ttarget.data( \"ui-tooltip-open\", true );\n\n\t\t// kill parent tooltips, custom or native, for hover\n\t\tif ( event && event.type === \"mouseover\" ) {\n\t\t\ttarget.parents().each(function() {\n\t\t\t\tvar parent = $( this ),\n\t\t\t\t\tblurEvent;\n\t\t\t\tif ( parent.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\t\tblurEvent = $.Event( \"blur\" );\n\t\t\t\t\tblurEvent.target = blurEvent.currentTarget = this;\n\t\t\t\t\tthat.close( blurEvent, true );\n\t\t\t\t}\n\t\t\t\tif ( parent.attr( \"title\" ) ) {\n\t\t\t\t\tparent.uniqueId();\n\t\t\t\t\tthat.parents[ this.id ] = {\n\t\t\t\t\t\telement: this,\n\t\t\t\t\t\ttitle: parent.attr( \"title\" )\n\t\t\t\t\t};\n\t\t\t\t\tparent.attr( \"title\", \"\" );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis._updateContent( target, event );\n\t},\n\n\t_updateContent: function( target, event ) {\n\t\tvar content,\n\t\t\tcontentOption = this.options.content,\n\t\t\tthat = this,\n\t\t\teventType = event ? event.type : null;\n\n\t\tif ( typeof contentOption === \"string\" ) {\n\t\t\treturn this._open( event, target, contentOption );\n\t\t}\n\n\t\tcontent = contentOption.call( target[0], function( response ) {\n\t\t\t// ignore async response if tooltip was closed already\n\t\t\tif ( !target.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// IE may instantly serve a cached response for ajax requests\n\t\t\t// delay this call to _open so the other call to _open runs first\n\t\t\tthat._delay(function() {\n\t\t\t\t// jQuery creates a special event for focusin when it doesn't\n\t\t\t\t// exist natively. To improve performance, the native event\n\t\t\t\t// object is reused and the type is changed. Therefore, we can't\n\t\t\t\t// rely on the type being correct after the event finished\n\t\t\t\t// bubbling, so we set it back to the previous value. (#8740)\n\t\t\t\tif ( event ) {\n\t\t\t\t\tevent.type = eventType;\n\t\t\t\t}\n\t\t\t\tthis._open( event, target, response );\n\t\t\t});\n\t\t});\n\t\tif ( content ) {\n\t\t\tthis._open( event, target, content );\n\t\t}\n\t},\n\n\t_open: function( event, target, content ) {\n\t\tvar tooltip, events, delayedShow,\n\t\t\tpositionOption = $.extend( {}, this.options.position );\n\n\t\tif ( !content ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Content can be updated multiple times. If the tooltip already\n\t\t// exists, then just update the content and bail.\n\t\ttooltip = this._find( target );\n\t\tif ( tooltip.length ) {\n\t\t\ttooltip.find( \".ui-tooltip-content\" ).html( content );\n\t\t\treturn;\n\t\t}\n\n\t\t// if we have a title, clear it to prevent the native tooltip\n\t\t// we have to check first to avoid defining a title if none exists\n\t\t// (we don't want to cause an element to start matching [title])\n\t\t//\n\t\t// We use removeAttr only for key events, to allow IE to export the correct\n\t\t// accessible attributes. For mouse events, set to empty string to avoid\n\t\t// native tooltip showing up (happens only when removing inside mouseover).\n\t\tif ( target.is( \"[title]\" ) ) {\n\t\t\tif ( event && event.type === \"mouseover\" ) {\n\t\t\t\ttarget.attr( \"title\", \"\" );\n\t\t\t} else {\n\t\t\t\ttarget.removeAttr( \"title\" );\n\t\t\t}\n\t\t}\n\n\t\ttooltip = this._tooltip( target );\n\t\taddDescribedBy( target, tooltip.attr( \"id\" ) );\n\t\ttooltip.find( \".ui-tooltip-content\" ).html( content );\n\n\t\tfunction position( event ) {\n\t\t\tpositionOption.of = event;\n\t\t\tif ( tooltip.is( \":hidden\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttooltip.position( positionOption );\n\t\t}\n\t\tif ( this.options.track && event && /^mouse/.test( event.type ) ) {\n\t\t\tthis._on( this.document, {\n\t\t\t\tmousemove: position\n\t\t\t});\n\t\t\t// trigger once to override element-relative positioning\n\t\t\tposition( event );\n\t\t} else {\n\t\t\ttooltip.position( $.extend({\n\t\t\t\tof: target\n\t\t\t}, this.options.position ) );\n\t\t}\n\n\t\ttooltip.hide();\n\n\t\tthis._show( tooltip, this.options.show );\n\t\t// Handle tracking tooltips that are shown with a delay (#8644). As soon\n\t\t// as the tooltip is visible, position the tooltip using the most recent\n\t\t// event.\n\t\tif ( this.options.show && this.options.show.delay ) {\n\t\t\tdelayedShow = this.delayedShow = setInterval(function() {\n\t\t\t\tif ( tooltip.is( \":visible\" ) ) {\n\t\t\t\t\tposition( positionOption.of );\n\t\t\t\t\tclearInterval( delayedShow );\n\t\t\t\t}\n\t\t\t}, $.fx.interval );\n\t\t}\n\n\t\tthis._trigger( \"open\", event, { tooltip: tooltip } );\n\n\t\tevents = {\n\t\t\tkeyup: function( event ) {\n\t\t\t\tif ( event.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tvar fakeEvent = $.Event(event);\n\t\t\t\t\tfakeEvent.currentTarget = target[0];\n\t\t\t\t\tthis.close( fakeEvent, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tremove: function() {\n\t\t\t\tthis._removeTooltip( tooltip );\n\t\t\t}\n\t\t};\n\t\tif ( !event || event.type === \"mouseover\" ) {\n\t\t\tevents.mouseleave = \"close\";\n\t\t}\n\t\tif ( !event || event.type === \"focusin\" ) {\n\t\t\tevents.focusout = \"close\";\n\t\t}\n\t\tthis._on( true, target, events );\n\t},\n\n\tclose: function( event ) {\n\t\tvar that = this,\n\t\t\ttarget = $( event ? event.currentTarget : this.element ),\n\t\t\ttooltip = this._find( target );\n\n\t\t// disabling closes the tooltip, so we need to track when we're closing\n\t\t// to avoid an infinite loop in case the tooltip becomes disabled on close\n\t\tif ( this.closing ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clear the interval for delayed tracking tooltips\n\t\tclearInterval( this.delayedShow );\n\n\t\t// only set title if we had one before (see comment in _open())\n\t\tif ( target.data( \"ui-tooltip-title\" ) ) {\n\t\t\ttarget.attr( \"title\", target.data( \"ui-tooltip-title\" ) );\n\t\t}\n\n\t\tremoveDescribedBy( target );\n\n\t\ttooltip.stop( true );\n\t\tthis._hide( tooltip, this.options.hide, function() {\n\t\t\tthat._removeTooltip( $( this ) );\n\t\t});\n\n\t\ttarget.removeData( \"ui-tooltip-open\" );\n\t\tthis._off( target, \"mouseleave focusout keyup\" );\n\t\t// Remove 'remove' binding only on delegated targets\n\t\tif ( target[0] !== this.element[0] ) {\n\t\t\tthis._off( target, \"remove\" );\n\t\t}\n\t\tthis._off( this.document, \"mousemove\" );\n\n\t\tif ( event && event.type === \"mouseleave\" ) {\n\t\t\t$.each( this.parents, function( id, parent ) {\n\t\t\t\t$( parent.element ).attr( \"title\", parent.title );\n\t\t\t\tdelete that.parents[ id ];\n\t\t\t});\n\t\t}\n\n\t\tthis.closing = true;\n\t\tthis._trigger( \"close\", event, { tooltip: tooltip } );\n\t\tthis.closing = false;\n\t},\n\n\t_tooltip: function( element ) {\n\t\tvar id = \"ui-tooltip-\" + increments++,\n\t\t\ttooltip = $( \"<div>\" )\n\t\t\t\t.attr({\n\t\t\t\t\tid: id,\n\t\t\t\t\trole: \"tooltip\"\n\t\t\t\t})\n\t\t\t\t.addClass( \"ui-tooltip ui-widget ui-corner-all ui-widget-content \" +\n\t\t\t\t\t( this.options.tooltipClass || \"\" ) );\n\t\t$( \"<div>\" )\n\t\t\t.addClass( \"ui-tooltip-content\" )\n\t\t\t.appendTo( tooltip );\n\t\ttooltip.appendTo( this.document[0].body );\n\t\tthis.tooltips[ id ] = element;\n\t\treturn tooltip;\n\t},\n\n\t_find: function( target ) {\n\t\tvar id = target.data( \"ui-tooltip-id\" );\n\t\treturn id ? $( \"#\" + id ) : $();\n\t},\n\n\t_removeTooltip: function( tooltip ) {\n\t\ttooltip.remove();\n\t\tdelete this.tooltips[ tooltip.attr( \"id\" ) ];\n\t},\n\n\t_destroy: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\t// Delegate to close method to handle common cleanup\n\t\t\tvar event = $.Event( \"blur\" );\n\t\t\tevent.target = event.currentTarget = element[0];\n\t\t\tthat.close( event, true );\n\n\t\t\t// Remove immediately; destroying an open tooltip doesn't use the\n\t\t\t// hide animation\n\t\t\t$( \"#\" + id ).remove();\n\n\t\t\t// Restore the title\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t\telement.removeData( \"ui-tooltip-title\" );\n\t\t\t}\n\t\t});\n\t}\n});\n\n}( jQuery ) );\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery-ui.js.url",
    "content": "https://code.jquery.com/ui/1.10.4/jquery-ui.js\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v2.1.0\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-01-23T21:10Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar arr = [];\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar trim = \"\".trim;\n\nvar support = {};\n\n\n\nvar\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\tversion = \"2.1.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return just the object\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray,\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\treturn obj - parseFloat( obj ) >= 0;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Not plain objects:\n\t\t// - Any object or value whose internal [[Class]] property is not \"[object Object]\"\n\t\t// - DOM nodes\n\t\t// - window\n\t\tif ( jQuery.type( obj ) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: Firefox <20\n\t\t// The try/catch suppresses exceptions thrown when attempting to access\n\t\t// the \"constructor\" property of certain host objects, ie. |window.location|\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=814622\n\t\ttry {\n\t\t\tif ( obj.constructor &&\n\t\t\t\t\t!hasOwn.call( obj.constructor.prototype, \"isPrototypeOf\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If the function hasn't returned already, we're confident that\n\t\t// |obj| is a plain object, created by {} or constructed with new Object\n\t\treturn true;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\t// Support: Android < 4.0, iOS < 6 (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tvar script,\n\t\t\tindirect = eval;\n\n\t\tcode = jQuery.trim( code );\n\n\t\tif ( code ) {\n\t\t\t// If the code includes a valid, prologue position\n\t\t\t// strict mode pragma, execute code by injecting a\n\t\t\t// script tag into the document.\n\t\t\tif ( code.indexOf(\"use strict\") === 1 ) {\n\t\t\t\tscript = document.createElement(\"script\");\n\t\t\t\tscript.text = code;\n\t\t\t\tdocument.head.appendChild( script ).parentNode.removeChild( script );\n\t\t\t} else {\n\t\t\t// Otherwise, avoid the DOM node creation, insertion\n\t\t\t// and removal by using an indirect global eval\n\t\t\t\tindirect( code );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\ttrim: function( text ) {\n\t\treturn text == null ? \"\" : trim.call( text );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: Date.now,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\tvar length = obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v1.10.16\n * http://sizzlejs.com/\n *\n * Copyright 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-01-13\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\tcompile,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + -(new Date()),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tstrundefined = typeof undefined,\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf if we can't use a native one\n\tindexOf = arr.indexOf || function( elem ) {\n\t\tvar i = 0,\n\t\t\tlen = this.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( this[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n\t\t\"*(?:([*^$|!~]?=)\" + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n\t// Prefer arguments quoted,\n\t//   then not containing pseudos/brackets,\n\t//   then attribute selectors/non-parenthetical expressions,\n\t//   then anything else\n\t// These preferences are here to reduce the number of selectors\n\t//   needing tokenize in the PSEUDO preFilter\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\(((['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes.replace( 3, 8 ) + \")*)|.*)\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tif ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\n\tif ( documentIsHTML && !seed ) {\n\n\t\t// Shortcuts\n\t\tif ( (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType === 9 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== strundefined && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc,\n\t\tparent = doc.defaultView;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\n\t// Support tests\n\tdocumentIsHTML = !isXML( doc );\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", function() {\n\t\t\t\tsetDocument();\n\t\t\t}, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", function() {\n\t\t\t\tsetDocument();\n\t\t\t});\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Check if getElementsByClassName can be trusted\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {\n\t\tdiv.innerHTML = \"<div class='a'></div><div class='a i'></div>\";\n\n\t\t// Support: Safari<4\n\t\t// Catch class over-caching\n\t\tdiv.firstChild.className = \"i\";\n\t\t// Support: Opera<10\n\t\t// Catch gEBCN failure to find non-leading classes\n\t\treturn div.getElementsByClassName(\"i\").length === 2;\n\t});\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== strundefined && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [m] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== strundefined ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\t\t\t}\n\t\t} :\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdiv.innerHTML = \"<select t=''><option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 10-12\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\tif ( div.querySelectorAll(\"[t^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch(e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [elem] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[5] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] && match[4] !== undefined ) {\n\t\t\t\tmatch[2] = match[4];\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\nfunction tokenize( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n}\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\treturn ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !group ) {\n\t\t\tgroup = tokenize( selector );\n\t\t}\n\t\ti = group.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( group[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\t}\n\treturn cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction select( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tmatch = tokenize( selector );\n\n\tif ( !seed ) {\n\t\t// Try to minimize operations if there is only one group\n\t\tif ( match.length === 1 ) {\n\n\t\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\t\ttokens = match[0] = match[0].slice( 0 );\n\t\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\t\tif ( !context ) {\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t\t}\n\n\t\t\t// Fetch a seed set for right-to-left matching\n\t\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\ttoken = tokens[i];\n\n\t\t\t\t// Abort if we hit a combinator\n\t\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\t\tif ( (seed = find(\n\t\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t\t)) ) {\n\n\t\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\tcompile( selector, match )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n}\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome<14\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( indexOf.call( qualifier, elem ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tlen = this.length,\n\t\t\tret = [],\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[0] === \"<\" && selector[ selector.length - 1 ] === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\ttruncate = until !== undefined;\n\n\t\twhile ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmatched.push( elem );\n\t\t\t}\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar matched = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tmatched.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn matched;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\twhile ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn elem.contentDocument || jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.unique( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// Flag to know if list is currently firing\n\t\tfiring,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\t\t\t\t\t} else if ( !( --remaining ) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.trigger ) {\n\t\t\tjQuery( document ).trigger(\"ready\").off(\"ready\");\n\t\t}\n\t}\n});\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\twindow.removeEventListener( \"load\", completed, false );\n\tjQuery.ready();\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t} else {\n\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n// Kick off the DOM ready check even if the user does not\njQuery.ready.promise();\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlen ? fn( elems[0], key ) : emptyGet;\n};\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( owner ) {\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\t/* jshint -W018 */\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\nfunction Data() {\n\t// Support: Android < 4,\n\t// Old WebKit does not have Object.preventExtensions/freeze method,\n\t// return new empty object instead with no [[set]] accessor\n\tObject.defineProperty( this.cache = {}, 0, {\n\t\tget: function() {\n\t\t\treturn {};\n\t\t}\n\t});\n\n\tthis.expando = jQuery.expando + Math.random();\n}\n\nData.uid = 1;\nData.accepts = jQuery.acceptData;\n\nData.prototype = {\n\tkey: function( owner ) {\n\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t// but we should not, see #8335.\n\t\t// Always return the key for a frozen object.\n\t\tif ( !Data.accepts( owner ) ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar descriptor = {},\n\t\t\t// Check if the owner object already has a cache key\n\t\t\tunlock = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !unlock ) {\n\t\t\tunlock = Data.uid++;\n\n\t\t\t// Secure it in a non-enumerable, non-writable property\n\t\t\ttry {\n\t\t\t\tdescriptor[ this.expando ] = { value: unlock };\n\t\t\t\tObject.defineProperties( owner, descriptor );\n\n\t\t\t// Support: Android < 4\n\t\t\t// Fallback to a less secure definition\n\t\t\t} catch ( e ) {\n\t\t\t\tdescriptor[ this.expando ] = unlock;\n\t\t\t\tjQuery.extend( owner, descriptor );\n\t\t\t}\n\t\t}\n\n\t\t// Ensure the cache object\n\t\tif ( !this.cache[ unlock ] ) {\n\t\t\tthis.cache[ unlock ] = {};\n\t\t}\n\n\t\treturn unlock;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\t// There may be an unlock assigned to this node,\n\t\t\t// if there is no entry for this \"owner\", create one inline\n\t\t\t// and set the unlock as though an owner entry had always existed\n\t\t\tunlock = this.key( owner ),\n\t\t\tcache = this.cache[ unlock ];\n\n\t\t// Handle: [ owner, key, value ] args\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ data ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\t\t\t// Fresh assignments by object are shallow copied\n\t\t\tif ( jQuery.isEmptyObject( cache ) ) {\n\t\t\t\tjQuery.extend( this.cache[ unlock ], data );\n\t\t\t// Otherwise, copy the properties one-by-one to the cache object\n\t\t\t} else {\n\t\t\t\tfor ( prop in data ) {\n\t\t\t\t\tcache[ prop ] = data[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\t// Either a valid cache is found, or will be created.\n\t\t// New caches will be created and the unlock returned,\n\t\t// allowing direct access to the newly created\n\t\t// empty data object. A valid owner object must be provided.\n\t\tvar cache = this.cache[ this.key( owner ) ];\n\n\t\treturn key === undefined ?\n\t\t\tcache : cache[ key ];\n\t},\n\taccess: function( owner, key, value ) {\n\t\tvar stored;\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t((key && typeof key === \"string\") && value === undefined) ) {\n\n\t\t\tstored = this.get( owner, key );\n\n\t\t\treturn stored !== undefined ?\n\t\t\t\tstored : this.get( owner, jQuery.camelCase(key) );\n\t\t}\n\n\t\t// [*]When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i, name, camel,\n\t\t\tunlock = this.key( owner ),\n\t\t\tcache = this.cache[ unlock ];\n\n\t\tif ( key === undefined ) {\n\t\t\tthis.cache[ unlock ] = {};\n\n\t\t} else {\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( jQuery.isArray( key ) ) {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = key.concat( key.map( jQuery.camelCase ) );\n\t\t\t} else {\n\t\t\t\tcamel = jQuery.camelCase( key );\n\t\t\t\t// Try the string as a key before any manipulation\n\t\t\t\tif ( key in cache ) {\n\t\t\t\t\tname = [ key, camel ];\n\t\t\t\t} else {\n\t\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\t\tname = camel;\n\t\t\t\t\tname = name in cache ?\n\t\t\t\t\t\t[ name ] : ( name.match( rnotwhite ) || [] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ name[ i ] ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\treturn !jQuery.isEmptyObject(\n\t\t\tthis.cache[ owner[ this.expando ] ] || {}\n\t\t);\n\t},\n\tdiscard: function( owner ) {\n\t\tif ( owner[ this.expando ] ) {\n\t\t\tdelete this.cache[ owner[ this.expando ] ];\n\t\t}\n\t}\n};\nvar data_priv = new Data();\n\nvar data_user = new Data();\n\n\n\n/*\n\tImplementation Summary\n\n\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n\t2. Improve the module's maintainability by reducing the storage\n\t\tpaths to a single mechanism.\n\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n*/\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdata_user.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend({\n\thasData: function( elem ) {\n\t\treturn data_user.hasData( elem ) || data_priv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn data_user.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdata_user.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to data_priv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn data_priv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdata_priv.remove( elem, name );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = data_user.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !data_priv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tname = attrs[ i ].name;\n\n\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdata_priv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tdata_user.set( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data,\n\t\t\t\tcamelKey = jQuery.camelCase( key );\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key as-is\n\t\t\t\tdata = data_user.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key camelized\n\t\t\t\tdata = data_user.get( elem, camelKey );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, camelKey, undefined );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each(function() {\n\t\t\t\t// First, attempt to store a copy or reference of any\n\t\t\t\t// data that might've been store with a camelCased key.\n\t\t\t\tvar data = data_user.get( this, camelKey );\n\n\t\t\t\t// For HTML5 data-* attribute interop, we have to\n\t\t\t\t// store property names with dashes in a camelCase form.\n\t\t\t\t// This might not apply to all properties...*\n\t\t\t\tdata_user.set( this, camelKey, value );\n\n\t\t\t\t// *... In the case of properties that might _actually_\n\t\t\t\t// have dashes, we need to also store a copy of that\n\t\t\t\t// unchanged property.\n\t\t\t\tif ( key.indexOf(\"-\") !== -1 && data !== undefined ) {\n\t\t\t\t\tdata_user.set( this, key, value );\n\t\t\t\t}\n\t\t\t});\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tdata_user.remove( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = data_priv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray( data ) ) {\n\t\t\t\t\tqueue = data_priv.access( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn data_priv.get( elem, key ) || data_priv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tdata_priv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = data_priv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) );\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE9-IE11+\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n})();\nvar strundefined = typeof undefined;\n\n\n\nsupport.focusinBubbles = \"onfocusin\" in window;\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = data_priv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = data_priv.hasData( elem ) && data_priv.get( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\t\t\tdata_priv.remove( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( data_priv.get( cur, \"events\" ) || {} )[ event.type ] && data_priv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, j, ret, matched, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( data_priv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, matches, sel, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.disabled !== true || event.type !== \"click\" ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar eventDoc, doc, body,\n\t\t\t\tbutton = original.button;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: Cordova 2.5 (WebKit) (#13255)\n\t\t// All events should have a target; Cordova deviceready doesn't\n\t\tif ( !event.target ) {\n\t\t\tevent.target = document;\n\t\t}\n\n\t\t// Support: Safari 6.0+, Chrome < 28\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && jQuery.nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle, false );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\t// Support: Android < 4.0\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\tsrc.getPreventDefault && src.getPreventDefault() ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && e.preventDefault ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// Support: Chrome 15+\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// Create \"bubbling\" focus and blur events\n// Support: Firefox, Chrome, Safari\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = data_priv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdata_priv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = data_priv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdata_priv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdata_priv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar origFn, type;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nvar\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\n\t\t// Support: IE 9\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t_default: [ 0, \"\", \"\" ]\n\t};\n\n// Support: IE 9\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: 1.x compatibility\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (elem.getAttribute(\"type\") !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdata_priv.set(\n\t\t\telems[ i ], \"globalEval\", !refElements || data_priv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( data_priv.hasData( src ) ) {\n\t\tpdataOld = data_priv.access( src );\n\t\tpdataCur = data_priv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( data_user.hasData( src ) ) {\n\t\tudataOld = data_user.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdata_user.set( dest, udataCur );\n\t}\n}\n\nfunction getAll( context, tag ) {\n\tvar ret = context.getElementsByTagName ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\tcontext.querySelectorAll ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\t[];\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], ret ) :\n\t\tret;\n}\n\n// Support: IE >= 9\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Support: IE >= 9\n\t\t// Fix Cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar elem, tmp, tag, wrap, contains, j,\n\t\t\tfragment = context.createDocumentFragment(),\n\t\t\tnodes = [],\n\t\t\ti = 0,\n\t\t\tl = elems.length;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\t// Support: QtWebKit\n\t\t\t\t\t// jQuery.merge because push.apply(_, arraylike) throws\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\t\ttmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[ 2 ];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[ 0 ];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: QtWebKit\n\t\t\t\t\t// jQuery.merge because push.apply(_, arraylike) throws\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Remember the top-level container\n\t\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t\t// Fixes #12346\n\t\t\t\t\t// Support: Webkit, IE\n\t\t\t\t\ttmp.textContent = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Remove wrapper from fragment\n\t\tfragment.textContent = \"\";\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn fragment;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, events, type, key, j,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[ i ]) !== undefined; i++ ) {\n\t\t\tif ( jQuery.acceptData( elem ) ) {\n\t\t\t\tkey = elem[ data_priv.expando ];\n\n\t\t\t\tif ( key && (data = data_priv.cache[ key ]) ) {\n\t\t\t\t\tevents = Object.keys( data.events || {} );\n\t\t\t\t\tif ( events.length ) {\n\t\t\t\t\t\tfor ( j = 0; (type = events[j]) !== undefined; j++ ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( data_priv.cache[ key ] ) {\n\t\t\t\t\t\t// Discard any remaining `private` data\n\t\t\t\t\t\tdelete data_priv.cache[ key ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Discard any remaining `user` data\n\t\t\tdelete data_user.cache[ elem[ data_user.expando ] ];\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each(function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[ 0 ],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\t// Support: QtWebKit\n\t\t\t\t\t\t\t// jQuery.merge because push.apply(_, arraylike) throws\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[ i ], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!data_priv.access( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( node.textContent.replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: QtWebKit\n\t\t\t// .get() because push.apply(_, arraylike) throws\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\twindow.getDefaultComputedStyle( elem[ 0 ] ).display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = iframe[ 0 ].contentDocument;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t};\n\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// Support: IE9\n\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\t}\n\n\tif ( computed ) {\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// Support: iOS < 6\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due to missing dependency),\n\t\t\t\t// remove it.\n\t\t\t\t// Since there are no other hooks for marginRight, remove the whole object.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\tvar pixelPositionVal, boxSizingReliableVal,\n\t\t// Support: Firefox, Android 2.3 (Prefixed box-sizing versions).\n\t\tdivReset = \"padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;\" +\n\t\t\t\"-moz-box-sizing:content-box;box-sizing:content-box\",\n\t\tdocElem = document.documentElement,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tcontainer.style.cssText = \"border:0;width:0;height:0;position:absolute;top:0;left:-9999px;\" +\n\t\t\"margin-top:1px\";\n\tcontainer.appendChild( div );\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computePixelPositionAndBoxSizingReliable() {\n\t\t// Support: Firefox, Android 2.3 (Prefixed box-sizing versions).\n\t\tdiv.style.cssText = \"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;\" +\n\t\t\t\"position:absolute;top:1%\";\n\t\tdocElem.appendChild( container );\n\n\t\tvar divStyle = window.getComputedStyle( div, null );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\t\tboxSizingReliableVal = divStyle.width === \"4px\";\n\n\t\tdocElem.removeChild( container );\n\t}\n\n\t// Use window.getComputedStyle because jsdom on node.js will break without it.\n\tif ( window.getComputedStyle ) {\n\t\tjQuery.extend(support, {\n\t\t\tpixelPosition: function() {\n\t\t\t\t// This test is executed only once but we still do memoizing\n\t\t\t\t// since we can use the boxSizingReliable pre-computing.\n\t\t\t\t// No need to check if the test was already performed, though.\n\t\t\t\tcomputePixelPositionAndBoxSizingReliable();\n\t\t\t\treturn pixelPositionVal;\n\t\t\t},\n\t\t\tboxSizingReliable: function() {\n\t\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\t\tcomputePixelPositionAndBoxSizingReliable();\n\t\t\t\t}\n\t\t\t\treturn boxSizingReliableVal;\n\t\t\t},\n\t\t\treliableMarginRight: function() {\n\t\t\t\t// Support: Android 2.3\n\t\t\t\t// Check if div with explicit width and no margin-right incorrectly\n\t\t\t\t// gets computed margin-right based on width of container. (#3333)\n\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t// This support function is only executed once so no memoizing is needed.\n\t\t\t\tvar ret,\n\t\t\t\t\tmarginDiv = div.appendChild( document.createElement( \"div\" ) );\n\t\t\t\tmarginDiv.style.cssText = div.style.cssText = divReset;\n\t\t\t\tmarginDiv.style.marginRight = marginDiv.style.width = \"0\";\n\t\t\t\tdiv.style.width = \"1px\";\n\t\t\t\tdocElem.appendChild( container );\n\n\t\t\t\tret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );\n\n\t\t\t\tdocElem.removeChild( container );\n\n\t\t\t\t// Clean up the div for other support tests.\n\t\t\t\tdiv.innerHTML = \"\";\n\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t});\n\t}\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: 0,\n\t\tfontWeight: 400\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name[0].toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox &&\n\t\t\t( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = data_priv.get( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = data_priv.access( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\n\t\t\tif ( !values[ index ] ) {\n\t\t\t\thidden = isHidden( elem );\n\n\t\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\t\tdata_priv.set( elem, \"olddisplay\", hidden ? display : jQuery.css(elem, \"display\") );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set. See: #7116\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifying setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\t\t\t\t// Support: Chrome, Safari\n\t\t\t\t// Setting style to blank string required to delete \"style: x !important;\"\n\t\t\t\tstyle[ name ] = \"\";\n\t\t\t\tstyle[ name ] = value;\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, \"display\" ) ) ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\n// Support: Android 2.3\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = data_priv.get( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE9-10 do not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t// Get default display if display is currently \"none\"\n\t\tif ( display === \"none\" ) {\n\t\t\tdisplay = defaultDisplay( elem.nodeName );\n\t\t}\n\t\tif ( display === \"inline\" &&\n\t\t\t\tjQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\tstyle.display = \"inline-block\";\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always(function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t});\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = data_priv.access( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\n\t\t\tdata_priv.remove( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || data_priv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = data_priv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = data_priv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: iOS 5.1, Android 4.x, Android 2.3\n\t// Check the default checkbox/radio value (\"\" on old WebKit; \"on\" elsewhere)\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Must access the parent to make an option select properly\n\t// Support: IE9, IE10\n\tsupport.optSelected = opt.selected;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Check if an input maintains its value after becoming a radio\n\t// Support: IE9, IE10\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tjQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle;\n\t\tif ( !isXML ) {\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ name ];\n\t\t\tattrHandle[ name ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tname.toLowerCase() :\n\t\t\t\tnull;\n\t\t\tattrHandle[ name ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n});\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.hasAttribute( \"tabindex\" ) || rfocusable.test( elem.nodeName ) || elem.href ?\n\t\t\t\t\telem.tabIndex :\n\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Support: IE9+\n// Selectedness for an option in an optgroup can be inaccurate\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\tproceed = typeof value === \"string\" && value,\n\t\t\ti = 0,\n\t\t\tlen = this.length;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value,\n\t\t\ti = 0,\n\t\t\tlen = this.length;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tdata_priv.set( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : data_priv.get( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// IE6-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute( \"disabled\" ) === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\t\t\t\t\tif ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\n// Support: Android 2.3\n// Workaround failure to string-cast null input\njQuery.parseJSON = function( data ) {\n\treturn JSON.parse( data + \"\" );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE9\n\ttry {\n\t\ttmp = new DOMParser();\n\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[0] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" )\n\t\t\t.replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[ 0 ] ) {\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0;\n};\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new XMLHttpRequest();\n\t} catch( e ) {}\n};\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSuccessStatus = {\n\t\t// file protocol always yields status code 0, assume 200\n\t\t0: 200,\n\t\t// Support: IE9\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE9\n// Open requests must be manually aborted on unload (#5280)\nif ( window.ActiveXObject ) {\n\tjQuery( window ).on( \"unload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]();\n\t\t}\n\t});\n}\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport(function( options ) {\n\tvar callback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = xhr.onload = xhr.onerror = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\t// file: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\t\t\t\t\t\t\t\t\t// Support: IE9\n\t\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText === \"string\" ? {\n\t\t\t\t\t\t\t\t\t\ttext: xhr.responseText\n\t\t\t\t\t\t\t\t\t} : undefined,\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\txhr.onerror = callback(\"error\");\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = xhrCallbacks[ id ] = callback(\"abort\");\n\n\t\t\t\t// Do send the request\n\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery(\"<script>\").prop({\n\t\t\t\t\tasync: true,\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t}).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = url.slice( off );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf(\"auto\") > -1;\n\n\t\t// Need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\telem = this[ 0 ],\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\t// BlackBerry 5, iOS 3 (original iPhone)\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top + win.pageYOffset - docElem.clientTop,\n\t\t\tleft: box.left + win.pageXOffset - docElem.clientLeft\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// We assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : window.pageXOffset,\n\t\t\t\t\ttop ? val : window.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// getComputedStyle returns percent when specified for top/left/bottom/right\n// rather than make the css module depend on the offset module, we just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in\n// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery.js.url",
    "content": "https://code.jquery.com/jquery-2.1.0.js\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery.pretty-text-diff.js",
    "content": "// Generated by CoffeeScript 1.4.0\n\n/*\n@preserve jQuery.PrettyTextDiff 1.0.2\nSee https://github.com/arnab/jQuery.PrettyTextDiff/\n*/\n\n\n(function() {\n  var $;\n\n  $ = jQuery;\n\n  $.fn.extend({\n    prettyTextDiff: function(options) {\n      var dmp, settings;\n      settings = {\n        originalContainer: \".original\",\n        changedContainer: \".changed\",\n        diffContainer: \".diff\",\n        cleanup: true,\n        debug: false\n      };\n      settings = $.extend(settings, options);\n      $.fn.prettyTextDiff.debug(\"Options: \", settings, settings);\n      dmp = new diff_match_patch();\n      return this.each(function() {\n        var changed, diff_as_html, diffs, original;\n        original = $(settings.originalContainer, this).text();\n        $.fn.prettyTextDiff.debug(\"Original text found: \", original, settings);\n        changed = $(settings.changedContainer, this).text();\n        $.fn.prettyTextDiff.debug(\"Changed  text found: \", changed, settings);\n        diffs = dmp.diff_main(original, changed);\n        if (settings.cleanup) {\n          dmp.diff_cleanupSemantic(diffs);\n        }\n        $.fn.prettyTextDiff.debug(\"Diffs: \", diffs, settings);\n        diff_as_html = diffs.map(function(diff) {\n          return $.fn.prettyTextDiff.createHTML(diff);\n        });\n        $(settings.diffContainer, this).html(diff_as_html.join(''));\n        return this;\n      });\n    }\n  });\n\n  $.fn.prettyTextDiff.debug = function(message, object, settings) {\n    if (settings.debug) {\n      return console.log(message, object);\n    }\n  };\n\n  $.fn.prettyTextDiff.createHTML = function(diff) {\n    var data, html, operation, pattern_amp, pattern_gt, pattern_lt, pattern_para, text;\n    html = [];\n    pattern_amp = /&/g;\n    pattern_lt = /</g;\n    pattern_gt = />/g;\n    pattern_para = /\\n/g;\n    operation = diff[0], data = diff[1];\n    text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;').replace(pattern_gt, '&gt;').replace(pattern_para, '<br>');\n    switch (operation) {\n      case DIFF_INSERT:\n        return '<ins>' + text + '</ins>';\n      case DIFF_DELETE:\n        return '<del>' + text + '</del>';\n      case DIFF_EQUAL:\n        return '<span>' + text + '</span>';\n    }\n  };\n\n}).call(this);\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery.pretty-text-diff.js.url",
    "content": "https://raw.githubusercontent.com/arnab/jQuery.PrettyTextDiff/1.0.2/jquery.pretty-text-diff.js\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery.tipsy.js",
    "content": "// tipsy, facebook style tooltips for jquery\n// version 1.0.0a\n// (c) 2008-2010 jason frame [jason@onehackoranother.com]\n// releated under the MIT license\n\n(function($) {\n    \n    function fixTitle($ele) {\n        if ($ele.attr('title') || typeof($ele.attr('original-title')) != 'string') {\n            $ele.attr('original-title', $ele.attr('title') || '').removeAttr('title');\n        }\n    }\n    \n    function Tipsy(element, options) {\n        this.$element = $(element);\n        this.options = options;\n        this.enabled = true;\n        fixTitle(this.$element);\n    }\n    \n    Tipsy.prototype = {\n        show: function() {\n            var title = this.getTitle();\n            if (title && this.enabled) {\n                var $tip = this.tip();\n                \n                $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);\n                $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity\n                $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);\n                \n                var pos = $.extend({}, this.$element.offset(), {\n                    width: this.$element[0].offsetWidth,\n                    height: this.$element[0].offsetHeight\n                });\n                \n                var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight;\n                var gravity = (typeof this.options.gravity == 'function')\n                                ? this.options.gravity.call(this.$element[0])\n                                : this.options.gravity;\n                \n                var tp;\n                switch (gravity.charAt(0)) {\n                    case 'n':\n                        tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};\n                        break;\n                    case 's':\n                        tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};\n                        break;\n                    case 'e':\n                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};\n                        break;\n                    case 'w':\n                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};\n                        break;\n                }\n                \n                if (gravity.length == 2) {\n                    if (gravity.charAt(1) == 'w') {\n                        tp.left = pos.left + pos.width / 2 - 15;\n                    } else {\n                        tp.left = pos.left + pos.width / 2 - actualWidth + 15;\n                    }\n                }\n                \n                $tip.css(tp).addClass('tipsy-' + gravity);\n                \n                if (this.options.fade) {\n                    $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});\n                } else {\n                    $tip.css({visibility: 'visible', opacity: this.options.opacity});\n                }\n            }\n        },\n        \n        hide: function() {\n            if (this.options.fade) {\n                this.tip().stop().fadeOut(function() { $(this).remove(); });\n            } else {\n                this.tip().remove();\n            }\n        },\n        \n        getTitle: function() {\n            var title, $e = this.$element, o = this.options;\n            fixTitle($e);\n            var title, o = this.options;\n            if (typeof o.title == 'string') {\n                title = $e.attr(o.title == 'title' ? 'original-title' : o.title);\n            } else if (typeof o.title == 'function') {\n                title = o.title.call($e[0]);\n            }\n            title = ('' + title).replace(/(^\\s*|\\s*$)/, \"\");\n            return title || o.fallback;\n        },\n        \n        tip: function() {\n            if (!this.$tip) {\n                this.$tip = $('<div class=\"tipsy\"></div>').html('<div class=\"tipsy-arrow\"></div><div class=\"tipsy-inner\"/></div>');\n            }\n            return this.$tip;\n        },\n        \n        validate: function() {\n            if (!this.$element[0].parentNode) this.hide();\n        },\n        \n        enable: function() { this.enabled = true; },\n        disable: function() { this.enabled = false; },\n        toggleEnabled: function() { this.enabled = !this.enabled; }\n    };\n    \n    $.fn.tipsy = function(options) {\n        \n        if (options === true) {\n            return this.data('tipsy');\n        } else if (typeof options == 'string') {\n            return this.data('tipsy')[options]();\n        }\n        \n        options = $.extend({}, $.fn.tipsy.defaults, options);\n        \n        function get(ele) {\n            var tipsy = $.data(ele, 'tipsy');\n            if (!tipsy) {\n                tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));\n                $.data(ele, 'tipsy', tipsy);\n            }\n            return tipsy;\n        }\n        \n        function enter() {\n            var tipsy = get(this);\n            tipsy.hoverState = 'in';\n            if (options.delayIn == 0) {\n                tipsy.show();\n            } else {\n                setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);\n            }\n        };\n        \n        function leave() {\n            var tipsy = get(this);\n            tipsy.hoverState = 'out';\n            if (options.delayOut == 0) {\n                tipsy.hide();\n            } else {\n                setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);\n            }\n        };\n        \n        if (!options.live) this.each(function() { get(this); });\n        \n        if (options.trigger != 'manual') {\n            var binder   = options.live ? 'live' : 'bind',\n                eventIn  = options.trigger == 'hover' ? 'mouseenter' : 'focus',\n                eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';\n            this[binder](eventIn, enter)[binder](eventOut, leave);\n        }\n        \n        return this;\n        \n    };\n    \n    $.fn.tipsy.defaults = {\n        delayIn: 0,\n        delayOut: 0,\n        fade: false,\n        fallback: '',\n        gravity: 'n',\n        html: false,\n        live: false,\n        offset: 0,\n        opacity: 0.8,\n        title: 'title',\n        trigger: 'hover'\n    };\n    \n    // Overwrite this method to provide options on a per-element basis.\n    // For example, you could store the gravity in a 'tipsy-gravity' attribute:\n    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });\n    // (remember - do not modify 'options' in place!)\n    $.fn.tipsy.elementOptions = function(ele, options) {\n        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;\n    };\n    \n    $.fn.tipsy.autoNS = function() {\n        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';\n    };\n    \n    $.fn.tipsy.autoWE = function() {\n        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';\n    };\n    \n})(jQuery);\n"
  },
  {
    "path": "web/client/resources/js/lib/jquery.tipsy.js.url",
    "content": "https://raw.githubusercontent.com/jaz303/tipsy/v1.0.0a/src/javascripts/jquery.tipsy.js\n"
  },
  {
    "path": "web/client/resources/js/lib/markup.js",
    "content": "/*\n  Markup.js v1.5.21: http://github.com/adammark/Markup.js\n  MIT License\n  (c) 2011 - 2014 Adam Mark\n*/\nvar Mark = {\n    // Templates to include, by name. A template is a string.\n    includes: {},\n\n    // Global variables, by name. Global variables take precedence over context variables.\n    globals: {},\n\n    // The delimiter to use in pipe expressions, e.g. {{if color|like>red}}.\n    delimiter: \">\",\n\n    // Collapse white space between HTML elements in the resulting string.\n    compact: false,\n\n    // Shallow-copy an object.\n    _copy: function (a, b) {\n        b = b || [];\n\n        for (var i in a) {\n            b[i] = a[i];\n        }\n\n        return b;\n    },\n\n    // Get the value of a number or size of an array. This is a helper function for several pipes.\n    _size: function (a) {\n        return a instanceof Array ? a.length : (a || 0);\n    },\n\n    // This object represents an iteration. It has an index and length.\n    _iter: function (idx, size) {\n        this.idx = idx;\n        this.size = size;\n        this.length = size;\n        this.sign = \"#\";\n\n        // Print the index if \"#\" or the count if \"##\".\n        this.toString = function () {\n            return this.idx + this.sign.length - 1;\n        };\n    },\n\n    // Pass a value through a series of pipe expressions, e.g. _pipe(123, [\"add>10\",\"times>5\"]).\n    _pipe: function (val, expressions) {\n        var expression, parts, fn, result;\n\n        // If we have expressions, pull out the first one, e.g. \"add>10\".\n        if ((expression = expressions.shift())) {\n\n            // Split the expression into its component parts, e.g. [\"add\", \"10\"].\n            parts = expression.split(this.delimiter);\n\n            // Pull out the function name, e.g. \"add\".\n            fn = parts.shift().trim();\n\n            try {\n                // Run the function, e.g. add(123, 10) ...\n                result = Mark.pipes[fn].apply(null, [val].concat(parts));\n\n                // ... then pipe again with remaining expressions.\n                val = this._pipe(result, expressions);\n            }\n            catch (e) {\n            }\n        }\n\n        // Return the piped value.\n        return val;\n    },\n\n    // TODO doc\n    _eval: function (context, filters, child) {\n        var result = this._pipe(context, filters),\n            ctx = result,\n            i = -1,\n            j,\n            opts;\n\n        if (result instanceof Array) {\n            result = \"\";\n            j = ctx.length;\n\n            while (++i < j) {\n                opts = {\n                    iter: new this._iter(i, j)\n                };\n                result += child ? Mark.up(child, ctx[i], opts) : ctx[i];\n            }\n        }\n        else if (result instanceof Object) {\n            result = Mark.up(child, ctx);\n        }\n\n        return result;\n    },\n\n    // Process the contents of an IF or IF/ELSE block.\n    _test: function (bool, child, context, options) {\n        // Process the child string, then split it into the IF and ELSE parts.\n        var str = Mark.up(child, context, options).split(/\\{\\{\\s*else\\s*\\}\\}/);\n\n        // Return the IF or ELSE part. If no ELSE, return an empty string.\n        return (bool === false ? str[1] : str[0]) || \"\";\n    },\n\n    // Determine the extent of a block expression, e.g. \"{{foo}}...{{/foo}}\"\n    _bridge: function (tpl, tkn) {\n        tkn = tkn == \".\" ? \"\\\\.\" : tkn.replace(/\\$/g, \"\\\\$\");\n\n        var exp = \"{{\\\\s*\" + tkn + \"([^/}]+\\\\w*)?}}|{{/\" + tkn + \"\\\\s*}}\",\n            re = new RegExp(exp, \"g\"),\n            tags = tpl.match(re) || [],\n            t,\n            i,\n            a = 0,\n            b = 0,\n            c = -1,\n            d = 0;\n\n        for (i = 0; i < tags.length; i++) {\n            t = i;\n            c = tpl.indexOf(tags[t], c + 1);\n\n            if (tags[t].indexOf(\"{{/\") > -1) {\n                b++;\n            }\n            else {\n                a++;\n            }\n\n            if (a === b) {\n                break;\n            }\n        }\n\n        a = tpl.indexOf(tags[0]);\n        b = a + tags[0].length;\n        d = c + tags[t].length;\n\n        // Return the block, e.g. \"{{foo}}bar{{/foo}}\" and its child, e.g. \"bar\".\n        return [tpl.substring(a, d), tpl.substring(b, c)];\n    }\n};\n\n// Inject a template string with contextual data and return a new string.\nMark.up = function (template, context, options) {\n    context = context || {};\n    options = options || {};\n\n    // Match all tags like \"{{...}}\".\n    var re = /\\{\\{(.+?)\\}\\}/g,\n        // All tags in the template.\n        tags = template.match(re) || [],\n        // The tag being evaluated, e.g. \"{{hamster|dance}}\".\n        tag,\n        // The expression to evaluate inside the tag, e.g. \"hamster|dance\".\n        prop,\n        // The token itself, e.g. \"hamster\".\n        token,\n        // An array of pipe expressions, e.g. [\"more>1\", \"less>2\"].\n        filters = [],\n        // Does the tag close itself? e.g. \"{{stuff/}}\".\n        selfy,\n        // Is the tag an \"if\" statement?\n        testy,\n        // The contents of a block tag, e.g. \"{{aa}}bb{{/aa}}\" -> \"bb\".\n        child,\n        // The resulting string.\n        result,\n        // The global variable being evaluated, or undefined.\n        global,\n        // The included template being evaluated, or undefined.\n        include,\n        // A placeholder variable.\n        ctx,\n        // Iterators.\n        i = 0,\n        j = 0;\n\n    // Set custom pipes, if provided.\n    if (options.pipes) {\n        this._copy(options.pipes, this.pipes);\n    }\n\n    // Set templates to include, if provided.\n    if (options.includes) {\n        this._copy(options.includes, this.includes);\n    }\n\n    // Set global variables, if provided.\n    if (options.globals) {\n        this._copy(options.globals, this.globals);\n    }\n\n    // Optionally override the delimiter.\n    if (options.delimiter) {\n        this.delimiter = options.delimiter;\n    }\n\n    // Optionally collapse white space.\n    if (options.compact !== undefined) {\n        this.compact = options.compact;\n    }\n\n    // Loop through tags, e.g. {{a}}, {{b}}, {{c}}, {{/c}}.\n    while ((tag = tags[i++])) {\n        result = undefined;\n        child = \"\";\n        selfy = tag.indexOf(\"/}}\") > -1;\n        prop = tag.substr(2, tag.length - (selfy ? 5 : 4));\n        prop = prop.replace(/`(.+?)`/g, function (s, p1) {\n            return Mark.up(\"{{\" + p1 + \"}}\", context);\n        });\n        testy = prop.trim().indexOf(\"if \") === 0;\n        filters = prop.split(\"|\");\n        filters.shift(); // instead of splice(1)\n        prop = prop.replace(/^\\s*if/, \"\").split(\"|\").shift().trim();\n        token = testy ? \"if\" : prop.split(\"|\")[0];\n        ctx = context[prop];\n\n        // If an \"if\" statement without filters, assume \"{{if foo|notempty}}\"\n        if (testy && !filters.length) {\n            filters = [\"notempty\"];\n        }\n\n        // Does the tag have a corresponding closing tag? If so, find it and move the cursor.\n        if (!selfy && template.indexOf(\"{{/\" + token) > -1) {\n            result = this._bridge(template, token);\n            tag = result[0];\n            child = result[1];\n            i += tag.match(re).length - 1; // fast forward\n        }\n\n        // Skip \"else\" tags. These are pulled out in _test().\n        if (/^\\{\\{\\s*else\\s*\\}\\}$/.test(tag)) {\n            continue;\n        }\n\n        // Evaluating a global variable.\n        else if ((global = this.globals[prop]) !== undefined) {\n            result = this._eval(global, filters, child);\n        }\n\n        // Evaluating an included template.\n        else if ((include = this.includes[prop])) {\n            if (include instanceof Function) {\n                include = include();\n            }\n            result = this._pipe(Mark.up(include, context, options), filters);\n        }\n\n        // Evaluating a loop counter (\"#\" or \"##\").\n        else if (prop.indexOf(\"#\") > -1) {\n            options.iter.sign = prop;\n            result = this._pipe(options.iter, filters);\n        }\n\n        // Evaluating the current context.\n        else if (prop === \".\") {\n            result = this._pipe(context, filters);\n        }\n\n        // Evaluating a variable with dot notation, e.g. \"a.b.c\"\n        else if (prop.indexOf(\".\") > -1) {\n            prop = prop.split(\".\");\n            ctx = Mark.globals[prop[0]];\n\n            if (ctx) {\n                j = 1;\n            }\n            else {\n                j = 0;\n                ctx = context;\n            }\n\n            // Get the actual context\n            while (ctx && j < prop.length) {\n                ctx = ctx[prop[j++]];\n            }\n\n            result = this._eval(ctx, filters, child);\n        }\n\n        // Evaluating an \"if\" statement.\n        else if (testy) {\n            result = this._pipe(ctx, filters);\n        }\n\n        // Evaluating an array, which might be a block expression.\n        else if (ctx instanceof Array) {\n            result = this._eval(ctx, filters, child);\n        }\n\n        // Evaluating a block expression.\n        else if (child) {\n            result = ctx ? Mark.up(child, ctx) : undefined;\n        }\n\n        // Evaluating anything else.\n        else if (context.hasOwnProperty(prop)) {\n            result = this._pipe(ctx, filters);\n        }\n\n        // Evaluating special case: if the resulting context is actually an Array\n        if (result instanceof Array) {\n            result = this._eval(result, filters, child);\n        }\n\n        // Evaluating an \"if\" statement.\n        if (testy) {\n            result = this._test(result, child, context, options);\n        }\n\n        // Replace the tag, e.g. \"{{name}}\", with the result, e.g. \"Adam\".\n        template = template.replace(tag, result === undefined ? \"???\" : result);\n    }\n\n    return this.compact ? template.replace(/>\\s+</g, \"><\") : template;\n};\n\n// Freebie pipes. See usage in README.md\nMark.pipes = {\n    empty: function (obj) {\n        return !obj || (obj + \"\").trim().length === 0 ? obj : false;\n    },\n    notempty: function (obj) {\n        return obj && (obj + \"\").trim().length ? obj : false;\n    },\n    blank: function (str, val) {\n        return !!str || str === 0 ? str : val;\n    },\n    more: function (a, b) {\n        return Mark._size(a) > b ? a : false;\n    },\n    less: function (a, b) {\n        return Mark._size(a) < b ? a : false;\n    },\n    ormore: function (a, b) {\n        return Mark._size(a) >= b ? a : false;\n    },\n    orless: function (a, b) {\n        return Mark._size(a) <= b ? a : false;\n    },\n    between: function (a, b, c) {\n        a = Mark._size(a);\n        return a >= b && a <= c ? a : false;\n    },\n    equals: function (a, b) {\n        return a == b ? a : false;\n    },\n    notequals: function (a, b) {\n        return a != b ? a : false;\n    },\n    like: function (str, pattern) {\n        return new RegExp(pattern, \"i\").test(str) ? str : false;\n    },\n    notlike: function (str, pattern) {\n        return !Mark.pipes.like(str, pattern) ? str : false;\n    },\n    upcase: function (str) {\n        return String(str).toUpperCase();\n    },\n    downcase: function (str) {\n        return String(str).toLowerCase();\n    },\n    capcase: function (str) {\n        return str.replace(/(?:^|\\s)\\S/g, function (a) { return a.toUpperCase(); });\n    },\n    chop: function (str, n) {\n        return str.length > n ? str.substr(0, n) + \"...\" : str;\n    },\n    tease: function (str, n) {\n        var a = str.split(/\\s+/);\n        return a.slice(0, n).join(\" \") + (a.length > n ? \"...\" : \"\");\n    },\n    trim: function (str) {\n        return str.trim();\n    },\n    pack: function (str) {\n        return str.trim().replace(/\\s{2,}/g, \" \");\n    },\n    round: function (num) {\n        return Math.round(+num);\n    },\n    clean: function (str) {\n        return String(str).replace(/<\\/?[^>]+>/gi, \"\");\n    },\n    size: function (obj) {\n        return obj.length;\n    },\n    length: function (obj) {\n        return obj.length;\n    },\n    reverse: function (arr) {\n        return [].concat(arr).reverse();\n    },\n    join: function (arr, separator) {\n        return arr.join(separator);\n    },\n    limit: function (arr, count, idx) {\n        return arr.slice(+idx || 0, +count + (+idx || 0));\n    },\n    split: function (str, separator) {\n        return str.split(separator || \",\");\n    },\n    choose: function (bool, iffy, elsy) {\n        return !!bool ? iffy : (elsy || \"\");\n    },\n    toggle: function (obj, csv1, csv2, str) {\n        return csv2.split(\",\")[csv1.match(/\\w+/g).indexOf(obj + \"\")] || str;\n    },\n    sort: function (arr, prop) {\n        var fn = function (a, b) {\n            return a[prop] > b[prop] ? 1 : -1;\n        };\n        return [].concat(arr).sort(prop ? fn : undefined);\n    },\n    fix: function (num, n) {\n        return (+num).toFixed(n);\n    },\n    mod: function (num, n) {\n        return (+num) % (+n);\n    },\n    divisible: function (num, n) {\n        return num && (+num % n) === 0 ? num : false;\n    },\n    even: function (num) {\n        return num && (+num & 1) === 0 ? num : false;\n    },\n    odd: function (num) {\n        return num && (+num & 1) === 1 ? num : false;\n    },\n    number: function (str) {\n        return parseFloat(str.replace(/[^\\-\\d\\.]/g, \"\"));\n    },\n    url: function (str) {\n        return encodeURI(str);\n    },\n    bool: function (obj) {\n        return !!obj;\n    },\n    falsy: function (obj) {\n        return !obj;\n    },\n    first: function (iter) {\n        return iter.idx === 0;\n    },\n    last: function (iter) {\n        return iter.idx === iter.size - 1;\n    },\n    call: function (obj, fn) {\n        return obj[fn].apply(obj, [].slice.call(arguments, 2));\n    },\n    set: function (obj, key) {\n        Mark.globals[key] = obj; return \"\";\n    },\n    log: function (obj) {\n        console.log(obj);\n        return obj;\n    }\n};\n\n// Shim for IE.\nif (typeof String.prototype.trim !== \"function\") {\n    String.prototype.trim = function() {\n        return this.replace(/^\\s+|\\s+$/g, \"\"); \n    }\n}\n\n// Export for Node.js and AMD.\nif (typeof module !== \"undefined\" && module.exports) {\n    module.exports = Mark;\n}\nelse if (typeof define === \"function\" && define.amd) {\n    define(function() {\n        return Mark;\n    });\n}\n"
  },
  {
    "path": "web/client/resources/js/lib/markup.js.url",
    "content": "https://raw.githubusercontent.com/adammark/Markup.js/master/src/markup.js\n"
  },
  {
    "path": "web/client/resources/js/lib/moment.js",
    "content": "//! moment.js\n//! version : 2.10.2\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, function () { 'use strict';\n\n    var hookCallback;\n\n    function utils_hooks__hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n\n    // This is done to register the method called with moment()\n    // without creating circular dependencies.\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object.\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false\n        };\n    }\n\n    function isArray(input) {\n        return Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isDate(input) {\n        return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function create_utc__createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function valid__isValid(m) {\n        if (m._isValid == null) {\n            m._isValid = !isNaN(m._d.getTime()) &&\n                m._pf.overflow < 0 &&\n                !m._pf.empty &&\n                !m._pf.invalidMonth &&\n                !m._pf.nullInput &&\n                !m._pf.invalidFormat &&\n                !m._pf.userInvalidated;\n\n            if (m._strict) {\n                m._isValid = m._isValid &&\n                    m._pf.charsLeftOver === 0 &&\n                    m._pf.unusedTokens.length === 0 &&\n                    m._pf.bigHour === undefined;\n            }\n        }\n        return m._isValid;\n    }\n\n    function valid__createInvalid (flags) {\n        var m = create_utc__createUTC(NaN);\n        if (flags != null) {\n            extend(m._pf, flags);\n        }\n        else {\n            m._pf.userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    var momentProperties = utils_hooks__hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (typeof from._isAMomentObject !== 'undefined') {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (typeof from._i !== 'undefined') {\n            to._i = from._i;\n        }\n        if (typeof from._f !== 'undefined') {\n            to._f = from._f;\n        }\n        if (typeof from._l !== 'undefined') {\n            to._l = from._l;\n        }\n        if (typeof from._strict !== 'undefined') {\n            to._strict = from._strict;\n        }\n        if (typeof from._tzm !== 'undefined') {\n            to._tzm = from._tzm;\n        }\n        if (typeof from._isUTC !== 'undefined') {\n            to._isUTC = from._isUTC;\n        }\n        if (typeof from._offset !== 'undefined') {\n            to._offset = from._offset;\n        }\n        if (typeof from._pf !== 'undefined') {\n            to._pf = from._pf;\n        }\n        if (typeof from._locale !== 'undefined') {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i in momentProperties) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (typeof val !== 'undefined') {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n\n    // Moment prototype object\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(+config._d);\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            utils_hooks__hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && hasOwnProp(obj, '_isAMomentObject'));\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            if (coercedNumber >= 0) {\n                value = Math.floor(coercedNumber);\n            } else {\n                value = Math.ceil(coercedNumber);\n            }\n        }\n\n        return value;\n    }\n\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function Locale() {\n    }\n\n    var locales = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return null;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        // TODO: Find a better way to register and load all the locales in Node\n        if (!locales[name] && typeof module !== 'undefined' &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                require('./locale/' + name);\n                // because defineLocale currently also sets the global locale, we\n                // want to undo that for lazy loaded locales\n                locale_locales__getSetGlobalLocale(oldLocale);\n            } catch (e) { }\n        }\n        return locales[name];\n    }\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    function locale_locales__getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (typeof values === 'undefined') {\n                data = locale_locales__getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                // moment.duration._locale = moment._locale = data;\n                globalLocale = data;\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, values) {\n        if (values !== null) {\n            values.abbr = name;\n            if (!locales[name]) {\n                locales[name] = new Locale();\n            }\n            locales[name].set(values);\n\n            // backwards compat for now: also set the locale\n            locale_locales__getSetGlobalLocale(name);\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    }\n\n    // returns locale data\n    function locale_locales__getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                get_set__set(this, unit, value);\n                utils_hooks__hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get_set__get(this, unit);\n            }\n        };\n    }\n\n    function get_set__get (mom, unit) {\n        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n    }\n\n    function get_set__set (mom, unit, value) {\n        return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n\n    // MOMENTS\n\n    function getSet (units, value) {\n        var unit;\n        if (typeof units === 'object') {\n            for (unit in units) {\n                this.set(unit, units[unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (typeof this[units] === 'function') {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var output = '' + Math.abs(number),\n            sign = number >= 0;\n\n        while (output.length < targetLength) {\n            output = '0' + output;\n        }\n        return (sign ? (forceSign ? '+' : '') : '-') + output;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n\n    // token:    'M'\n    // padded:   ['MM', 2]\n    // ordinal:  'Mo'\n    // callback: function () { this.month() + 1 }\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '';\n            for (i = 0; i < length; i++) {\n                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n\n        if (!formatFunctions[format]) {\n            formatFunctions[format] = makeFormatFunction(format);\n        }\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n    // any word (or two) characters or numbers including two/three word month in arabic.\n    var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function unescapeFormat(s) {\n        return s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }).replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (typeof callback === 'number') {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n\n    function daysInMonth(year, month) {\n        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n    }\n\n    // FORMATTING\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    // ALIASES\n\n    addUnitAlias('month', 'M');\n\n    // PARSING\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  matchWord);\n    addRegexToken('MMMM', matchWord);\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        // if we didn't find a month name, mark the date as invalid.\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            config._pf.invalidMonth = input;\n        }\n    });\n\n    // LOCALES\n\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m) {\n        return this._months[m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m) {\n        return this._monthsShort[m.month()];\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = create_utc__createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n\n        // TODO: Move this out of here!\n        if (typeof value === 'string') {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (typeof value !== 'number') {\n                return mom;\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            utils_hooks__hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get_set__get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && m._pf.overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n\n            m._pf.overflow = overflow;\n        }\n\n        return m;\n    }\n\n    function warn(msg) {\n        if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n        return extend(function () {\n            if (firstTime) {\n                warn(msg);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    utils_hooks__hooks.suppressDeprecationWarnings = false;\n\n    var from_string__isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n        ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/]\n    ];\n\n    // iso time formats and regexes\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n        ['HH', /(T| )\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n    // date from iso format\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = from_string__isoRegex.exec(string);\n\n        if (match) {\n            config._pf.iso = true;\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(string)) {\n                    // match[5] should be 'T' or undefined\n                    config._f = isoDates[i][0] + (match[6] || ' ');\n                    break;\n                }\n            }\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(string)) {\n                    config._f += isoTimes[i][0];\n                    break;\n                }\n            }\n            if (string.match(matchOffset)) {\n                config._f += 'Z';\n            }\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    utils_hooks__hooks.createFromInputFallback = deprecate(\n        'moment construction falls back to js Date. This is ' +\n        'discouraged and will be removed in upcoming major ' +\n        'release. Please refer to ' +\n        'https://github.com/moment/moment/issues/1407 for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    function createDate (y, m, d, h, M, s, ms) {\n        //can't just apply() to create a date:\n        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply\n        var date = new Date(y, m, d, h, M, s, ms);\n\n        //the date constructor doesn't accept years < 1970\n        if (y < 1970) {\n            date.setFullYear(y);\n        }\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date = new Date(Date.UTC.apply(null, arguments));\n        if (y < 1970) {\n            date.setUTCFullYear(y);\n        }\n        return date;\n    }\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    // ALIASES\n\n    addUnitAlias('year', 'y');\n\n    // PARSING\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    // HELPERS\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    // HOOKS\n\n    utils_hooks__hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    // MOMENTS\n\n    var getSetYear = makeGetSet('FullYear', false);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    // ALIASES\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    // PARSING\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n\n    // HELPERS\n\n    // firstDayOfWeek       0 = sun, 6 = sat\n    //                      the day of the week that starts the week\n    //                      (usually sunday or monday)\n    // firstDayOfWeekOfYear 0 = sun, 6 = sat\n    //                      the first week is the week that contains the first\n    //                      of this day of the week\n    //                      (eg. ISO weeks use thursday (4))\n    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n        var end = firstDayOfWeekOfYear - firstDayOfWeek,\n            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n            adjustedMoment;\n\n\n        if (daysToDayOfWeek > end) {\n            daysToDayOfWeek -= 7;\n        }\n\n        if (daysToDayOfWeek < end - 7) {\n            daysToDayOfWeek += 7;\n        }\n\n        adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');\n        return {\n            week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n            year: adjustedMoment.year()\n        };\n    }\n\n    // LOCALES\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    // MOMENTS\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    // ALIASES\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    // PARSING\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n\n    // HELPERS\n\n    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n        var d = createUTCDate(year, 0, 1).getUTCDay();\n        var daysToAdd;\n        var dayOfYear;\n\n        d = d === 0 ? 7 : d;\n        weekday = weekday != null ? weekday : firstDayOfWeek;\n        daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);\n        dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;\n\n        return {\n            year      : dayOfYear > 0 ? year      : year - 1,\n            dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear\n        };\n    }\n\n    // MOMENTS\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n\n    // Pick the first defined of two or three arguments.\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        var now = new Date();\n        if (config._useUTC) {\n            return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];\n        }\n        return [now.getFullYear(), now.getMonth(), now.getDate()];\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse)) {\n                config._pf._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);\n            week = defaults(w.w, 1);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < dow) {\n                    ++week;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from begining of week\n                weekday = w.e + dow;\n            } else {\n                // default to begining of week\n                weekday = dow;\n            }\n        }\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n\n    utils_hooks__hooks.ISO_8601 = function () {};\n\n    // date from string and format string\n    function configFromStringAndFormat(config) {\n        // TODO: Move this to another part of the creation flow to prevent circular deps\n        if (config._f === utils_hooks__hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n\n        config._a = [];\n        config._pf.empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    config._pf.unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    config._pf.empty = false;\n                }\n                else {\n                    config._pf.unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                config._pf.unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        config._pf.charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            config._pf.unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (config._pf.bigHour === true && config._a[HOUR] <= 12) {\n            config._pf.bigHour = undefined;\n        }\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // this is not supposed to happen\n            return hour;\n        }\n    }\n\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            config._pf.invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._pf = defaultParsingFlags();\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!valid__isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += tempConfig._pf.charsLeftOver;\n\n            //or tokens\n            currentScore += tempConfig._pf.unusedTokens.length * 10;\n\n            tempConfig._pf.score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var input = config._i,\n            format = config._f,\n            res;\n\n        config._locale = config._locale || locale_locales__getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return valid__createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        } else {\n            configFromInput(config);\n        }\n\n        res = new Moment(checkOverflow(config));\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (input === undefined) {\n            config._d = new Date();\n        } else if (isDate(input)) {\n            config._d = new Date(+input);\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (typeof(input) === 'object') {\n            configFromObject(config);\n        } else if (typeof(input) === 'number') {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (typeof(locale) === 'boolean') {\n            strict = locale;\n            locale = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n        c._pf = defaultParsingFlags();\n\n        return createFromConfig(c);\n    }\n\n    function local__createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n         'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n         function () {\n             var other = local__createLocal.apply(null, arguments);\n             return other < this ? this : other;\n         }\n     );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n        function () {\n            var other = local__createLocal.apply(null, arguments);\n            return other > this ? this : other;\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return local__createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    // TODO: Use [].sort instead?\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 36e5; // 1000 * 60 * 60\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = locale_locales__getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    // PARSING\n\n    addRegexToken('Z',  matchOffset);\n    addRegexToken('ZZ', matchOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(input);\n    });\n\n    // HELPERS\n\n    // timezone chunker\n    // '+10:00' > ['10',  '00']\n    // '-1530'  > ['-15', '30']\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(string) {\n        var matches = ((string || '').match(matchOffset) || []);\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // Return a moment from input, that is local/utc/zone equivalent to model.\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(+res._d + diff);\n            utils_hooks__hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return local__createLocal(input).local();\n        }\n        return model._isUTC ? local__createLocal(input).zone(model._offset || 0) : local__createLocal(input).local();\n    }\n\n    function getDateOffset (m) {\n        // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n        // https://github.com/moment/moment/pull/1871\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n\n    // HOOKS\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    utils_hooks__hooks.updateOffset = function () {};\n\n    // MOMENTS\n\n    // keepLocalTime = true means only change the timezone, without\n    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n    // +0200, so we adjust the time as needed, to be valid.\n    //\n    // Keeping the time actually adds/subtracts (one hour)\n    // from the actual represented time. That is why we call updateOffset\n    // a second time. In case it wants us to change the offset again\n    // _changeInProgress == true case, then we have to adjust, because\n    // there is no such time in the given timezone.\n    function getSetOffset (input, keepLocalTime) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(input);\n            }\n            if (Math.abs(input) < 16) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    utils_hooks__hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm) {\n            this.utcOffset(this._tzm);\n        } else if (typeof this._i === 'string') {\n            this.utcOffset(offsetFromString(this._i));\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!input) {\n            input = 0;\n        }\n        else {\n            input = local__createLocal(input).utcOffset();\n        }\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (this._a) {\n            var other = this._isUTC ? create_utc__createUTC(this._a) : local__createLocal(this._a);\n            return this.isValid() && compareArrays(this._a, other.toArray()) > 0;\n        }\n\n        return false;\n    }\n\n    function isLocal () {\n        return !this._isUTC;\n    }\n\n    function isUtcOffset () {\n        return this._isUTC;\n    }\n\n    function isUtc () {\n        return this._isUTC && this._offset === 0;\n    }\n\n    var aspNetRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;\n\n    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n    var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;\n\n    function create__createDuration (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (typeof input === 'number') {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])        * sign,\n                h  : toInt(match[HOUR])        * sign,\n                m  : toInt(match[MINUTE])      * sign,\n                s  : toInt(match[SECOND])      * sign,\n                ms : toInt(match[MILLISECOND]) * sign\n            };\n        } else if (!!(match = create__isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                d : parseIso(match[4], sign),\n                h : parseIso(match[5], sign),\n                m : parseIso(match[6], sign),\n                s : parseIso(match[7], sign),\n                w : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    create__createDuration.fn = Duration.prototype;\n\n    function parseIso (inp, sign) {\n        // We'd normally use ~~inp for this, but unfortunately it also\n        // converts floats to ints.\n        // inp may be undefined, so careful calling replace on it.\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        // apply sign while we're at it\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {milliseconds: 0, months: 0};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = create__createDuration(val, period);\n            add_subtract__addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = duration._days,\n            months = duration._months;\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (milliseconds) {\n            mom._d.setTime(+mom._d + milliseconds * isAdding);\n        }\n        if (days) {\n            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);\n        }\n        if (months) {\n            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);\n        }\n        if (updateOffset) {\n            utils_hooks__hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add_subtract__add      = createAdder(1, 'add');\n    var add_subtract__subtract = createAdder(-1, 'subtract');\n\n    function moment_calendar__calendar (time) {\n        // We want to compare the start of today, vs this.\n        // Getting start-of-today depends on whether we're local/utc/offset or not.\n        var now = time || local__createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            diff = this.diff(sod, 'days', true),\n            format = diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n        return this.format(this.localeData().calendar(format, this, local__createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this > +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return inputMs < +this.clone().startOf(units);\n        }\n    }\n\n    function isBefore (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this < +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return +this.clone().endOf(units) < inputMs;\n        }\n    }\n\n    function isBetween (from, to, units) {\n        return this.isAfter(from, units) && this.isBefore(to, units);\n    }\n\n    function isSame (input, units) {\n        var inputMs;\n        units = normalizeUnits(units || 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this === +input;\n        } else {\n            inputMs = +local__createLocal(input);\n            return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n        }\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            return Math.ceil(number);\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function diff (input, units, asFloat) {\n        var that = cloneWithOffset(input, this),\n            zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,\n            delta, output;\n\n        units = normalizeUnits(units);\n\n        if (units === 'year' || units === 'month' || units === 'quarter') {\n            output = monthDiff(this, that);\n            if (units === 'quarter') {\n                output = output / 3;\n            } else if (units === 'year') {\n                output = output / 12;\n            }\n        } else {\n            delta = this - that;\n            output = units === 'second' ? delta / 1e3 : // 1000\n                units === 'minute' ? delta / 6e4 : // 1000 * 60\n                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n                delta;\n        }\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        return -(wholeMonthDiff + adjust);\n    }\n\n    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function moment_format__toISOString () {\n        var m = this.clone().utc();\n        if (0 < m.year() && m.year() <= 9999) {\n            if ('function' === typeof Date.prototype.toISOString) {\n                // native implementation is ~50x faster, use it when we can\n                return this.toDate().toISOString();\n            } else {\n                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n            }\n        } else {\n            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n        }\n    }\n\n    function format (inputString) {\n        var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(local__createLocal(), withoutSuffix);\n    }\n\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = locale_locales__getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    function startOf (units) {\n        units = normalizeUnits(units);\n        // the following switch intentionally omits break keywords\n        // to utilize falling through the cases.\n        switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n        }\n\n        // weeks are a special case\n        if (units === 'week') {\n            this.weekday(0);\n        }\n        if (units === 'isoWeek') {\n            this.isoWeekday(1);\n        }\n\n        // quarters are also special\n        if (units === 'quarter') {\n            this.month(Math.floor(this.month() / 3) * 3);\n        }\n\n        return this;\n    }\n\n    function endOf (units) {\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond') {\n            return this;\n        }\n        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n    }\n\n    function to_type__valueOf () {\n        return +this._d - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(+this / 1000);\n    }\n\n    function toDate () {\n        return this._offset ? new Date(+this) : this._d;\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function moment_valid__isValid () {\n        return valid__isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, this._pf);\n    }\n\n    function invalidAt () {\n        return this._pf.overflow;\n    }\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    // ALIASES\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    // PARSING\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    // HELPERS\n\n    function weeksInYear(year, dow, doy) {\n        return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;\n    }\n\n    // MOMENTS\n\n    function getSetWeekYear (input) {\n        var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getSetISOWeekYear (input) {\n        var year = weekOfYear(this, 1, 4).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    addFormatToken('Q', 0, 0, 'quarter');\n\n    // ALIASES\n\n    addUnitAlias('quarter', 'Q');\n\n    // PARSING\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    // MOMENTS\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    // ALIASES\n\n    addUnitAlias('date', 'D');\n\n    // PARSING\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0], 10);\n    });\n\n    // MOMENTS\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    // ALIASES\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    // PARSING\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   matchWord);\n    addRegexToken('ddd',  matchWord);\n    addRegexToken('dddd', matchWord);\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {\n        var weekday = config._locale.weekdaysParse(input);\n        // if we didn't get a weekday name, mark the date as invalid\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            config._pf.invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    // HELPERS\n\n    function parseWeekday(input, locale) {\n        if (typeof input === 'string') {\n            if (!isNaN(input)) {\n                input = parseInt(input, 10);\n            }\n            else {\n                input = locale.weekdaysParse(input);\n                if (typeof input !== 'number') {\n                    return null;\n                }\n            }\n        }\n        return input;\n    }\n\n    // LOCALES\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m) {\n        return this._weekdays[m.day()];\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return this._weekdaysShort[m.day()];\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return this._weekdaysMin[m.day()];\n    }\n\n    function localeWeekdaysParse (weekdayName) {\n        var i, mom, regex;\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n            if (!this._weekdaysParse[i]) {\n                mom = local__createLocal([2000, 1]).day(i);\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function getSetDayOfWeek (input) {\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        // behaves the same as moment#day except\n        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n        // as a setter, sunday should belong to the previous week.\n        return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, function () {\n        return this.hours() % 12 || 12;\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    // ALIASES\n\n    addUnitAlias('hour', 'h');\n\n    // PARSING\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        config._pf.bigHour = true;\n    });\n\n    // LOCALES\n\n    function localeIsPM (input) {\n        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n        // Using charAt should be more compatible.\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n\n\n    // MOMENTS\n\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour he wants. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    var getSetHour = makeGetSet('Hours', true);\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    // ALIASES\n\n    addUnitAlias('minute', 'm');\n\n    // PARSING\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    // MOMENTS\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    // ALIASES\n\n    addUnitAlias('second', 's');\n\n    // PARSING\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    // MOMENTS\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    function millisecond__milliseconds (token) {\n        addFormatToken(0, [token, 3], 0, 'millisecond');\n    }\n\n    millisecond__milliseconds('SSS');\n    millisecond__milliseconds('SSSS');\n\n    // ALIASES\n\n    addUnitAlias('millisecond', 'ms');\n\n    // PARSING\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n    addRegexToken('SSSS', matchUnsigned);\n    addParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    });\n\n    // MOMENTS\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    // MOMENTS\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var momentPrototype__proto = Moment.prototype;\n\n    momentPrototype__proto.add          = add_subtract__add;\n    momentPrototype__proto.calendar     = moment_calendar__calendar;\n    momentPrototype__proto.clone        = clone;\n    momentPrototype__proto.diff         = diff;\n    momentPrototype__proto.endOf        = endOf;\n    momentPrototype__proto.format       = format;\n    momentPrototype__proto.from         = from;\n    momentPrototype__proto.fromNow      = fromNow;\n    momentPrototype__proto.get          = getSet;\n    momentPrototype__proto.invalidAt    = invalidAt;\n    momentPrototype__proto.isAfter      = isAfter;\n    momentPrototype__proto.isBefore     = isBefore;\n    momentPrototype__proto.isBetween    = isBetween;\n    momentPrototype__proto.isSame       = isSame;\n    momentPrototype__proto.isValid      = moment_valid__isValid;\n    momentPrototype__proto.lang         = lang;\n    momentPrototype__proto.locale       = locale;\n    momentPrototype__proto.localeData   = localeData;\n    momentPrototype__proto.max          = prototypeMax;\n    momentPrototype__proto.min          = prototypeMin;\n    momentPrototype__proto.parsingFlags = parsingFlags;\n    momentPrototype__proto.set          = getSet;\n    momentPrototype__proto.startOf      = startOf;\n    momentPrototype__proto.subtract     = add_subtract__subtract;\n    momentPrototype__proto.toArray      = toArray;\n    momentPrototype__proto.toDate       = toDate;\n    momentPrototype__proto.toISOString  = moment_format__toISOString;\n    momentPrototype__proto.toJSON       = moment_format__toISOString;\n    momentPrototype__proto.toString     = toString;\n    momentPrototype__proto.unix         = unix;\n    momentPrototype__proto.valueOf      = to_type__valueOf;\n\n    // Year\n    momentPrototype__proto.year       = getSetYear;\n    momentPrototype__proto.isLeapYear = getIsLeapYear;\n\n    // Week Year\n    momentPrototype__proto.weekYear    = getSetWeekYear;\n    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;\n\n    // Quarter\n    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;\n\n    // Month\n    momentPrototype__proto.month       = getSetMonth;\n    momentPrototype__proto.daysInMonth = getDaysInMonth;\n\n    // Week\n    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;\n    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;\n    momentPrototype__proto.weeksInYear    = getWeeksInYear;\n    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;\n\n    // Day\n    momentPrototype__proto.date       = getSetDayOfMonth;\n    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;\n    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;\n    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;\n    momentPrototype__proto.dayOfYear  = getSetDayOfYear;\n\n    // Hour\n    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;\n\n    // Minute\n    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;\n\n    // Second\n    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;\n\n    // Millisecond\n    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;\n\n    // Offset\n    momentPrototype__proto.utcOffset            = getSetOffset;\n    momentPrototype__proto.utc                  = setOffsetToUTC;\n    momentPrototype__proto.local                = setOffsetToLocal;\n    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;\n    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    momentPrototype__proto.isDST                = isDaylightSavingTime;\n    momentPrototype__proto.isDSTShifted         = isDaylightSavingTimeShifted;\n    momentPrototype__proto.isLocal              = isLocal;\n    momentPrototype__proto.isUtcOffset          = isUtcOffset;\n    momentPrototype__proto.isUtc                = isUtc;\n    momentPrototype__proto.isUTC                = isUtc;\n\n    // Timezone\n    momentPrototype__proto.zoneAbbr = getZoneAbbr;\n    momentPrototype__proto.zoneName = getZoneName;\n\n    // Deprecations\n    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);\n\n    var momentPrototype = momentPrototype__proto;\n\n    function moment__createUnix (input) {\n        return local__createLocal(input * 1000);\n    }\n\n    function moment__createInZone () {\n        return local__createLocal.apply(null, arguments).parseZone();\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function locale_calendar__calendar (key, mom, now) {\n        var output = this._calendar[key];\n        return typeof output === 'function' ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY LT',\n        LLLL : 'dddd, MMMM D, YYYY LT'\n    };\n\n    function longDateFormat (key) {\n        var output = this._longDateFormat[key];\n        if (!output && this._longDateFormat[key.toUpperCase()]) {\n            output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {\n                return val.slice(1);\n            });\n            this._longDateFormat[key] = output;\n        }\n        return output;\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relative__relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (typeof output === 'function') ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n    }\n\n    function locale_set__set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (typeof prop === 'function') {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        // Lenient ordinal parsing accepts just a number in addition to\n        // number + (possibly) stuff coming from _ordinalParseLenient.\n        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\\d{1,2}/.source);\n    }\n\n    var prototype__proto = Locale.prototype;\n\n    prototype__proto._calendar       = defaultCalendar;\n    prototype__proto.calendar        = locale_calendar__calendar;\n    prototype__proto._longDateFormat = defaultLongDateFormat;\n    prototype__proto.longDateFormat  = longDateFormat;\n    prototype__proto._invalidDate    = defaultInvalidDate;\n    prototype__proto.invalidDate     = invalidDate;\n    prototype__proto._ordinal        = defaultOrdinal;\n    prototype__proto.ordinal         = ordinal;\n    prototype__proto._ordinalParse   = defaultOrdinalParse;\n    prototype__proto.preparse        = preParsePostFormat;\n    prototype__proto.postformat      = preParsePostFormat;\n    prototype__proto._relativeTime   = defaultRelativeTime;\n    prototype__proto.relativeTime    = relative__relativeTime;\n    prototype__proto.pastFuture      = pastFuture;\n    prototype__proto.set             = locale_set__set;\n\n    // Month\n    prototype__proto.months       =        localeMonths;\n    prototype__proto._months      = defaultLocaleMonths;\n    prototype__proto.monthsShort  =        localeMonthsShort;\n    prototype__proto._monthsShort = defaultLocaleMonthsShort;\n    prototype__proto.monthsParse  =        localeMonthsParse;\n\n    // Week\n    prototype__proto.week = localeWeek;\n    prototype__proto._week = defaultLocaleWeek;\n    prototype__proto.firstDayOfYear = localeFirstDayOfYear;\n    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;\n\n    // Day of Week\n    prototype__proto.weekdays       =        localeWeekdays;\n    prototype__proto._weekdays      = defaultLocaleWeekdays;\n    prototype__proto.weekdaysMin    =        localeWeekdaysMin;\n    prototype__proto._weekdaysMin   = defaultLocaleWeekdaysMin;\n    prototype__proto.weekdaysShort  =        localeWeekdaysShort;\n    prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;\n    prototype__proto.weekdaysParse  =        localeWeekdaysParse;\n\n    // Hours\n    prototype__proto.isPM = localeIsPM;\n    prototype__proto._meridiemParse = defaultLocaleMeridiemParse;\n    prototype__proto.meridiem = localeMeridiem;\n\n    function lists__get (format, index, field, setter) {\n        var locale = locale_locales__getLocale();\n        var utc = create_utc__createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function list (format, index, field, count, setter) {\n        if (typeof format === 'number') {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return lists__get(format, index, field, setter);\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < count; i++) {\n            out[i] = lists__get(format, i, field, setter);\n        }\n        return out;\n    }\n\n    function lists__listMonths (format, index) {\n        return list(format, index, 'months', 12, 'month');\n    }\n\n    function lists__listMonthsShort (format, index) {\n        return list(format, index, 'monthsShort', 12, 'month');\n    }\n\n    function lists__listWeekdays (format, index) {\n        return list(format, index, 'weekdays', 7, 'day');\n    }\n\n    function lists__listWeekdaysShort (format, index) {\n        return list(format, index, 'weekdaysShort', 7, 'day');\n    }\n\n    function lists__listWeekdaysMin (format, index) {\n        return list(format, index, 'weekdaysMin', 7, 'day');\n    }\n\n    locale_locales__getSetGlobalLocale('en', {\n        ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    // Side effect imports\n    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);\n    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);\n\n    var mathAbs = Math.abs;\n\n    function duration_abs__abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function duration_add_subtract__addSubtract (duration, input, value, direction) {\n        var other = create__createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n\n    // supports only 2.0-style add(1, 's') or add(duration)\n    function duration_add_subtract__add (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, 1);\n    }\n\n    // supports only 2.0-style subtract(1, 's') or subtract(duration)\n    function duration_add_subtract__subtract (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, -1);\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years = 0;\n\n        // The following code bubbles up values, see the tests for\n        // examples of what that means.\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n\n        // Accurately convert days to years, assume start from year 0.\n        years = absFloor(daysToYears(days));\n        days -= absFloor(yearsToDays(years));\n\n        // 30 days to a month\n        // TODO (iskren): Use anchor date (like 1st Jan) to compute this.\n        months += absFloor(days / 30);\n        days   %= 30;\n\n        // 12 months -> 1 year\n        years  += absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToYears (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        return days * 400 / 146097;\n    }\n\n    function yearsToDays (years) {\n        // years * 365 + absFloor(years / 4) -\n        //     absFloor(years / 100) + absFloor(years / 400);\n        return years * 146097 / 400;\n    }\n\n    function as (units) {\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'year') {\n            days   = this._days   + milliseconds / 864e5;\n            months = this._months + daysToYears(days) * 12;\n            return units === 'month' ? months : months / 12;\n        } else {\n            // handle milliseconds separately because of floating point math errors (issue #1867)\n            days = this._days + Math.round(yearsToDays(this._months / 12));\n            switch (units) {\n                case 'week'   : return days / 7            + milliseconds / 6048e5;\n                case 'day'    : return days                + milliseconds / 864e5;\n                case 'hour'   : return days * 24           + milliseconds / 36e5;\n                case 'minute' : return days * 24 * 60      + milliseconds / 6e4;\n                case 'second' : return days * 24 * 60 * 60 + milliseconds / 1000;\n                // Math.floor prevents floating point math errors here\n                case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n\n    // TODO: Use this.as('ms')?\n    function duration_as__valueOf () {\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asYears        = makeAs('y');\n\n    function duration_get__get (units) {\n        units = normalizeUnits(units);\n        return this[units + 's']();\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this._data[name];\n        };\n    }\n\n    var duration_get__milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        s: 45,  // seconds to minute\n        m: 45,  // minutes to hour\n        h: 22,  // hours to day\n        d: 26,  // days to month\n        M: 11   // months to year\n    };\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {\n        var duration = create__createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds < thresholds.s && ['s', seconds]  ||\n                minutes === 1          && ['m']           ||\n                minutes < thresholds.m && ['mm', minutes] ||\n                hours   === 1          && ['h']           ||\n                hours   < thresholds.h && ['hh', hours]   ||\n                days    === 1          && ['d']           ||\n                days    < thresholds.d && ['dd', days]    ||\n                months  === 1          && ['M']           ||\n                months  < thresholds.M && ['MM', months]  ||\n                years   === 1          && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n\n    // This function allows you to set a threshold for relative time strings\n    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        var locale = this.localeData();\n        var output = duration_humanize__relativeTime(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var iso_string__abs = Math.abs;\n\n    function iso_string__toISOString() {\n        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n        var Y = iso_string__abs(this.years());\n        var M = iso_string__abs(this.months());\n        var D = iso_string__abs(this.days());\n        var h = iso_string__abs(this.hours());\n        var m = iso_string__abs(this.minutes());\n        var s = iso_string__abs(this.seconds() + this.milliseconds() / 1000);\n        var total = this.asSeconds();\n\n        if (!total) {\n            // this is the same as C#'s (Noda) and python (isodate)...\n            // but not other JS (goog.date)\n            return 'P0D';\n        }\n\n        return (total < 0 ? '-' : '') +\n            'P' +\n            (Y ? Y + 'Y' : '') +\n            (M ? M + 'M' : '') +\n            (D ? D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? h + 'H' : '') +\n            (m ? m + 'M' : '') +\n            (s ? s + 'S' : '');\n    }\n\n    var duration_prototype__proto = Duration.prototype;\n\n    duration_prototype__proto.abs            = duration_abs__abs;\n    duration_prototype__proto.add            = duration_add_subtract__add;\n    duration_prototype__proto.subtract       = duration_add_subtract__subtract;\n    duration_prototype__proto.as             = as;\n    duration_prototype__proto.asMilliseconds = asMilliseconds;\n    duration_prototype__proto.asSeconds      = asSeconds;\n    duration_prototype__proto.asMinutes      = asMinutes;\n    duration_prototype__proto.asHours        = asHours;\n    duration_prototype__proto.asDays         = asDays;\n    duration_prototype__proto.asWeeks        = asWeeks;\n    duration_prototype__proto.asMonths       = asMonths;\n    duration_prototype__proto.asYears        = asYears;\n    duration_prototype__proto.valueOf        = duration_as__valueOf;\n    duration_prototype__proto._bubble        = bubble;\n    duration_prototype__proto.get            = duration_get__get;\n    duration_prototype__proto.milliseconds   = duration_get__milliseconds;\n    duration_prototype__proto.seconds        = seconds;\n    duration_prototype__proto.minutes        = minutes;\n    duration_prototype__proto.hours          = hours;\n    duration_prototype__proto.days           = days;\n    duration_prototype__proto.weeks          = weeks;\n    duration_prototype__proto.months         = months;\n    duration_prototype__proto.years          = years;\n    duration_prototype__proto.humanize       = humanize;\n    duration_prototype__proto.toISOString    = iso_string__toISOString;\n    duration_prototype__proto.toString       = iso_string__toISOString;\n    duration_prototype__proto.toJSON         = iso_string__toISOString;\n    duration_prototype__proto.locale         = locale;\n    duration_prototype__proto.localeData     = localeData;\n\n    // Deprecations\n    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);\n    duration_prototype__proto.lang = lang;\n\n    // Side effect imports\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    // PARSING\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    // Side effect imports\n\n\n    utils_hooks__hooks.version = '2.10.2';\n\n    setHookCallback(local__createLocal);\n\n    utils_hooks__hooks.fn                    = momentPrototype;\n    utils_hooks__hooks.min                   = min;\n    utils_hooks__hooks.max                   = max;\n    utils_hooks__hooks.utc                   = create_utc__createUTC;\n    utils_hooks__hooks.unix                  = moment__createUnix;\n    utils_hooks__hooks.months                = lists__listMonths;\n    utils_hooks__hooks.isDate                = isDate;\n    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;\n    utils_hooks__hooks.invalid               = valid__createInvalid;\n    utils_hooks__hooks.duration              = create__createDuration;\n    utils_hooks__hooks.isMoment              = isMoment;\n    utils_hooks__hooks.weekdays              = lists__listWeekdays;\n    utils_hooks__hooks.parseZone             = moment__createInZone;\n    utils_hooks__hooks.localeData            = locale_locales__getLocale;\n    utils_hooks__hooks.isDuration            = isDuration;\n    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;\n    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;\n    utils_hooks__hooks.defineLocale          = defineLocale;\n    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;\n    utils_hooks__hooks.normalizeUnits        = normalizeUnits;\n    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;\n\n    var _moment = utils_hooks__hooks;\n\n    return _moment;\n\n}));"
  },
  {
    "path": "web/client/resources/js/lib/moment.js.url",
    "content": "https://raw.githubusercontent.com/moment/moment/2.10.2/moment.js\n"
  },
  {
    "path": "web/client/resources/js/lib/taboverride.js",
    "content": "/*! taboverride v4.0.3 | https://github.com/wjbryant/taboverride\n(c) 2015 Bill Bryant | http://opensource.org/licenses/mit */\n\n/**\n * @fileOverview taboverride\n * @author       Bill Bryant\n * @version      4.0.3\n */\n\n/*jslint browser: true */\n/*global exports, define */\n\n// use CommonJS or AMD if available\n(function (factory) {\n    'use strict';\n\n    var mod;\n\n    if (typeof exports === 'object') {\n        // Node.js/CommonJS\n        factory(exports);\n    } else if (typeof define === 'function' && define.amd) {\n        // AMD - register as an anonymous module\n        // files must be concatenated using an AMD-aware tool such as r.js\n        define(['exports'], factory);\n    } else {\n        // no module format - create global variable\n        mod = window.tabOverride = {};\n        factory(mod);\n    }\n}(function (tabOverride) {\n    'use strict';\n\n    /**\n     * The tabOverride namespace object\n     *\n     * @namespace tabOverride\n     */\n\n    var document = window.document,\n        listeners,\n        aTab = '\\t', // the string representing a tab\n        tabKey = 9,\n        untabKey = 9,\n        tabModifierKeys = [],\n        untabModifierKeys = ['shiftKey'],\n        autoIndent = true, // whether each line should be automatically indented\n        inWhitespace = false, // whether the start of the selection is in the leading whitespace on enter\n        textareaElem = document.createElement('textarea'), // temp textarea element to get newline character(s)\n        newline, // the newline character sequence (\\n or \\r\\n)\n        newlineLen, // the number of characters used for a newline (1 or 2)\n        hooks = {};\n\n    /**\n     * Determines whether the specified modifier keys match the modifier keys\n     * that were pressed.\n     *\n     * @param  {string[]} modifierKeys  the modifier keys to check - ex: ['shiftKey']\n     * @param  {Event}    e             the event object for the keydown event\n     * @return {boolean}                whether modifierKeys are valid for the event\n     *\n     * @method tabOverride.utils.isValidModifierKeyCombo\n     */\n    function isValidModifierKeyCombo(modifierKeys, e) {\n        var modifierKeyNames = ['alt', 'ctrl', 'meta', 'shift'],\n            numModKeys = modifierKeys.length,\n            i,\n            j,\n            currModifierKey,\n            isValid = true;\n\n        // check that all required modifier keys were pressed\n        for (i = 0; i < numModKeys; i += 1) {\n            if (!e[modifierKeys[i]]) {\n                isValid = false;\n                break;\n            }\n        }\n\n        // if the requirements were met, check for additional modifier keys\n        if (isValid) {\n            for (i = 0; i < modifierKeyNames.length; i += 1) {\n                currModifierKey = modifierKeyNames[i] + 'Key';\n\n                // if this key was pressed\n                if (e[currModifierKey]) {\n                    // if there are required keys, check whether the current key\n                    // is required\n                    if (numModKeys) {\n                        isValid = false;\n\n                        // if this is a required key, continue\n                        for (j = 0; j < numModKeys; j += 1) {\n                            if (currModifierKey === modifierKeys[j]) {\n                                isValid = true;\n                                break;\n                            }\n                        }\n                    } else {\n                        // no required keys, but one was pressed\n                        isValid = false;\n                    }\n                }\n\n                // an extra key was pressed, don't check anymore\n                if (!isValid) {\n                    break;\n                }\n            }\n        }\n\n        return isValid;\n    }\n\n    /**\n     * Determines whether the tab key combination was pressed.\n     *\n     * @param  {number}  keyCode  the key code of the key that was pressed\n     * @param  {Event}   e        the event object for the key event\n     * @return {boolean}          whether the tab key combo was pressed\n     *\n     * @private\n     */\n    function tabKeyComboPressed(keyCode, e) {\n        return keyCode === tabKey && isValidModifierKeyCombo(tabModifierKeys, e);\n    }\n\n    /**\n     * Determines whether the untab key combination was pressed.\n     *\n     * @param  {number}  keyCode  the key code of the key that was pressed\n     * @param  {Event}   e        the event object for the key event\n     * @return {boolean}          whether the untab key combo was pressed\n     *\n     * @private\n     */\n    function untabKeyComboPressed(keyCode, e) {\n        return keyCode === untabKey && isValidModifierKeyCombo(untabModifierKeys, e);\n    }\n\n    /**\n     * Creates a function to get and set the specified key combination.\n     *\n     * @param  {Function} keyFunc       getter/setter function for the key\n     * @param  {string[]} modifierKeys  the array of modifier keys to manipulate\n     * @return {Function}               a getter/setter function for the specified\n     *                                  key combination\n     *\n     * @private\n     */\n    function createKeyComboFunction(keyFunc, modifierKeys) {\n        return function (keyCode, modifierKeyNames) {\n            var i,\n                keyCombo = '';\n\n            if (arguments.length) {\n                if (typeof keyCode === 'number') {\n                    keyFunc(keyCode);\n\n                    modifierKeys.length = 0; // clear the array\n\n                    if (modifierKeyNames && modifierKeyNames.length) {\n                        for (i = 0; i < modifierKeyNames.length; i += 1) {\n                            modifierKeys.push(modifierKeyNames[i] + 'Key');\n                        }\n                    }\n                }\n\n                return this;\n            }\n\n            for (i = 0; i < modifierKeys.length; i += 1) {\n                keyCombo += modifierKeys[i].slice(0, -3) + '+';\n            }\n\n            return keyCombo + keyFunc();\n        };\n    }\n\n    /**\n     * Event handler to insert or remove tabs and newlines on the keydown event\n     * for the tab or enter key.\n     *\n     * @param {Event} e  the event object\n     *\n     * @method tabOverride.handlers.keydown\n     */\n    function overrideKeyDown(e) {\n        e = e || event;\n\n        // textarea elements can only contain text nodes which don't receive\n        // keydown events, so the event target/srcElement will always be the\n        // textarea element, however, prefer currentTarget in order to support\n        // delegated events in compliant browsers\n        var target = e.currentTarget || e.srcElement, // don't use the \"this\" keyword (doesn't work in old IE)\n            key = e.keyCode, // the key code for the key that was pressed\n            tab, // the string representing a tab\n            tabLen, // the length of a tab\n            text, // initial text in the textarea\n            range, // the IE TextRange object\n            tempRange, // used to calculate selection start and end positions in IE\n            preNewlines, // the number of newline character sequences before the selection start (for IE)\n            selNewlines, // the number of newline character sequences within the selection (for IE)\n            initScrollTop, // initial scrollTop value used to fix scrolling in Firefox\n            selStart, // the selection start position\n            selEnd, // the selection end position\n            sel, // the selected text\n            startLine, // for multi-line selections, the first character position of the first line\n            endLine, // for multi-line selections, the last character position of the last line\n            numTabs, // the number of tabs inserted / removed in the selection\n            startTab, // if a tab was removed from the start of the first line\n            preTab, // if a tab was removed before the start of the selection\n            whitespace, // the whitespace at the beginning of the first selected line\n            whitespaceLen, // the length of the whitespace at the beginning of the first selected line\n            CHARACTER = 'character'; // string constant used for the Range.move methods\n\n        // don't do any unnecessary work\n        if ((target.nodeName && target.nodeName.toLowerCase() !== 'textarea') ||\n                (key !== tabKey && key !== untabKey && (key !== 13 || !autoIndent))) {\n            return;\n        }\n\n        // initialize variables used for tab and enter keys\n        inWhitespace = false; // this will be set to true if enter is pressed in the leading whitespace\n        text = target.value;\n\n        // this is really just for Firefox, but will be used by all browsers that support\n        // selectionStart and selectionEnd - whenever the textarea value property is reset,\n        // Firefox scrolls back to the top - this is used to set it back to the original value\n        // scrollTop is nonstandard, but supported by all modern browsers\n        initScrollTop = target.scrollTop;\n\n        // get the text selection\n        if (typeof target.selectionStart === 'number') {\n            selStart = target.selectionStart;\n            selEnd = target.selectionEnd;\n            sel = text.slice(selStart, selEnd);\n\n        } else if (document.selection) { // IE\n            range = document.selection.createRange();\n            sel = range.text;\n            tempRange = range.duplicate();\n            tempRange.moveToElementText(target);\n            tempRange.setEndPoint('EndToEnd', range);\n            selEnd = tempRange.text.length;\n            selStart = selEnd - sel.length;\n\n            // whenever the value of the textarea is changed, the range needs to be reset\n            // IE <9 (and Opera) use both \\r and \\n for newlines - this adds an extra character\n            // that needs to be accounted for when doing position calculations with ranges\n            // these values are used to offset the selection start and end positions\n            if (newlineLen > 1) {\n                preNewlines = text.slice(0, selStart).split(newline).length - 1;\n                selNewlines = sel.split(newline).length - 1;\n            } else {\n                preNewlines = selNewlines = 0;\n            }\n        } else {\n            return; // cannot access textarea selection - do nothing\n        }\n\n        // tab / untab key - insert / remove tab\n        if (key === tabKey || key === untabKey) {\n\n            // initialize tab variables\n            tab = aTab;\n            tabLen = tab.length;\n            numTabs = 0;\n            startTab = 0;\n            preTab = 0;\n\n            // multi-line selection\n            if (selStart !== selEnd && sel.indexOf('\\n') !== -1) {\n                // for multiple lines, only insert / remove tabs from the beginning of each line\n\n                // find the start of the first selected line\n                if (selStart === 0 || text.charAt(selStart - 1) === '\\n') {\n                    // the selection starts at the beginning of a line\n                    startLine = selStart;\n                } else {\n                    // the selection starts after the beginning of a line\n                    // set startLine to the beginning of the first partially selected line\n                    // subtract 1 from selStart in case the cursor is at the newline character,\n                    // for instance, if the very end of the previous line was selected\n                    // add 1 to get the next character after the newline\n                    // if there is none before the selection, lastIndexOf returns -1\n                    // when 1 is added to that it becomes 0 and the first character is used\n                    startLine = text.lastIndexOf('\\n', selStart - 1) + 1;\n                }\n\n                // find the end of the last selected line\n                if (selEnd === text.length || text.charAt(selEnd) === '\\n') {\n                    // the selection ends at the end of a line\n                    endLine = selEnd;\n                } else if (text.charAt(selEnd - 1) === '\\n') {\n                    // the selection ends at the start of a line, but no\n                    // characters are selected - don't indent this line\n                    endLine = selEnd - 1;\n                } else {\n                    // the selection ends before the end of a line\n                    // set endLine to the end of the last partially selected line\n                    endLine = text.indexOf('\\n', selEnd);\n                    if (endLine === -1) {\n                        endLine = text.length;\n                    }\n                }\n\n                // tab key combo - insert tabs\n                if (tabKeyComboPressed(key, e)) {\n\n                    numTabs = 1; // for the first tab\n\n                    // insert tabs at the beginning of each line of the selection\n                    target.value = text.slice(0, startLine) + tab +\n                        text.slice(startLine, endLine).replace(/\\n/g, function () {\n                            numTabs += 1;\n                            return '\\n' + tab;\n                        }) + text.slice(endLine);\n\n                    // set start and end points\n                    if (range) { // IE\n                        range.collapse();\n                        range.moveEnd(CHARACTER, selEnd + (numTabs * tabLen) - selNewlines - preNewlines);\n                        range.moveStart(CHARACTER, selStart + tabLen - preNewlines);\n                        range.select();\n                    } else {\n                        // the selection start is always moved by 1 character\n                        target.selectionStart = selStart + tabLen;\n                        // move the selection end over by the total number of tabs inserted\n                        target.selectionEnd = selEnd + (numTabs * tabLen);\n                        target.scrollTop = initScrollTop;\n                    }\n                } else if (untabKeyComboPressed(key, e)) {\n                    // if the untab key combo was pressed, remove tabs instead of inserting them\n\n                    if (text.slice(startLine).indexOf(tab) === 0) {\n                        // is this tab part of the selection?\n                        if (startLine === selStart) {\n                            // it is, remove it\n                            sel = sel.slice(tabLen);\n                        } else {\n                            // the tab comes before the selection\n                            preTab = tabLen;\n                        }\n                        startTab = tabLen;\n                    }\n\n                    target.value = text.slice(0, startLine) + text.slice(startLine + preTab, selStart) +\n                        sel.replace(new RegExp('\\n' + tab, 'g'), function () {\n                            numTabs += 1;\n                            return '\\n';\n                        }) + text.slice(selEnd);\n\n                    // set start and end points\n                    if (range) { // IE\n                        // setting end first makes calculations easier\n                        range.collapse();\n                        range.moveEnd(CHARACTER, selEnd - startTab - (numTabs * tabLen) - selNewlines - preNewlines);\n                        range.moveStart(CHARACTER, selStart - preTab - preNewlines);\n                        range.select();\n                    } else {\n                        // set start first for Opera\n                        target.selectionStart = selStart - preTab; // preTab is 0 or tabLen\n                        // move the selection end over by the total number of tabs removed\n                        target.selectionEnd = selEnd - startTab - (numTabs * tabLen);\n                    }\n                } else {\n                    return; // do nothing for invalid key combinations\n                }\n\n            } else { // single line selection\n\n                // tab key combo - insert a tab\n                if (tabKeyComboPressed(key, e)) {\n                    if (range) { // IE\n                        range.text = tab;\n                        range.select();\n                    } else {\n                        target.value = text.slice(0, selStart) + tab + text.slice(selEnd);\n                        target.selectionEnd = target.selectionStart = selStart + tabLen;\n                        target.scrollTop = initScrollTop;\n                    }\n                } else if (untabKeyComboPressed(key, e)) {\n                    // if the untab key combo was pressed, remove a tab instead of inserting one\n\n                    // if the character before the selection is a tab, remove it\n                    if (text.slice(selStart - tabLen).indexOf(tab) === 0) {\n                        target.value = text.slice(0, selStart - tabLen) + text.slice(selStart);\n\n                        // set start and end points\n                        if (range) { // IE\n                            // collapses range and moves it by -1 tab\n                            range.move(CHARACTER, selStart - tabLen - preNewlines);\n                            range.select();\n                        } else {\n                            target.selectionEnd = target.selectionStart = selStart - tabLen;\n                            target.scrollTop = initScrollTop;\n                        }\n                    }\n                } else {\n                    return; // do nothing for invalid key combinations\n                }\n            }\n        } else if (autoIndent) { // Enter key\n            // insert a newline and copy the whitespace from the beginning of the line\n\n            // find the start of the first selected line\n            if (selStart === 0 || text.charAt(selStart - 1) === '\\n') {\n                // the selection starts at the beginning of a line\n                // do nothing special\n                inWhitespace = true;\n                return;\n            }\n\n            // see explanation under \"multi-line selection\" above\n            startLine = text.lastIndexOf('\\n', selStart - 1) + 1;\n\n            // find the end of the first selected line\n            endLine = text.indexOf('\\n', selStart);\n\n            // if no newline is found, set endLine to the end of the text\n            if (endLine === -1) {\n                endLine = text.length;\n            }\n\n            // get the whitespace at the beginning of the first selected line (spaces and tabs only)\n            whitespace = text.slice(startLine, endLine).match(/^[ \\t]*/)[0];\n            whitespaceLen = whitespace.length;\n\n            // the cursor (selStart) is in the whitespace at beginning of the line\n            // do nothing special\n            if (selStart < startLine + whitespaceLen) {\n                inWhitespace = true;\n                return;\n            }\n\n            if (range) { // IE\n                // insert the newline and whitespace\n                range.text = '\\n' + whitespace;\n                range.select();\n            } else {\n                // insert the newline and whitespace\n                target.value = text.slice(0, selStart) + '\\n' + whitespace + text.slice(selEnd);\n                // Opera uses \\r\\n for a newline, instead of \\n,\n                // so use newlineLen instead of a hard-coded value\n                target.selectionEnd = target.selectionStart = selStart + newlineLen + whitespaceLen;\n                target.scrollTop = initScrollTop;\n            }\n        }\n\n        if (e.preventDefault) {\n            e.preventDefault();\n        } else {\n            e.returnValue = false;\n            return false;\n        }\n    }\n\n    /**\n     * Event handler to prevent the default action for the keypress event when\n     * tab or enter is pressed. Opera and Firefox also fire a keypress event\n     * when the tab or enter key is pressed. Opera requires that the default\n     * action be prevented on this event or the textarea will lose focus.\n     *\n     * @param {Event} e  the event object\n     *\n     * @method tabOverride.handlers.keypress\n     */\n    function overrideKeyPress(e) {\n        e = e || event;\n\n        var key = e.keyCode;\n\n        if (tabKeyComboPressed(key, e) || untabKeyComboPressed(key, e) ||\n                (key === 13 && autoIndent && !inWhitespace)) {\n\n            if (e.preventDefault) {\n                e.preventDefault();\n            } else {\n                e.returnValue = false;\n                return false;\n            }\n        }\n    }\n\n    /**\n     * Executes all registered extension functions for the specified hook.\n     *\n     * @param {string} hook    the name of the hook for which the extensions are registered\n     * @param {Array}  [args]  the arguments to pass to the extension\n     *\n     * @method tabOverride.utils.executeExtensions\n     */\n    function executeExtensions(hook, args) {\n        var i,\n            extensions = hooks[hook] || [],\n            len = extensions.length;\n\n        for (i = 0; i < len; i += 1) {\n            extensions[i].apply(null, args);\n        }\n    }\n\n    /**\n     * @typedef {Object} tabOverride.utils~handlerObj\n     *\n     * @property {string}   type     the event type\n     * @property {Function} handler  the handler function - passed an Event object\n     */\n\n    /**\n     * @typedef {Object} tabOverride.utils~listenersObj\n     *\n     * @property {Function} add     Adds all the event listeners to the\n     *                              specified element\n     * @property {Function} remove  Removes all the event listeners from\n     *                              the specified element\n     */\n\n    /**\n     * Creates functions to add and remove event listeners in a cross-browser\n     * compatible way.\n     *\n     * @param  {tabOverride.utils~handlerObj[]} handlerList  an array of {@link tabOverride.utils~handlerObj handlerObj} objects\n     * @return {tabOverride.utils~listenersObj}              a listenersObj object used to add and remove the event listeners\n     *\n     * @method tabOverride.utils.createListeners\n     */\n    function createListeners(handlerList) {\n        var i,\n            len = handlerList.length,\n            remove,\n            add;\n\n        function loop(func) {\n            for (i = 0; i < len; i += 1) {\n                func(handlerList[i].type, handlerList[i].handler);\n            }\n        }\n\n        // use the standard event handler registration method when available\n        if (document.addEventListener) {\n            remove = function (elem) {\n                loop(function (type, handler) {\n                    elem.removeEventListener(type, handler, false);\n                });\n            };\n            add = function (elem) {\n                // remove listeners before adding them to make sure they are not\n                // added more than once\n                remove(elem);\n                loop(function (type, handler) {\n                    elem.addEventListener(type, handler, false);\n                });\n            };\n        } else if (document.attachEvent) {\n            // support IE 6-8\n            remove = function (elem) {\n                loop(function (type, handler) {\n                    elem.detachEvent('on' + type, handler);\n                });\n            };\n            add = function (elem) {\n                remove(elem);\n                loop(function (type, handler) {\n                    elem.attachEvent('on' + type, handler);\n                });\n            };\n        }\n\n        return {\n            add: add,\n            remove: remove\n        };\n    }\n\n    /**\n     * Adds the Tab Override event listeners to the specified element.\n     *\n     * Hooks: addListeners - passed the element to which the listeners will\n     * be added.\n     *\n     * @param {Element} elem  the element to which the listeners will be added\n     *\n     * @method tabOverride.utils.addListeners\n     */\n    function addListeners(elem) {\n        executeExtensions('addListeners', [elem]);\n        listeners.add(elem);\n    }\n\n    /**\n     * Removes the Tab Override event listeners from the specified element.\n     *\n     * Hooks: removeListeners - passed the element from which the listeners\n     * will be removed.\n     *\n     * @param {Element} elem  the element from which the listeners will be removed\n     *\n     * @method tabOverride.utils.removeListeners\n     */\n    function removeListeners(elem) {\n        executeExtensions('removeListeners', [elem]);\n        listeners.remove(elem);\n    }\n\n\n    // Initialize Variables\n\n    listeners = createListeners([\n        { type: 'keydown', handler: overrideKeyDown },\n        { type: 'keypress', handler: overrideKeyPress }\n    ]);\n\n    // get the characters used for a newline\n    textareaElem.value = '\\n';\n    newline = textareaElem.value;\n    newlineLen = newline.length;\n    textareaElem = null;\n\n\n    // Public Properties and Methods\n\n    /**\n     * Namespace for utility methods\n     *\n     * @namespace\n     */\n    tabOverride.utils = {\n        executeExtensions: executeExtensions,\n        isValidModifierKeyCombo: isValidModifierKeyCombo,\n        createListeners: createListeners,\n        addListeners: addListeners,\n        removeListeners: removeListeners\n    };\n\n    /**\n     * Namespace for event handler functions\n     *\n     * @namespace\n     */\n    tabOverride.handlers = {\n        keydown: overrideKeyDown,\n        keypress: overrideKeyPress\n    };\n\n    /**\n     * Adds an extension function to be executed when the specified hook is\n     * \"fired.\" The extension function is called for each element and is passed\n     * any relevant arguments for the hook.\n     *\n     * @param  {string}   hook  the name of the hook for which the extension\n     *                          will be registered\n     * @param  {Function} func  the function to be executed when the hook is \"fired\"\n     * @return {Object}         the tabOverride object\n     */\n    tabOverride.addExtension = function (hook, func) {\n        if (hook && typeof hook === 'string' && typeof func === 'function') {\n            if (!hooks[hook]) {\n                hooks[hook] = [];\n            }\n            hooks[hook].push(func);\n        }\n\n        return this;\n    };\n\n    /**\n     * Enables or disables Tab Override for the specified textarea element(s).\n     *\n     * Hooks: set - passed the current element and a boolean indicating whether\n     * Tab Override was enabled or disabled.\n     *\n     * @param  {Element|Element[]} elems          the textarea element(s) for\n     *                                            which to enable or disable\n     *                                            Tab Override\n     * @param  {boolean}           [enable=true]  whether Tab Override should be\n     *                                            enabled for the element(s)\n     * @return {Object}                           the tabOverride object\n     */\n    tabOverride.set = function (elems, enable) {\n        var enableFlag,\n            elemsArr,\n            numElems,\n            setListeners,\n            attrValue,\n            i,\n            elem;\n\n        if (elems) {\n            enableFlag = arguments.length < 2 || enable;\n\n            // don't manipulate param when referencing arguments object\n            // this is just a matter of practice\n            elemsArr = elems;\n            numElems = elemsArr.length;\n\n            if (typeof numElems !== 'number') {\n                elemsArr = [elemsArr];\n                numElems = 1;\n            }\n\n            if (enableFlag) {\n                setListeners = addListeners;\n                attrValue = 'true';\n            } else {\n                setListeners = removeListeners;\n                attrValue = '';\n            }\n\n            for (i = 0; i < numElems; i += 1) {\n                elem = elemsArr[i];\n                if (elem && elem.nodeName && elem.nodeName.toLowerCase() === 'textarea') {\n                    executeExtensions('set', [elem, enableFlag]);\n                    elem.setAttribute('data-taboverride-enabled', attrValue);\n                    setListeners(elem);\n                }\n            }\n        }\n\n        return this;\n    };\n\n    /**\n     * Gets or sets the tab size for all elements that have Tab Override enabled.\n     * 0 represents the tab character.\n     *\n     * @param  {number}        [size]  the tab size\n     * @return {number|Object}         the tab size or the tabOverride object\n     */\n    tabOverride.tabSize = function (size) {\n        var i;\n\n        if (arguments.length) {\n            if (size && typeof size === 'number' && size > 0) {\n                aTab = '';\n                for (i = 0; i < size; i += 1) {\n                    aTab += ' ';\n                }\n            } else {\n                // size is falsy (0), not a number, or a negative number\n                aTab = '\\t';\n            }\n            return this;\n        }\n\n        return (aTab === '\\t') ? 0 : aTab.length;\n    };\n\n    /**\n     * Gets or sets the auto indent setting. True if each line should be\n     * automatically indented (default = true).\n     *\n     * @param  {boolean}        [enable]  whether auto indent should be enabled\n     * @return {boolean|Object}           whether auto indent is enabled or the\n     *                                    tabOverride object\n     */\n    tabOverride.autoIndent = function (enable) {\n        if (arguments.length) {\n            autoIndent = enable ? true : false;\n            return this;\n        }\n\n        return autoIndent;\n    };\n\n    /**\n     * Gets or sets the tab key combination.\n     *\n     * @param  {number}        keyCode             the key code of the key to use for tab\n     * @param  {string[]}      [modifierKeyNames]  the modifier key names - valid names are\n     *                                             'alt', 'ctrl', 'meta', and 'shift'\n     * @return {string|Object}                     the current tab key combination or the\n     *                                             tabOverride object\n     *\n     * @method\n     */\n    tabOverride.tabKey = createKeyComboFunction(function (keyCode) {\n        if (!arguments.length) {\n            return tabKey;\n        }\n        tabKey = keyCode;\n    }, tabModifierKeys);\n\n    /**\n     * Gets or sets the untab key combination.\n     *\n     * @param  {number}        keyCode             the key code of the key to use for untab\n     * @param  {string[]}      [modifierKeyNames]  the modifier key names - valid names are\n     *                                             'alt', 'ctrl', 'meta', and 'shift'\n     * @return {string|Object}                     the current untab key combination or the\n     *                                             tabOverride object\n     *\n     * @method\n     */\n    tabOverride.untabKey = createKeyComboFunction(function (keyCode) {\n        if (!arguments.length) {\n            return untabKey;\n        }\n        untabKey = keyCode;\n    }, untabModifierKeys);\n}));\n"
  },
  {
    "path": "web/client/resources/js/lib/taboverride.js.url",
    "content": "https://raw.githubusercontent.com/wjbryant/taboverride/4.0.3/build/output/taboverride.js\n"
  },
  {
    "path": "web/client/resources/js/lib/update.sh",
    "content": "#!/usr/bin/env bash\n\ncd \"$(dirname $(realpath $0))\"\n\nconfig_file=()\n\nfor url in *.url; do\n  config_file+=(-o\"$(basename \"$url\" .url)\" url=\\\"$(cat \"$url\")\\\")\ndone\n\nprintf \"%s\\n\" \"${config_file[@]}\" | curl --parallel --parallel-immediate --config -\n"
  },
  {
    "path": "web/client/resources/js/poller.js",
    "content": "function Poller(config)\n{\n\t// CONFIGURABLE\n\tvar endpoints = {\n\t\tup: \"/status/poll\",\t\t// url to poll when the server is up\n\t\tdown: \"/status\"\t\t\t// url to poll at regular intervals when the server is down\n\t};\n\tvar timeout =  60000 * 2;\t// how many ms between polling attempts\n\tvar intervalMs = 1000;\t\t// ms between polls when the server is down\n\n\t// INTERNAL STATE\n\tvar up = true;\t\t\t\t// whether or not we can connect to the server\n\tvar req;\t\t\t\t\t// the pending ajax request\n\tvar downPoller;\t\t\t\t// the setInterval for polling when the server is down\n\tvar self = this;\n\n\tif (typeof config === 'object')\n\t{\n\t\tif (typeof config.endpoints === 'object')\n\t\t{\n\t\t\tendpoints.up = config.endpoints.up;\n\t\t\tendpoints.down = config.endpoints.down;\n\t\t}\n\t\tif (config.timeout)\n\t\t\ttimeout = config.timeout;\n\t\tif (config.interval)\n\t\t\tintervalMs = config.interval;\n\t}\n\n\t$(self).on('pollstart', function(event, data) {\n\t\tlog(\"Started poller\");\n\t}).on('pollstop', function(event, data) {\n\t\tlog(\"Stopped poller\");\n\t});\n\n\n\tthis.start = function()\n\t{\n\t\tif (req)\n\t\t\treturn false;\n\t\tdoPoll();\n\t\t$(self).trigger('pollstart', {url: endpoints.up, timeout: timeout});\n\t\treturn true;\n\t};\n\n\tthis.stop = function()\n\t{\n\t\tif (!req)\n\t\t\treturn false;\n\t\treq.abort();\n\t\treq = undefined;\n\t\tstopped = true;\n\t\tstopDownPoller();\n\t\t$(self).trigger('pollstop', {});\n\t\treturn true;\n\t};\n\n\tthis.setTimeout = function(tmout)\n\t{\n\t\ttimeout = tmout;\t// takes effect at next poll\n\t};\n\n\tthis.isUp = function()\n\t{\n\t\treturn up;\n\t};\n\n\tfunction doPoll()\n\t{\n\t\treq = $.ajax({\n\t\t\turl: endpoints.up + \"?timeout=\" + timeout,\n\t\t\ttimeout: timeout\n\t\t}).done(pollSuccess).fail(pollFailed);\n\t}\n\n\tfunction pollSuccess(data, message, jqxhr)\n\t{\n\t\tstopDownPoller();\n\t\tdoPoll();\n\n\t\tvar wasUp = up;\n\t\tup = true;\n\t\tstatus = data;\n\n\t\tvar arg = {\n\t\t\tstatus: status,\n\t\t\tdata: data,\n\t\t\tjqxhr: jqxhr\n\t\t};\n\n\t\tif (!wasUp)\n\t\t\t$(convey.poller).trigger('serverstarting', arg);\n\t\telse\n\t\t\t$(self).trigger('pollsuccess', arg);\n\t}\n\n\tfunction pollFailed(jqxhr, message, exception)\n\t{\n\t\tif (message === \"timeout\")\n\t\t{\n\t\t\tlog(\"Poller timeout; re-polling...\", req);\n\t\t\tdoPoll();\t// in our case, timeout actually means no activity; poll again\n\t\t\treturn;\n\t\t}\n\n\t\tup = false;\n\n\t\tdownPoller = setInterval(function()\n\t\t{\n\t\t\t// If the server is still down, do a ping to see\n\t\t\t// if it's up; pollSuccess() will do the rest.\n\t\t\tif (!up)\n\t\t\t\t$.get(endpoints.down).done(pollSuccess);\n\t\t}, intervalMs);\n\n\t\t$(self).trigger('pollfail', {\n\t\t\texception: exception,\n\t\t\tmessage: message,\n\t\t\tjqxhr: jqxhr\n\t\t});\n\t}\n\n\tfunction stopDownPoller()\n\t{\n\t\tif (!downPoller)\n\t\t\treturn;\n\t\tclearInterval(downPoller);\n\t\tdownPoller = undefined;\n\t}\n}\n"
  },
  {
    "path": "web/server/api/api.goconvey",
    "content": "#ignore\n-timeout=1s\n"
  },
  {
    "path": "web/server/api/server.go",
    "content": "package api\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n)\n\ntype HTTPServer struct {\n\twatcher     chan messaging.WatcherCommand\n\texecutor    contract.Executor\n\tlatest      *contract.CompleteOutput\n\tcurrentRoot string\n\tlongpoll    chan chan string\n\tpaused      bool\n}\n\nfunc (self *HTTPServer) ReceiveUpdate(root string, update *contract.CompleteOutput) {\n\tself.currentRoot = root\n\tself.latest = update\n}\n\nfunc (self *HTTPServer) Watch(response http.ResponseWriter, request *http.Request) {\n\tif request.Method == \"POST\" {\n\t\tself.adjustRoot(response, request)\n\t} else if request.Method == \"GET\" {\n\t\tresponse.Write([]byte(self.currentRoot))\n\t}\n}\n\nfunc (self *HTTPServer) adjustRoot(response http.ResponseWriter, request *http.Request) {\n\tnewRoot := self.parseQueryString(\"root\", response, request)\n\tif newRoot == \"\" {\n\t\treturn\n\t}\n\tinfo, err := os.Stat(newRoot) // TODO: how to unit test?\n\tif !info.IsDir() || err != nil {\n\t\thttp.Error(response, err.Error(), http.StatusNotFound)\n\t\treturn\n\t}\n\n\tself.watcher <- messaging.WatcherCommand{\n\t\tInstruction: messaging.WatcherAdjustRoot,\n\t\tDetails:     newRoot,\n\t}\n}\n\nfunc (self *HTTPServer) Ignore(response http.ResponseWriter, request *http.Request) {\n\tpaths := self.parseQueryString(\"paths\", response, request)\n\tif paths != \"\" {\n\t\tself.watcher <- messaging.WatcherCommand{\n\t\t\tInstruction: messaging.WatcherIgnore,\n\t\t\tDetails:     paths,\n\t\t}\n\t}\n}\n\nfunc (self *HTTPServer) Reinstate(response http.ResponseWriter, request *http.Request) {\n\tpaths := self.parseQueryString(\"paths\", response, request)\n\tif paths != \"\" {\n\t\tself.watcher <- messaging.WatcherCommand{\n\t\t\tInstruction: messaging.WatcherReinstate,\n\t\t\tDetails:     paths,\n\t\t}\n\t}\n}\n\nfunc (self *HTTPServer) parseQueryString(key string, response http.ResponseWriter, request *http.Request) string {\n\tvalue := request.URL.Query()[key]\n\n\tif len(value) == 0 {\n\t\thttp.Error(response, fmt.Sprintf(\"No '%s' query string parameter included!\", key), http.StatusBadRequest)\n\t\treturn \"\"\n\t}\n\n\tpath := value[0]\n\tif path == \"\" {\n\t\thttp.Error(response, \"You must provide a non-blank path.\", http.StatusBadRequest)\n\t}\n\treturn path\n}\n\nfunc (self *HTTPServer) Status(response http.ResponseWriter, request *http.Request) {\n\tstatus := self.executor.Status()\n\tresponse.Write([]byte(status))\n}\n\nfunc (self *HTTPServer) LongPollStatus(response http.ResponseWriter, request *http.Request) {\n\tif self.executor.ClearStatusFlag() {\n\t\tresponse.Write([]byte(self.executor.Status()))\n\t\treturn\n\t}\n\n\ttimeout, err := strconv.Atoi(request.URL.Query().Get(\"timeout\"))\n\tif err != nil || timeout > 180000 || timeout < 0 {\n\t\ttimeout = 60000 // default timeout is 60 seconds\n\t}\n\n\tmyReqChan := make(chan string)\n\n\tselect {\n\tcase self.longpoll <- myReqChan: // this case means the executor's status is changing\n\tcase <-time.After(time.Duration(timeout) * time.Millisecond): // this case means the executor hasn't changed status\n\t\treturn\n\t}\n\n\tout := <-myReqChan\n\n\tif out != \"\" { // TODO: Why is this check necessary? Sometimes it writes empty string...\n\t\tresponse.Write([]byte(out))\n\t}\n}\n\nfunc (self *HTTPServer) Results(response http.ResponseWriter, request *http.Request) {\n\tresponse.Header().Set(\"Content-Type\", \"application/json\")\n\tresponse.Header().Set(\"Cache-Control\", \"no-cache, no-store, must-revalidate\")\n\tresponse.Header().Set(\"Pragma\", \"no-cache\")\n\tresponse.Header().Set(\"Expires\", \"0\")\n\tif self.latest != nil {\n\t\tself.latest.Paused = self.paused\n\t}\n\tstuff, _ := json.Marshal(self.latest)\n\tresponse.Write(stuff)\n}\n\nfunc (self *HTTPServer) Execute(response http.ResponseWriter, request *http.Request) {\n\tgo self.execute()\n}\n\nfunc (self *HTTPServer) execute() {\n\tself.watcher <- messaging.WatcherCommand{Instruction: messaging.WatcherExecute}\n}\n\nfunc (self *HTTPServer) TogglePause(response http.ResponseWriter, request *http.Request) {\n\tinstruction := messaging.WatcherPause\n\tif self.paused {\n\t\tinstruction = messaging.WatcherResume\n\t}\n\n\tself.watcher <- messaging.WatcherCommand{Instruction: instruction}\n\tself.paused = !self.paused\n\n\tfmt.Fprint(response, self.paused) // we could write out whatever helps keep the UI honest...\n}\n\nfunc NewHTTPServer(\n\troot string,\n\twatcher chan messaging.WatcherCommand,\n\texecutor contract.Executor,\n\tstatus chan chan string) *HTTPServer {\n\n\tself := new(HTTPServer)\n\tself.currentRoot = root\n\tself.watcher = watcher\n\tself.executor = executor\n\tself.longpoll = status\n\treturn self\n}\n"
  },
  {
    "path": "web/server/api/server_test.go",
    "content": "package api\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n)\n\nconst initialRoot = \"/root/gopath/src/github.com/smartystreets/project\"\nconst nonexistentRoot = \"I don't exist\"\nconst unreadableContent = \"!!error!!\"\n\nfunc TestHTTPServer(t *testing.T) {\n\t// TODO: fix the skipped tests...\n\n\tConvey(\"Subject: HttpServer responds to requests appropriately\", t, func() {\n\t\tfixture := newServerFixture()\n\n\t\tConvey(\"Before any update is received\", func() {\n\t\t\tConvey(\"When the update is requested\", func() {\n\t\t\t\tupdate, _ := fixture.RequestLatest()\n\n\t\t\t\tConvey(\"No panic should occur\", func() {\n\t\t\t\t\tSo(func() { fixture.RequestLatest() }, ShouldNotPanic)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The update will be empty\", func() {\n\t\t\t\t\tSo(update, ShouldResemble, new(contract.CompleteOutput))\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"Given an update is received\", func() {\n\t\t\tfixture.ReceiveUpdate(\"\", &contract.CompleteOutput{Revision: \"asdf\"})\n\n\t\t\tConvey(\"When the update is requested\", func() {\n\t\t\t\tupdate, response := fixture.RequestLatest()\n\n\t\t\t\tConvey(\"The server returns it\", func() {\n\t\t\t\t\tSo(update, ShouldResemble, &contract.CompleteOutput{Revision: \"asdf\"})\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The server returns 200\", func() {\n\t\t\t\t\tSo(response.Code, ShouldEqual, http.StatusOK)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The server should include important cache-related headers\", func() {\n\t\t\t\t\tSo(len(response.HeaderMap), ShouldEqual, 4)\n\t\t\t\t\tSo(response.HeaderMap[\"Content-Type\"][0], ShouldEqual, \"application/json\")\n\t\t\t\t\tSo(response.HeaderMap[\"Cache-Control\"][0], ShouldEqual, \"no-cache, no-store, must-revalidate\")\n\t\t\t\t\tSo(response.HeaderMap[\"Pragma\"][0], ShouldEqual, \"no-cache\")\n\t\t\t\t\tSo(response.HeaderMap[\"Expires\"][0], ShouldEqual, \"0\")\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When the root watch is queried\", func() {\n\t\t\troot, status := fixture.QueryRootWatch(false)\n\n\t\t\tSkipConvey(\"The server returns it\", func() {\n\t\t\t\tSo(root, ShouldEqual, initialRoot)\n\t\t\t})\n\n\t\t\tConvey(\"The server returns HTTP 200 - OK\", func() {\n\t\t\t\tSo(status, ShouldEqual, http.StatusOK)\n\t\t\t})\n\t\t})\n\n\t\tSkipConvey(\"When the root watch is adjusted\", func() {\n\n\t\t\tConvey(\"But the request has no root parameter\", func() {\n\t\t\t\tstatus, body := fixture.AdjustRootWatchMalformed()\n\n\t\t\t\tConvey(\"The server returns HTTP 400 - Bad Input\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusBadRequest)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The body should contain a helpful error message\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, \"No 'root' query string parameter included!\")\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The server should not change the existing root\", func() {\n\t\t\t\t\troot, _ := fixture.QueryRootWatch(false)\n\t\t\t\t\tSo(root, ShouldEqual, initialRoot)\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"But the root parameter is empty\", func() {\n\t\t\t\tstatus, body := fixture.AdjustRootWatch(\"\")\n\n\t\t\t\tConvey(\"The server returns HTTP 400 - Bad Input\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusBadRequest)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The server should provide a helpful error message\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, \"You must provide a non-blank path.\")\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The server should not change the existing root\", func() {\n\t\t\t\t\troot, _ := fixture.QueryRootWatch(false)\n\t\t\t\t\tSo(root, ShouldEqual, initialRoot)\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"And the new root exists\", func() {\n\t\t\t\tstatus, body := fixture.AdjustRootWatch(initialRoot + \"/package\")\n\n\t\t\t\tConvey(\"The server returns HTTP 200 - OK\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusOK)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The body should NOT contain any error message or content\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, \"\")\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The server informs the watcher of the new root\", func() {\n\t\t\t\t\troot, _ := fixture.QueryRootWatch(false)\n\t\t\t\t\tSo(root, ShouldEqual, initialRoot+\"/package\")\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"And the new root does NOT exist\", func() {\n\t\t\t\tstatus, body := fixture.AdjustRootWatch(nonexistentRoot)\n\n\t\t\t\tConvey(\"The server returns HTTP 404 - Not Found\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusNotFound)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The body should contain a helpful error message\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, fmt.Sprintf(\"Directory does not exist: '%s'\", nonexistentRoot))\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The server should not change the existing root\", func() {\n\t\t\t\t\troot, _ := fixture.QueryRootWatch(false)\n\t\t\t\t\tSo(root, ShouldEqual, initialRoot)\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tSkipConvey(\"When a package is ignored\", func() {\n\n\t\t\tConvey(\"But the request has no path parameter\", func() {\n\t\t\t\tstatus, body := fixture.IgnoreMalformed()\n\n\t\t\t\tConvey(\"The server returns HTTP 400 - Bad Input\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusBadRequest)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The body should contain a helpful error message\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, \"No 'paths' query string parameter included!\")\n\t\t\t\t})\n\n\t\t\t\tSkipConvey(\"The server should not ignore anything\", func() {\n\t\t\t\t\t// So(fixture.watcher.ignored, ShouldEqual, \"\")\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"But the request is blank\", func() {\n\t\t\t\tstatus, body := fixture.Ignore(\"\")\n\n\t\t\t\tConvey(\"The server returns HTTP 400 - Bad Input\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusBadRequest)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The body should contain a helpful error message\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, \"You must provide a non-blank path.\")\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"And the request is well formed\", func() {\n\t\t\t\tstatus, _ := fixture.Ignore(initialRoot)\n\n\t\t\t\tSkipConvey(\"The server informs the watcher\", func() {\n\t\t\t\t\t// So(fixture.watcher.ignored, ShouldEqual, initialRoot)\n\t\t\t\t})\n\t\t\t\tConvey(\"The server returns HTTP 200 - OK\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusOK)\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tSkipConvey(\"When a package is reinstated\", func() {\n\t\t\tConvey(\"But the request has no path parameter\", func() {\n\t\t\t\tstatus, body := fixture.ReinstateMalformed()\n\n\t\t\t\tConvey(\"The server returns HTTP 400 - Bad Input\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusBadRequest)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The body should contain a helpful error message\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, \"No 'paths' query string parameter included!\")\n\t\t\t\t})\n\n\t\t\t\tSkipConvey(\"The server should not ignore anything\", func() {\n\t\t\t\t\t// So(fixture.watcher.reinstated, ShouldEqual, \"\")\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"But the request is blank\", func() {\n\t\t\t\tstatus, body := fixture.Reinstate(\"\")\n\n\t\t\t\tConvey(\"The server returns HTTP 400 - Bad Input\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusBadRequest)\n\t\t\t\t})\n\n\t\t\t\tConvey(\"The body should contain a helpful error message\", func() {\n\t\t\t\t\tSo(body, ShouldEqual, \"You must provide a non-blank path.\")\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tConvey(\"And the request is well formed\", func() {\n\t\t\t\tstatus, _ := fixture.Reinstate(initialRoot)\n\n\t\t\t\tSkipConvey(\"The server informs the watcher\", func() {\n\t\t\t\t\t// So(fixture.watcher.reinstated, ShouldEqual, initialRoot)\n\t\t\t\t})\n\t\t\t\tConvey(\"The server returns HTTP 200 - OK\", func() {\n\t\t\t\t\tSo(status, ShouldEqual, http.StatusOK)\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When the status of the executor is requested\", func() {\n\t\t\tfixture.executor.status = \"blah blah blah\"\n\t\t\tstatusCode, statusBody := fixture.RequestExecutorStatus()\n\n\t\t\tConvey(\"The server asks the executor its status and returns it\", func() {\n\t\t\t\tSo(statusBody, ShouldEqual, \"blah blah blah\")\n\t\t\t})\n\n\t\t\tConvey(\"The server returns HTTP 200 - OK\", func() {\n\t\t\t\tSo(statusCode, ShouldEqual, http.StatusOK)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When a manual execution of the test packages is requested\", func() {\n\t\t\tstatus := fixture.ManualExecution()\n\t\t\tupdate, _ := fixture.RequestLatest()\n\n\t\t\tSkipConvey(\"The server invokes the executor using the watcher's listing and save the result\", func() {\n\t\t\t\tSo(update, ShouldResemble, &contract.CompleteOutput{Revision: initialRoot})\n\t\t\t})\n\n\t\t\tConvey(\"The server returns HTTP 200 - OK\", func() {\n\t\t\t\tSo(status, ShouldEqual, http.StatusOK)\n\t\t\t})\n\t\t})\n\n\t\tSkipConvey(\"When the pause setting is toggled via the server\", func() {\n\t\t\tpaused := fixture.TogglePause()\n\n\t\t\tSkipConvey(\"The pause channel buffer should have a true value\", func() {\n\t\t\t\t// var value bool\n\t\t\t\t// select {\n\t\t\t\t// case value = <-fixture.pauseUpdate:\n\t\t\t\t// default:\n\t\t\t\t// }\n\t\t\t\t// So(value, ShouldBeTrue)\n\t\t\t})\n\n\t\t\tConvey(\"The latest results should show that the server is paused\", func() {\n\t\t\t\tfixture.ReceiveUpdate(\"\", &contract.CompleteOutput{Revision: \"asdf\"})\n\t\t\t\tupdate, _ := fixture.RequestLatest()\n\n\t\t\t\tSo(update.Paused, ShouldBeTrue)\n\t\t\t})\n\n\t\t\tConvey(\"The toggle handler should return its new status\", func() {\n\t\t\t\tSo(paused, ShouldEqual, \"true\")\n\t\t\t})\n\t\t})\n\t})\n}\n\n/********* Server Fixture *********/\n\ntype ServerFixture struct {\n\tserver       *HTTPServer\n\twatcher      chan messaging.WatcherCommand\n\texecutor     *FakeExecutor\n\tstatusUpdate chan bool\n}\n\nfunc (self *ServerFixture) ReceiveUpdate(root string, update *contract.CompleteOutput) {\n\tself.server.ReceiveUpdate(root, update)\n}\n\nfunc (self *ServerFixture) RequestLatest() (*contract.CompleteOutput, *httptest.ResponseRecorder) {\n\trequest, _ := http.NewRequest(\"GET\", \"http://localhost:8080/results\", nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Results(response, request)\n\n\tdecoder := json.NewDecoder(strings.NewReader(response.Body.String()))\n\tupdate := new(contract.CompleteOutput)\n\tdecoder.Decode(update)\n\treturn update, response\n}\n\nfunc (self *ServerFixture) QueryRootWatch(newclient bool) (string, int) {\n\turl := \"http://localhost:8080/watch\"\n\tif newclient {\n\t\turl += \"?newclient=1\"\n\t}\n\trequest, _ := http.NewRequest(\"GET\", url, nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Watch(response, request)\n\n\treturn strings.TrimSpace(response.Body.String()), response.Code\n}\n\nfunc (self *ServerFixture) AdjustRootWatchMalformed() (status int, body string) {\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/watch\", nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Watch(response, request)\n\n\tstatus, body = response.Code, strings.TrimSpace(response.Body.String())\n\treturn\n}\n\nfunc (self *ServerFixture) AdjustRootWatch(newRoot string) (status int, body string) {\n\tescapedRoot := url.QueryEscape(newRoot)\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/watch?root=\"+escapedRoot, nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Watch(response, request)\n\n\tstatus, body = response.Code, strings.TrimSpace(response.Body.String())\n\treturn\n}\n\nfunc (self *ServerFixture) IgnoreMalformed() (status int, body string) {\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/ignore\", nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Ignore(response, request)\n\n\tstatus, body = response.Code, strings.TrimSpace(response.Body.String())\n\treturn\n}\n\nfunc (self *ServerFixture) Ignore(folder string) (status int, body string) {\n\tescapedFolder := url.QueryEscape(folder)\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/ignore?paths=\"+escapedFolder, nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Ignore(response, request)\n\n\tstatus, body = response.Code, strings.TrimSpace(response.Body.String())\n\treturn\n}\n\nfunc (self *ServerFixture) ReinstateMalformed() (status int, body string) {\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/reinstate\", nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Reinstate(response, request)\n\n\tstatus, body = response.Code, strings.TrimSpace(response.Body.String())\n\treturn\n}\n\nfunc (self *ServerFixture) Reinstate(folder string) (status int, body string) {\n\tescapedFolder := url.QueryEscape(folder)\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/reinstate?paths=\"+escapedFolder, nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Reinstate(response, request)\n\n\tstatus, body = response.Code, strings.TrimSpace(response.Body.String())\n\treturn\n}\n\nfunc (self *ServerFixture) SetExecutorStatus(status string) {\n\t// self.executor.status = status\n\t// select {\n\t// case self.executor.statusUpdate <- make(chan string):\n\t// default:\n\t// }\n}\n\nfunc (self *ServerFixture) RequestExecutorStatus() (code int, status string) {\n\trequest, _ := http.NewRequest(\"GET\", \"http://localhost:8080/status\", nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Status(response, request)\n\n\tcode, status = response.Code, strings.TrimSpace(response.Body.String())\n\treturn\n}\n\nfunc (self *ServerFixture) ManualExecution() int {\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/execute\", nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.Execute(response, request)\n\tnap, _ := time.ParseDuration(\"100ms\")\n\ttime.Sleep(nap)\n\treturn response.Code\n}\n\nfunc (self *ServerFixture) TogglePause() string {\n\trequest, _ := http.NewRequest(\"POST\", \"http://localhost:8080/pause\", nil)\n\tresponse := httptest.NewRecorder()\n\n\tself.server.TogglePause(response, request)\n\n\treturn response.Body.String()\n}\n\nfunc newServerFixture() *ServerFixture {\n\tself := new(ServerFixture)\n\tself.watcher = make(chan messaging.WatcherCommand)\n\t// self.watcher.SetRootWatch(initialRoot)\n\tstatusUpdate := make(chan chan string)\n\tself.executor = newFakeExecutor(\"\", statusUpdate)\n\tself.server = NewHTTPServer(\"initial-working-dir\", self.watcher, self.executor, statusUpdate)\n\treturn self\n}\n\n/********* Fake Executor *********/\n\ntype FakeExecutor struct {\n\tstatus       string\n\texecuted     bool\n\tstatusFlag   bool\n\tstatusUpdate chan chan string\n}\n\nfunc (self *FakeExecutor) Status() string {\n\treturn self.status\n}\n\nfunc (self *FakeExecutor) ClearStatusFlag() bool {\n\thasNewStatus := self.statusFlag\n\tself.statusFlag = false\n\treturn hasNewStatus\n}\n\nfunc (self *FakeExecutor) ExecuteTests(watched []*contract.Package) *contract.CompleteOutput {\n\toutput := new(contract.CompleteOutput)\n\toutput.Revision = watched[0].Path\n\treturn output\n}\n\nfunc newFakeExecutor(status string, statusUpdate chan chan string) *FakeExecutor {\n\tself := new(FakeExecutor)\n\tself.status = status\n\tself.statusUpdate = statusUpdate\n\treturn self\n}\n"
  },
  {
    "path": "web/server/contract/contracts.go",
    "content": "package contract\n\nimport \"net/http\"\n\ntype (\n\tServer interface {\n\t\tReceiveUpdate(root string, update *CompleteOutput)\n\t\tWatch(writer http.ResponseWriter, request *http.Request)\n\t\tIgnore(writer http.ResponseWriter, request *http.Request)\n\t\tReinstate(writer http.ResponseWriter, request *http.Request)\n\t\tStatus(writer http.ResponseWriter, request *http.Request)\n\t\tLongPollStatus(writer http.ResponseWriter, request *http.Request)\n\t\tResults(writer http.ResponseWriter, request *http.Request)\n\t\tExecute(writer http.ResponseWriter, request *http.Request)\n\t\tTogglePause(writer http.ResponseWriter, request *http.Request)\n\t}\n\n\tExecutor interface {\n\t\tExecuteTests([]*Package) *CompleteOutput\n\t\tStatus() string\n\t\tClearStatusFlag() bool\n\t}\n\n\tShell interface {\n\t\tGoTest(directory, packageName string, tags, arguments []string) (output string, err error)\n\t}\n)\n"
  },
  {
    "path": "web/server/contract/doc_test.go",
    "content": "package contract\n"
  },
  {
    "path": "web/server/contract/result.go",
    "content": "package contract\n\nimport (\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n)\n\ntype Package struct {\n\tPath          string\n\tName          string\n\tIgnored       bool\n\tDisabled      bool\n\tBuildTags     []string\n\tTestArguments []string\n\tError         error\n\tOutput        string\n\tResult        *PackageResult\n\n\tHasImportCycle bool\n}\n\nfunc NewPackage(folder *messaging.Folder, name string, hasImportCycle bool) *Package {\n\tself := new(Package)\n\tself.Path = folder.Path\n\tself.Name = name\n\tself.Result = NewPackageResult(self.Name)\n\tself.Ignored = folder.Ignored\n\tself.Disabled = folder.Disabled\n\tself.BuildTags = folder.BuildTags\n\tself.TestArguments = folder.TestArguments\n\tself.HasImportCycle = hasImportCycle\n\treturn self\n}\n\nfunc (self *Package) Active() bool {\n\treturn !self.Disabled && !self.Ignored\n}\n\nfunc (self *Package) HasUsableResult() bool {\n\treturn self.Active() && (self.Error == nil || (self.Output != \"\"))\n}\n\ntype CompleteOutput struct {\n\tPackages []*PackageResult\n\tRevision string\n\tPaused   bool\n}\n\nvar ( // PackageResult.Outcome values:\n\tIgnored         = \"ignored\"\n\tDisabled        = \"disabled\"\n\tPassed          = \"passed\"\n\tFailed          = \"failed\"\n\tPanicked        = \"panicked\"\n\tBuildFailure    = \"build failure\"\n\tNoTestFiles     = \"no test files\"\n\tNoTestFunctions = \"no test functions\"\n\tNoGoFiles       = \"no go code\"\n\n\tTestRunAbortedUnexpectedly = \"test run aborted unexpectedly\"\n)\n\ntype PackageResult struct {\n\tPackageName string\n\tElapsed     float64\n\tCoverage    float64\n\tOutcome     string\n\tBuildOutput string\n\tTestResults []TestResult\n}\n\nfunc NewPackageResult(packageName string) *PackageResult {\n\tself := new(PackageResult)\n\tself.PackageName = packageName\n\tself.TestResults = []TestResult{}\n\tself.Coverage = -1\n\treturn self\n}\n\ntype TestResult struct {\n\tTestName string\n\tElapsed  float64\n\tPassed   bool\n\tSkipped  bool\n\tFile     string\n\tLine     int\n\tMessage  string\n\tError    string\n\tStories  []reporting.ScopeResult\n\n\tRawLines []string `json:\",omitempty\"`\n}\n\nfunc NewTestResult(testName string) *TestResult {\n\tself := new(TestResult)\n\tself.Stories = []reporting.ScopeResult{}\n\tself.RawLines = []string{}\n\tself.TestName = testName\n\treturn self\n}\n"
  },
  {
    "path": "web/server/executor/contract.go",
    "content": "package executor\n\nimport \"github.com/smartystreets/goconvey/web/server/contract\"\n\ntype Parser interface {\n\tParse([]*contract.Package)\n}\n\ntype Tester interface {\n\tSetBatchSize(batchSize int)\n\tTestAll(folders []*contract.Package)\n}\n"
  },
  {
    "path": "web/server/executor/coordinator.go",
    "content": "package executor\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\ntype concurrentCoordinator struct {\n\tbatchSize int\n\tqueue     chan *contract.Package\n\tfolders   []*contract.Package\n\tshell     contract.Shell\n\twaiter    sync.WaitGroup\n}\n\nfunc (self *concurrentCoordinator) ExecuteConcurrently() {\n\tself.enlistWorkers()\n\tself.scheduleTasks()\n\tself.awaitCompletion()\n}\n\nfunc (self *concurrentCoordinator) enlistWorkers() {\n\tfor i := 0; i < self.batchSize; i++ {\n\t\tself.waiter.Add(1)\n\t\tgo self.worker(i)\n\t}\n}\nfunc (self *concurrentCoordinator) worker(id int) {\n\tfor folder := range self.queue {\n\t\tpackageName := strings.Replace(folder.Name, \"\\\\\", \"/\", -1)\n\t\tif !folder.Active() {\n\t\t\tlog.Printf(\"Skipping concurrent execution: %s\\n\", packageName)\n\t\t\tcontinue\n\t\t}\n\n\t\tif folder.HasImportCycle {\n\t\t\tmessage := fmt.Sprintf(\"can't load package: import cycle not allowed\\npackage %s\\n\\timports %s\", packageName, packageName)\n\t\t\tlog.Println(message)\n\t\t\tfolder.Output, folder.Error = message, errors.New(message)\n\t\t} else {\n\t\t\tlog.Printf(\"Executing concurrent tests: %s\\n\", packageName)\n\t\t\tfolder.Output, folder.Error = self.shell.GoTest(folder.Path, packageName, folder.BuildTags, folder.TestArguments)\n\t\t}\n\t}\n\tself.waiter.Done()\n}\n\nfunc (self *concurrentCoordinator) scheduleTasks() {\n\tfor _, folder := range self.folders {\n\t\tself.queue <- folder\n\t}\n}\n\nfunc (self *concurrentCoordinator) awaitCompletion() {\n\tclose(self.queue)\n\tself.waiter.Wait()\n}\n\nfunc newConcurrentCoordinator(folders []*contract.Package, batchSize int, shell contract.Shell) *concurrentCoordinator {\n\tself := new(concurrentCoordinator)\n\tself.queue = make(chan *contract.Package)\n\tself.folders = folders\n\tself.batchSize = batchSize\n\tself.shell = shell\n\treturn self\n}\n"
  },
  {
    "path": "web/server/executor/executor.go",
    "content": "package executor\n\nimport (\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\nconst (\n\tIdle      = \"idle\"\n\tExecuting = \"executing\"\n)\n\ntype Executor struct {\n\ttester     Tester\n\tparser     Parser\n\tstatus     string\n\tstatusChan chan chan string\n\tstatusFlag bool\n}\n\nfunc (self *Executor) Status() string {\n\treturn self.status\n}\n\nfunc (self *Executor) ClearStatusFlag() bool {\n\thasNewStatus := self.statusFlag\n\tself.statusFlag = false\n\treturn hasNewStatus\n}\n\nfunc (self *Executor) ExecuteTests(folders []*contract.Package) *contract.CompleteOutput {\n\tdefer func() { self.setStatus(Idle) }()\n\tself.execute(folders)\n\tresult := self.parse(folders)\n\treturn result\n}\n\nfunc (self *Executor) execute(folders []*contract.Package) {\n\tself.setStatus(Executing)\n\tself.tester.TestAll(folders)\n}\n\nfunc (self *Executor) parse(folders []*contract.Package) *contract.CompleteOutput {\n\tresult := &contract.CompleteOutput{Revision: now().String()}\n\tself.parser.Parse(folders)\n\tfor _, folder := range folders {\n\t\tresult.Packages = append(result.Packages, folder.Result)\n\t}\n\treturn result\n}\n\nfunc (self *Executor) setStatus(status string) {\n\tself.status = status\n\tself.statusFlag = true\n\nLoop:\n\tfor {\n\t\tselect {\n\t\tcase c := <-self.statusChan:\n\t\t\tself.statusFlag = false\n\t\t\tc <- status\n\t\tdefault:\n\t\t\tbreak Loop\n\t\t}\n\t}\n\n\tlog.Printf(\"Executor status: '%s'\\n\", self.status)\n}\n\nfunc NewExecutor(tester Tester, parser Parser, ch chan chan string) *Executor {\n\treturn &Executor{\n\t\ttester:     tester,\n\t\tparser:     parser,\n\t\tstatus:     Idle,\n\t\tstatusChan: ch,\n\t\tstatusFlag: false,\n\t}\n}\n\nvar now = func() time.Time {\n\treturn time.Now()\n}\n"
  },
  {
    "path": "web/server/executor/executor.goconvey",
    "content": "#ignore\n-timeout=1s\n"
  },
  {
    "path": "web/server/executor/executor_test.go",
    "content": "package executor\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\nfunc TestExecutor(t *testing.T) {\n\tt.Skip(\"BROKEN!\")\n\n\tConvey(\"Subject: Execution of test packages and aggregation of parsed results\", t, func() {\n\t\tfixture := newExecutorFixture()\n\n\t\tConvey(\"When tests packages are executed\", func() {\n\t\t\tfixture.ExecuteTests()\n\n\t\t\tConvey(\"The result should include parsed results for each test package.\",\n\t\t\t\tfixture.ResultShouldBePopulated)\n\t\t})\n\n\t\tConvey(\"When the executor is idle\", func() {\n\t\t\tConvey(\"The status of the executor should be 'idle'\", func() {\n\t\t\t\tSo(fixture.executor.Status(), ShouldEqual, Idle)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When the status is updated\", func() {\n\t\t\tfixture.executor.setStatus(Executing)\n\n\t\t\tConvey(\"The status flag should be set to true\", func() {\n\t\t\t\tSo(fixture.executor.statusFlag, ShouldBeTrue)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"During test execution\", func() {\n\t\t\tstatus := fixture.CaptureStatusDuringExecutionPhase()\n\n\t\t\tConvey(\"The status of the executor should be 'executing'\", func() {\n\t\t\t\tSo(status, ShouldEqual, Executing)\n\t\t\t})\n\t\t})\n\t})\n}\n\ntype ExecutorFixture struct {\n\texecutor *Executor\n\ttester   *FakeTester\n\tparser   *FakeParser\n\tfolders  []*contract.Package\n\tresult   *contract.CompleteOutput\n\texpected *contract.CompleteOutput\n\tstamp    time.Time\n}\n\nfunc (self *ExecutorFixture) ExecuteTests() {\n\tself.result = self.executor.ExecuteTests(self.folders)\n}\n\nfunc (self *ExecutorFixture) CaptureStatusDuringExecutionPhase() string {\n\tnap, _ := time.ParseDuration(\"25ms\")\n\tself.tester.addDelay(nap)\n\treturn self.delayedExecution(nap)\n}\n\nfunc (self *ExecutorFixture) delayedExecution(nap time.Duration) string {\n\tgo self.ExecuteTests()\n\ttime.Sleep(nap)\n\treturn self.executor.Status()\n}\n\nfunc (self *ExecutorFixture) ResultShouldBePopulated() {\n\tSo(self.result, ShouldResemble, self.expected)\n}\n\nvar (\n\tprefix   = \"/Users/blah/gopath/src/\"\n\tpackageA = \"github.com/smartystreets/goconvey/a\"\n\tpackageB = \"github.com/smartystreets/goconvey/b\"\n\tresultA  = &contract.PackageResult{PackageName: packageA}\n\tresultB  = &contract.PackageResult{PackageName: packageB}\n)\n\nfunc newExecutorFixture() *ExecutorFixture {\n\tself := new(ExecutorFixture)\n\tself.tester = newFakeTester()\n\tself.parser = newFakeParser()\n\tself.executor = NewExecutor(self.tester, self.parser, make(chan chan string))\n\tself.folders = []*contract.Package{\n\t\t&contract.Package{Path: prefix + packageA, Name: packageA},\n\t\t&contract.Package{Path: prefix + packageB, Name: packageB},\n\t}\n\tself.stamp = time.Now()\n\tnow = func() time.Time { return self.stamp }\n\n\tself.expected = &contract.CompleteOutput{\n\t\tPackages: []*contract.PackageResult{\n\t\t\tresultA,\n\t\t\tresultB,\n\t\t},\n\t\tRevision: self.stamp.String(),\n\t}\n\treturn self\n}\n\n/******** FakeTester ********/\n\ntype FakeTester struct {\n\tnap time.Duration\n}\n\nfunc (self *FakeTester) SetBatchSize(batchSize int) { panic(\"NOT SUPPORTED\") }\nfunc (self *FakeTester) TestAll(folders []*contract.Package) {\n\tfor _, p := range folders {\n\t\tp.Output = p.Path\n\t}\n\ttime.Sleep(self.nap)\n}\nfunc (self *FakeTester) addDelay(nap time.Duration) {\n\tself.nap = nap\n}\n\nfunc newFakeTester() *FakeTester {\n\tself := new(FakeTester)\n\tzero, _ := time.ParseDuration(\"0\")\n\tself.nap = zero\n\treturn self\n}\n\n/******** FakeParser ********/\n\ntype FakeParser struct {\n\tnap time.Duration\n}\n\nfunc (self *FakeParser) Parse(packages []*contract.Package) {\n\ttime.Sleep(self.nap)\n\tfor _, package_ := range packages {\n\t\tif package_.Name == packageA && strings.HasSuffix(package_.Output, packageA) {\n\t\t\tpackage_.Result = resultA\n\t\t}\n\t\tif package_.Name == packageB && strings.HasSuffix(package_.Output, packageB) {\n\t\t\tpackage_.Result = resultB\n\t\t}\n\t}\n}\n\nfunc (self *FakeParser) addDelay(nap time.Duration) {\n\tself.nap = nap\n}\n\nfunc newFakeParser() *FakeParser {\n\tself := new(FakeParser)\n\tzero, _ := time.ParseDuration(\"0\")\n\tself.nap = zero\n\treturn self\n}\n"
  },
  {
    "path": "web/server/executor/tester.go",
    "content": "package executor\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\ntype ConcurrentTester struct {\n\tshell     contract.Shell\n\tbatchSize int\n}\n\nfunc (self *ConcurrentTester) SetBatchSize(batchSize int) {\n\tself.batchSize = batchSize\n\tlog.Printf(\"Now configured to test %d packages concurrently.\\n\", self.batchSize)\n}\n\nfunc (self *ConcurrentTester) TestAll(folders []*contract.Package) {\n\tif self.batchSize == 1 {\n\t\tself.executeSynchronously(folders)\n\t} else {\n\t\tnewConcurrentCoordinator(folders, self.batchSize, self.shell).ExecuteConcurrently()\n\t}\n\treturn\n}\n\nfunc (self *ConcurrentTester) executeSynchronously(folders []*contract.Package) {\n\tfor _, folder := range folders {\n\t\tpackageName := strings.Replace(folder.Name, \"\\\\\", \"/\", -1)\n\t\tif !folder.Active() {\n\t\t\tlog.Printf(\"Skipping execution: %s\\n\", packageName)\n\t\t\tcontinue\n\t\t}\n\t\tif folder.HasImportCycle {\n\t\t\tmessage := fmt.Sprintf(\"can't load package: import cycle not allowed\\npackage %s\\n\\timports %s\", packageName, packageName)\n\t\t\tlog.Println(message)\n\t\t\tfolder.Output, folder.Error = message, errors.New(message)\n\t\t} else {\n\t\t\tlog.Printf(\"Executing tests: %s\\n\", packageName)\n\t\t\tfolder.Output, folder.Error = self.shell.GoTest(folder.Path, packageName, folder.BuildTags, folder.TestArguments)\n\t\t}\n\t}\n}\n\nfunc NewConcurrentTester(shell contract.Shell) *ConcurrentTester {\n\tself := new(ConcurrentTester)\n\tself.shell = shell\n\tself.batchSize = defaultBatchSize\n\treturn self\n}\n\nconst defaultBatchSize = 10\n"
  },
  {
    "path": "web/server/executor/tester_test.go",
    "content": "package executor\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\nfunc init() {\n\tlog.SetOutput(ioutil.Discard)\n}\n\nfunc TestConcurrentTester(t *testing.T) {\n\tt.Skip(\"BROKEN!\")\n\n\tConvey(\"Subject: Controlled execution of test packages\", t, func() {\n\t\tfixture := NewTesterFixture()\n\n\t\tConvey(\"Whenever tests for each package are executed\", func() {\n\t\t\tfixture.InBatchesOf(1).RunTests()\n\n\t\t\tConvey(\"The tester should execute the tests in each active package with the correct arguments\",\n\t\t\t\tfixture.ShouldHaveRecordOfExecutionCommands)\n\n\t\t\tConvey(\"There should be a test output result for each active package\",\n\t\t\t\tfixture.ShouldHaveOneOutputPerInput)\n\n\t\t\tConvey(\"The output should be as expected\",\n\t\t\t\tfixture.OutputShouldBeAsExpected)\n\t\t})\n\n\t\tConvey(\"When the tests for each package are executed synchronously\", func() {\n\t\t\tfixture.InBatchesOf(1).RunTests()\n\n\t\t\tConvey(\"Each active package should be run synchronously and in the given order\",\n\t\t\t\tfixture.TestsShouldHaveRunContiguously)\n\t\t})\n\n\t\tConvey(\"When the tests for each package are executed synchronously with failures\", func() {\n\t\t\tfixture.InBatchesOf(1).SetupFailedTestSuites().RunTests()\n\n\t\t\tConvey(\"The failed test packages should not result in any panics\", func() {\n\t\t\t\tSo(fixture.recovered, ShouldBeNil)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When packages are tested concurrently\", func() {\n\t\t\tfixture.InBatchesOf(concurrentBatchSize).RunTests()\n\n\t\t\tConvey(\"Active packages should be arranged and tested in batches of the appropriate size\",\n\t\t\t\tfixture.TestsShouldHaveRunInBatchesOfTwo)\n\t\t})\n\n\t\tConvey(\"When packages are tested concurrently with failures\", func() {\n\t\t\tfixture.InBatchesOf(concurrentBatchSize).SetupFailedTestSuites().RunTests()\n\n\t\t\tConvey(\"The failed test packages should not result in any panics\", func() {\n\t\t\t\tSo(fixture.recovered, ShouldBeNil)\n\t\t\t})\n\t\t})\n\t})\n}\n\nconst concurrentBatchSize = 2\n\ntype TesterFixture struct {\n\ttester       *ConcurrentTester\n\tshell        *TimedShell\n\tresults      []string\n\tcompilations []*ShellCommand\n\texecutions   []*ShellCommand\n\tpackages     []*contract.Package\n\trecovered    error\n}\n\nfunc NewTesterFixture() *TesterFixture {\n\tself := new(TesterFixture)\n\tself.shell = NewTimedShell()\n\tself.tester = NewConcurrentTester(self.shell)\n\tself.packages = []*contract.Package{\n\t\t{Path: \"a\"},\n\t\t{Path: \"b\"},\n\t\t{Path: \"c\"},\n\t\t{Path: \"d\"},\n\t\t{Path: \"e\", Ignored: true},\n\t\t{Path: \"f\"},\n\t\t{Path: \"g\", HasImportCycle: true},\n\t}\n\treturn self\n}\n\nfunc (self *TesterFixture) InBatchesOf(batchSize int) *TesterFixture {\n\tself.tester.SetBatchSize(batchSize)\n\treturn self\n}\n\nfunc (self *TesterFixture) SetupAbnormalError(message string) *TesterFixture {\n\tself.shell.setTripWire(message)\n\treturn self\n}\n\nfunc (self *TesterFixture) SetupFailedTestSuites() *TesterFixture {\n\tself.shell.setExitWithError()\n\treturn self\n}\n\nfunc (self *TesterFixture) RunTests() {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tself.recovered = r.(error)\n\t\t}\n\t}()\n\n\tself.tester.TestAll(self.packages)\n\tfor _, p := range self.packages {\n\t\tself.results = append(self.results, p.Output)\n\t}\n\tself.executions = self.shell.Executions()\n}\n\nfunc (self *TesterFixture) ShouldHaveRecordOfExecutionCommands() {\n\texecuted := []string{\"a\", \"b\", \"c\", \"d\", \"f\"}\n\tignored := \"e\"\n\timportCycle := \"g\"\n\tactual := []string{}\n\tfor _, pkg := range self.executions {\n\t\tactual = append(actual, pkg.Command)\n\t}\n\tSo(actual, ShouldResemble, executed)\n\tSo(actual, ShouldNotContain, ignored)\n\tSo(actual, ShouldNotContain, importCycle)\n}\n\nfunc (self *TesterFixture) ShouldHaveOneOutputPerInput() {\n\tSo(len(self.results), ShouldEqual, len(self.packages))\n}\n\nfunc (self *TesterFixture) OutputShouldBeAsExpected() {\n\tfor _, p := range self.packages {\n\t\tif p.HasImportCycle {\n\t\t\tSo(p.Output, ShouldContainSubstring, \"can't load package: import cycle not allowed\")\n\t\t\tSo(p.Error.Error(), ShouldContainSubstring, \"can't load package: import cycle not allowed\")\n\t\t} else {\n\t\t\tif p.Active() {\n\t\t\t\tSo(p.Output, ShouldEndWith, p.Path)\n\t\t\t} else {\n\t\t\t\tSo(p.Output, ShouldBeBlank)\n\t\t\t}\n\t\t\tSo(p.Error, ShouldBeNil)\n\t\t}\n\t}\n}\n\nfunc (self *TesterFixture) TestsShouldHaveRunContiguously() {\n\tself.OutputShouldBeAsExpected()\n\n\tSo(self.shell.MaxConcurrentCommands(), ShouldEqual, 1)\n\n\tfor i := 0; i < len(self.executions)-1; i++ {\n\t\tcurrent := self.executions[i]\n\t\tnext := self.executions[i+1]\n\t\tSo(current.Started, ShouldHappenBefore, next.Started)\n\t\tSo(current.Ended, ShouldHappenOnOrBefore, next.Started)\n\t}\n}\n\nfunc (self *TesterFixture) TestsShouldHaveRunInBatchesOfTwo() {\n\tself.OutputShouldBeAsExpected()\n\n\tSo(self.shell.MaxConcurrentCommands(), ShouldEqual, concurrentBatchSize)\n}\n\n/**** Fakes ****/\n\ntype ShellCommand struct {\n\tCommand string\n\tStarted time.Time\n\tEnded   time.Time\n}\n\ntype TimedShell struct {\n\texecutions   []*ShellCommand\n\tpanicMessage string\n\terr          error\n}\n\nfunc (self *TimedShell) Executions() []*ShellCommand {\n\treturn self.executions\n}\n\nfunc (self *TimedShell) MaxConcurrentCommands() int {\n\tvar concurrent int\n\n\tfor x, current := range self.executions {\n\t\tconcurrentWith_x := 1\n\t\tfor y, comparison := range self.executions {\n\t\t\tif y == x {\n\t\t\t\tcontinue\n\t\t\t} else if concurrentWith(current, comparison) {\n\t\t\t\tconcurrentWith_x++\n\t\t\t}\n\t\t}\n\t\tif concurrentWith_x > concurrent {\n\t\t\tconcurrent = concurrentWith_x\n\t\t}\n\t}\n\treturn concurrent\n}\n\nfunc concurrentWith(current, comparison *ShellCommand) bool {\n\treturn ((comparison.Started == current.Started || comparison.Started.After(current.Started)) &&\n\t\t(comparison.Started.Before(current.Ended)))\n}\n\nfunc (self *TimedShell) setTripWire(message string) {\n\tself.panicMessage = message\n}\n\nfunc (self *TimedShell) setExitWithError() {\n\tself.err = errors.New(\"Simulate test failure\")\n}\n\nfunc (self *TimedShell) GoTest(directory, packageName string, arguments, tags []string) (output string, err error) {\n\tif self.panicMessage != \"\" {\n\t\treturn \"\", errors.New(self.panicMessage)\n\t}\n\n\toutput = directory\n\terr = self.err\n\tself.executions = append(self.executions, self.composeCommand(directory))\n\treturn\n}\n\nfunc (self *TimedShell) composeCommand(commandText string) *ShellCommand {\n\tstart := time.Now()\n\ttime.Sleep(nap)\n\tend := time.Now()\n\treturn &ShellCommand{commandText, start, end}\n}\n\nfunc NewTimedShell() *TimedShell {\n\tself := new(TimedShell)\n\tself.executions = []*ShellCommand{}\n\treturn self\n}\n\nvar nap, _ = time.ParseDuration(\"10ms\")\nvar _ = fmt.Sprintf(\"fmt\")\n"
  },
  {
    "path": "web/server/messaging/doc_test.go",
    "content": "package messaging\n"
  },
  {
    "path": "web/server/messaging/messages.go",
    "content": "package messaging\n\n///////////////////////////////////////////////////////////////////////////////\n\ntype WatcherCommand struct {\n\tInstruction WatcherInstruction\n\tDetails     string\n}\n\ntype WatcherInstruction int\n\nfunc (this WatcherInstruction) String() string {\n\tswitch this {\n\tcase WatcherPause:\n\t\treturn \"Pause\"\n\tcase WatcherResume:\n\t\treturn \"Resume\"\n\tcase WatcherIgnore:\n\t\treturn \"Ignore\"\n\tcase WatcherReinstate:\n\t\treturn \"Reinstate\"\n\tcase WatcherAdjustRoot:\n\t\treturn \"AdjustRoot\"\n\tcase WatcherExecute:\n\t\treturn \"Execute\"\n\tcase WatcherStop:\n\t\treturn \"Stop\"\n\tdefault:\n\t\treturn \"UNKNOWN INSTRUCTION\"\n\t}\n}\n\nconst (\n\tWatcherPause WatcherInstruction = iota\n\tWatcherResume\n\tWatcherIgnore\n\tWatcherReinstate\n\tWatcherAdjustRoot\n\tWatcherExecute\n\tWatcherStop\n)\n\n///////////////////////////////////////////////////////////////////////////////\n\ntype Folders map[string]*Folder\n\ntype Folder struct {\n\tPath          string // key\n\tRoot          string\n\tIgnored       bool\n\tDisabled      bool\n\tBuildTags     []string\n\tTestArguments []string\n}\n\n///////////////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "web/server/parser/packageParser.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\nvar (\n\ttestNamePattern = regexp.MustCompile(\"^=== RUN:? +(.+)$\")\n)\n\nfunc ParsePackageResults(result *contract.PackageResult, rawOutput string) {\n\tnewOutputParser(result, rawOutput).parse()\n}\n\ntype outputParser struct {\n\traw    string\n\tlines  []string\n\tresult *contract.PackageResult\n\ttests  []*contract.TestResult\n\n\t// place holders for loops\n\tline    string\n\ttest    *contract.TestResult\n\ttestMap map[string]*contract.TestResult\n}\n\nfunc newOutputParser(result *contract.PackageResult, rawOutput string) *outputParser {\n\traw := strings.TrimSpace(rawOutput)\n\treturn &outputParser{\n\t\traw:     raw,\n\t\tlines:   strings.Split(raw, \"\\n\"),\n\t\tresult:  result,\n\t\ttestMap: make(map[string]*contract.TestResult),\n\t}\n}\n\nfunc (self *outputParser) parse() {\n\tself.separateTestFunctionsAndMetadata()\n\tself.parseEachTestFunction()\n}\n\nfunc (self *outputParser) separateTestFunctionsAndMetadata() {\n\tfor _, self.line = range self.lines {\n\t\tif self.processNonTestOutput() {\n\t\t\tbreak\n\t\t}\n\t\t// Hack for results from ginkgo tests\n\t\tlines := strings.Split(self.line, \" --- \")\n\t\tif len(lines) == 2 && len(strings.TrimSpace(lines[0])) > 0 && strings.HasPrefix(lines[1], \"PASS\") {\n\t\t\tself.line = lines[0]\n\t\t\tself.processTestOutput()\n\t\t\tself.line = \"--- \" + lines[1]\n\t\t\tself.processTestOutput()\n\t\t\tcontinue\n\t\t}\n\t\tself.processTestOutput()\n\t}\n}\nfunc (self *outputParser) processNonTestOutput() bool {\n\tif noGoFiles(self.line) {\n\t\tself.recordFinalOutcome(contract.NoGoFiles)\n\n\t} else if buildFailed(self.line) {\n\t\tself.recordFinalOutcome(contract.BuildFailure)\n\n\t} else if noTestFiles(self.line) {\n\t\tself.recordFinalOutcome(contract.NoTestFiles)\n\n\t} else if noTestFunctions(self.line) {\n\t\tself.recordFinalOutcome(contract.NoTestFunctions)\n\n\t} else {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (self *outputParser) recordFinalOutcome(outcome string) {\n\tself.result.Outcome = outcome\n\tself.result.BuildOutput = strings.Join(self.lines, \"\\n\")\n}\n\nfunc (self *outputParser) processTestOutput() {\n\tself.line = strings.TrimSpace(self.line)\n\tif isNewTest(self.line) {\n\t\tself.registerTestFunction()\n\n\t} else if isTestResult(self.line) {\n\t\tself.recordTestMetadata()\n\n\t} else if isPackageReport(self.line) {\n\t\tself.recordPackageMetadata()\n\n\t} else {\n\t\tself.saveLineForParsingLater()\n\n\t}\n}\n\nfunc (self *outputParser) registerTestFunction() {\n\ttestNameReg := testNamePattern.FindStringSubmatch(self.line)\n\tif len(testNameReg) < 2 { // Test-related lines that aren't about a new test\n\t\treturn\n\t}\n\tself.test = contract.NewTestResult(testNameReg[1])\n\tself.tests = append(self.tests, self.test)\n\tself.testMap[self.test.TestName] = self.test\n}\nfunc (self *outputParser) recordTestMetadata() {\n\ttestName := strings.Split(self.line, \" \")[2]\n\tif test, ok := self.testMap[testName]; ok {\n\t\tself.test = test\n\t\tself.test.Passed = !strings.HasPrefix(self.line, \"--- FAIL: \")\n\t\tself.test.Skipped = strings.HasPrefix(self.line, \"--- SKIP: \")\n\t\tself.test.Elapsed = parseTestFunctionDuration(self.line)\n\t}\n}\nfunc (self *outputParser) recordPackageMetadata() {\n\tif packageFailed(self.line) {\n\t\tself.recordTestingOutcome(contract.Failed)\n\n\t} else if packagePassed(self.line) {\n\t\tself.recordTestingOutcome(contract.Passed)\n\n\t} else if isCoverageSummary(self.line) {\n\t\tself.recordCoverageSummary(self.line)\n\t}\n}\nfunc (self *outputParser) recordTestingOutcome(outcome string) {\n\tself.result.Outcome = outcome\n\tfields := strings.Split(self.line, \"\\t\")\n\tself.result.PackageName = strings.TrimSpace(fields[1])\n\tself.result.Elapsed = parseDurationInSeconds(fields[2], 3)\n}\n\nvar coverageStatementRE = regexp.MustCompile(`coverage: (\\d+\\.\\d)%%? of statements`)\n\nfunc (self *outputParser) recordCoverageSummary(summary string) {\n\tmatches := coverageStatementRE.FindStringSubmatch(summary)\n\n\tcoverage := -1.0\n\t// if there were no matches, or if matches[1] doesn't parse as a float, then we'll return -1\n\tif len(matches) != 0 {\n\t\tcoverage, _ = strconv.ParseFloat(matches[1], 64)\n\t}\n\tself.result.Coverage = coverage\n}\nfunc (self *outputParser) saveLineForParsingLater() {\n\tself.line = strings.TrimLeft(self.line, \"\\t\")\n\tif self.test == nil {\n\t\tfmt.Println(\"Potential error parsing output of\", self.result.PackageName, \"; couldn't handle this stray line:\", self.line)\n\t\treturn\n\t}\n\tself.test.RawLines = append(self.test.RawLines, self.line)\n}\n\n// TestResults is a collection of TestResults that implements sort.Interface.\ntype TestResults []contract.TestResult\n\nfunc (r TestResults) Len() int {\n\treturn len(r)\n}\n\n// Less compares TestResults on TestName\nfunc (r TestResults) Less(i, j int) bool {\n\treturn r[i].TestName < r[j].TestName\n}\n\nfunc (r TestResults) Swap(i, j int) {\n\tr[i], r[j] = r[j], r[i]\n}\n\nfunc (self *outputParser) parseEachTestFunction() {\n\tfor _, self.test = range self.tests {\n\t\tself.test = parseTestOutput(self.test)\n\t\tif self.test.Error != \"\" {\n\t\t\tself.result.Outcome = contract.Panicked\n\t\t}\n\t\tself.test.RawLines = []string{}\n\t\tself.result.TestResults = append(self.result.TestResults, *self.test)\n\t}\n\tsort.Sort(TestResults(self.result.TestResults))\n}\n"
  },
  {
    "path": "web/server/parser/package_parser_test.go",
    "content": "package parser\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\nfunc init() {\n\tlog.SetOutput(io.Discard)\n}\n\nfunc TestParsePackage_NoGoFiles_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expected_NoGoFiles.PackageName}\n\tParsePackageResults(actual, input_NoGoFiles)\n\tassertEqual(t, expected_NoGoFiles, *actual)\n}\n\nfunc TestParsePackage_NoTestFiles_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expected_NoTestFiles.PackageName}\n\tParsePackageResults(actual, input_NoTestFiles)\n\tassertEqual(t, expected_NoTestFiles, *actual)\n}\n\nfunc TestParsePacakge_NoTestFunctions_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expected_NoTestFunctions.PackageName}\n\tParsePackageResults(actual, input_NoTestFunctions)\n\tassertEqual(t, expected_NoTestFunctions, *actual)\n}\n\nfunc TestParsePackage_BuildFailed_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expected_BuildFailed_InvalidPackageDeclaration.PackageName}\n\tParsePackageResults(actual, input_BuildFailed_InvalidPackageDeclaration)\n\tassertEqual(t, expected_BuildFailed_InvalidPackageDeclaration, *actual)\n\n\tactual = &contract.PackageResult{PackageName: expected_BuildFailed_OtherErrors.PackageName}\n\tParsePackageResults(actual, input_BuildFailed_OtherErrors)\n\tassertEqual(t, expected_BuildFailed_OtherErrors, *actual)\n\n\tactual = &contract.PackageResult{PackageName: expected_BuildFailed_ImportCycle.PackageName}\n\tParsePackageResults(actual, input_BuildFailed_ImportCycle)\n\tassertEqual(t, expected_BuildFailed_ImportCycle, *actual)\n\n\tactual = &contract.PackageResult{PackageName: expected_BuildFailed_CantFindPackage.PackageName}\n\tParsePackageResults(actual, input_BuildFailed_CantFindPackage)\n\tassertEqual(t, expected_BuildFailed_CantFindPackage, *actual)\n\n\tactual = &contract.PackageResult{PackageName: expected_BuildFailed_ConflictingImport.PackageName}\n\tParsePackageResults(actual, input_BuildFailed_ConfictingImport)\n\tassertEqual(t, expected_BuildFailed_ConflictingImport, *actual)\n}\n\nfunc TestParsePackage_OldSchoolWithFailureOutput_ReturnsCompletePackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedOldSchool_Fails.PackageName}\n\tParsePackageResults(actual, inputOldSchool_Fails)\n\tassertEqual(t, expectedOldSchool_Fails, *actual)\n}\n\nfunc TestParsePackage_OldSchoolWithSuccessOutput_ReturnsCompletePackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedOldSchool_Passes.PackageName}\n\tParsePackageResults(actual, inputOldSchool_Passes)\n\tassertEqual(t, expectedOldSchool_Passes, *actual)\n}\n\nfunc TestParsePackage_GoConveyWithDiffOutput_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedOldSchoolWithDiff_Fails.PackageName}\n\tParsePackageResults(actual, inputOldSchoolWithDiff_Fails)\n\tassertEqual(t, expectedOldSchoolWithDiff_Fails, *actual)\n}\n\nfunc TestParsePackage_GoConveyWithDiff2Output_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedOldSchoolWithDiff2_Fails.PackageName}\n\tParsePackageResults(actual, inputOldSchoolWithDiff2_Fails)\n\tassertEqual(t, expectedOldSchoolWithDiff2_Fails, *actual)\n}\n\nfunc TestParsePackage_OldSchoolWithPanicOutput_ReturnsCompletePackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedOldSchool_Panics.PackageName}\n\tParsePackageResults(actual, inputOldSchool_Panics)\n\tassertEqual(t, expectedOldSchool_Panics, *actual)\n}\n\nfunc TestParsePackage_GoConveyOutput_ReturnsCompletePackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedGoConvey.PackageName}\n\tParsePackageResults(actual, inputGoConvey)\n\tassertEqual(t, expectedGoConvey, *actual)\n}\n\nfunc TestParsePackage_ActualPackageNameDifferentThanDirectoryName_ReturnsActualPackageName(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: strings.Replace(expectedGoConvey.PackageName, \"examples\", \"stuff\", -1)}\n\tParsePackageResults(actual, inputGoConvey)\n\tassertEqual(t, expectedGoConvey, *actual)\n}\n\nfunc TestParsePackage_GoConveyOutputMalformed_CausesPanic(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tmessage := fmt.Sprintf(\"%v\", r)\n\t\t\tif !strings.Contains(message, \"bug report\") {\n\t\t\t\tt.Errorf(\"Should have panicked with a request to file a bug report but we received this error instead: %s\", message)\n\t\t\t}\n\t\t} else {\n\t\t\tt.Errorf(\"Should have panicked with a request to file a bug report but we received no error.\")\n\t\t}\n\t}()\n\n\tactual := &contract.PackageResult{PackageName: expectedGoConvey.PackageName}\n\tParsePackageResults(actual, inputGoConvey_Malformed)\n}\n\nfunc TestParsePackage_GoConveyWithRandomOutput_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedGoConvey_WithRandomOutput.PackageName}\n\tParsePackageResults(actual, inputGoConvey_WithRandomOutput)\n\tassertEqual(t, expectedGoConvey_WithRandomOutput, *actual)\n}\n\nfunc TestParsePackage_OldSchoolWithSuccessAndBogusCoverage_ReturnsCompletePackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedOldSchool_PassesButCoverageIsBogus.PackageName}\n\tParsePackageResults(actual, inputOldSchool_PassesButCoverageIsBogus)\n\tassertEqual(t, expectedOldSchool_PassesButCoverageIsBogus, *actual)\n}\n\nfunc TestParsePackage_NestedTests_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedNestedTests.PackageName}\n\tParsePackageResults(actual, inputNestedTests)\n\tassertEqual(t, expectedNestedTests, *actual)\n}\n\nfunc TestParsePackage_WithExampleFunctions_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedExampleFunctions.PackageName}\n\tParsePackageResults(actual, inputExampleFunctions)\n\tassertEqual(t, expectedExampleFunctions, *actual)\n}\n\nfunc TestParsePackage_Golang15Output_ShouldNotPanic(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedGolang15.PackageName}\n\tParsePackageResults(actual, inputGolang15)\n\tassertEqual(t, expectedGolang15, *actual)\n}\n\nfunc TestParsePackage_Golang17Subtests_ReturnsPackageResult(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedGolang17Subtests.PackageName}\n\tParsePackageResults(actual, inputGolang17Subtests)\n\tassertEqual(t, expectedGolang17Subtests, *actual)\n}\n\nfunc assertEqual(t *testing.T, expected, actual any) {\n\ta, _ := json.Marshal(expected)\n\tb, _ := json.Marshal(actual)\n\tif string(a) != string(b) {\n\t\tt.Errorf(failureTemplate, string(a), string(b))\n\t}\n}\n\nconst failureTemplate = \"Comparison failed:\\n  Expected: %v\\n    Actual: %v\\n\"\n\nconst input_NoGoFiles = `can't load package: package github.com/smartystreets/goconvey: no buildable Go source files in /Users/matt/Work/Dev/goconvey/src/github.com/smartystreets/goconvey`\n\nvar expected_NoGoFiles = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey\",\n\tOutcome:     contract.NoGoFiles,\n\tBuildOutput: input_NoGoFiles,\n}\n\nconst input_NoTestFiles = `?   \tpkg.smartystreets.net/liveaddress-zipapi\t[no test files]`\n\nvar expected_NoTestFiles = contract.PackageResult{\n\tPackageName: \"pkg.smartystreets.net/liveaddress-zipapi\",\n\tOutcome:     contract.NoTestFiles,\n\tBuildOutput: input_NoTestFiles,\n}\n\nconst input_NoTestFunctions = `testing: warning: no tests to run\nPASS\nok  \tgithub.com/smartystreets/goconvey/scripts\t0.011s`\n\nvar expected_NoTestFunctions = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/scripts\",\n\tOutcome:     contract.NoTestFunctions,\n\tBuildOutput: input_NoTestFunctions,\n}\n\nconst input_BuildFailed_InvalidPackageDeclaration = `\ncan't load package: package github.com/smartystreets/goconvey/examples:\nbowling_game_test.go:9:1: expected 'package', found 'IDENT' asdf\nbowling_game_test.go:10:1: invalid package name _\n`\n\nvar expected_BuildFailed_InvalidPackageDeclaration = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/examples\",\n\tOutcome:     contract.BuildFailure,\n\tBuildOutput: strings.TrimSpace(input_BuildFailed_InvalidPackageDeclaration),\n}\n\nconst input_BuildFailed_CantFindPackage = `\nbowling_game.go:3:8: cannot find package \"format\" in any of:\n\t/usr/local/go/src/pkg/format (from $GOROOT)\n\t/Users/mike/work/dev/goconvey/src/format (from $GOPATH)\nFAIL\tgithub.com/smartystreets/goconvey/examples [setup failed]\n`\n\nvar expected_BuildFailed_CantFindPackage = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/examples\",\n\tOutcome:     contract.BuildFailure,\n\tBuildOutput: strings.TrimSpace(input_BuildFailed_CantFindPackage),\n}\n\nconst input_BuildFailed_ConfictingImport = `\nmutustus.go:4:2: found packages e (e.go) and err (prepend.go) in /Users/mike/src/utensils.git/e\n`\n\nvar expected_BuildFailed_ConflictingImport = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/examples\",\n\tOutcome:     contract.BuildFailure,\n\tBuildOutput: strings.TrimSpace(input_BuildFailed_ConfictingImport),\n}\n\nconst input_BuildFailed_OtherErrors = `\n# github.com/smartystreets/goconvey/examples\n./bowling_game_test.go:22: undefined: game\n./bowling_game_test.go:22: cannot assign to game\n./bowling_game_test.go:25: undefined: game\n./bowling_game_test.go:28: undefined: game\n./bowling_game_test.go:33: undefined: game\n./bowling_game_test.go:36: undefined: game\n./bowling_game_test.go:41: undefined: game\n./bowling_game_test.go:42: undefined: game\n./bowling_game_test.go:43: undefined: game\n./bowling_game_test.go:46: undefined: game\n./bowling_game_test.go:46: too many errors\nFAIL\tgithub.com/smartystreets/goconvey/examples [build failed]\n`\n\nvar expected_BuildFailed_OtherErrors = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/examples\",\n\tOutcome:     contract.BuildFailure,\n\tBuildOutput: strings.TrimSpace(input_BuildFailed_OtherErrors),\n}\n\nconst input_BuildFailed_ImportCycle = `\n# github.com/smartystreets/goconvey/t\n./t_test.go:23: import \"github.com/smartystreets/goconvey/t\" while compiling that package (import cycle)\nFAIL\tgithub.com/smartystreets/goconvey/t [build failed]\n`\n\nvar expected_BuildFailed_ImportCycle = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/t\",\n\tOutcome:     contract.BuildFailure,\n\tBuildOutput: strings.TrimSpace(input_BuildFailed_ImportCycle),\n}\n\nconst inputOldSchool_Passes = `\n=== RUN TestOldSchool_Passes\n--- PASS: TestOldSchool_Passes (0.02 seconds)\n=== RUN TestSkippingTests\n--- SKIP: TestSkippingTests (0.00 seconds)\n\told_school_test.go:8: blah\n=== RUN TestOldSchool_PassesWithMessage\n--- PASS: TestOldSchool_PassesWithMessage (0.05 seconds)\n\told_school_test.go:10: I am a passing test.\n\t\tWith a newline.\nPASS\ncoverage: 100.0%% of statements in github.com/smartystreets/goconvey/convey, github.com/smartystreets/goconvey/convey/gotest, github.com/smartystreets/goconvey/convey/reporting\nok  \tgithub.com/smartystreets/goconvey/webserver/examples\t0.018s\n`\n\nvar expectedOldSchool_Passes = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.018,\n\tCoverage:    100,\n\tOutcome:     contract.Passed,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_Passes\",\n\t\t\tElapsed:  0.02,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_PassesWithMessage\",\n\t\t\tElapsed:  0.05,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"old_school_test.go\",\n\t\t\tLine:     10,\n\t\t\tMessage:  \"old_school_test.go:10: I am a passing test.\\nWith a newline.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestSkippingTests\",\n\t\t\tElapsed:  0,\n\t\t\tPassed:   true,\n\t\t\tSkipped:  true,\n\t\t\tFile:     \"old_school_test.go\",\n\t\t\tLine:     8,\n\t\t\tMessage:  \"old_school_test.go:8: blah\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputOldSchool_Fails = `\n=== RUN TestOldSchool_Passes\n--- PASS: TestOldSchool_Passes (0.01 seconds)\n=== RUN TestOldSchool_PassesWithMessage\n--- PASS: TestOldSchool_PassesWithMessage (0.03 seconds)\n\told_school_test.go:10: I am a passing test.\n\t\tWith a newline.\n=== RUN TestOldSchool_Failure\n--- FAIL: TestOldSchool_Failure (0.06 seconds)\n=== RUN TestOldSchool_FailureWithReason\n--- FAIL: TestOldSchool_FailureWithReason (0.11 seconds)\n\told_school_test.go:18: I am a failing test.\nFAIL\nexit status 1\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.017s\n`\n\nvar expectedOldSchool_Fails = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tOutcome:     contract.Failed,\n\tElapsed:     0.017,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_Failure\",\n\t\t\tElapsed:  0.06,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_FailureWithReason\",\n\t\t\tElapsed:  0.11,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"old_school_test.go\",\n\t\t\tLine:     18,\n\t\t\tMessage:  \"old_school_test.go:18: I am a failing test.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_Passes\",\n\t\t\tElapsed:  0.01,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_PassesWithMessage\",\n\t\t\tElapsed:  0.03,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"old_school_test.go\",\n\t\t\tLine:     10,\n\t\t\tMessage:  \"old_school_test.go:10: I am a passing test.\\nWith a newline.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputOldSchoolWithDiff2_Fails = `\n/home/apryl/gopath/src/gitlab.qarea.org/tgms/collabms/tracker/testdata/staging.setup: 11: /home/apryl/gopath/src/gitlab.qarea.org/tgms/collabms/tracker/testdata/staging.setup: [[: not found\n=== RUN   TestExterlanLoginURL\n--- PASS: TestExterlanLoginURL (0.00s)\n=== RUN   TestToProject\n--- FAIL: TestToProject (0.00s)\n        Error Trace:    converters_test.go:29\n        Error:          Not equal: entities.Project{ID:\"1\", Title:\"Todolist1\", Link:\"host.com/123/projects/1\", Description:\"\", IssueTypes:[]entities.TypeID{entities.TypeID{ID:5, Name:\"NEW\"}, entities.TypeID{ID:6, Name:\"CONFIRMED\"}, entities.TypeID{ID:7, Name:\"WORKS FOR ME\"}}, ActivityTypes:[]entities.TypeID{entities.TypeID{ID:1, Name:\"General\"}, entities.TypeID{ID:2, Name:\"i don't know\"}, entities.TypeID{ID:3, Name:\"maaaan\"}}} (expected)\n                                != entities.Project{ID:\"1\", Title:\"Todolist\", Link:\"host.com/123/projects/1\", Description:\"\", IssueTypes:[]entities.TypeID{entities.TypeID{ID:5, Name:\"NEW\"}, entities.TypeID{ID:6, Name:\"CONFIRMED\"}, entities.TypeID{ID:7, Name:\"WORKS FOR ME\"}}, ActivityTypes:[]entities.TypeID{entities.TypeID{ID:1, Name:\"General\"}, entities.TypeID{ID:2, Name:\"i don't know\"}, entities.TypeID{ID:3, Name:\"maaaan\"}}} (actual)\n\n                        Diff:\n                        --- Expected\n                        +++ Actual\n                        @@ -2,6 +2,6 @@\n                          ID: (entities.ProjectID) (len=1) \"1\",\n                        - Title: (string) (len=9) \"Todolist1\",\n                        + Title: (string) (len=8) \"Todolist\",\n                          Link: (string) (len=23) \"host.com/123/projects/1\",\n                          Description: (string) \"\",\n                        - IssueTypes: ([]entities.TypeID) (len=3 cap=3) {\n                        + IssueTypes: ([]entities.TypeID) (len=3 cap=4) {\n                           (entities.TypeID) {\n                        @@ -19,3 +19,3 @@\n                          },\n                        - ActivityTypes: ([]entities.TypeID) (len=3 cap=3) {\n                        + ActivityTypes: ([]entities.TypeID) (len=3 cap=4) {\n                           (entities.TypeID) {\n\n=== RUN   TestIssue\n--- FAIL: TestIssue (0.00s)\n        Error Trace:    converters_test.go:49\n        Error:          Not equal: entities.Issue{ID:\"1\", ProjectID:\"1\", Type:entities.TypeID{ID:8, Name:\"DUPLICATE\"}, Title:\"ser1\", Description:\"\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\"host.com/123/projects/1/tasks/1\"} (expected)\n                                != entities.Issue{ID:\"1\", ProjectID:\"1\", Type:entities.TypeID{ID:8, Name:\"DUPLICATE\"}, Title:\"ser\", Description:\"\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\"host.com/123/projects/1/tasks/1\"} (actual)\n\n                        Diff:\n                        --- Expected\n                        +++ Actual\n                        @@ -7,3 +7,3 @@\n                          },\n                        - Title: (string) (len=4) \"ser1\",\n                        + Title: (string) (len=3) \"ser\",\n                          Description: (string) \"\",\n        Messages:       Message\n\n=== RUN   TestIssues\n--- PASS: TestIssues (2.00s)\nFAIL\ncoverage: 51.7% of statements\nexit status 1\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.414s\n`\n\nvar expectedOldSchoolWithDiff2_Fails = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tOutcome:     contract.Failed,\n\tElapsed:     0.414,\n\tCoverage:    51.7,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestExterlanLoginURL\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   true,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestIssue\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"converters_test.go\",\n\t\t\tLine:     49,\n\t\t\tMessage:  \"Error Trace:    converters_test.go:49\\nError:          Not equal: entities.Issue{ID:\\\"1\\\", ProjectID:\\\"1\\\", Type:entities.TypeID{ID:8, Name:\\\"DUPLICATE\\\"}, Title:\\\"ser1\\\", Description:\\\"\\\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\\\"host.com/123/projects/1/tasks/1\\\"} (expected)\\n!= entities.Issue{ID:\\\"1\\\", ProjectID:\\\"1\\\", Type:entities.TypeID{ID:8, Name:\\\"DUPLICATE\\\"}, Title:\\\"ser\\\", Description:\\\"\\\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\\\"host.com/123/projects/1/tasks/1\\\"} (actual)\\n\\nDiff:\\n--- Expected\\n+++ Actual\\n@@ -7,3 +7,3 @@\\n},\\n- Title: (string) (len=4) \\\"ser1\\\",\\n+ Title: (string) (len=3) \\\"ser\\\",\\nDescription: (string) \\\"\\\",\\nMessages:       Message\\n\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestIssues\",\n\t\t\tElapsed:  2.00,\n\t\t\tPassed:   true,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestToProject\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"converters_test.go\",\n\t\t\tLine:     29,\n\t\t\tMessage:  \"Error Trace:    converters_test.go:29\\nError:          Not equal: entities.Project{ID:\\\"1\\\", Title:\\\"Todolist1\\\", Link:\\\"host.com/123/projects/1\\\", Description:\\\"\\\", IssueTypes:[]entities.TypeID{entities.TypeID{ID:5, Name:\\\"NEW\\\"}, entities.TypeID{ID:6, Name:\\\"CONFIRMED\\\"}, entities.TypeID{ID:7, Name:\\\"WORKS FOR ME\\\"}}, ActivityTypes:[]entities.TypeID{entities.TypeID{ID:1, Name:\\\"General\\\"}, entities.TypeID{ID:2, Name:\\\"i don't know\\\"}, entities.TypeID{ID:3, Name:\\\"maaaan\\\"}}} (expected)\\n!= entities.Project{ID:\\\"1\\\", Title:\\\"Todolist\\\", Link:\\\"host.com/123/projects/1\\\", Description:\\\"\\\", IssueTypes:[]entities.TypeID{entities.TypeID{ID:5, Name:\\\"NEW\\\"}, entities.TypeID{ID:6, Name:\\\"CONFIRMED\\\"}, entities.TypeID{ID:7, Name:\\\"WORKS FOR ME\\\"}}, ActivityTypes:[]entities.TypeID{entities.TypeID{ID:1, Name:\\\"General\\\"}, entities.TypeID{ID:2, Name:\\\"i don't know\\\"}, entities.TypeID{ID:3, Name:\\\"maaaan\\\"}}} (actual)\\n\\nDiff:\\n--- Expected\\n+++ Actual\\n@@ -2,6 +2,6 @@\\nID: (entities.ProjectID) (len=1) \\\"1\\\",\\n- Title: (string) (len=9) \\\"Todolist1\\\",\\n+ Title: (string) (len=8) \\\"Todolist\\\",\\nLink: (string) (len=23) \\\"host.com/123/projects/1\\\",\\nDescription: (string) \\\"\\\",\\n- IssueTypes: ([]entities.TypeID) (len=3 cap=3) {\\n+ IssueTypes: ([]entities.TypeID) (len=3 cap=4) {\\n(entities.TypeID) {\\n@@ -19,3 +19,3 @@\\n},\\n- ActivityTypes: ([]entities.TypeID) (len=3 cap=3) {\\n+ ActivityTypes: ([]entities.TypeID) (len=3 cap=4) {\\n(entities.TypeID) {\\n\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputOldSchoolWithDiff_Fails = `\n/home/apryl/gopath/src/gitlab.qarea.org/tgms/collabms/tracker/testdata/staging.setup: 11: /home/apryl/gopath/src/gitlab.qarea.org/tgms/collabms/tracker/testdata/staging.setup: [[: not found\n=== RUN TestOldSchool_Passes\n--- PASS: TestOldSchool_Passes (0.01 seconds)\n=== RUN TestOldSchool_PassesWithMessage\n--- PASS: TestOldSchool_PassesWithMessage (0.03 seconds)\n\told_school_test.go:10: I am a passing test.\n\t\tWith a newline.\n=== RUN TestOldSchool_Failure\n--- FAIL: TestOldSchool_Failure (0.06 seconds)\n=== RUN TestOldSchool_FailureWithReason\n--- FAIL: TestOldSchool_FailureWithReason (0.11 seconds)\n\told_school_test.go:18: I am a failing test.\n=== RUN TestOldSchool_FailureWithDiff\n--- FAIL: TestOldSchool_FailureWithDiff (0.17 seconds)\n        Error Trace:    converters_test.go:49\n        Error:          Not equal: entities.Issue{ID:\"1\", ProjectID:\"1\", Type:entities.TypeID{ID:8, Name:\"DUPLICATE\"}, Title:\"ser1\", Description:\"\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\"host.com/123/projects/1/tasks/1\"} (expected)\n                                != entities.Issue{ID:\"1\", ProjectID:\"1\", Type:entities.TypeID{ID:8, Name:\"DUPLICATE\"}, Title:\"ser\", Description:\"\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\"host.com/123/projects/1/tasks/1\"} (actual)\n\n                        Diff:\n                        --- Expected\n                        +++ Actual\n                        @@ -7,3 +7,3 @@\n                          },\n                        - Title: (string) (len=4) \"ser1\",\n                        + Title: (string) (len=3) \"ser\",\n                          Description: (string) \"\",\n        Messages:       Message\n\nFAIL\nexit status 1\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.017s\n`\n\nvar expectedOldSchoolWithDiff_Fails = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tOutcome:     contract.Failed,\n\tElapsed:     0.017,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_Failure\",\n\t\t\tElapsed:  0.06,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_FailureWithDiff\",\n\t\t\tElapsed:  0.17,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"converters_test.go\",\n\t\t\tLine:     49,\n\t\t\tMessage:  \"Error Trace:    converters_test.go:49\\nError:          Not equal: entities.Issue{ID:\\\"1\\\", ProjectID:\\\"1\\\", Type:entities.TypeID{ID:8, Name:\\\"DUPLICATE\\\"}, Title:\\\"ser1\\\", Description:\\\"\\\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\\\"host.com/123/projects/1/tasks/1\\\"} (expected)\\n!= entities.Issue{ID:\\\"1\\\", ProjectID:\\\"1\\\", Type:entities.TypeID{ID:8, Name:\\\"DUPLICATE\\\"}, Title:\\\"ser\\\", Description:\\\"\\\", Estimate:19800, DueDate:1479859200, Done:0, Spent:23400, URL:\\\"host.com/123/projects/1/tasks/1\\\"} (actual)\\n\\nDiff:\\n--- Expected\\n+++ Actual\\n@@ -7,3 +7,3 @@\\n},\\n- Title: (string) (len=4) \\\"ser1\\\",\\n+ Title: (string) (len=3) \\\"ser\\\",\\nDescription: (string) \\\"\\\",\\nMessages:       Message\\n\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_FailureWithReason\",\n\t\t\tElapsed:  0.11,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"old_school_test.go\",\n\t\t\tLine:     18,\n\t\t\tMessage:  \"old_school_test.go:18: I am a failing test.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_Passes\",\n\t\t\tElapsed:  0.01,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_PassesWithMessage\",\n\t\t\tElapsed:  0.03,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"old_school_test.go\",\n\t\t\tLine:     10,\n\t\t\tMessage:  \"old_school_test.go:10: I am a passing test.\\nWith a newline.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputOldSchool_Panics = `\n=== RUN TestOldSchool_Panics\n--- FAIL: TestOldSchool_Panics (0.02 seconds)\npanic: runtime error: index out of range [recovered]\n\tpanic: runtime error: index out of range\n\ngoroutine 3 [running]:\ntesting.func·004()\n\t/usr/local/go/src/pkg/testing/testing.go:348 +0xcd\ngithub.com/smartystreets/goconvey/webserver/examples.TestOldSchool_Panics(0x210292000)\n\t/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go:15 +0xec\ntesting.tRunner(0x210292000, 0x1b09f0)\n\t/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\t/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n\ngoroutine 1 [chan receive]:\ntesting.RunTests(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1, ...)\n\t/usr/local/go/src/pkg/testing/testing.go:434 +0x88e\ntesting.Main(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1b7f60, ...)\n\t/usr/local/go/src/pkg/testing/testing.go:365 +0x8a\nmain.main()\n\tgithub.com/smartystreets/goconvey/webserver/examples/_test/_testmain.go:43 +0x9a\nexit status 2\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.014s\n`\n\nvar expectedOldSchool_Panics = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.014,\n\tOutcome:     contract.Panicked,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_Panics\",\n\t\t\tElapsed:  0.02,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go\",\n\t\t\tLine:     15,\n\t\t\tMessage:  \"\",\n\t\t\tError: strings.Replace(`panic: runtime error: index out of range [recovered]\n\tpanic: runtime error: index out of range\n\ngoroutine 3 [running]:\ntesting.func·004()\n\t/usr/local/go/src/pkg/testing/testing.go:348 +0xcd\ngithub.com/smartystreets/goconvey/webserver/examples.TestOldSchool_Panics(0x210292000)\n\t/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go:15 +0xec\ntesting.tRunner(0x210292000, 0x1b09f0)\n\t/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\t/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n\ngoroutine 1 [chan receive]:\ntesting.RunTests(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1, ...)\n\t/usr/local/go/src/pkg/testing/testing.go:434 +0x88e\ntesting.Main(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1b7f60, ...)\n\t/usr/local/go/src/pkg/testing/testing.go:365 +0x8a\nmain.main()\n\tgithub.com/smartystreets/goconvey/webserver/examples/_test/_testmain.go:43 +0x9a`, \"\\u0009\", \"\\t\", -1),\n\t\t\tStories: []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputGoConvey_Malformed = `\n=== RUN TestPassingStory\n>->->OPEN-JSON->->->\n{\n  \"Title\": \"A passing story\",\n  \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go\",\n  \"Line\": 11,\n  \"Depth\": 0,\n  \"Assertions\": [\n    {\n      \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go\",\n      \"Line\": 10,\n      \"Failure\": \"\",\n\n      ;aiwheopinen39 n3902n92m\n\n      \"Error\": null,\n      \"Skipped\": false,\n      \"StackTrace\": \"goroutine 3 [running]:\\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\\ntesting.tRunner(0x210314000, 0x21ab10)\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\\ncreated by testing.RunTests\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\\n\"\n    }\n  ]\n},\n<-<-<-CLOSE-JSON<-<-<\n--- PASS: TestPassingStory (0.01 seconds)\nPASS\nok  \tgithub.com/smartystreets/goconvey/webserver/examples\t0.019s\n`\n\nconst inputGoConvey = `\n=== RUN TestPassingStory\n>->->OPEN-JSON->->->\n{\n  \"Title\": \"A passing story\",\n  \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go\",\n  \"Line\": 11,\n  \"Depth\": 0,\n  \"Assertions\": [\n    {\n      \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go\",\n      \"Line\": 10,\n      \"Failure\": \"\",\n      \"Error\": null,\n      \"Skipped\": false,\n      \"StackTrace\": \"goroutine 3 [running]:\\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\\ntesting.tRunner(0x210314000, 0x21ab10)\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\\ncreated by testing.RunTests\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\\n\"\n    }\n  ]\n},\n<-<-<-CLOSE-JSON<-<-<\n--- PASS: TestPassingStory (0.01 seconds)\nPASS\ncoverage: 75.5%% of statements\nok  \tgithub.com/smartystreets/goconvey/webserver/examples\t0.019s\n`\n\nvar expectedGoConvey = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.019,\n\tOutcome:     contract.Passed,\n\tCoverage:    75.5,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestPassingStory\",\n\t\t\tElapsed:  0.01,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories: []reporting.ScopeResult{\n\t\t\t\treporting.ScopeResult{\n\t\t\t\t\tTitle: \"A passing story\",\n\t\t\t\t\tFile:  \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go\",\n\t\t\t\t\tLine:  11,\n\t\t\t\t\tDepth: 0,\n\t\t\t\t\tAssertions: []*reporting.AssertionResult{\n\t\t\t\t\t\t&reporting.AssertionResult{\n\t\t\t\t\t\t\tFile:       \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go\",\n\t\t\t\t\t\t\tLine:       10,\n\t\t\t\t\t\t\tFailure:    \"\",\n\t\t\t\t\t\t\tError:      nil,\n\t\t\t\t\t\t\tSkipped:    false,\n\t\t\t\t\t\t\tStackTrace: \"goroutine 3 [running]:\\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\\ntesting.tRunner(0x210314000, 0x21ab10)\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\\ncreated by testing.RunTests\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\\n\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n}\n\nconst inputGoConvey_WithRandomOutput = `\n=== RUN TestPassingStory\n*** Hello, World! (1) ***\n*** Hello, World! (2) ***\n*** Hello, World! (3) ***>->->OPEN-JSON->->->\n{\n  \"Title\": \"A passing story\",\n  \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n  \"Line\": 16,\n  \"Depth\": 0,\n  \"Assertions\": [\n    {\n      \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n      \"Line\": 14,\n      \"Failure\": \"\",\n      \"Error\": null,\n      \"Skipped\": false,\n      \"StackTrace\": \"goroutine 3 [running]:\\ngithub.com/smartystreets/goconvey/web/server/testing.func·001()\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:14 +0x186\\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:16 +0x1b9\\ntesting.tRunner(0x210315000, 0x21bb10)\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\\ncreated by testing.RunTests\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\\n\"\n    }\n  ]\n},\n<-<-<-CLOSE-JSON<-<-<\n*** Hello, World! (4)***\n*** Hello, World! (5) ***\n>->->OPEN-JSON->->->\n{\n  \"Title\": \"A passing story\",\n  \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n  \"Line\": 22,\n  \"Depth\": 0,\n  \"Assertions\": [\n    {\n      \"File\": \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n      \"Line\": 20,\n      \"Failure\": \"\",\n      \"Error\": null,\n      \"Skipped\": false,\n      \"StackTrace\": \"goroutine 3 [running]:\\ngithub.com/smartystreets/goconvey/web/server/testing.func·002()\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:20 +0x186\\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:22 +0x294\\ntesting.tRunner(0x210315000, 0x21bb10)\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\\ncreated by testing.RunTests\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\\n\"\n    }\n  ]\n},\n<-<-<-CLOSE-JSON<-<-<\n*** Hello, World! (6) ***\n--- PASS: TestPassingStory (0.03 seconds)\nPASS\ncoverage: 45.0%% of statements\nok  \tgithub.com/smartystreets/goconvey/web/server/testing\t0.024s\n`\n\nvar expectedGoConvey_WithRandomOutput = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/web/server/testing\",\n\tElapsed:     0.024,\n\tOutcome:     contract.Passed,\n\tCoverage:    45.0,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestPassingStory\",\n\t\t\tElapsed:  0.03,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"*** Hello, World! (1) ***\\n*** Hello, World! (2) ***\\n*** Hello, World! (3) ***\\n*** Hello, World! (4)***\\n*** Hello, World! (5) ***\\n*** Hello, World! (6) ***\",\n\t\t\tStories: []reporting.ScopeResult{\n\t\t\t\treporting.ScopeResult{\n\t\t\t\t\tTitle: \"A passing story\",\n\t\t\t\t\tFile:  \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n\t\t\t\t\tLine:  16,\n\t\t\t\t\tDepth: 0,\n\t\t\t\t\tAssertions: []*reporting.AssertionResult{\n\t\t\t\t\t\t&reporting.AssertionResult{\n\t\t\t\t\t\t\tFile:       \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n\t\t\t\t\t\t\tLine:       14,\n\t\t\t\t\t\t\tFailure:    \"\",\n\t\t\t\t\t\t\tError:      nil,\n\t\t\t\t\t\t\tSkipped:    false,\n\t\t\t\t\t\t\tStackTrace: \"goroutine 3 [running]:\\ngithub.com/smartystreets/goconvey/web/server/testing.func·001()\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:14 +0x186\\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:16 +0x1b9\\ntesting.tRunner(0x210315000, 0x21bb10)\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\\ncreated by testing.RunTests\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\\n\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\treporting.ScopeResult{\n\t\t\t\t\tTitle: \"A passing story\",\n\t\t\t\t\tFile:  \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n\t\t\t\t\tLine:  22,\n\t\t\t\t\tDepth: 0,\n\t\t\t\t\tAssertions: []*reporting.AssertionResult{\n\t\t\t\t\t\t&reporting.AssertionResult{\n\t\t\t\t\t\t\tFile:       \"/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go\",\n\t\t\t\t\t\t\tLine:       20,\n\t\t\t\t\t\t\tFailure:    \"\",\n\t\t\t\t\t\t\tError:      nil,\n\t\t\t\t\t\t\tSkipped:    false,\n\t\t\t\t\t\t\tStackTrace: \"goroutine 3 [running]:\\ngithub.com/smartystreets/goconvey/web/server/testing.func·002()\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:20 +0x186\\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\\n\\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:22 +0x294\\ntesting.tRunner(0x210315000, 0x21bb10)\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\\ncreated by testing.RunTests\\n\\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\\n\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n}\n\nconst inputOldSchool_PassesButCoverageIsBogus = `\n=== RUN TestOldSchool_Passes\n--- PASS: TestOldSchool_Passes (0.02 seconds)\n=== RUN TestOldSchool_PassesWithMessage\n--- PASS: TestOldSchool_PassesWithMessage (0.05 seconds)\n\told_school_test.go:10: I am a passing test.\n\t\tWith a newline.\nPASS\ncoverage: bogus%% of statements\nok  \tgithub.com/smartystreets/goconvey/webserver/examples\t0.018s\n`\n\nvar expectedOldSchool_PassesButCoverageIsBogus = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.018,\n\tCoverage:    -1,\n\tOutcome:     contract.Passed,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_Passes\",\n\t\t\tElapsed:  0.02,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestOldSchool_PassesWithMessage\",\n\t\t\tElapsed:  0.05,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"old_school_test.go\",\n\t\t\tLine:     10,\n\t\t\tMessage:  \"old_school_test.go:10: I am a passing test.\\nWith a newline.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputNestedTests = `\n=== RUN TestNestedTests\n=== RUN TestNestedTests_Passes\n--- PASS: TestNestedTests_Passes (0.02 seconds)\n=== RUN TestNestedTests_Failure\n--- FAIL: TestNestedTests_Failure (0.06 seconds)\n=== RUN TestNestedTests_FailureWithReason\n--- FAIL: TestNestedTests_FailureWithReason (0.11 seconds)\n\tnested_test.go:18: I am a failing test.\n=== RUN TestNestedTests_Skipping\n--- SKIP: TestNestedTests_Skipping (0.00 seconds)\n\tnested_test.go:8: blah\n=== RUN TestNestedTests_PassesWithMessage\n--- PASS: TestNestedTests_PassesWithMessage (0.05 seconds)\n\tnested_test.go:10: I am a passing test.\n\t\tWith a newline.\n--- FAIL: TestNestedTests (0.25 seconds)\nFAIL\nexit status 1\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.018s\n`\n\nvar expectedNestedTests = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.018,\n\tOutcome:     contract.Failed,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestNestedTests\",\n\t\t\tElapsed:  0.25,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestNestedTests_Failure\",\n\t\t\tElapsed:  0.06,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestNestedTests_FailureWithReason\",\n\t\t\tElapsed:  0.11,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"nested_test.go\",\n\t\t\tLine:     18,\n\t\t\tMessage:  \"nested_test.go:18: I am a failing test.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestNestedTests_Passes\",\n\t\t\tElapsed:  0.02,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestNestedTests_PassesWithMessage\",\n\t\t\tElapsed:  0.05,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"nested_test.go\",\n\t\t\tLine:     10,\n\t\t\tMessage:  \"nested_test.go:10: I am a passing test.\\nWith a newline.\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"TestNestedTests_Skipping\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   true,\n\t\t\tSkipped:  true,\n\t\t\tFile:     \"nested_test.go\",\n\t\t\tLine:     8,\n\t\t\tMessage:  \"nested_test.go:8: blah\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputExampleFunctions = `\n=== RUN Example_Failure\n--- FAIL: Example_Failure (0.11 seconds)\ngot:\nactuall output\nwant:\nreal output\n=== RUN Example_Pass\n--- PASS: Example_Pass (0.06 seconds)\nFAIL\nexit status 1\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.18s\n`\n\nvar expectedExampleFunctions = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.18,\n\tOutcome:     contract.Failed,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Example_Failure\",\n\t\t\tElapsed:  0.11,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"got:\\nactuall output\\nwant:\\nreal output\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Example_Pass\",\n\t\t\tElapsed:  0.06,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputGolang15 = `\n=== RUN   Golang15\n--- PASS: Golang15 (0.01s)\nPASS\nok  \tgithub.com/smartystreets/goconvey/webserver/examples\t0.008s\n`\n\nvar expectedGolang15 = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.008,\n\tOutcome:     contract.Passed,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Golang15\",\n\t\t\tElapsed:  0.01,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputGolang17Subtests = `\n=== RUN   Test\n=== RUN   Test/success\n=== RUN   Test/fail\n=== RUN   Test/nested\n=== RUN   Test/nested/nested_success\n=== RUN   Test/nested/nested_fail\n--- FAIL: Test (0.00s)\n    --- PASS: Test/success (0.01s)\n    --- FAIL: Test/fail (0.00s)\n    --- FAIL: Test/nested (0.00s)\n        --- PASS: Test/nested/nested_success (0.02s)\n        --- FAIL: Test/nested/nested_fail (0.00s)\nFAIL\nexit status 1\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.007s\n`\n\nvar expectedGolang17Subtests = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.007,\n\tOutcome:     contract.Failed,\n\tTestResults: []contract.TestResult{\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Test\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Test/fail\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Test/nested\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Test/nested/nested_fail\",\n\t\t\tElapsed:  0.00,\n\t\t\tPassed:   false,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Test/nested/nested_success\",\n\t\t\tElapsed:  0.02,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t\tcontract.TestResult{\n\t\t\tTestName: \"Test/success\",\n\t\t\tElapsed:  0.01,\n\t\t\tPassed:   true,\n\t\t\tFile:     \"\",\n\t\t\tLine:     0,\n\t\t\tMessage:  \"\",\n\t\t\tStories:  []reporting.ScopeResult{},\n\t\t},\n\t},\n}\n\nconst inputGinkgo_Passes = `\nSUCCESS! -- 12 Passed | 0 Failed | 0 Pending | 0 Skipped --- PASS: TestModels (0.01s)\nPASS\nok  \tgithub.com/smartystreets/goconvey/webserver/examples\t3.433s\n`\n\nvar expectedGinkgo_Passes = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     3.433,\n\tOutcome:     contract.Passed,\n}\n\nfunc TestParsePackage_GinkgoWithSuccessOutput(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedGinkgo_Passes.PackageName}\n\tParsePackageResults(actual, inputGinkgo_Passes)\n\tassertEqual(t, expectedGinkgo_Passes, *actual)\n}\n\nconst inputGinkgo_Fails = `\nSummarizing 1 Failure:\n\n[Fail] main.go GetHostname [It] returns an error if systemInfo.hostname == nil\n/Users/joeuser/go/src/github.com/smartystreets/goconvey/webserver/examples/main.go:141\n\nRan 33 of 33 Specs in 0.005 seconds\nFAIL! -- 32 Passed | 1 Failed | 0 Pending | 0 Skipped --- FAIL: TestRoutes (0.01s)\nFAIL\nFAIL\tgithub.com/smartystreets/goconvey/webserver/examples\t0.810s\n`\n\nvar expectedGinkgo_Fails = contract.PackageResult{\n\tPackageName: \"github.com/smartystreets/goconvey/webserver/examples\",\n\tElapsed:     0.810,\n\tOutcome:     contract.Failed,\n}\n\nfunc TestParsePackage_GinkgoWithFailureOutput(t *testing.T) {\n\tactual := &contract.PackageResult{PackageName: expectedGinkgo_Fails.PackageName}\n\tParsePackageResults(actual, inputGinkgo_Fails)\n\tassertEqual(t, expectedGinkgo_Fails, *actual)\n}\n"
  },
  {
    "path": "web/server/parser/parser.go",
    "content": "package parser\n\nimport (\n\t\"log\"\n\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\ntype Parser struct {\n\tparser func(*contract.PackageResult, string)\n}\n\nfunc (self *Parser) Parse(packages []*contract.Package) {\n\tfor _, p := range packages {\n\t\tif p.Active() && p.HasUsableResult() {\n\t\t\tself.parser(p.Result, p.Output)\n\t\t} else if p.Ignored {\n\t\t\tp.Result.Outcome = contract.Ignored\n\t\t} else if p.Disabled {\n\t\t\tp.Result.Outcome = contract.Disabled\n\t\t} else {\n\t\t\tp.Result.Outcome = contract.TestRunAbortedUnexpectedly\n\t\t}\n\t\tlog.Printf(\"[%s]: %s\\n\", p.Result.Outcome, p.Name)\n\t}\n}\n\nfunc NewParser(helper func(*contract.PackageResult, string)) *Parser {\n\tself := new(Parser)\n\tself.parser = helper\n\treturn self\n}\n"
  },
  {
    "path": "web/server/parser/parser.goconvey",
    "content": "#ignore\n-timeout=1s\n"
  },
  {
    "path": "web/server/parser/parser_test.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\nfunc TestParser(t *testing.T) {\n\n\tConvey(\"Subject: Parser parses test output for active packages\", t, func() {\n\t\tpackages := []*contract.Package{\n\t\t\t&contract.Package{Ignored: false, Output: \"Active\", Result: contract.NewPackageResult(\"asdf\")},\n\t\t\t&contract.Package{Ignored: true, Output: \"Inactive\", Result: contract.NewPackageResult(\"qwer\")},\n\t\t}\n\t\tparser := NewParser(fakeParserImplementation)\n\n\t\tConvey(\"When given a collection of packages\", func() {\n\t\t\tparser.Parse(packages)\n\n\t\t\tConvey(\"The parser uses its internal parsing mechanism to parse the output of only the active packages\", func() {\n\t\t\t\tSo(packages[0].Result.Outcome, ShouldEqual, packages[0].Output)\n\t\t\t})\n\n\t\t\tConvey(\"The parser should mark inactive packages as ignored\", func() {\n\t\t\t\tSo(packages[1].Result.Outcome, ShouldEqual, contract.Ignored)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When a package could not be tested (maybe it was deleted between scanning and execution?)\", func() {\n\t\t\tpackages[0].Output = \"\"\n\t\t\tpackages[0].Error = errors.New(\"Directory does not exist\")\n\n\t\t\tparser.Parse(packages)\n\n\t\t\tConvey(\"The package result should not be parsed and the outcome should actually resemble the problem\", func() {\n\t\t\t\tSo(packages[0].Result.Outcome, ShouldEqual, contract.TestRunAbortedUnexpectedly)\n\t\t\t})\n\t\t})\n\t})\n}\n\nfunc fakeParserImplementation(result *contract.PackageResult, rawOutput string) {\n\tresult.Outcome = rawOutput\n}\n"
  },
  {
    "path": "web/server/parser/rules.go",
    "content": "package parser\n\nimport \"strings\"\n\nfunc noGoFiles(line string) bool {\n\treturn strings.HasPrefix(line, \"can't load package: \") &&\n\t\t(strings.Contains(line, \": no buildable Go source files in \") ||\n\t\t\tstrings.Contains(line, \": no Go \") ||\n\t\t\tstrings.Contains(line, \"cannot find module providing package\"))\n}\nfunc buildFailed(line string) bool {\n\treturn strings.HasPrefix(line, \"# \") ||\n\t\tstrings.Contains(line, \"cannot find package\") ||\n\t\t(strings.HasPrefix(line, \"can't load package: \") && !strings.Contains(line, \": no Go \")) ||\n\t\t(strings.Contains(line, \": found packages \") && strings.Contains(line, \".go) and \") && strings.Contains(line, \".go) in \"))\n}\nfunc noTestFunctions(line string) bool {\n\treturn line == \"testing: warning: no tests to run\"\n}\nfunc noTestFiles(line string) bool {\n\treturn strings.HasPrefix(line, \"?\") && strings.Contains(line, \"[no test files]\")\n}\nfunc isNewTest(line string) bool {\n\treturn strings.HasPrefix(line, \"=== \")\n}\nfunc isTestResult(line string) bool {\n\treturn strings.HasPrefix(line, \"--- FAIL:\") || strings.HasPrefix(line, \"--- PASS:\") || strings.HasPrefix(line, \"--- SKIP:\")\n}\nfunc isPackageReport(line string) bool {\n\treturn (strings.HasPrefix(line, \"FAIL\") ||\n\t\tstrings.HasPrefix(line, \"exit status\") ||\n\t\tstrings.HasPrefix(line, \"PASS\") ||\n\t\tisCoverageSummary(line) ||\n\t\tpackagePassed(line))\n}\n\nfunc packageFailed(line string) bool {\n\treturn strings.HasPrefix(line, \"FAIL\\t\")\n}\nfunc packagePassed(line string) bool {\n\treturn strings.HasPrefix(line, \"ok  \\t\")\n}\nfunc isCoverageSummary(line string) bool {\n\treturn strings.Contains(line, \"coverage: \") && strings.Contains(line, \"% of statements\")\n}\n"
  },
  {
    "path": "web/server/parser/testParser.go",
    "content": "package parser\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n\t\"github.com/smartystreets/goconvey/web/server/contract\"\n)\n\ntype testParser struct {\n\ttest       *contract.TestResult\n\tline       string\n\tindex      int\n\tinJson     bool\n\tjsonLines  []string\n\totherLines []string\n}\n\nfunc parseTestOutput(test *contract.TestResult) *contract.TestResult {\n\tparser := newTestParser(test)\n\tparser.parseTestFunctionOutput()\n\treturn test\n}\n\nfunc newTestParser(test *contract.TestResult) *testParser {\n\tself := new(testParser)\n\tself.test = test\n\treturn self\n}\n\nfunc (self *testParser) parseTestFunctionOutput() {\n\tif len(self.test.RawLines) > 0 {\n\t\tself.processLines()\n\t\tself.deserializeJson()\n\t\tself.composeCapturedOutput()\n\t}\n}\n\nfunc (self *testParser) processLines() {\n\tfor self.index, self.line = range self.test.RawLines {\n\t\tif !self.processLine() {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (self *testParser) processLine() bool {\n\tif strings.HasSuffix(self.line, reporting.OpenJson) {\n\t\tself.inJson = true\n\t\tself.accountForOutputWithoutNewline()\n\n\t} else if self.line == reporting.CloseJson {\n\t\tself.inJson = false\n\n\t} else if self.inJson {\n\t\tself.jsonLines = append(self.jsonLines, self.line)\n\n\t} else if isPanic(self.line) {\n\t\tself.parsePanicOutput()\n\t\treturn false\n\n\t} else if isGoTestLogOutput(self.line) {\n\t\tself.parseLogLocation()\n\n\t} else {\n\t\tself.otherLines = append(self.otherLines, self.line)\n\t}\n\treturn true\n}\n\n// If fmt.Print(f) produces output with no \\n and that output\n// is that last output before the framework spits out json\n// (which starts with ''>>>>>'') then without this code\n// all of the json is counted as output, not as json to be\n// parsed and displayed by the web UI.\nfunc (self *testParser) accountForOutputWithoutNewline() {\n\tprefix := strings.Split(self.line, reporting.OpenJson)[0]\n\tif prefix != \"\" {\n\t\tself.otherLines = append(self.otherLines, prefix)\n\t}\n}\n\nfunc (self *testParser) deserializeJson() {\n\tformatted := createArrayForJsonItems(self.jsonLines)\n\tvar scopes []reporting.ScopeResult\n\terr := json.Unmarshal(formatted, &scopes)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(bugReportRequest, err, formatted))\n\t}\n\tself.test.Stories = scopes\n}\nfunc (self *testParser) parsePanicOutput() {\n\tfor index, line := range self.test.RawLines[self.index:] {\n\t\tself.parsePanicLocation(index, line)\n\t\tself.preserveStackTraceIndentation(index, line)\n\t}\n\tself.test.Error = strings.Join(self.test.RawLines, \"\\n\")\n}\nfunc (self *testParser) parsePanicLocation(index int, line string) {\n\tif !panicLineHasMetadata(line) {\n\t\treturn\n\t}\n\tmetaLine := self.test.RawLines[index+4]\n\tfields := strings.Split(metaLine, \" \")\n\tfileAndLine := strings.Split(fields[0], \":\")\n\tself.test.File = fileAndLine[0]\n\tif len(fileAndLine) >= 2 {\n\t\tself.test.Line, _ = strconv.Atoi(fileAndLine[1])\n\t}\n}\nfunc (self *testParser) preserveStackTraceIndentation(index int, line string) {\n\tif panicLineShouldBeIndented(index, line) {\n\t\tself.test.RawLines[index] = \"\\t\" + line\n\t}\n}\nfunc (self *testParser) parseLogLocation() {\n\tself.otherLines = append(self.otherLines, self.line)\n\tlineFields := strings.TrimSpace(self.line)\n\tif strings.HasPrefix(lineFields, \"Error Trace:\") {\n\t\tlineFields = strings.TrimPrefix(lineFields, \"Error Trace:\")\n\t}\n\tfields := strings.Split(lineFields, \":\")\n\tself.test.File = strings.TrimSpace(fields[0])\n\tself.test.Line, _ = strconv.Atoi(fields[1])\n}\n\nfunc (self *testParser) composeCapturedOutput() {\n\tself.test.Message = strings.Join(self.otherLines, \"\\n\")\n}\n\nfunc createArrayForJsonItems(lines []string) []byte {\n\tjsonArrayItems := strings.Join(lines, \"\")\n\tjsonArrayItems = removeTrailingComma(jsonArrayItems)\n\treturn []byte(fmt.Sprintf(\"[%s]\\n\", jsonArrayItems))\n}\nfunc removeTrailingComma(rawJson string) string {\n\tif trailingComma(rawJson) {\n\t\treturn rawJson[:len(rawJson)-1]\n\t}\n\treturn rawJson\n}\nfunc trailingComma(value string) bool {\n\treturn strings.HasSuffix(value, \",\")\n}\n\nfunc isGoTestLogOutput(line string) bool {\n\treturn strings.Count(line, \":\") == 2\n}\n\nfunc isPanic(line string) bool {\n\treturn strings.HasPrefix(line, \"panic: \")\n}\n\nfunc panicLineHasMetadata(line string) bool {\n\treturn strings.HasPrefix(line, \"goroutine\") && strings.Contains(line, \"[running]\")\n}\nfunc panicLineShouldBeIndented(index int, line string) bool {\n\treturn strings.Contains(line, \"+\") || (index > 0 && strings.Contains(line, \"panic: \"))\n}\n\nconst bugReportRequest = `\nUh-oh! Looks like something went wrong. Please copy the following text and file a bug report at: \n\nhttps://github.com/smartystreets/goconvey/issues?state=open\n\n======= BEGIN BUG REPORT =======\n\nERROR: %v\n\nOUTPUT: %s\n\n======= END BUG REPORT =======\n\n`\n"
  },
  {
    "path": "web/server/parser/util.go",
    "content": "package parser\n\nimport (\n\t\"math\"\n\t\"strings\"\n\t\"time\"\n)\n\n// parseTestFunctionDuration parses the duration in seconds as a float64\n// from a line of go test output that looks something like this:\n// --- PASS: TestOldSchool_PassesWithMessage (0.03 seconds)\nfunc parseTestFunctionDuration(line string) float64 {\n\tline = strings.Replace(line, \"(\", \"\", 1)\n\tline = strings.Replace(line, \")\", \"\", 1)\n\tfields := strings.Split(line, \" \")\n\treturn parseDurationInSeconds(fields[3], 2)\n}\n\nfunc parseDurationInSeconds(raw string, precision int) float64 {\n\telapsed, err := time.ParseDuration(raw)\n\tif err != nil {\n\t\telapsed, _ = time.ParseDuration(raw + \"s\")\n\t}\n\treturn round(elapsed.Seconds(), precision)\n}\n\n// round returns the rounded version of x with precision.\n//\n// Special cases are:\n//  round(±0) = ±0\n//  round(±Inf) = ±Inf\n//  round(NaN) = NaN\n//\n// Why, oh why doesn't the math package come with a round function?\n// Inspiration: http://play.golang.org/p/ZmFfr07oHp\nfunc round(x float64, precision int) float64 {\n\tvar rounder float64\n\tpow := math.Pow(10, float64(precision))\n\tintermediate := x * pow\n\n\tif intermediate < 0.0 {\n\t\tintermediate -= 0.5\n\t} else {\n\t\tintermediate += 0.5\n\t}\n\trounder = float64(int64(intermediate))\n\n\treturn rounder / float64(pow)\n}\n"
  },
  {
    "path": "web/server/system/shell.go",
    "content": "package system\n\nimport (\n\t\"log\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n///////////////////////////////////////////////////////////////////////////////\n// Integration: ///////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////\n\ntype Shell struct {\n\tcoverage       bool\n\tgobin          string\n\treportsPath    string\n\tdefaultTimeout string\n}\n\nfunc NewShell(gobin, reportsPath string, coverage bool, defaultTimeout string) *Shell {\n\treturn &Shell{\n\t\tcoverage:       coverage,\n\t\tgobin:          gobin,\n\t\treportsPath:    reportsPath,\n\t\tdefaultTimeout: defaultTimeout,\n\t}\n}\n\nfunc (self *Shell) GoTest(directory, packageName string, tags, arguments []string) (output string, err error) {\n\treportFilename := strings.Replace(packageName, \"/\", \"-\", -1)\n\treportPath := filepath.Join(self.reportsPath, reportFilename)\n\treportData := reportPath + \".txt\"\n\treportHTML := reportPath + \".html\"\n\ttagsArg := \"-tags=\" + strings.Join(tags, \",\")\n\n\tgoconvey := findGoConvey(directory, self.gobin, packageName, tagsArg).Execute()\n\twithCoverage := runWithCoverage(goconvey, self.coverage, reportData, directory, self.gobin, self.defaultTimeout, tagsArg, arguments).Execute()\n\tfinal := runWithoutCoverage(withCoverage, goconvey, directory, self.gobin, self.defaultTimeout, tagsArg, arguments).Execute()\n\tgo generateReports(final, self.coverage, directory, self.gobin, reportData, reportHTML).Execute()\n\n\treturn final.Output, final.Error\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// Functional Core:////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////\n\nfunc findGoConvey(directory, gobin, packageName, tagsArg string) Command {\n\treturn NewCommand(directory, gobin, \"list\", \"-f\", \"'{{.TestImports}}{{.XTestImports}}'\", tagsArg, packageName)\n}\n\nfunc runWithCoverage(goconvey Command, coverage bool, reportPath, directory, gobin, defaultTimeout, tagsArg string, customArguments []string) Command {\n\tif !coverage || goconvey.Error != nil {\n\t\treturn Command{}\n\t}\n\n\targuments := []string{\"test\", \"-v\", \"-coverprofile=\" + reportPath, tagsArg}\n\n\tcustomArgsText := strings.Join(customArguments, \"\\t\")\n\tif !strings.Contains(customArgsText, \"-covermode=\") {\n\t\targuments = append(arguments, \"-covermode=set\")\n\t}\n\n\tif !strings.Contains(customArgsText, \"-timeout=\") {\n\t\targuments = append(arguments, \"-timeout=\"+defaultTimeout)\n\t}\n\n\tif strings.Contains(goconvey.Output, goconveyDSLImport) {\n\t\targuments = append(arguments, \"-convey-json\")\n\t}\n\n\targuments = append(arguments, customArguments...)\n\n\treturn NewCommand(directory, gobin, arguments...)\n}\n\nfunc runWithoutCoverage(withCoverage, goconvey Command, directory, gobin, defaultTimeout, tagsArg string, customArguments []string) Command {\n\tif goconvey.Error != nil {\n\t\tlog.Println(gopathProblem, goconvey.Output, goconvey.Error)\n\t\treturn goconvey\n\t}\n\n\tif coverageStatementRE.MatchString(withCoverage.Output) {\n\t\treturn withCoverage\n\t}\n\n\tlog.Printf(\"Coverage output: %v\", withCoverage.Output)\n\n\tlog.Print(\"Run without coverage\")\n\n\targuments := []string{\"test\", \"-v\", tagsArg}\n\tcustomArgsText := strings.Join(customArguments, \"\\t\")\n\tif !strings.Contains(customArgsText, \"-timeout=\") {\n\t\targuments = append(arguments, \"-timeout=\"+defaultTimeout)\n\t}\n\n\tif strings.Contains(goconvey.Output, goconveyDSLImport) {\n\t\targuments = append(arguments, \"-convey-json\")\n\t}\n\targuments = append(arguments, customArguments...)\n\treturn NewCommand(directory, gobin, arguments...)\n}\n\nfunc generateReports(previous Command, coverage bool, directory, gobin, reportData, reportHTML string) Command {\n\tif previous.Error != nil {\n\t\treturn previous\n\t}\n\n\tif !coverage {\n\t\treturn previous\n\t}\n\n\treturn NewCommand(directory, gobin, \"tool\", \"cover\", \"-html=\"+reportData, \"-o\", reportHTML)\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// Imperative Shell: //////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////\n\ntype Command struct {\n\tdirectory  string\n\texecutable string\n\targuments  []string\n\n\tOutput string\n\tError  error\n}\n\nfunc NewCommand(directory, executable string, arguments ...string) Command {\n\treturn Command{\n\t\tdirectory:  directory,\n\t\texecutable: executable,\n\t\targuments:  arguments,\n\t}\n}\n\nfunc (this Command) Execute() Command {\n\tif len(this.executable) == 0 {\n\t\treturn this\n\t}\n\n\tif len(this.Output) > 0 || this.Error != nil {\n\t\treturn this\n\t}\n\n\tcommand := exec.Command(this.executable, this.arguments...)\n\tcommand.Dir = this.directory\n\tvar rawOutput []byte\n\trawOutput, this.Error = command.CombinedOutput()\n\tthis.Output = string(rawOutput)\n\treturn this\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nconst goconveyDSLImport = \"github.com/smartystreets/goconvey/convey \" // note the trailing space: we don't want to target packages nested in the /convey package.\nconst gopathProblem = \"Please run goconvey from within $GOPATH/src (also, symlinks might be problematic). Output and Error: \"\n\nvar coverageStatementRE = regexp.MustCompile(`(?m)coverage: \\d+\\.\\d% of statements(.*)$|^panic: test timed out after `)\n"
  },
  {
    "path": "web/server/system/shell_integration_test.go",
    "content": "package system\n\nimport (\n\t\"log\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"testing\"\n)\n\nfunc TestShellIntegration(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"Skipping potentially long-running integration test...\")\n\t\treturn\n\t}\n\n\tlog.SetFlags(log.LstdFlags | log.Lshortfile | log.Lmicroseconds)\n\n\t_, filename, _, _ := runtime.Caller(0)\n\tdirectory := filepath.Join(filepath.Dir(filename), \"..\", \"watch\", \"integration_testing\", \"sub\")\n\tpackageName := \"github.com/smartystreets/goconvey/web/server/watch/integration_testing/sub\"\n\n\tshell := NewShell(\"go\", \"\", true, \"5s\")\n\toutput, err := shell.GoTest(directory, packageName, []string{}, []string{\"-short\"})\n\n\tif !strings.Contains(output, \"PASS\\n\") || !strings.Contains(output, \"ok\") {\n\t\tt.Errorf(\"Expected output that resembed tests passing but got this instead: [%s]\", output)\n\t}\n\tif err != nil {\n\t\tt.Error(\"Test run resulted in the following error:\", err)\n\t}\n}\n"
  },
  {
    "path": "web/server/system/shell_test.go",
    "content": "package system\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n)\n\nfunc TestShellCommandComposition(t *testing.T) {\n\tvar (\n\t\tbuildFailed      = Command{Error: errors.New(\"BUILD FAILURE!\")}\n\t\tbuildSucceeded   = Command{Output: \"ok\"}\n\t\tgoConvey         = Command{Output: \"[fmt github.com/smartystreets/goconvey/convey net/http net/http/httptest path runtime strconv strings testing time]\"}\n\t\tnoGoConvey       = Command{Output: \"[fmt net/http net/http/httptest path runtime strconv strings testing time]\"}\n\t\terrorGoConvey    = Command{Output: \"This is a wacky error\", Error: errors.New(\"This happens when running goconvey outside your $GOPATH (symlinked code).\")}\n\t\tnoCoveragePassed = Command{Output: \"PASS\\nok  \tgithub.com/smartystreets/goconvey/examples\t0.012s\"}\n\t\tcoveragePassed   = Command{Output: \"PASS\\ncoverage: 100.0% of statements\\nok  \tgithub.com/smartystreets/goconvey/examples\t0.012s\"}\n\t\tcoverageFailed   = Command{\n\t\t\tError: errors.New(\"Tests bombed!\"),\n\t\t\tOutput: \"--- FAIL: TestIntegerManipulation (0.00 seconds)\\nFAIL\\ncoverage: 100.0% of statements\\nexit status 1\\nFAIL\tgithub.com/smartystreets/goconvey/examples\t0.013s\",\n\t\t}\n\t\tcoverageFailedTimeout = Command{\n\t\t\tError:  errors.New(\"Tests bombed!\"),\n\t\t\tOutput: \"=== RUN SomeTest\\n--- PASS: SomeTest (0.00 seconds)\\n=== RUN TimeoutTest\\npanic: test timed out after 5s\\n\\ngoroutine 27 [running]:\\n\",\n\t\t}\n\t)\n\n\tconst (\n\t\tyesCoverage = true\n\t\tnoCoverage  = false\n\t)\n\n\tConvey(\"When attempting to run tests with coverage flags\", t, func() {\n\t\tConvey(\"And coverage is not wanted\", func() {\n\t\t\tresult := runWithCoverage(goConvey, noCoverage, \"\", \"\", \"\", \"\", \"-tags=\", nil)\n\n\t\t\tConvey(\"Then no action should be taken\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested usees the GoConvey DSL (`convey` package)\", func() {\n\t\t\tresult := runWithCoverage(goConvey, yesCoverage, \"reportsPath\", \"/directory\", \"go\", \"5s\", \"-tags=bob\", []string{\"-arg1\", \"-arg2\"})\n\n\t\t\tConvey(\"The returned command should be well formed (and include the -json flag)\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"test\", \"-v\", \"-coverprofile=reportsPath\", \"-tags=bob\", \"-covermode=set\", \"-timeout=5s\", \"-convey-json\", \"-arg1\", \"-arg2\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested does NOT use the GoConvey DSL\", func() {\n\t\t\tresult := runWithCoverage(noGoConvey, yesCoverage, \"reportsPath\", \"/directory\", \"go\", \"1s\", \"-tags=bob\", []string{\"-arg1\", \"-arg2\"})\n\n\t\t\tConvey(\"The returned command should be well formed (and NOT include the -json flag)\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"test\", \"-v\", \"-coverprofile=reportsPath\", \"-tags=bob\", \"-covermode=set\", \"-timeout=1s\", \"-arg1\", \"-arg2\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested has been symlinked outside the $GOAPTH\", func() {\n\t\t\tresult := runWithCoverage(errorGoConvey, yesCoverage, \"reportsPath\", \"/directory\", \"go\", \"1s\", \"-tags=\", nil)\n\n\t\t\tConvey(\"The returned command should be empty\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested specifies an alternate covermode\", func() {\n\t\t\tresult := runWithCoverage(noGoConvey, yesCoverage, \"reportsPath\", \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-covermode=atomic\"})\n\n\t\t\tConvey(\"The returned command should allow the alternate value\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"test\", \"-v\", \"-coverprofile=reportsPath\", \"-tags=\", \"-timeout=1s\", \"-covermode=atomic\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested specifies an alternate timeout\", func() {\n\t\t\tresult := runWithCoverage(noGoConvey, yesCoverage, \"reportsPath\", \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-timeout=5s\"})\n\n\t\t\tConvey(\"The returned command should allow the alternate value\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"test\", \"-v\", \"-coverprofile=reportsPath\", \"-tags=\", \"-covermode=set\", \"-timeout=5s\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t})\n\n\tConvey(\"When attempting to run tests without the coverage flags\", t, func() {\n\t\tConvey(\"And tests already succeeded with coverage\", func() {\n\t\t\tresult := runWithoutCoverage(coveragePassed, goConvey, \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-arg1\", \"-arg2\"})\n\n\t\t\tConvey(\"Then no action should be taken\", func() {\n\t\t\t\tSo(result, ShouldResemble, coveragePassed)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And tests already failed (legitimately) with coverage\", func() {\n\t\t\tresult := runWithoutCoverage(coverageFailed, goConvey, \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-arg1\", \"-arg2\"})\n\n\t\t\tConvey(\"Then no action should be taken\", func() {\n\t\t\t\tSo(result, ShouldResemble, coverageFailed)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And tests already failed (timeout) with coverage\", func() {\n\t\t\tresult := runWithoutCoverage(coverageFailedTimeout, goConvey, \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-arg1\", \"-arg2\"})\n\n\t\t\tConvey(\"Then no action should be taken\", func() {\n\t\t\t\tSo(result, ShouldResemble, coverageFailedTimeout)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the goconvey dsl command failed (probably because of symlinks)\", func() {\n\t\t\tresult := runWithoutCoverage(Command{}, errorGoConvey, \"\", \"\", \"\", \"-tags=\", nil)\n\n\t\t\tConvey(\"Then no action should be taken\", func() {\n\t\t\t\tSo(result, ShouldResemble, errorGoConvey)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested uses the GoConvey DSL (`convey` package)\", func() {\n\t\t\tresult := runWithoutCoverage(buildSucceeded, goConvey, \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-arg1\", \"-arg2\"})\n\n\t\t\tConvey(\"Then the returned command should be well formed (and include the -json flag)\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"test\", \"-v\", \"-tags=\", \"-timeout=1s\", \"-convey-json\", \"-arg1\", \"-arg2\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested does NOT use the GoConvey DSL\", func() {\n\t\t\tresult := runWithoutCoverage(noCoveragePassed, noGoConvey, \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-arg1\", \"-arg2\"})\n\n\t\t\tConvey(\"Then the returned command should be well formed (and NOT include the -json flag)\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"test\", \"-v\", \"-tags=\", \"-timeout=1s\", \"-arg1\", \"-arg2\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And the package being tested specifies an alternate timeout\", func() {\n\t\t\tresult := runWithoutCoverage(buildSucceeded, noGoConvey, \"/directory\", \"go\", \"1s\", \"-tags=\", []string{\"-timeout=5s\"})\n\n\t\t\tConvey(\"The returned command should allow the alternate value\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"test\", \"-v\", \"-tags=\", \"-timeout=5s\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t})\n\n\tConvey(\"When generating coverage reports\", t, func() {\n\t\tConvey(\"And the previous command failed for any reason (compilation or failed tests)\", func() {\n\t\t\tresult := generateReports(buildFailed, yesCoverage, \"/directory\", \"go\", \"reportData\", \"reportHTML\")\n\n\t\t\tConvey(\"Then no action should be taken\", func() {\n\t\t\t\tSo(result, ShouldResemble, buildFailed)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And coverage reports are unwanted\", func() {\n\t\t\tresult := generateReports(noCoveragePassed, noCoverage, \"/directory\", \"go\", \"reportData\", \"reportHTML\")\n\n\t\t\tConvey(\"Then no action should beg taken\", func() {\n\t\t\t\tSo(result, ShouldResemble, noCoveragePassed)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"And tests passed and coverage reports are wanted\", func() {\n\t\t\tresult := generateReports(coveragePassed, yesCoverage, \"/directory\", \"go\", \"reportData\", \"reportHTML\")\n\n\t\t\tConvey(\"Then the resulting command should be well-formed\", func() {\n\t\t\t\tSo(result, ShouldResemble, Command{\n\t\t\t\t\tdirectory:  \"/directory\",\n\t\t\t\t\texecutable: \"go\",\n\t\t\t\t\targuments:  []string{\"tool\", \"cover\", \"-html=reportData\", \"-o\", \"reportHTML\"},\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "web/server/system/system.goconvey",
    "content": "#ignore\n-timeout=1s\n-short"
  },
  {
    "path": "web/server/watch/functional_core.go",
    "content": "package watch\n\nimport (\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n)\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc Categorize(items chan *FileSystemItem, root string, watchSuffixes []string) (folders, profiles, goFiles []*FileSystemItem) {\n\tfor item := range items {\n\t\tif item.IsFolder && !isHidden(item.Name) && !foundInHiddenDirectory(item, root) {\n\t\t\tfolders = append(folders, item)\n\n\t\t} else if strings.HasSuffix(item.Name, \".goconvey\") && len(item.Name) > len(\".goconvey\") {\n\t\t\tprofiles = append(profiles, item)\n\n\t\t} else {\n\t\t\tfor _, suffix := range watchSuffixes {\n\t\t\t\tif strings.HasSuffix(item.Name, suffix) && !isHidden(item.Name) && !foundInHiddenDirectory(item, root) {\n\t\t\t\t\tgoFiles = append(goFiles, item)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn folders, profiles, goFiles\n}\n\nfunc foundInHiddenDirectory(item *FileSystemItem, root string) bool {\n\tpath := item.Path\n\tif len(path) > len(root) {\n\t\tpath = path[len(root):]\n\t}\n\n\tfor _, folder := range strings.Split(filepath.Dir(path), slash) {\n\t\tif isHidden(folder) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\nfunc isHidden(path string) bool {\n\treturn strings.HasPrefix(path, \".\") || strings.HasPrefix(path, \"_\") || strings.HasPrefix(path, \"flymake_\")\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc ParseProfile(profile string) (isDisabled bool, tags, arguments []string) {\n\tlines := strings.Split(profile, \"\\n\")\n\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\n\t\tif len(arguments) == 0 && strings.ToLower(line) == \"ignore\" {\n\t\t\treturn true, nil, nil\n\n\t\t} else if strings.HasPrefix(line, \"-tags=\") {\n\t\t\ttags = append(tags, strings.Split(strings.SplitN(line, \"=\", 2)[1], \",\")...)\n\t\t\tcontinue\n\n\t\t} else if len(line) == 0 {\n\t\t\tcontinue\n\n\t\t} else if strings.HasPrefix(line, \"#\") {\n\t\t\tcontinue\n\n\t\t} else if strings.HasPrefix(line, \"//\") {\n\t\t\tcontinue\n\n\t\t} else if line == \"-cover\" || strings.HasPrefix(line, \"-coverprofile\") {\n\t\t\tcontinue\n\n\t\t} else if line == \"-v\" {\n\t\t\tcontinue // Verbose mode is always enabled so there is no need to record it here.\n\n\t\t}\n\n\t\targuments = append(arguments, line)\n\t}\n\n\treturn false, tags, arguments\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc CreateFolders(items []*FileSystemItem) messaging.Folders {\n\tfolders := map[string]*messaging.Folder{}\n\n\tfor _, item := range items {\n\t\tfolders[item.Path] = &messaging.Folder{Path: item.Path, Root: item.Root}\n\t}\n\n\treturn folders\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc LimitDepth(folders messaging.Folders, depth int) {\n\tif depth < 0 {\n\t\treturn\n\t}\n\n\tfor path, folder := range folders {\n\t\tif strings.Count(path[len(folder.Root):], slash) > depth {\n\t\t\tdelete(folders, path)\n\t\t}\n\t}\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc AttachProfiles(folders messaging.Folders, items []*FileSystemItem) {\n\tvar rootProfile *FileSystemItem\n\tfor _, profile := range items {\n\t\tpath := path.Dir(profile.Path)\n\t\tif path == profile.Root && profile.Name == \"main.goconvey\" {\n\t\t\trootProfile = profile\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// put root profile to all folders\n\tif rootProfile != nil {\n\t\tfor _, folder := range folders {\n\t\t\tfolder.Disabled, folder.BuildTags, folder.TestArguments = rootProfile.ProfileDisabled, rootProfile.ProfileTags, rootProfile.ProfileArguments\n\t\t}\n\t}\n\n\t// use folder profile to replace root profile\n\tfor _, profile := range items {\n\t\tif folder, exists := folders[filepath.Dir(profile.Path)]; exists {\n\t\t\tfolder.Disabled, folder.BuildTags, folder.TestArguments = profile.ProfileDisabled, profile.ProfileTags, profile.ProfileArguments\n\t\t}\n\t}\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc MarkIgnored(folders messaging.Folders, ignored map[string]struct{}) {\n\tif len(ignored) == 0 {\n\t\treturn\n\t}\n\n\tfor _, folder := range folders {\n\t\tfor ignored := range ignored {\n\t\t\tif !folder.Ignored && strings.HasSuffix(folder.Path, ignored) {\n\t\t\t\tfolder.Ignored = true\n\t\t\t}\n\t\t}\n\t}\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc ActiveFolders(folders messaging.Folders) messaging.Folders {\n\tvar active messaging.Folders = map[string]*messaging.Folder{}\n\n\tfor path, folder := range folders {\n\t\tif folder.Ignored || folder.Disabled {\n\t\t\tcontinue\n\t\t}\n\n\t\tactive[path] = folder\n\t}\n\treturn active\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc Sum(folders messaging.Folders, items []*FileSystemItem) int64 {\n\tvar sum int64\n\tfor _, item := range items {\n\t\tif _, exists := folders[filepath.Dir(item.Path)]; exists {\n\t\t\tsum += item.Size + item.Modified\n\t\t}\n\t}\n\treturn sum\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nconst slash = string(os.PathSeparator)\n\n///////////////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "web/server/watch/functional_core_test.go",
    "content": "package watch\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n)\n\nfunc TestCategorize(t *testing.T) {\n\tfileSystem := []*FileSystemItem{\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello\",\n\t\t\tName:     \"hello\",\n\t\t\tIsFolder: true,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/1/hello/world.txt\",\n\t\t\tName:     \"world.txt\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/1/2/3/4/5/hello/world.go\",\n\t\t\tName:     \"world.go\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/world.go\",\n\t\t\tName:     \"world.go\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/hello/world.tmpl\",\n\t\t\tName:     \"world.tmpl\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/hello/.world.go\",\n\t\t\tName:     \".world.go\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/hello/_world.go\",\n\t\t\tName:     \".world.go\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/hello/flymake_world.go\",\n\t\t\tName:     \"flymake_world.go\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/.hello\",\n\t\t\tName:     \".hello\",\n\t\t\tIsFolder: true,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/.hello/hello\",\n\t\t\tName:     \"hello\",\n\t\t\tIsFolder: true,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/.hello/world.go\",\n\t\t\tName:     \"world.go\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/hello/hi.goconvey\",\n\t\t\tName:     \"hi.goconvey\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/hello2/.goconvey\",\n\t\t\tName:     \".goconvey\",\n\t\t\tIsFolder: false,\n\t\t},\n\t\t{\n\t\t\tRoot:     \"/.hello\",\n\t\t\tPath:     \"/.hello/_hello\",\n\t\t\tName:     \"_hello\",\n\t\t\tIsFolder: true,\n\t\t},\n\t}\n\n\tConvey(\"A stream of file system items should be categorized correctly\", t, func() {\n\t\titems := make(chan *FileSystemItem)\n\n\t\tgo func() {\n\t\t\tfor _, item := range fileSystem {\n\t\t\t\titems <- item\n\t\t\t}\n\t\t\tclose(items)\n\t\t}()\n\n\t\tfolders, profiles, goFiles := Categorize(items, \"/.hello\", []string{\".go\"})\n\t\tSo(folders, ShouldResemble, fileSystem[:1])\n\t\tSo(profiles, ShouldResemble, fileSystem[11:12])\n\t\tSo(goFiles, ShouldResemble, fileSystem[2:4])\n\t})\n\n\tConvey(\"A stream of file system items should be categorized correctly\", t, func() {\n\t\titems := make(chan *FileSystemItem)\n\n\t\tgo func() {\n\t\t\tfor _, item := range fileSystem {\n\t\t\t\titems <- item\n\t\t\t}\n\t\t\tclose(items)\n\t\t}()\n\n\t\tfolders, profiles, goFiles := Categorize(items, \"/.hello\", []string{\".go\", \".tmpl\"})\n\t\tSo(folders, ShouldResemble, fileSystem[:1])\n\t\tSo(profiles, ShouldResemble, fileSystem[11:12])\n\t\tSo(goFiles, ShouldResemble, fileSystem[2:5])\n\t})\n}\n\nfunc TestParseProfile(t *testing.T) {\n\tvar parseProfileTestCases = []struct {\n\t\tSKIP           bool\n\t\tdescription    string\n\t\tinput          string\n\t\tresultIgnored  bool\n\t\tresultTestTags []string\n\t\tresultTestArgs []string\n\t}{\n\t\t{\n\t\t\tSKIP:          false,\n\t\t\tdescription:   \"Blank profile\",\n\t\t\tinput:         \"\",\n\t\t\tresultIgnored: false,\n\t\t},\n\t\t{\n\t\t\tSKIP:          false,\n\t\t\tdescription:   \"All lines are blank or whitespace\",\n\t\t\tinput:         \"\\n \\n \\t\\t\\t  \\n \\n \\n\",\n\t\t\tresultIgnored: false,\n\t\t},\n\t\t{\n\t\t\tSKIP:          false,\n\t\t\tdescription:   \"Ignored package, no args included\",\n\t\t\tinput:         \"IGNORE\\n-timeout=4s\",\n\t\t\tresultIgnored: true,\n\t\t},\n\t\t{\n\t\t\tSKIP:           false,\n\t\t\tdescription:    \"Ignore directive is commented, all args are included\",\n\t\t\tinput:          \"#IGNORE\\n-timeout=4s\\n-parallel=5\",\n\t\t\tresultIgnored:  false,\n\t\t\tresultTestArgs: []string{\"-timeout=4s\", \"-parallel=5\"},\n\t\t},\n\t\t{\n\t\t\tSKIP:           false,\n\t\t\tdescription:    \"No ignore directive, all args are included\",\n\t\t\tinput:          \"-run=TestBlah\\n-timeout=42s\",\n\t\t\tresultIgnored:  false,\n\t\t\tresultTestArgs: []string{\"-run=TestBlah\", \"-timeout=42s\"},\n\t\t},\n\t\t{\n\t\t\tSKIP:           false,\n\t\t\tdescription:    \"Some args are commented, therefore ignored\",\n\t\t\tinput:          \"-run=TestBlah\\n #-timeout=42s\",\n\t\t\tresultIgnored:  false,\n\t\t\tresultTestArgs: []string{\"-run=TestBlah\"},\n\t\t},\n\t\t{\n\t\t\tSKIP:          false,\n\t\t\tdescription:   \"All args are commented, therefore all are ignored\",\n\t\t\tinput:         \"#-run=TestBlah\\n//-timeout=42\",\n\t\t\tresultIgnored: false,\n\t\t},\n\t\t{\n\t\t\tSKIP:          false,\n\t\t\tdescription:   \"We ignore certain flags like -v and -cover and -coverprofile because they are specified by the shell\",\n\t\t\tinput:         \"-v\\n-cover\\n-coverprofile=blah.out\",\n\t\t\tresultIgnored: false,\n\t\t},\n\t\t{\n\t\t\tSKIP:           false,\n\t\t\tdescription:    \"We allow certain coverage flags like -coverpkg and -covermode\",\n\t\t\tinput:          \"-coverpkg=blah\\n-covermode=atomic\",\n\t\t\tresultIgnored:  false,\n\t\t\tresultTestArgs: []string{\"-coverpkg=blah\", \"-covermode=atomic\"},\n\t\t},\n\t\t{\n\t\t\tSKIP:           false,\n\t\t\tdescription:    \"We parse out -tags particularly\",\n\t\t\tinput:          \"-coverpkg=blah\\n-covermode=atomic\\n-tags=foo,bar\",\n\t\t\tresultIgnored:  false,\n\t\t\tresultTestTags: []string{\"foo\", \"bar\"},\n\t\t\tresultTestArgs: []string{\"-coverpkg=blah\", \"-covermode=atomic\"},\n\t\t},\n\t}\n\n\tfor i, test := range parseProfileTestCases {\n\t\tif test.SKIP {\n\t\t\tSkipConvey(fmt.Sprintf(\"Profile Parsing, Test Case #%d: %s (SKIPPED)\", i, test.description), t, nil)\n\t\t} else {\n\t\t\tConvey(fmt.Sprintf(\"Profile Parsing, Test Case #%d: %s\", i, test.description), t, func() {\n\t\t\t\tignored, testTags, testArgs := ParseProfile(test.input)\n\n\t\t\t\tSo(ignored, ShouldEqual, test.resultIgnored)\n\t\t\t\tSo(testTags, ShouldResemble, test.resultTestTags)\n\t\t\t\tSo(testArgs, ShouldResemble, test.resultTestArgs)\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc TestCreateFolders(t *testing.T) {\n\tConvey(\"File system items that represent folders should be converted to folder structs correctly\", t, func() {\n\t\texpected := map[string]*messaging.Folder{\n\t\t\t\"/root/1\":     {Path: \"/root/1\", Root: \"/root\"},\n\t\t\t\"/root/1/2\":   {Path: \"/root/1/2\", Root: \"/root\"},\n\t\t\t\"/root/1/2/3\": {Path: \"/root/1/2/3\", Root: \"/root\"},\n\t\t}\n\n\t\tinputs := []*FileSystemItem{\n\t\t\t{Path: \"/root/1\", Root: \"/root\", IsFolder: true},\n\t\t\t{Path: \"/root/1/2\", Root: \"/root\", IsFolder: true},\n\t\t\t{Path: \"/root/1/2/3\", Root: \"/root\", IsFolder: true},\n\t\t}\n\n\t\tactual := CreateFolders(inputs)\n\n\t\tfor key, actualValue := range actual {\n\t\t\tSo(actualValue, ShouldResemble, expected[key])\n\t\t}\n\t})\n}\n\nfunc TestLimitDepth(t *testing.T) {\n\tConvey(\"Subject: Limiting folders based on relative depth from a common root\", t, func() {\n\n\t\tfolders := map[string]*messaging.Folder{\n\t\t\t\"/root/1\": {\n\t\t\t\tPath: \"/root/1\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2\": {\n\t\t\t\tPath: \"/root/1/2\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2/3\": {\n\t\t\t\tPath: \"/root/1/2/3\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t}\n\n\t\tConvey(\"When there is no depth limit\", func() {\n\t\t\tLimitDepth(folders, -1)\n\n\t\t\tConvey(\"No folders should be excluded\", func() {\n\t\t\t\tSo(len(folders), ShouldEqual, 3)\n\t\t\t})\n\t\t})\n\n\t\tConvey(\"When there is a limit\", func() {\n\t\t\tLimitDepth(folders, 2)\n\n\t\t\tConvey(\"The deepest folder (in this case) should be excluded\", func() {\n\t\t\t\tSo(len(folders), ShouldEqual, 2)\n\t\t\t\t_, exists := folders[\"/root/1/2/3\"]\n\t\t\t\tSo(exists, ShouldBeFalse)\n\t\t\t})\n\t\t})\n\t})\n}\n\nfunc TestAttachProfiles(t *testing.T) {\n\tConvey(\"Subject: Attaching profile information to a folder\", t, func() {\n\t\tfolders := map[string]*messaging.Folder{\n\t\t\t\"/root/1\": {\n\t\t\t\tPath: \"/root/1\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2\": {\n\t\t\t\tPath: \"/root/1/2\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2/3\": {\n\t\t\t\tPath: \"/root/1/2/3\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t}\n\n\t\tprofiles := []*FileSystemItem{\n\t\t\t{\n\t\t\t\tPath:             \"/root/too-shallow.goconvey\",\n\t\t\t\tProfileDisabled:  true,\n\t\t\t\tProfileArguments: []string{\"1\", \"2\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tPath:             \"/root/1/2/hi.goconvey\",\n\t\t\t\tProfileDisabled:  true,\n\t\t\t\tProfileArguments: []string{\"1\", \"2\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tPath:             \"/root/1/2/3/4/does-not-exist\",\n\t\t\t\tProfileDisabled:  true,\n\t\t\t\tProfileArguments: []string{\"1\", \"2\", \"3\", \"4\"},\n\t\t\t},\n\t\t}\n\n\t\tConvey(\"Profiles that match folders should be merged with those folders\", func() {\n\t\t\tAttachProfiles(folders, profiles)\n\n\t\t\tConvey(\"No profiles matched the first folder, so no assignments should occur\", func() {\n\t\t\t\tSo(folders[\"/root/1\"].Disabled, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root/1\"].TestArguments, ShouldBeEmpty)\n\t\t\t})\n\n\t\t\tConvey(\"The second folder should match the first profile\", func() {\n\t\t\t\tSo(folders[\"/root/1/2\"].Disabled, ShouldBeTrue)\n\t\t\t\tSo(folders[\"/root/1/2\"].TestArguments, ShouldResemble, []string{\"1\", \"2\"})\n\t\t\t})\n\n\t\t\tConvey(\"No profiles match the third folder so no assignments should occur\", func() {\n\t\t\t\tSo(folders[\"/root/1/2/3\"].Disabled, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root/1/2/3\"].TestArguments, ShouldBeEmpty)\n\t\t\t})\n\t\t})\n\t})\n}\n\nfunc TestAttachMainProfiles(t *testing.T) {\n\tConvey(\"Subject: Attaching profile information to a folder\", t, func() {\n\t\tfolders := map[string]*messaging.Folder{\n\t\t\t\"/root\": {\n\t\t\t\tPath: \"/root\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1\": {\n\t\t\t\tPath: \"/root/1\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2\": {\n\t\t\t\tPath: \"/root/1/2\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t}\n\n\t\tprofiles := []*FileSystemItem{\n\t\t\t{\n\t\t\t\tRoot:             \"/root\",\n\t\t\t\tName:             \"main.goconvey\",\n\t\t\t\tPath:             \"/root/main.goconvey\",\n\t\t\t\tProfileDisabled:  false,\n\t\t\t\tProfileArguments: []string{\"1\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tRoot:             \"/root\",\n\t\t\t\tName:             \"hi.goconvey\",\n\t\t\t\tPath:             \"/root/1/2/hi.goconvey\",\n\t\t\t\tProfileDisabled:  false,\n\t\t\t\tProfileArguments: []string{\"1\", \"2\"},\n\t\t\t},\n\t\t}\n\n\t\tConvey(\"Main profiles at root should be merged with all folders without folder profile\", func() {\n\t\t\tAttachProfiles(folders, profiles)\n\n\t\t\tConvey(\"Main profiles matched the all other folder\", func() {\n\t\t\t\tSo(folders[\"/root\"].Disabled, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root\"].TestArguments, ShouldResemble, []string{\"1\"})\n\n\t\t\t\tSo(folders[\"/root/1\"].Disabled, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root/1\"].TestArguments, ShouldResemble, []string{\"1\"})\n\t\t\t})\n\n\t\t\tConvey(\"The second folder should match the first profile\", func() {\n\t\t\t\tSo(folders[\"/root/1/2\"].Disabled, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root/1/2\"].TestArguments, ShouldResemble, []string{\"1\", \"2\"})\n\t\t\t})\n\t\t})\n\t})\n}\n\nfunc TestMarkIgnored(t *testing.T) {\n\tConvey(\"Subject: folders that have been ignored should be marked as such\", t, func() {\n\t\tfolders := map[string]*messaging.Folder{\n\t\t\t\"/root/1\": {\n\t\t\t\tPath: \"/root/1\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2\": {\n\t\t\t\tPath: \"/root/1/2\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2/3\": {\n\t\t\t\tPath: \"/root/1/2/3\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t}\n\n\t\tConvey(\"When there are no ignored folders\", func() {\n\t\t\tignored := map[string]struct{}{}\n\t\t\tMarkIgnored(folders, ignored)\n\n\t\t\tConvey(\"No folders should be marked as ignored\", func() {\n\t\t\t\tSo(folders[\"/root/1\"].Ignored, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root/1/2\"].Ignored, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root/1/2/3\"].Ignored, ShouldBeFalse)\n\t\t\t})\n\t\t})\n\t\tConvey(\"When there are ignored folders\", func() {\n\t\t\tignored := map[string]struct{}{\"1/2\": {}}\n\t\t\tMarkIgnored(folders, ignored)\n\n\t\t\tConvey(\"The ignored folders should be marked as ignored\", func() {\n\t\t\t\tSo(folders[\"/root/1\"].Ignored, ShouldBeFalse)\n\t\t\t\tSo(folders[\"/root/1/2\"].Ignored, ShouldBeTrue)\n\t\t\t\tSo(folders[\"/root/1/2/3\"].Ignored, ShouldBeFalse)\n\t\t\t})\n\t\t})\n\t})\n}\n\nfunc TestActiveFolders(t *testing.T) {\n\tConvey(\"Subject: Folders that are not ignored or disabled are active\", t, func() {\n\t\tfolders := map[string]*messaging.Folder{\n\t\t\t\"/root/1\": {\n\t\t\t\tPath:    \"/root/1\",\n\t\t\t\tRoot:    \"/root\",\n\t\t\t\tIgnored: true,\n\t\t\t},\n\t\t\t\"/root/1/2\": {\n\t\t\t\tPath: \"/root/1/2\",\n\t\t\t\tRoot: \"/root\",\n\t\t\t},\n\t\t\t\"/root/1/2/3\": {\n\t\t\t\tPath:     \"/root/1/2/3\",\n\t\t\t\tRoot:     \"/root\",\n\t\t\t\tDisabled: true,\n\t\t\t},\n\t\t}\n\n\t\tactive := ActiveFolders(folders)\n\n\t\tSo(len(active), ShouldEqual, 1)\n\t\tSo(active[\"/root/1/2\"], ShouldResemble, folders[\"/root/1/2\"])\n\t})\n}\n\nfunc TestSum(t *testing.T) {\n\tConvey(\"Subject: file system items within specified directories should be counted and summed\", t, func() {\n\t\tfolders := map[string]*messaging.Folder{\n\t\t\t\"/root/1\": {Path: \"/root/1\", Root: \"/root\", Ignored: true},\n\t\t}\n\t\titems := []*FileSystemItem{\n\t\t\t{Size: 1, Modified: 3, Path: \"/root/1/hi.go\"},\n\t\t\t{Size: 7, Modified: 13, Path: \"/root/1/bye.go\"},\n\t\t\t{Size: 33, Modified: 45, Path: \"/root/1/2/salutations.go\"}, // not counted\n\t\t}\n\n\t\tSo(Sum(folders, items), ShouldEqual, 1+3+7+13)\n\t})\n}\n"
  },
  {
    "path": "web/server/watch/imperative_shell.go",
    "content": "package watch\n\nimport (\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n///////////////////////////////////////////////////////////////////////////////\n\ntype FileSystemItem struct {\n\tRoot     string\n\tPath     string\n\tName     string\n\tSize     int64\n\tModified int64\n\tIsFolder bool\n\n\tProfileDisabled  bool\n\tProfileTags      []string\n\tProfileArguments []string\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc YieldFileSystemItems(root string, excludedDirs []string) chan *FileSystemItem {\n\titems := make(chan *FileSystemItem)\n\n\tgo func() {\n\t\tfilepath.Walk(root, func(path string, info os.FileInfo, err error) error {\n\t\t\tif err != nil {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tif info.IsDir() && strings.HasPrefix(info.Name(), \".\") {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tbasePath := filepath.Base(path)\n\t\t\tfor _, item := range excludedDirs {\n\t\t\t\tif item == basePath && info.IsDir() && item != \"\" && basePath != \"\" {\n\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titems <- &FileSystemItem{\n\t\t\t\tRoot:     root,\n\t\t\t\tPath:     path,\n\t\t\t\tName:     info.Name(),\n\t\t\t\tSize:     info.Size(),\n\t\t\t\tModified: info.ModTime().Unix(),\n\t\t\t\tIsFolder: info.IsDir(),\n\t\t\t}\n\n\t\t\treturn nil\n\t\t})\n\t\tclose(items)\n\t}()\n\n\treturn items\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n// ReadContents reads files wholesale. This function is only called on files\n// that end in '.goconvey'. These files should be very small, probably not\n// ever more than a few hundred bytes. The ignored errors are ok because in\n// the event of an IO error all that need be returned is an empty string.\nfunc ReadContents(path string) string {\n\tfile, err := os.Open(path)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tdefer file.Close()\n\treader := io.LimitReader(file, 1024*4)\n\tcontent, _ := ioutil.ReadAll(reader)\n\treturn string(content)\n}\n\n///////////////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "web/server/watch/integration.go",
    "content": "package watch\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n)\n\ntype Watcher struct {\n\tnap             time.Duration\n\trootFolder      string\n\tfolderDepth     int\n\tignoredFolders  map[string]struct{}\n\tfileSystemState int64\n\tpaused          bool\n\tstopped         bool\n\twatchSuffixes   []string\n\texcludedDirs    []string\n\n\tinput  chan messaging.WatcherCommand\n\toutput chan messaging.Folders\n\n\tlock sync.RWMutex\n}\n\nfunc NewWatcher(rootFolder string, folderDepth int, nap time.Duration,\n\tinput chan messaging.WatcherCommand, output chan messaging.Folders, watchSuffixes string, excludedDirs []string) *Watcher {\n\n\treturn &Watcher{\n\t\tnap:           nap,\n\t\trootFolder:    rootFolder,\n\t\tfolderDepth:   folderDepth,\n\t\tinput:         input,\n\t\toutput:        output,\n\t\twatchSuffixes: strings.Split(watchSuffixes, \",\"),\n\t\texcludedDirs:  excludedDirs,\n\n\t\tignoredFolders: make(map[string]struct{}),\n\t}\n}\n\nfunc (w *Watcher) Listen() {\n\tfor {\n\t\tif !w.paused {\n\t\t\tw.scan()\n\t\t}\n\t\tselect {\n\t\tcase command := <-w.input:\n\t\t\tif stopped := w.respond(command); stopped {\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-time.After(w.nap):\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// respond handles the command and returns whether the watcher is permanently stopped\nfunc (w *Watcher) respond(command messaging.WatcherCommand) bool {\n\tswitch command.Instruction {\n\n\tcase messaging.WatcherAdjustRoot:\n\t\tlog.Println(\"Adjusting root...\")\n\t\tw.rootFolder = command.Details\n\t\tw.execute()\n\n\tcase messaging.WatcherIgnore:\n\t\tlog.Println(\"Ignoring specified folders\")\n\t\tw.ignore(command.Details)\n\t\t// Prevent a filesystem change due to the number of active folders changing\n\t\t_, checksum := w.gather()\n\t\tw.set(checksum)\n\n\tcase messaging.WatcherReinstate:\n\t\tlog.Println(\"Reinstating specified folders\")\n\t\tw.reinstate(command.Details)\n\t\t// Prevent a filesystem change due to the number of active folders changing\n\t\t_, checksum := w.gather()\n\t\tw.set(checksum)\n\n\tcase messaging.WatcherPause:\n\t\tlog.Println(\"Pausing watcher...\")\n\t\tw.paused = true\n\n\tcase messaging.WatcherResume:\n\t\tlog.Println(\"Resuming watcher...\")\n\t\tw.paused = false\n\n\tcase messaging.WatcherExecute:\n\t\tlog.Println(\"Gathering folders for immediate execution...\")\n\t\tw.execute()\n\n\tcase messaging.WatcherStop:\n\t\tlog.Println(\"Stopping the watcher...\")\n\t\tclose(w.output)\n\t\tw.stopped = true\n\t\treturn true\n\n\tdefault:\n\t\tlog.Println(\"Unrecognized command from server:\", command.Instruction)\n\t}\n\treturn false\n}\n\nfunc (w *Watcher) execute() {\n\tfolders, _ := w.gather()\n\tw.sendToExecutor(folders)\n}\n\nfunc (w *Watcher) scan() {\n\tfolders, checksum := w.gather()\n\n\tif checksum == w.fileSystemState {\n\t\treturn\n\t}\n\n\tlog.Println(\"File system state modified, publishing current folders...\", w.fileSystemState, checksum)\n\n\tdefer w.set(checksum)\n\tw.sendToExecutor(folders)\n}\n\nfunc (w *Watcher) gather() (folders messaging.Folders, checksum int64) {\n\titems := YieldFileSystemItems(w.rootFolder, w.excludedDirs)\n\tfolderItems, profileItems, goFileItems := Categorize(items, w.rootFolder, w.watchSuffixes)\n\n\tfor _, item := range profileItems {\n\t\t// TODO: don't even bother if the item's size is over a few hundred bytes...\n\t\tcontents := ReadContents(item.Path)\n\t\titem.ProfileDisabled, item.ProfileTags, item.ProfileArguments = ParseProfile(contents)\n\t}\n\n\tfolders = CreateFolders(folderItems)\n\tLimitDepth(folders, w.folderDepth)\n\tAttachProfiles(folders, profileItems)\n\tw.protectedRead(func() { MarkIgnored(folders, w.ignoredFolders) })\n\n\tactive := ActiveFolders(folders)\n\tchecksum = int64(len(active))\n\tchecksum += Sum(active, profileItems)\n\tchecksum += Sum(active, goFileItems)\n\n\treturn folders, checksum\n}\n\nfunc (w *Watcher) set(state int64) {\n\tw.fileSystemState = state\n}\n\nfunc (w *Watcher) sendToExecutor(folders messaging.Folders) {\n\tw.output <- folders\n}\n\nfunc (w *Watcher) ignore(paths string) {\n\tw.protectedWrite(func() {\n\t\tfor _, folder := range strings.Split(paths, string(os.PathListSeparator)) {\n\t\t\tw.ignoredFolders[folder] = struct{}{}\n\t\t\tlog.Println(\"Currently ignored folders:\", w.ignoredFolders)\n\t\t}\n\t})\n}\nfunc (w *Watcher) reinstate(paths string) {\n\tw.protectedWrite(func() {\n\t\tfor _, folder := range strings.Split(paths, string(os.PathListSeparator)) {\n\t\t\tdelete(w.ignoredFolders, folder)\n\t\t}\n\t})\n}\nfunc (w *Watcher) protectedWrite(protected func()) {\n\tw.lock.Lock()\n\tdefer w.lock.Unlock()\n\tprotected()\n}\nfunc (w *Watcher) protectedRead(protected func()) {\n\tw.lock.RLock()\n\tdefer w.lock.RUnlock()\n\tprotected()\n}\n"
  },
  {
    "path": "web/server/watch/integration_test.go",
    "content": "package watch\n\nimport (\n\t\"bytes\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\t\"github.com/smartystreets/goconvey/web/server/messaging\"\n)\n\nfunc TestWatcher(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"Skipping potentially long-running integration test...\")\n\t\treturn\n\t}\n\n\tlog.SetFlags(log.LstdFlags | log.Lshortfile | log.Lmicroseconds)\n\toutBuf := new(bytes.Buffer)\n\tlog.SetOutput(outBuf)\n\tdefer func() { t.Log(outBuf.String()) }()\n\n\t_, filename, _, _ := runtime.Caller(0)\n\toriginalRoot := filepath.Join(filepath.Dir(filename), \"integration_testing\")\n\ttemporary, err := os.MkdirTemp(\"\", \"goconvey\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\troot := filepath.Join(temporary, \"integration_testing\")\n\tsub := filepath.Join(root, \"sub\")\n\n\terr = CopyDir(originalRoot, root)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() {\n\t\terr = os.RemoveAll(temporary)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t}()\n\n\tvar ( // commands\n\t\tpause  = messaging.WatcherCommand{Instruction: messaging.WatcherPause}\n\t\tresume = messaging.WatcherCommand{Instruction: messaging.WatcherResume}\n\n\t\tignore    = messaging.WatcherCommand{Instruction: messaging.WatcherIgnore, Details: sub}\n\t\treinstate = messaging.WatcherCommand{Instruction: messaging.WatcherReinstate, Details: sub}\n\n\t\tadjustToSub  = messaging.WatcherCommand{Instruction: messaging.WatcherAdjustRoot, Details: sub}\n\t\tadjustToRoot = messaging.WatcherCommand{Instruction: messaging.WatcherAdjustRoot, Details: root}\n\n\t\texecute = messaging.WatcherCommand{Instruction: messaging.WatcherExecute}\n\n\t\tbogus = messaging.WatcherCommand{Instruction: 42}\n\n\t\tstop = messaging.WatcherCommand{Instruction: messaging.WatcherStop}\n\t)\n\n\tConvey(\"Subject: Watcher operations\", t, func() {\n\t\tinput := make(chan messaging.WatcherCommand)\n\t\toutput := make(chan messaging.Folders)\n\t\tvar excludedDirs []string\n\t\twatcher := NewWatcher(root, -1, time.Millisecond, input, output, \".go\", excludedDirs)\n\n\t\tgo watcher.Listen()\n\n\t\tConvey(\"Initial scan results\", func() {\n\t\t\tgo func() {\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(results, ShouldHaveLength, 1)\n\t\t})\n\n\t\tConvey(\"Manual execution produces additional results\", func() {\n\t\t\tgo func() {\n\t\t\t\tinput <- execute\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(results, ShouldHaveLength, 2)\n\t\t\tSo(results[0], ShouldHaveLength, 2)\n\t\t\tSo(results[1], ShouldHaveLength, 2)\n\t\t})\n\n\t\tConvey(\"Ignore and Reinstate commands are not reflected in the scan results\", func() {\n\t\t\tgo func() {\n\t\t\t\tinput <- ignore\n\t\t\t\tinput <- reinstate\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(results, ShouldHaveLength, 1)\n\t\t\tSo(results[0][sub].Ignored, ShouldBeFalse) // initial\n\t\t})\n\n\t\tConvey(\"Adjusting the root changes the number of folders in the scanned results\", func() {\n\t\t\tgo func() {\n\t\t\t\tinput <- adjustToSub\n\t\t\t\tinput <- adjustToRoot\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(results, ShouldHaveLength, 5)\n\t\t\tSo(results[0], ShouldHaveLength, 2) // initial\n\t\t\tSo(results[1], ShouldHaveLength, 1) // root moved to sub\n\t\t\tSo(results[2], ShouldHaveLength, 1) // additional scan happens\n\t\t\tSo(results[3], ShouldHaveLength, 2) // root moved back to original location\n\t\t\tSo(results[4], ShouldHaveLength, 2) // additional scan happens\n\t\t})\n\n\t\tConvey(\"A bogus command does not cause any additional scanning beyond the initial scan\", func() {\n\t\t\tgo func() {\n\t\t\t\tinput <- bogus\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(len(results), ShouldEqual, 1) // initial scan\n\t\t})\n\n\t\tConvey(\"Scanning occurs as a result of a file system update\", func() {\n\t\t\tgo func() {\n\t\t\t\ttime.Sleep(time.Second)\n\t\t\t\texec.Command(\"touch\", filepath.Join(root, \"main.go\")).Run()\n\t\t\t\ttime.Sleep(time.Second)\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(results, ShouldHaveLength, 2)\n\t\t})\n\n\t\tConvey(\"Scanning does not occur as a result of resuming after a pause\", func() {\n\t\t\tgo func() {\n\t\t\t\tinput <- pause\n\t\t\t\tinput <- resume\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(results, ShouldHaveLength, 1)\n\t\t})\n\n\t\tConvey(\"Scanning should not occur when the watcher is paused\", func() {\n\t\t\tgo func() {\n\t\t\t\tinput <- pause\n\t\t\t\tfor x := 0; x < 2; x++ {\n\t\t\t\t\ttime.Sleep(time.Millisecond * 250)\n\t\t\t\t\terr := exec.Command(\"touch\", filepath.Join(root, \"main.go\")).Run()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tt.Error(err)\n\t\t\t\t\t}\n\t\t\t\t\ttime.Sleep(time.Millisecond * 250)\n\t\t\t\t}\n\t\t\t\tinput <- resume\n\t\t\t\tinput <- stop\n\t\t\t}()\n\n\t\t\tvar results []messaging.Folders\n\t\t\tfor result := range output {\n\t\t\t\tresults = append(results, result)\n\t\t\t}\n\n\t\t\tSo(results, ShouldHaveLength, 2)\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "web/server/watch/integration_testing/doc_test.go",
    "content": "package main\n"
  },
  {
    "path": "web/server/watch/integration_testing/main.go",
    "content": "// This file's only purpose is to provide a realistic\n// environment from which to run integration tests\n// against the Watcher.\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"Hello, World!\")\n}\n"
  },
  {
    "path": "web/server/watch/integration_testing/sub/.gitignore",
    "content": "github.com-smartystreets-goconvey-web-server-watch-integration_testing-sub.html\ngithub.com-smartystreets-goconvey-web-server-watch-integration_testing-sub.txt\n"
  },
  {
    "path": "web/server/watch/integration_testing/sub/stuff.go",
    "content": "// This file's only purpose is to provide a realistic\n// environment from which to run integration tests\n// against the Watcher.\npackage sub\n"
  },
  {
    "path": "web/server/watch/integration_testing/sub/stuff_test.go",
    "content": "// This file's only purpose is to provide a realistic\n// environment from which to run integration tests\n// against the Watcher.\npackage sub\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestStuff(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\n\tfmt.Println()\n}\n"
  },
  {
    "path": "web/server/watch/integration_testing/sub/sub.goconvey",
    "content": "IGNORE\n-short\n-run=TestStuff\n\n// This file's only purpose is to provide a realistic\n// environment from which to run integration tests\n// against the Watcher.\n"
  },
  {
    "path": "web/server/watch/util_test.go",
    "content": "// Credits: https://gist.github.com/jaybill/2876519\npackage watch\n\nimport \"os\"\nimport \"io\"\nimport \"io/ioutil\"\nimport \"log\"\n\n// Copies original source to destination destination.\nfunc CopyFile(source string, destination string) (err error) {\n\toriginalFile, err := os.Open(source)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer originalFile.Close()\n\tdestinationFile, err := os.Create(destination)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer destinationFile.Close()\n\t_, err = io.Copy(destinationFile, originalFile)\n\tif err == nil {\n\t\tinfo, err := os.Stat(source)\n\t\tif err != nil {\n\t\t\terr = os.Chmod(destination, info.Mode())\n\t\t}\n\n\t}\n\n\treturn\n}\n\n// Recursively copies a directory tree, attempting to preserve permissions.\n// Source directory must exist, destination directory must *not* exist.\nfunc CopyDir(source string, destination string) (err error) {\n\n\t// get properties of source dir\n\tsourceFile, err := os.Stat(source)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !sourceFile.IsDir() {\n\t\treturn &CustomError{Message: \"Source is not a directory\"}\n\t}\n\n\t// ensure destination dir does not already exist\n\n\t_, err = os.Open(destination)\n\tif !os.IsNotExist(err) {\n\t\treturn &CustomError{Message: \"Destination already exists\"}\n\t}\n\n\t// create destination dir\n\n\terr = os.MkdirAll(destination, sourceFile.Mode())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tentries, err := ioutil.ReadDir(source)\n\n\tfor _, entry := range entries {\n\n\t\tsourcePath := source + \"/\" + entry.Name()\n\t\tdestinationPath := destination + \"/\" + entry.Name()\n\t\tif entry.IsDir() {\n\t\t\terr = CopyDir(sourcePath, destinationPath)\n\t\t\tif err != nil {\n\t\t\t\tlog.Println(err)\n\t\t\t}\n\t\t} else {\n\t\t\t// perform copy\n\t\t\terr = CopyFile(sourcePath, destinationPath)\n\t\t\tif err != nil {\n\t\t\t\tlog.Println(err)\n\t\t\t}\n\t\t}\n\n\t}\n\treturn\n}\n\n// A struct for returning custom error messages\ntype CustomError struct {\n\tMessage string\n}\n\n// Returns the error message defined in Message as a string\nfunc (this *CustomError) Error() string {\n\treturn this.Message\n}\n"
  },
  {
    "path": "web/server/watch/watch.goconvey",
    "content": "#ignore\n-timeout=1s\n-short"
  }
]