diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..fff8965d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# .editorconfig for Elixir projects +# https://git.io/elixir-editorconfig + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{md, markdown, eex}] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/.gitignore b/.gitignore index 3090f0b9..478f2bbb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,26 @@ -/_build -/cover -/deps +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). *.ez -.elixir_ls -.tool-versions + +# Ignore package tarball (built via "mix hex.build"). +paper_trail-*.tar + +# Temporary files for e.g. tests +/tmp diff --git a/CHANGELOG.md b/CHANGELOG.md index 993e9083..5b12d733 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +# Changelog + ### v0.8.3 - September 10th, 2019: - PaperTrail.delete now accepts Ecto.Changeset diff --git a/LICENSE.md b/LICENSE.md index 69efc907..c086cc23 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,5 +1,5 @@ The MIT License (MIT) -Copyright (c) 2016 Izel Nakri +Copyright (c) 2016-present Izel Nakri Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 93605655..d2199f6c 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,104 @@ [![Hex Version](http://img.shields.io/hexpm/v/paper_trail.svg?style=flat)](https://hex.pm/packages/paper_trail) [![Hex docs](http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat)](https://hexdocs.pm/paper_trail/PaperTrail.html) +[![Total Download](https://img.shields.io/hexpm/dt/paper_trail.svg)](https://hex.pm/packages/paper_trail) +[![License](https://img.shields.io/hexpm/l/paper_trail.svg)](https://github.com/izelnakri/paper_trail/blob/master/LICENSE) +[![Last Updated](https://img.shields.io/github/last-commit/izelnakri/paper_trail.svg)](https://github.com/izelnakri/paper_trail/commits/master) + +# Paper Trail + +Track and record all the changes in your database. Revert back to anytime in history. # How does it work? PaperTrail lets you record every change in your database in a separate database table called ```versions```. Library generates a new version record with associated data every time you run ```PaperTrail.insert/2```, ```PaperTrail.update/2``` or ```PaperTrail.delete/2``` functions. Simply these functions wrap your Repo insert, update or destroy actions in a database transaction, so if your database action fails you won't get a new version. -PaperTrail is assailed with hundreds of test assertions for each release. Data integrity is an important aim of this project, please refer to the strict_mode if you want to ensure data correctness and integrity of your versions. For simpler use cases the default mode of PaperTrail should suffice. +PaperTrail is assailed with hundreds of test assertions for each release. Data integrity is an important aim of this project, please refer to the `strict_mode` if you want to ensure data correctness and integrity of your versions. For simpler use cases the default mode of PaperTrail should suffice. ## Example ```elixir - changeset = Post.changeset(%Post{}, %{ - title: "Word on the street is Elixir got its own database versioning library", - content: "You should try it now!" - }) - - PaperTrail.insert(changeset) - # => on success: - # {:ok, - # %{model: %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, - # title: "Word on the street is Elixir got its own database versioning library", - # content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 21:42:38]}, - # version: %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "insert", id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # item_changes: %{title: "Word on the street is Elixir got its own database versioning library", - # content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 21:42:38]}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil}}} - - # => on error(it matches Repo.insert/2): - # {:error, Ecto.Changeset, - # valid?: false>, %{}} - - post = Repo.get!(Post, 1) - edit_changeset = Post.changeset(post, %{ - title: "Elixir matures fast", - content: "Future is already here, Elixir is the next step!" - }) - - PaperTrail.update(edit_changeset) - # => on success: - # {:ok, - # %{model: %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, - # title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", - # id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 22:00:59]}, - # version: %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "update", id: 2, inserted_at: ~N[2016-09-15 22:00:59], - # item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!"}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil - # meta: nil}}} - - # => on error(it matches Repo.update/2): - # {:error, Ecto.Changeset, - # valid?: false>, %{}} - - PaperTrail.get_version(post) - # %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "update", id: 2, inserted_at: ~N[2016-09-15 22:00:59], - # item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!"}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil}}} - - updated_post = Repo.get!(Post, 1) - - PaperTrail.delete(updated_post) - # => on success: - # {:ok, - # %{model: %Post{__meta__: #Ecto.Schema.Metadata<:deleted, "posts">, - # title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", - # id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 22:00:59]}, - # version: %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], - # item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", - # id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 22:00:59]}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil}}} - - Repo.aggregate(Post, :count, :id) # => 0 - PaperTrail.Version.count() # => 3 - # same as Repo.aggregate(PaperTrail.Version, :count, :id) - - PaperTrail.Version.last() # returns the last version in the db by inserted_at - # %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], - # item_changes: %{"title" => "Elixir matures fast", content: "Future is already here, Elixir is the next step!", "id" => 1, - # "inserted_at" => "2016-09-15T21:42:38", - # "updated_at" => "2016-09-15T22:00:59"}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} +changeset = Post.changeset(%Post{}, %{ + title: "Word on the street is Elixir got its own database versioning library", + content: "You should try it now!" +}) + +PaperTrail.insert(changeset) +# => on success: +# {:ok, +# %{model: %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, +# title: "Word on the street is Elixir got its own database versioning library", +# content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 21:42:38]}, +# version: %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "insert", id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# item_changes: %{title: "Word on the street is Elixir got its own database versioning library", +# content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 21:42:38]}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil}}} + +# => on error(it matches Repo.insert/2): +# {:error, Ecto.Changeset, +# valid?: false>, %{}} + +post = Repo.get!(Post, 1) +edit_changeset = Post.changeset(post, %{ + title: "Elixir matures fast", + content: "Future is already here, Elixir is the next step!" +}) + +PaperTrail.update(edit_changeset) +# => on success: +# {:ok, +# %{model: %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, +# title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", +# id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 22:00:59]}, +# version: %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "update", id: 2, inserted_at: ~N[2016-09-15 22:00:59], +# item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!"}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil +# meta: nil}}} + +# => on error(it matches Repo.update/2): +# {:error, Ecto.Changeset, +# valid?: false>, %{}} + +PaperTrail.get_version(post) +# %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "update", id: 2, inserted_at: ~N[2016-09-15 22:00:59], +# item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!"}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil}}} + +updated_post = Repo.get!(Post, 1) + +PaperTrail.delete(updated_post) +# => on success: +# {:ok, +# %{model: %Post{__meta__: #Ecto.Schema.Metadata<:deleted, "posts">, +# title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", +# id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 22:00:59]}, +# version: %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], +# item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", +# id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 22:00:59]}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil}}} + +Repo.aggregate(Post, :count, :id) # => 0 +PaperTrail.Version.count() # => 3 +# same as Repo.aggregate(PaperTrail.Version, :count, :id) + +PaperTrail.Version.last() # returns the last version in the db by inserted_at +# %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], +# item_changes: %{"title" => "Elixir matures fast", content: "Future is already here, Elixir is the next step!", "id" => 1, +# "inserted_at" => "2016-09-15T21:42:38", +# "updated_at" => "2016-09-15T22:00:59"}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} ``` PaperTrail is inspired by the ruby gem ```paper_trail```. However, unlike the ```paper_trail``` gem this library actually results in less data duplication, faster and more explicit programming model to version your record changes. @@ -100,36 +107,36 @@ The library source code is minimal and well tested. It is suggested to read the ## Installation - 1. Add paper_trail to your list of dependencies in `mix.exs`: +1. Add paper_trail to your list of dependencies in `mix.exs`: - ```elixir + ```elixir def deps do [{:paper_trail, "~> 0.9.0"}] end - ``` + ``` - 2. configure paper_trail to use your application repo in `config/config.exs`: +2. Configure paper_trail to use your application repo in `config/config.exs`: - ```elixir - config :paper_trail, repo: YourApplicationName.Repo - # if you don't specify this PaperTrail will assume your repo name is Repo - ``` + ```elixir + config :paper_trail, repo: YourApplicationName.Repo + # if you don't specify this PaperTrail will assume your repo name is Repo + ``` - 3. install and compile your dependency: +3. Install and compile your dependency: - ```mix deps.get && mix compile``` + ```mix deps.get && mix compile``` - 4. run this command to generate the migration: +4. Run this command to generate the migration: - ```mix papertrail.install``` + ```mix papertrail.install``` - You might want to edit the types for `:item_id` or `:originator_id` if you're - using UUID or other types for your primary keys before you execute - `mix ecto.migrate`. + You might want to edit the types for `:item_id` or `:originator_id` if you're + using UUID or other types for your primary keys before you execute + `mix ecto.migrate`. - 5. run the migration: +5. Run the migration: - ```mix ecto.migrate``` + ```mix ecto.migrate``` Your application is now ready to collect some history! @@ -163,6 +170,7 @@ config :paper_trail, item_type: Ecto.UUID, Remember to edit the types accordingly in the generated migration. ### Version origin references: + PaperTrail records have a string field called ```origin```. ```PaperTrail.insert/2```, ```PaperTrail.update/2```, ```PaperTrail.delete/2``` functions accept a second argument to describe the origin of this version: ```elixir PaperTrail.update(changeset, origin: "migration") @@ -177,12 +185,13 @@ PaperTrail.insert(new_user_changeset, origin: "facebook_registration") ``` ### Version originator relationships + You can specify setter/originator relationship to paper_trail versions with ```originator``` assignment. This feature is only possible by specifying `:originator` keyword list for your application configuration: ```elixir - # in your config/config.exs - config :paper_trail, originator: [name: :user, model: YourApp.User] - # For most applications originator should be the user since models can be updated/created/deleted by several users. +# In your config/config.exs +config :paper_trail, originator: [name: :user, model: YourApp.User] +# For most applications originator should be the user since models can be updated/created/deleted by several users. ``` Note: You will need to recompile your deps after you have added the config for originator. @@ -203,17 +212,18 @@ PaperTrail.delete(edit_changeset, user: user) Also make sure you have the foreign-key constraint in the database and in your version migration file. - ### Storing version meta data You might want to add some meta data that doesn't belong to ``originator`` and ``origin`` fields. Such data could be stored in one object named ```meta``` in paper_trail versions. Meta field could be passed as the second optional parameter to PaperTrail.insert/2, PaperTrail.update/2, PaperTrail.delete/2 functions: ```elixir company = Company.changeset(%Company{}, %{name: "Acme Inc."}) |> PaperTrail.insert(meta: %{slug: "acme-llc"}) -# you can also combine this with an origin: + +# You can also combine this with an origin: edited_company = Company.changeset(company, %{name: "Acme LLC"}) |> PaperTrail.update(origin: "documentation", meta: %{slug: "acme-llc"}) -# or even with an originator: + +# Or even with an originator: user = create_user() deleted_company = Company.changeset(edited_company, %{}) |> PaperTrail.delete(origin: "worker:github", originator: user, meta: %{slug: "acme-llc", important: true}) @@ -223,14 +233,14 @@ deleted_company = Company.changeset(edited_company, %{}) This is a feature more suitable for larger applications. Models can keep their version references via foreign key constraints. Therefore it would be impossible to delete the first and current version of a model if the model exists in the database, it also makes querying easier and the whole design more relational database/SQL friendly. In order to enable strict mode: ```elixir -# in your config/config.exs +# In your config/config.exs config :paper_trail, strict_mode: true ``` Strict mode expects tracked models to have foreign-key reference to their first_version and current_version. These columns must be named ```first_version_id```, and ```current_version_id``` in their respective model tables. A tracked model example with a migration file: ```elixir -# in the migration file: priv/repo/migrations/create_company.exs +# In the migration file: priv/repo/migrations/create_company.exs defmodule Repo.Migrations.CreateCompany do def change do create table(:companies) do @@ -249,7 +259,7 @@ defmodule Repo.Migrations.CreateCompany do end end -# in the model definition: +# In the model definition: defmodule Company do use Ecto.Schema @@ -308,78 +318,78 @@ PaperTrail also supports ```PaperTrail.insert!```, ```PaperTrail.update!```, ``` Bang functions assume the operation will always be successful, otherwise functions will raise ```Ecto.InvalidChangesetError``` just like ```Repo.insert!```, ```Repo.update!``` and ```Repo.delete!```: ```elixir - changeset = Post.changeset(%Post{}, %{ - title: "Word on the street is Elixir got its own database versioning library", - content: "You should try it now!" - }) - - inserted_post = PaperTrail.insert!(changeset) - # => on success: - # %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, - # title: "Word on the street is Elixir got its own database versioning library", - # content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 21:42:38] - # } - # - # => on error raises: Ecto.InvalidChangesetError !! - - inserted_post_version = PaperTrail.get_version(inserted_post) - # %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "insert", id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # item_changes: %{title: "Word on the street is Elixir got its own database versioning library", - # content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 21:42:38]}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} - - edit_changeset = Post.changeset(inserted_post, %{ - title: "Elixir matures fast", - content: "Future is already here, Elixir is the next step!" - }) - - updated_post = PaperTrail.update!(edit_changeset) - # => on success: - # %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, - # title: "Elixir matures fast", content: "Future is already here, you deserve to be awesome!", - # id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 22:00:59]} - # - # => on error raises: Ecto.InvalidChangesetError !! - - updated_post_version = PaperTrail.get_version(updated_post) - # %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "update", id: 2, inserted_at: ~N[2016-09-15 22:00:59], - # item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!"}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil - # meta: nil} - - PaperTrail.delete!(updated_post) - # => on success: - # %Post{__meta__: #Ecto.Schema.Metadata<:deleted, "posts">, - # title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", - # id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 22:00:59]} - # - # => on error raises: Ecto.InvalidChangesetError !! - - PaperTrail.get_version(updated_post) - # %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], - # item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", - # id: 1, inserted_at: ~N[2016-09-15 21:42:38], - # updated_at: ~N[2016-09-15 22:00:59]}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} - - Repo.aggregate(Post, :count, :id) # => 0 - PaperTrail.Version.count() # => 3 - # same as Repo.aggregate(PaperTrail.Version, :count, :id) - - PaperTrail.Version.last() # returns the last version in the db by inserted_at - # %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, - # event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], - # item_changes: %{"title" => "Elixir matures fast", content: "Future is already here, Elixir is the next step!", "id" => 1, - # "inserted_at" => "2016-09-15T21:42:38", - # "updated_at" => "2016-09-15T22:00:59"}, - # item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} +changeset = Post.changeset(%Post{}, %{ + title: "Word on the street is Elixir got its own database versioning library", + content: "You should try it now!" +}) + +inserted_post = PaperTrail.insert!(changeset) +# => on success: +# %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, +# title: "Word on the street is Elixir got its own database versioning library", +# content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 21:42:38] +# } +# +# => on error raises: Ecto.InvalidChangesetError !! + +inserted_post_version = PaperTrail.get_version(inserted_post) +# %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "insert", id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# item_changes: %{title: "Word on the street is Elixir got its own database versioning library", +# content: "You should try it now!", id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 21:42:38]}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} + +edit_changeset = Post.changeset(inserted_post, %{ + title: "Elixir matures fast", + content: "Future is already here, Elixir is the next step!" +}) + +updated_post = PaperTrail.update!(edit_changeset) +# => on success: +# %Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, +# title: "Elixir matures fast", content: "Future is already here, you deserve to be awesome!", +# id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 22:00:59]} +# +# => on error raises: Ecto.InvalidChangesetError !! + +updated_post_version = PaperTrail.get_version(updated_post) +# %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "update", id: 2, inserted_at: ~N[2016-09-15 22:00:59], +# item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!"}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil +# meta: nil} + +PaperTrail.delete!(updated_post) +# => on success: +# %Post{__meta__: #Ecto.Schema.Metadata<:deleted, "posts">, +# title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", +# id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 22:00:59]} +# +# => on error raises: Ecto.InvalidChangesetError !! + +PaperTrail.get_version(updated_post) +# %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], +# item_changes: %{title: "Elixir matures fast", content: "Future is already here, Elixir is the next step!", +# id: 1, inserted_at: ~N[2016-09-15 21:42:38], +# updated_at: ~N[2016-09-15 22:00:59]}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} + +Repo.aggregate(Post, :count, :id) # => 0 +PaperTrail.Version.count() # => 3 +# same as Repo.aggregate(PaperTrail.Version, :count, :id) + +PaperTrail.Version.last() # returns the last version in the db by inserted_at +# %PaperTrail.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, +# event: "delete", id: 3, inserted_at: ~N[2016-09-15 22:22:12], +# item_changes: %{"title" => "Elixir matures fast", content: "Future is already here, Elixir is the next step!", "id" => 1, +# "inserted_at" => "2016-09-15T21:42:38", +# "updated_at" => "2016-09-15T22:00:59"}, +# item_id: 1, item_type: "Post", originator_id: nil, originator: nil, meta: nil} ``` ## Working with multi tenancy @@ -422,7 +432,7 @@ specified by the `:prefix` value (`tenant_id`). Note that the `User`'s changeset it's sent with the `:prefix`, so PaperTrail **will take care of the storage of the generated `Version` entry in the desired schema/database**. Make sure -to add this prefix to your changeset before the execution of the PaperTrail function if you want to do versioning on a seperate schema. +to add this prefix to your changeset before the execution of the PaperTrail function if you want to do versioning on a separate schema. PaperTrail can also get versions of records or models from different schemas/databases as well by using the `:prefix` option. Example: @@ -439,16 +449,16 @@ PaperTrail.get_versions(User, id, [prefix: tenant]) PaperTrail can be configured to use `utc_datetime` or `utc_datetime_usec` for Version timestamps. ```elixir -# in your config/config.exs - +# In your config/config.exs config :paper_trail, timestamps_type: :utc_datetime ``` Note: You will need to recompile your deps after you have added the config for timestamps. ## Suggestions + - PaperTrail.Version(s) order matter, -- don't delete your paper_trail versions, instead you can merge them +- Don't delete your paper_trail versions, instead you can merge them - If you have a question or a problem, do not hesitate to create an issue or submit a pull request ## Contributing @@ -483,3 +493,7 @@ Many thanks to: Additional thanks to: - [Ruby paper_trail gem](https://github.com/airblade/paper_trail) - Initial inspiration of this project. - [Ecto](https://github.com/elixir-ecto/ecto) - For the great API. + +## License + +This source code is licensed under the MIT license. Copyright (c) 2016-present Izel Nakri. diff --git a/doc/.build b/doc/.build deleted file mode 100644 index 7305e7c8..00000000 --- a/doc/.build +++ /dev/null @@ -1,19 +0,0 @@ -404.html -Mix.Tasks.Papertrail.Install.html -PaperTrail.Multi.html -PaperTrail.RepoClient.html -PaperTrail.Serializer.html -PaperTrail.Version.html -PaperTrail.VersionQueries.html -PaperTrail.html -api-reference.html -dist/app-60a0c9f10e9e52eae31f.js -dist/elixir-9f91ebe876dc01d67920.css -dist/html/fonts/icomoon.eot -dist/html/fonts/icomoon.svg -dist/html/fonts/icomoon.ttf -dist/html/fonts/icomoon.woff -dist/search_items-67e6a940fe.js -dist/sidebar_items-1590d474d6.js -index.html -search.html diff --git a/doc/404.html b/doc/404.html deleted file mode 100644 index fc3079ae..00000000 --- a/doc/404.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - 404 — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

Page not found

- -

Sorry, but the page you were trying to get to, does not exist. You -may want to try searching this site using the sidebar - - or using our API Reference page - -to find what you were looking for.

- -
-
-
-
- - - diff --git a/doc/Mix.Tasks.Papertrail.Install.html b/doc/Mix.Tasks.Papertrail.Install.html deleted file mode 100644 index 57e637b9..00000000 --- a/doc/Mix.Tasks.Papertrail.Install.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - - - - - mix papertrail.install — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

-mix papertrail.install (paper_trail v0.10.1) - -

- - - -
-

- - - Link to this section - - Summary -

- -
-

- Functions -

-
-
- run(args) - -
- -

Callback implementation for Mix.Task.run/1.

- -
- -
- -
- - -
-

- - - Link to this section - -Functions -

-
-
- -
- - - Link to this function - -

run(args)

- - -
- -
- -

Callback implementation for Mix.Task.run/1.

-
-
- -
-
- - -
-
-
-
- - - diff --git a/doc/PaperTrail.Multi.html b/doc/PaperTrail.Multi.html deleted file mode 100644 index 37939fa8..00000000 --- a/doc/PaperTrail.Multi.html +++ /dev/null @@ -1,646 +0,0 @@ - - - - - - - - - - PaperTrail.Multi — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

-PaperTrail.Multi (paper_trail v0.10.1) - -

- - - -
-

- - - Link to this section - - Summary -

- -
-

- Functions -

- - -
- - -
- - - - - - - - - -
-
- new() - -
- - - -
- - - - -
- - - - -
- - -
- -
- - -
-

- - - Link to this section - -Functions -

-
-
- -
- - - Link to this function - -

add_prefix(schema, prefix)

- - -
- -
- -

See PaperTrail.Serializer.add_prefix/2.

-
-
-
- -
- - - Link to this function - -

append(lhs, rhs)

- - -
- -
- -

See Ecto.Multi.append/2.

-
-
-
- -
- - - Link to this function - -

commit(multi)

- - -
- -
- - -
-
-
- - - -
- - - Link to this function - -

delete(multi, struct, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil])

- - -
- -
- - -
-
-
- -
- - - Link to this function - -

error(multi, name, value)

- - -
- -
- -

See Ecto.Multi.error/3.

-
-
-
- -
- - - Link to this function - -

get_item_type(data)

- - -
- -
- -

See PaperTrail.Serializer.get_item_type/1.

-
-
-
- -
- - - Link to this function - -

get_model_id(model)

- - -
- -
- -

See PaperTrail.Serializer.get_model_id/1.

-
-
-
- -
- - - Link to this function - -

get_sequence_id(table_name)

- - -
- -
- -

See PaperTrail.Serializer.get_sequence_id/1.

-
-
-
- - - -
- - - Link to this function - -

insert(multi, changeset, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil, model_key: :model, version_key: :version, ecto_options: []])

- - -
- -
- - -
-
-
- -
- - - Link to this function - -

make_version_struct(version, model, options)

- - -
- -
- -

See PaperTrail.Serializer.make_version_struct/3.

-
-
-
- -
- - - Link to this function - -

merge(multi, merge)

- - -
- -
- -

See Ecto.Multi.merge/2.

-
-
-
- -
- - - Link to this function - -

merge(multi, mod, fun, args)

- - -
- -
- -

See Ecto.Multi.merge/4.

-
-
-
- - - -
- -

See Ecto.Multi.new/0.

-
-
-
- -
- - - Link to this function - -

prepend(lhs, rhs)

- - -
- -
- -

See Ecto.Multi.prepend/2.

-
-
-
- -
- - - Link to this function - -

run(multi, name, run)

- - -
- -
- -

See Ecto.Multi.run/3.

-
-
-
- -
- - - Link to this function - -

run(multi, name, mod, fun, args)

- - -
- -
- -

See Ecto.Multi.run/5.

-
-
-
- -
- - - Link to this function - -

serialize(data)

- - -
- -
- -

See PaperTrail.Serializer.serialize/1.

-
-
-
- -
- - - Link to this function - -

to_list(multi)

- - -
- -
- -

See Ecto.Multi.to_list/1.

-
-
-
- - - -
- - - Link to this function - -

update(multi, changeset, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil])

- - -
- -
- - -
-
- -
-
- - -
-
-
-
- - - diff --git a/doc/PaperTrail.RepoClient.html b/doc/PaperTrail.RepoClient.html deleted file mode 100644 index 0349469a..00000000 --- a/doc/PaperTrail.RepoClient.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - PaperTrail.RepoClient — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

-PaperTrail.RepoClient (paper_trail v0.10.1) - -

- - - -
-

- - - Link to this section - - Summary -

- -
-

- Functions -

-
-
- originator() - -
- -
-
-
- repo() - -
- -

Gets the configured repo module or defaults to Repo if none configured

- -
-
- - -
- -
- -
- - -
-

- - - Link to this section - -Functions -

-
-
- -
- - - Link to this function - -

originator()

- - -
- -
- - -
-
-
- - - -
- -

Gets the configured repo module or defaults to Repo if none configured

-
-
-
- -
- - - Link to this function - -

strict_mode()

- - -
- -
- - -
-
- -
-
- - -
-
-
-
- - - diff --git a/doc/PaperTrail.Serializer.html b/doc/PaperTrail.Serializer.html deleted file mode 100644 index f2c1e6bb..00000000 --- a/doc/PaperTrail.Serializer.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - - - - - PaperTrail.Serializer — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

-PaperTrail.Serializer (paper_trail v0.10.1) - -

- - -
-

Serialization functions to create a version struct

-
- - -
-

- - - Link to this section - - Summary -

- -
-

- Types -

-
-
- model() - -
- -
-
-
- options() - -
- -
-
- - -
- -
- -
-

- Functions -

-
- - -

Adds a prefix to the Ecto schema

- -
-
- - -

Returns the model type, which is the last module name

- -
-
- - -

Returns the model primary id

- -
-
- - -

Returns the last primary key value of a table

- -
-
- - -

Creates a version struct for a model and a specific changeset action

- -
-
- - -

Shows DB representation of an Ecto model, filters relationships and virtual attributes from an Ecto.Changeset or %ModelStruct{}

- -
-
- - -

Dumps changes using Ecto fields

- -
- -
- -
- - -
-

- - - Link to this section - -Types -

-
-
- -
- - - Link to this type - -

model()

- - -
- -
- -

Specs

-
- -
model() :: struct() | Ecto.Changeset.t()
- -
- - -
-
-
- -
- - - Link to this type - -

options()

- - -
- -
- -

Specs

-
- -
options() :: Keyword.t()
- -
- - -
-
-
- -
- - - Link to this type - -

primary_key()

- - -
- -
- -

Specs

-
- -
primary_key() :: integer() | String.t()
- -
- - -
-
- -
-
- -
-

- - - Link to this section - -Functions -

-
-
- -
- - - Link to this function - -

add_prefix(schema, prefix)

- - -
- -
- -

Specs

-
- -
add_prefix(Ecto.Schema.schema(), nil | String.t()) :: Ecto.Schema.schema()
- -
- -

Adds a prefix to the Ecto schema

-
-
-
- -
- - - Link to this function - -

get_item_type(arg1)

- - -
- -
- -

Specs

-
- -
get_item_type(model()) :: String.t()
- -
- -

Returns the model type, which is the last module name

-
-
-
- -
- - - Link to this function - -

get_model_id(model)

- - -
- -
- -

Specs

-
- -
get_model_id(model()) :: primary_key()
- -
- -

Returns the model primary id

-
-
-
- -
- - - Link to this function - -

get_sequence_id(table_name)

- - -
- -
- -

Specs

-
- -
get_sequence_id(model() | String.t()) :: primary_key()
- -
- -

Returns the last primary key value of a table

-
-
-
- -
- - - Link to this function - -

make_version_struct(map, model, options)

- - -
- -
- -

Specs

-
- -
make_version_struct(map(), model(), options()) :: PaperTrail.Version.t()
- -
- -

Creates a version struct for a model and a specific changeset action

-
-
-
- -
- - - Link to this function - -

serialize(model)

- - -
- -
- -

Specs

-
- -
serialize(nil | Ecto.Changeset.t() | struct()) :: nil | map()
- -
- -

Shows DB representation of an Ecto model, filters relationships and virtual attributes from an Ecto.Changeset or %ModelStruct{}

-
-
-
- -
- - - Link to this function - -

serialize_changes(changeset)

- - -
- -
- -

Specs

-
- -
serialize_changes(Ecto.Changeset.t()) :: map()
- -
- -

Dumps changes using Ecto fields

-
-
- -
-
- - -
-
-
-
- - - diff --git a/doc/PaperTrail.Version.html b/doc/PaperTrail.Version.html deleted file mode 100644 index 48ea3c94..00000000 --- a/doc/PaperTrail.Version.html +++ /dev/null @@ -1,392 +0,0 @@ - - - - - - - - - - PaperTrail.Version — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

-PaperTrail.Version (paper_trail v0.10.1) - -

- - - -
-

- - - Link to this section - - Summary -

- -
-

- Types -

-
-
- t() - -
- -
- -
- -
-

- Functions -

- -
-
- count() - -
- -

Returns the count of all version records in the database

- -
-
- - -
-
-
- first() - -
- -

Returns the first version record in the database by :inserted_at

- -
-
- - -
-
-
- last() - -
- -

Returns the last version record in the database by :inserted_at

- -
-
- - -
- -
- -
- - -
-

- - - Link to this section - -Types -

-
-
- - - -
- -

Specs

-
- -
t() :: %PaperTrail.Version{
-  __meta__: term(),
-  event: term(),
-  id: term(),
-  inserted_at: term(),
-  item_changes: term(),
-  item_id: term(),
-  item_type: term(),
-  meta: term(),
-  origin: term(),
-  originator_id: term()
-}
- -
- - -
-
- -
-
- -
-

- - - Link to this section - -Functions -

-
-
- - - -
- - - Link to this function - -

changeset(model, params \\ :empty)

- - -
- -
- - -
-
-
- - - -
- -

Returns the count of all version records in the database

-
-
-
- -
- - - Link to this function - -

count(options)

- - -
- -
- - -
-
-
- - - -
- -

Returns the first version record in the database by :inserted_at

-
-
-
- -
- - - Link to this function - -

first(options)

- - -
- -
- - -
-
-
- - - -
- -

Returns the last version record in the database by :inserted_at

-
-
-
- -
- - - Link to this function - -

last(options)

- - -
- -
- - -
-
- -
-
- - -
-
-
-
- - - diff --git a/doc/PaperTrail.VersionQueries.html b/doc/PaperTrail.VersionQueries.html deleted file mode 100644 index bb4573c6..00000000 --- a/doc/PaperTrail.VersionQueries.html +++ /dev/null @@ -1,386 +0,0 @@ - - - - - - - - - - PaperTrail.VersionQueries — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

-PaperTrail.VersionQueries (paper_trail v0.10.1) - -

- - - -
-

- - - Link to this section - - Summary -

- -
-

- Functions -

-
- - -

Gets the current model record/struct of a version

- -
-
- - -

Gets the last version of a record.

- -
- - -
- - -

Gets all the versions of a record.

- -
-
- - -

Gets all the versions of a record given a module and its id

- -
- - -
- -
- - -
-

- - - Link to this section - -Functions -

-
-
- -
- - - Link to this function - -

get_current_model(version)

- - -
- -
- -

Gets the current model record/struct of a version

-
-
-
- -
- - - Link to this function - -

get_version(record)

- - -
- -
- -

Specs

-
- -
get_version(record :: Ecto.Schema.t()) :: Ecto.Query.t()
- -
- -

Gets the last version of a record.

A list of options is optional, so you can set for example the :prefix of the query, -wich allows you to change between different tenants.

Usage examples:

iex(1)> PaperTrail.VersionQueries.get_version(record, id) - iex(1)> PaperTrail.VersionQueries.get_version(record, [prefix: "tenant_id"]) - iex(1)> PaperTrail.VersionQueries.get_version(ModelName, id) - iex(1)> PaperTrail.VersionQueries.get_version(ModelName, id, [prefix: "tenant_id"])

-
-
-
- -
- - - Link to this function - -

get_version(model, id)

- - -
- -
- -

Specs

-
- -
get_version(model :: module(), id :: pos_integer()) :: Ecto.Query.t()
- -
get_version(record :: Ecto.Schema.t(), options :: []) :: Ecto.Query.t()
- -
- - -
-
-
- -
- - - Link to this function - -

get_version(model, id, options)

- - -
- -
- -

Specs

-
- -
get_version(model :: module(), id :: pos_integer(), options :: []) ::
-  Ecto.Query.t()
- -
- - -
-
-
- -
- - - Link to this function - -

get_versions(record)

- - -
- -
- -

Specs

-
- -
get_versions(record :: Ecto.Schema.t()) :: Ecto.Query.t()
- -
- -

Gets all the versions of a record.

A list of options is optional, so you can set for example the :prefix of the query, -wich allows you to change between different tenants.

Usage examples:

iex(1)> PaperTrail.VersionQueries.get_versions(record) - iex(1)> PaperTrail.VersionQueries.get_versions(record, [prefix: "tenant_id"]) - iex(1)> PaperTrail.VersionQueries.get_versions(ModelName, id) - iex(1)> PaperTrail.VersionQueries.get_versions(ModelName, id, [prefix: "tenant_id"])

-
-
-
- -
- - - Link to this function - -

get_versions(model, id)

- - -
- -
- -

Specs

-
- -
get_versions(model :: module(), id :: pos_integer()) :: Ecto.Query.t()
- -
get_versions(record :: Ecto.Schema.t(), options :: []) :: Ecto.Query.t()
- -
- -

Gets all the versions of a record given a module and its id

-
-
-
- -
- - - Link to this function - -

get_versions(model, id, options)

- - -
- -
- -

Specs

-
- -
get_versions(model :: module(), id :: pos_integer(), options :: []) ::
-  Ecto.Query.t()
- -
- - -
-
- -
-
- - -
-
-
-
- - - diff --git a/doc/PaperTrail.html b/doc/PaperTrail.html deleted file mode 100644 index 73a37500..00000000 --- a/doc/PaperTrail.html +++ /dev/null @@ -1,660 +0,0 @@ - - - - - - - - - - PaperTrail — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

-PaperTrail (paper_trail v0.10.1) - -

- - - -
-

- - - Link to this section - - Summary -

- -
-

- Functions -

- -
- - -

Deletes a record from the database with a related version insertion in one transaction

- -
-
- - -

Same as delete/2 but returns only the model struct or raises if the changeset is invalid.

- -
- - - - - - - - - - -
- - -

Inserts a record to the database with a related version insertion in one transaction

- -
-
- - -

Same as insert/2 but returns only the model struct or raises if the changeset is invalid.

- -
- - -
- - -

Updates a record from the database with a related version insertion in one transaction

- -
-
- - -

Same as update/2 but returns only the model struct or raises if the changeset is invalid.

- -
- -
- -
- - -
-

- - - Link to this section - -Functions -

-
-
- -
- - - Link to this function - -

add_prefix(schema, prefix)

- - -
- -
- -

See PaperTrail.Serializer.add_prefix/2.

-
-
-
- - - -
- - - Link to this function - -

delete(struct, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil])

- - -
- -
- -

Deletes a record from the database with a related version insertion in one transaction

-
-
-
- - - -
- - - Link to this function - -

delete!(struct, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil])

- - -
- -
- -

Same as delete/2 but returns only the model struct or raises if the changeset is invalid.

-
-
-
- -
- - - Link to this function - -

get_current_model(version)

- - -
- -
- -

See PaperTrail.VersionQueries.get_current_model/1.

-
-
-
- -
- - - Link to this function - -

get_item_type(data)

- - -
- -
- -

See PaperTrail.Serializer.get_item_type/1.

-
-
-
- -
- - - Link to this function - -

get_model_id(model)

- - -
- -
- -

See PaperTrail.Serializer.get_model_id/1.

-
-
-
- -
- - - Link to this function - -

get_sequence_id(table_name)

- - -
- -
- -

See PaperTrail.Serializer.get_sequence_id/1.

-
-
-
- -
- - - Link to this function - -

get_version(record)

- - -
- -
- -

See PaperTrail.VersionQueries.get_version/1.

-
-
-
- -
- - - Link to this function - -

get_version(model_or_record, id_or_options)

- - -
- -
- -

See PaperTrail.VersionQueries.get_version/2.

-
-
-
- -
- - - Link to this function - -

get_version(model, id, options)

- - -
- -
- -

See PaperTrail.VersionQueries.get_version/3.

-
-
-
- -
- - - Link to this function - -

get_versions(record)

- - -
- -
- -

See PaperTrail.VersionQueries.get_versions/1.

-
-
-
- -
- - - Link to this function - -

get_versions(model_or_record, id_or_options)

- - -
- -
- -

See PaperTrail.VersionQueries.get_versions/2.

-
-
-
- -
- - - Link to this function - -

get_versions(model, id, options)

- - -
- -
- -

See PaperTrail.VersionQueries.get_versions/3.

-
-
-
- - - -
- - - Link to this function - -

insert(changeset, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil, model_key: :model, version_key: :version, ecto_options: []])

- - -
- -
- -

Inserts a record to the database with a related version insertion in one transaction

-
-
-
- - - -
- - - Link to this function - -

insert!(changeset, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil, model_key: :model, version_key: :version, ecto_options: []])

- - -
- -
- -

Same as insert/2 but returns only the model struct or raises if the changeset is invalid.

-
-
-
- -
- - - Link to this function - -

make_version_struct(version, model, options)

- - -
- -
- -

See PaperTrail.Serializer.make_version_struct/3.

-
-
-
- -
- - - Link to this function - -

serialize(data)

- - -
- -
- -

See PaperTrail.Serializer.serialize/1.

-
-
-
- - - -
- - - Link to this function - -

update(changeset, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil])

- - -
- -
- -

Updates a record from the database with a related version insertion in one transaction

-
-
-
- - - -
- - - Link to this function - -

update!(changeset, options \\ [origin: nil, meta: nil, originator: nil, prefix: nil])

- - -
- -
- -

Same as update/2 but returns only the model struct or raises if the changeset is invalid.

-
-
- -
-
- - -
-
-
-
- - - diff --git a/doc/api-reference.html b/doc/api-reference.html deleted file mode 100644 index a61cac7c..00000000 --- a/doc/api-reference.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - API Reference — paper_trail v0.10.1 - - - - - - - - - - - - - - -
- - - - - -
-
-
- -

- API Reference paper_trail v0.10.1 -

- -
-

- - Modules -

- -
-
-
- PaperTrail - -
- -
-
- - -
- -
- - -

Serialization functions to create a version struct

- -
-
- - -
- - -
-
- - -
-

- - Mix Tasks -

- -
- - -
-
- - -
-
-
-
- - - diff --git a/doc/dist/app-60a0c9f10e9e52eae31f.js b/doc/dist/app-60a0c9f10e9e52eae31f.js deleted file mode 100644 index 8a06cd60..00000000 --- a/doc/dist/app-60a0c9f10e9e52eae31f.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see app-60a0c9f10e9e52eae31f.js.LICENSE.txt */ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=60)}([function(e,t,n){var r;!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(n,i){"use strict";var o=[],a=Object.getPrototypeOf,s=o.slice,l=o.flat?function(e){return o.flat.call(e)}:function(e){return o.concat.apply([],e)},u=o.push,c=o.indexOf,d={},f=d.toString,p=d.hasOwnProperty,h=p.toString,m=h.call(Object),g={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},y=function(e){return null!=e&&e===e.window},b=n.document,x={type:!0,src:!0,nonce:!0,noModule:!0};function w(e,t,n){var r,i,o=(n=n||b).createElement("script");if(o.text=e,t)for(r in x)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function _(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?d[f.call(e)]||"object":typeof e}var k=function(e,t){return new k.fn.init(e,t)};function E(e){var t=!!e&&"length"in e&&e.length,n=_(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}k.fn=k.prototype={jquery:"3.5.0",constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(e){return this.pushStack(k.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(k.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(k.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+I+")"+I+"*"),W=new RegExp(I+"|>"),U=new RegExp(B),V=new RegExp("^"+q+"$"),G={ID:new RegExp("^#("+q+")"),CLASS:new RegExp("^\\.("+q+")"),TAG:new RegExp("^("+q+"|[*])"),ATTR:new RegExp("^"+H),PSEUDO:new RegExp("^"+B),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+I+"*(even|odd|(([+-]|)(\\d*)n|)"+I+"*(?:([+-]|)"+I+"*(\\d+)|))"+I+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+I+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+I+"*((?:-\\d)?\\d*)"+I+"*\\)|)(?=[^-]|$)","i")},K=/HTML$/i,X=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+I+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){f()},ae=xe((function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{L.apply(j=D.call(w.childNodes),w.childNodes),j[w.childNodes.length].nodeType}catch(e){L={apply:j.length?function(e,t){A.apply(e,D.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function se(e,t,r,i){var o,s,u,c,d,h,v,y=t&&t.ownerDocument,w=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==w&&9!==w&&11!==w)return r;if(!i&&(f(t),t=t||p,m)){if(11!==w&&(d=Z.exec(e)))if(o=d[1]){if(9===w){if(!(u=t.getElementById(o)))return r;if(u.id===o)return r.push(u),r}else if(y&&(u=y.getElementById(o))&&b(t,u)&&u.id===o)return r.push(u),r}else{if(d[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=d[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!O[e+" "]&&(!g||!g.test(e))&&(1!==w||"object"!==t.nodeName.toLowerCase())){if(v=e,y=t,1===w&&(W.test(e)||z.test(e))){for((y=ee.test(e)&&ve(t.parentNode)||t)===t&&n.scope||((c=t.getAttribute("id"))?c=c.replace(re,ie):t.setAttribute("id",c=x)),s=(h=a(e)).length;s--;)h[s]=(c?"#"+c:":scope")+" "+be(h[s]);v=h.join(",")}try{return L.apply(r,y.querySelectorAll(v)),r}catch(t){O(e,!0)}finally{c===x&&t.removeAttribute("id")}}}return l(e.replace(F,"$1"),t,r,i)}function le(){var e=[];return function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}}function ue(e){return e[x]=!0,e}function ce(e){var t=p.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)r.attrHandle[n[i]]=t}function fe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function pe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function he(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function me(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ae(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function ge(e){return ue((function(t){return t=+t,ue((function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))}))}))}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!K.test(t||n&&n.nodeName||"HTML")},f=se.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!=p&&9===a.nodeType&&a.documentElement?(h=(p=a).documentElement,m=!o(p),w!=p&&(i=p.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",oe,!1):i.attachEvent&&i.attachEvent("onunload",oe)),n.scope=ce((function(e){return h.appendChild(e).appendChild(p.createElement("div")),void 0!==e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length})),n.attributes=ce((function(e){return e.className="i",!e.getAttribute("className")})),n.getElementsByTagName=ce((function(e){return e.appendChild(p.createComment("")),!e.getElementsByTagName("*").length})),n.getElementsByClassName=Y.test(p.getElementsByClassName),n.getById=ce((function(e){return h.appendChild(e).id=x,!p.getElementsByName||!p.getElementsByName(x).length})),n.getById?(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&m){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&m){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&m)return t.getElementsByClassName(e)},v=[],g=[],(n.qsa=Y.test(p.querySelectorAll))&&(ce((function(e){var t;h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+I+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+I+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+x+"-]").length||g.push("~="),(t=p.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||g.push("\\["+I+"*name"+I+"*="+I+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+x+"+*").length||g.push(".#.+[+~]"),e.querySelectorAll("\\\f"),g.push("[\\r\\n\\f]")})),ce((function(e){e.innerHTML="";var t=p.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+I+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")}))),(n.matchesSelector=Y.test(y=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ce((function(e){n.disconnectedMatch=y.call(e,"*"),y.call(e,"[s!='']:x"),v.push("!=",B)})),g=g.length&&new RegExp(g.join("|")),v=v.length&&new RegExp(v.join("|")),t=Y.test(h.compareDocumentPosition),b=t||Y.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},T=t?function(e,t){if(e===t)return d=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e==p||e.ownerDocument==w&&b(w,e)?-1:t==p||t.ownerDocument==w&&b(w,t)?1:c?M(c,e)-M(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return d=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==p?-1:t==p?1:i?-1:o?1:c?M(c,e)-M(c,t):0;if(i===o)return fe(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?fe(a[r],s[r]):a[r]==w?-1:s[r]==w?1:0},p):p},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(f(e),n.matchesSelector&&m&&!O[t+" "]&&(!v||!v.test(t))&&(!g||!g.test(t)))try{var r=y.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){O(t,!0)}return se(t,p,null,[e]).length>0},se.contains=function(e,t){return(e.ownerDocument||e)!=p&&f(e),b(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=p&&f(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!m):void 0;return void 0!==o?o:n.attributes||!m?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,r=[],i=0,o=0;if(d=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(T),d){for(;t=e[o++];)t===e[o]&&(i=r.push(o));for(;i--;)e.splice(r[i],1)}return c=null,e},i=se.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=i(t);return n},(r=se.selectors={cacheLength:50,createPseudo:ue,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&U.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+I+")"+e+"("+I+"|$)"))&&E(e,(function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,n){return function(r){var i=se.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace(Q," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,d,f,p,h,m=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!l&&!s,b=!1;if(g){if(o){for(;m;){for(f=t;f=f[m];)if(s?f.nodeName.toLowerCase()===v:1===f.nodeType)return!1;h=m="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?g.firstChild:g.lastChild],a&&y){for(b=(p=(u=(c=(d=(f=g)[x]||(f[x]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]||[])[0]===_&&u[1])&&u[2],f=p&&g.childNodes[p];f=++p&&f&&f[m]||(b=p=0)||h.pop();)if(1===f.nodeType&&++b&&f===t){c[e]=[_,p,b];break}}else if(y&&(b=p=(u=(c=(d=(f=t)[x]||(f[x]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]||[])[0]===_&&u[1]),!1===b)for(;(f=++p&&f&&f[m]||(b=p=0)||h.pop())&&((s?f.nodeName.toLowerCase()!==v:1!==f.nodeType)||!++b||(y&&((c=(d=f[x]||(f[x]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]=[_,b]),f!==t)););return(b-=i)===r||b%r==0&&b/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return i[x]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?ue((function(e,n){for(var r,o=i(e,t),a=o.length;a--;)e[r=M(e,o[a])]=!(n[r]=o[a])})):function(e){return i(e,0,n)}):i}},pseudos:{not:ue((function(e){var t=[],n=[],r=s(e.replace(F,"$1"));return r[x]?ue((function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))})):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}})),has:ue((function(e){return function(t){return se(e,t).length>0}})),contains:ue((function(e){return e=e.replace(te,ne),function(t){return(t.textContent||i(t)).indexOf(e)>-1}})),lang:ue((function(e){return V.test(e||"")||se.error("unsupported lang: "+e),e=e.replace(te,ne).toLowerCase(),function(t){var n;do{if(n=m?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:me(!1),disabled:me(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return X.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ge((function(){return[0]})),last:ge((function(e,t){return[t-1]})),eq:ge((function(e,t,n){return[n<0?n+t:n]})),even:ge((function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e})),gt:ge((function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function _e(e,t,n,r,i){for(var o,a=[],s=0,l=e.length,u=null!=t;s-1&&(o[u]=!(a[u]=d))}}else v=_e(v===a?v.splice(h,v.length):v),i?i(null,a,v,l):L.apply(a,v)}))}function Ee(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],l=a?1:0,c=xe((function(e){return e===t}),s,!0),d=xe((function(e){return M(t,e)>-1}),s,!0),f=[function(e,n,r){var i=!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):d(e,n,r));return t=null,i}];l1&&we(f),l>1&&be(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(F,"$1"),n,l0,i=e.length>0,o=function(o,a,s,l,c){var d,h,g,v=0,y="0",b=o&&[],x=[],w=u,k=o||i&&r.find.TAG("*",c),E=_+=null==w?1:Math.random()||.1,C=k.length;for(c&&(u=a==p||a||c);y!==C&&null!=(d=k[y]);y++){if(i&&d){for(h=0,a||d.ownerDocument==p||(f(d),s=!m);g=e[h++];)if(g(d,a||p,s)){l.push(d);break}c&&(_=E)}n&&((d=!g&&d)&&v--,o&&b.push(d))}if(v+=y,n&&y!==v){for(h=0;g=t[h++];)g(b,x,a,s);if(o){if(v>0)for(;y--;)b[y]||x[y]||(x[y]=P.call(l));x=_e(x)}L.apply(l,x),c&&!o&&x.length>0&&v+t.length>1&&se.uniqueSort(l)}return c&&(_=E,u=w),b};return n?ue(o):o}(o,i))).selector=e}return s},l=se.select=function(e,t,n,i){var o,l,u,c,d,f="function"==typeof e&&e,p=!i&&a(e=f.selector||e);if(n=n||[],1===p.length){if((l=p[0]=p[0].slice(0)).length>2&&"ID"===(u=l[0]).type&&9===t.nodeType&&m&&r.relative[l[1].type]){if(!(t=(r.find.ID(u.matches[0].replace(te,ne),t)||[])[0]))return n;f&&(t=t.parentNode),e=e.slice(l.shift().value.length)}for(o=G.needsContext.test(e)?0:l.length;o--&&(u=l[o],!r.relative[c=u.type]);)if((d=r.find[c])&&(i=d(u.matches[0].replace(te,ne),ee.test(l[0].type)&&ve(t.parentNode)||t))){if(l.splice(o,1),!(e=i.length&&be(l)))return L.apply(n,i),n;break}}return(f||s(e,p))(i,t,!m,n,!t||ee.test(e)&&ve(t.parentNode)||t),n},n.sortStable=x.split("").sort(T).join("")===x,n.detectDuplicates=!!d,f(),n.sortDetached=ce((function(e){return 1&e.compareDocumentPosition(p.createElement("fieldset"))})),ce((function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")}))||de("type|href|height|width",(function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)})),n.attributes&&ce((function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}))||de("value",(function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue})),ce((function(e){return null==e.getAttribute("disabled")}))||de(R,(function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null})),se}(n);k.find=C,k.expr=C.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=C.uniqueSort,k.text=C.getText,k.isXMLDoc=C.isXML,k.contains=C.contains,k.escapeSelector=C.escape;var S=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r},O=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},T=k.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var j=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function P(e,t,n){return v(t)?k.grep(e,(function(e,r){return!!t.call(e,r,e)!==n})):t.nodeType?k.grep(e,(function(e){return e===t!==n})):"string"!=typeof t?k.grep(e,(function(e){return c.call(t,e)>-1!==n})):k.filter(t,e,n)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,(function(e){return 1===e.nodeType})))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter((function(){for(t=0;t1?k.uniqueSort(n):n},filter:function(e){return this.pushStack(P(this,e||[],!1))},not:function(e){return this.pushStack(P(this,e||[],!0))},is:function(e){return!!P(this,"string"==typeof e&&T.test(e)?k(e):e||[],!1).length}});var A,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||A,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:b,!0)),j.test(r[1])&&k.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=b.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,A=k(b);var D=/^(?:parents|prev(?:Until|All))/,M={children:!0,contents:!0,next:!0,prev:!0};function R(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter((function(){for(var e=0;e-1:1===n.nodeType&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?c.call(k(e),this[0]):c.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return S(e,"parentNode")},parentsUntil:function(e,t,n){return S(e,"parentNode",n)},next:function(e){return R(e,"nextSibling")},prev:function(e){return R(e,"previousSibling")},nextAll:function(e){return S(e,"nextSibling")},prevAll:function(e){return S(e,"previousSibling")},nextUntil:function(e,t,n){return S(e,"nextSibling",n)},prevUntil:function(e,t,n){return S(e,"previousSibling",n)},siblings:function(e){return O((e.parentNode||{}).firstChild,e)},children:function(e){return O(e.firstChild)},contents:function(e){return null!=e.contentDocument&&a(e.contentDocument)?e.contentDocument:(N(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},(function(e,t){k.fn[e]=function(n,r){var i=k.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=k.filter(r,i)),this.length>1&&(M[e]||k.uniqueSort(i),D.test(e)&&i.reverse()),this.pushStack(i)}}));var I=/[^\x20\t\r\n\f]+/g;function q(e){return e}function H(e){throw e}function B(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n):e&&v(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}k.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return k.each(e.match(I)||[],(function(e,n){t[n]=!0})),t}(e):k.extend({},e);var t,n,r,i,o=[],a=[],s=-1,l=function(){for(i=i||e.once,r=t=!0;a.length;s=-1)for(n=a.shift();++s-1;)o.splice(n,1),n<=s&&s--})),this},has:function(e){return e?k.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||l()),this},fire:function(){return u.fireWith(this,arguments),this},fired:function(){return!!r}};return u},k.extend({Deferred:function(e){var t=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return k.Deferred((function(n){k.each(t,(function(t,r){var i=v(e[r[4]])&&e[r[4]];o[r[1]]((function(){var e=i&&i.apply(this,arguments);e&&v(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,i?[e]:arguments)}))})),e=null})).promise()},then:function(e,r,i){var o=0;function a(e,t,r,i){return function(){var s=this,l=arguments,u=function(){var n,u;if(!(e=o&&(r!==H&&(s=void 0,l=[n]),t.rejectWith(s,l))}};e?c():(k.Deferred.getStackHook&&(c.stackTrace=k.Deferred.getStackHook()),n.setTimeout(c))}}return k.Deferred((function(n){t[0][3].add(a(0,n,v(i)?i:q,n.notifyWith)),t[1][3].add(a(0,n,v(e)?e:q)),t[2][3].add(a(0,n,v(r)?r:H))})).promise()},promise:function(e){return null!=e?k.extend(e,i):i}},o={};return k.each(t,(function(e,n){var a=n[2],s=n[5];i[n[1]]=a.add,s&&a.add((function(){r=s}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),a.add(n[3].fire),o[n[0]]=function(){return o[n[0]+"With"](this===o?void 0:this,arguments),this},o[n[0]+"With"]=a.fireWith})),i.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=s.call(arguments),o=k.Deferred(),a=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?s.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(B(e,o.done(a(n)).resolve,o.reject,!t),"pending"===o.state()||v(i[n]&&i[n].then)))return o.then();for(;n--;)B(i[n],a(n),o.reject);return o.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){n.console&&n.console.warn&&e&&Q.test(e.name)&&n.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){n.setTimeout((function(){throw e}))};var F=k.Deferred();function $(){b.removeEventListener("DOMContentLoaded",$),n.removeEventListener("load",$),k.ready()}k.fn.ready=function(e){return F.then(e).catch((function(e){k.readyException(e)})),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0,!0!==e&&--k.readyWait>0||F.resolveWith(b,[k]))}}),k.ready.then=F.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?n.setTimeout(k.ready):(b.addEventListener("DOMContentLoaded",$),n.addEventListener("load",$));var z=function(e,t,n,r,i,o,a){var s=0,l=e.length,u=null==n;if("object"===_(n))for(s in i=!0,n)z(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,v(r)||(a=!0),u&&(a?(t.call(e,r),t=null):(u=t,t=function(e,t,n){return u.call(k(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each((function(){Y.remove(this,e)}))}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,(function(){k.dequeue(e,t)}),o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:k.Callbacks("once memory").add((function(){J.remove(e,[t+"queue",n])}))})}}),k.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,ve=/^$|^module$|\/(?:java|ecma)script/i;pe=b.createDocumentFragment().appendChild(b.createElement("div")),(he=b.createElement("input")).setAttribute("type","radio"),he.setAttribute("checked","checked"),he.setAttribute("name","t"),pe.appendChild(he),g.checkClone=pe.cloneNode(!0).cloneNode(!0).lastChild.checked,pe.innerHTML="",g.noCloneChecked=!!pe.cloneNode(!0).lastChild.defaultValue,pe.innerHTML="",g.option=!!pe.lastChild;var ye={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function be(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?k.merge([e],n):n}function xe(e,t){for(var n=0,r=e.length;n",""]);var we=/<|&#?\w+;/;function _e(e,t,n,r,i){for(var o,a,s,l,u,c,d=t.createDocumentFragment(),f=[],p=0,h=e.length;p-1)i&&i.push(o);else if(u=ae(o),a=be(d.appendChild(o),"script"),u&&xe(a),n)for(c=0;o=a[c++];)ve.test(o.type||"")&&n.push(o);return d}var ke=/^key/,Ee=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Se(){return!0}function Oe(){return!1}function Te(e,t){return e===function(){try{return b.activeElement}catch(e){}}()==("focus"===t)}function Ne(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ne(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Oe;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each((function(){k.event.add(this,t,i,r,n)}))}function je(e,t,n){n?(J.set(e,t,!1),k.event.add(e,t,{namespace:!1,handler:function(e){var r,i,o=J.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(k.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=s.call(arguments),J.set(this,t,o),r=n(this,t),this[t](),o!==(i=J.get(this,t))||r?J.set(this,t,!1):i={},o!==i)return e.stopImmediatePropagation(),e.preventDefault(),i.value}else o.length&&(J.set(this,t,{value:k.event.trigger(k.extend(o[0],k.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===J.get(e,t)&&k.event.add(e,t,Se)}k.event={global:{},add:function(e,t,n,r,i){var o,a,s,l,u,c,d,f,p,h,m,g=J.get(e);if(K(e))for(n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(oe,i),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events=Object.create(null)),(a=g.handle)||(a=g.handle=function(t){return void 0!==k&&k.event.triggered!==t.type?k.event.dispatch.apply(e,arguments):void 0}),u=(t=(t||"").match(I)||[""]).length;u--;)p=m=(s=Ce.exec(t[u])||[])[1],h=(s[2]||"").split(".").sort(),p&&(d=k.event.special[p]||{},p=(i?d.delegateType:d.bindType)||p,d=k.event.special[p]||{},c=k.extend({type:p,origType:m,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(f=l[p])||((f=l[p]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(p,a)),d.add&&(d.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?f.splice(f.delegateCount++,0,c):f.push(c),k.event.global[p]=!0)},remove:function(e,t,n,r,i){var o,a,s,l,u,c,d,f,p,h,m,g=J.hasData(e)&&J.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(I)||[""]).length;u--;)if(p=m=(s=Ce.exec(t[u])||[])[1],h=(s[2]||"").split(".").sort(),p){for(d=k.event.special[p]||{},f=l[p=(r?d.delegateType:d.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=f.length;o--;)c=f[o],!i&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,d.remove&&d.remove.call(e,c));a&&!f.length&&(d.teardown&&!1!==d.teardown.call(e,h,g.handle)||k.removeEvent(e,p,g.handle),delete l[p])}else for(p in l)k.event.remove(e,p+t[u],n,r,!0);k.isEmptyObject(l)&&J.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),l=k.event.fix(e),u=(J.get(this,"events")||Object.create(null))[l.type]||[],c=k.event.special[l.type]||{};for(s[0]=l,t=1;t=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==e.type||!0!==u.disabled)){for(o=[],a={},n=0;n-1:k.find(i,this,null,[u]).length),a[i]&&o.push(r);o.length&&s.push({elem:u,handlers:o})}return u=this,l\s*$/g;function De(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Me(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Ie(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(J.hasData(e)&&(s=J.get(e).events))for(i in J.remove(t,"handle events"),s)for(n=0,r=s[i].length;n1&&"string"==typeof h&&!g.checkClone&&Ae.test(h))return e.each((function(i){var o=e.eq(i);m&&(t[0]=h.call(this,i,o.html())),He(o,t,n,r)}));if(f&&(o=(i=_e(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=o),o||r)){for(s=(a=k.map(be(i,"script"),Me)).length;d0&&xe(a,!l&&be(e,"script")),s},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(K(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[Y.expando]&&(n[Y.expando]=void 0)}}}),k.fn.extend({detach:function(e){return Be(this,e,!0)},remove:function(e){return Be(this,e)},text:function(e){return z(this,(function(e){return void 0===e?k.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return He(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||De(this,e).appendChild(e)}))},prepend:function(){return He(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=De(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return He(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return He(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(be(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return k.clone(this,e,t)}))},html:function(e){return z(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Pe.test(e)&&!ye[(ge.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n3,oe.removeChild(e)),s}}))}();var Ve=["Webkit","Moz","ms"],Ge=b.createElement("div").style,Ke={};function Xe(e){var t=k.cssProps[e]||Ke[e];return t||(e in Ge?e:Ke[e]=function(e){for(var t=e[0].toUpperCase()+e.slice(1),n=Ve.length;n--;)if((e=Ve[n]+t)in Ge)return e}(e)||e)}var Je=/^(none|table(?!-c[ea]).+)/,Ye=/^--/,Ze={position:"absolute",visibility:"hidden",display:"block"},et={letterSpacing:"0",fontWeight:"400"};function tt(e,t,n){var r=re.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function nt(e,t,n,r,i,o){var a="width"===t?1:0,s=0,l=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(l+=k.css(e,n+ie[a],!0,i)),r?("content"===n&&(l-=k.css(e,"padding"+ie[a],!0,i)),"margin"!==n&&(l-=k.css(e,"border"+ie[a]+"Width",!0,i))):(l+=k.css(e,"padding"+ie[a],!0,i),"padding"!==n?l+=k.css(e,"border"+ie[a]+"Width",!0,i):s+=k.css(e,"border"+ie[a]+"Width",!0,i));return!r&&o>=0&&(l+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-l-s-.5))||0),l}function rt(e,t,n){var r=Fe(e),i=(!g.boxSizingReliable()||n)&&"border-box"===k.css(e,"boxSizing",!1,r),o=i,a=We(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Qe.test(a)){if(!n)return a;a="auto"}return(!g.boxSizingReliable()&&i||!g.reliableTrDimensions()&&N(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===k.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===k.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+nt(e,t,n||(i?"border":"content"),o,r,a)+"px"}function it(e,t,n,r,i){return new it.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=We(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),l=Ye.test(t),u=e.style;if(l||(t=Xe(s)),a=k.cssHooks[t]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];"string"===(o=typeof n)&&(i=re.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||l||(n+=i&&i[3]||(k.cssNumber[s]?"":"px")),g.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(l?u.setProperty(t,n):u[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Ye.test(t)||(t=Xe(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=We(e,t,r)),"normal"===i&&t in et&&(i=et[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],(function(e,t){k.cssHooks[t]={get:function(e,n,r){if(n)return!Je.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?rt(e,t,r):$e(e,Ze,(function(){return rt(e,t,r)}))},set:function(e,n,r){var i,o=Fe(e),a=!g.scrollboxSize()&&"absolute"===o.position,s=(a||r)&&"border-box"===k.css(e,"boxSizing",!1,o),l=r?nt(e,t,r,s,o):0;return s&&a&&(l-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-nt(e,t,"border",!1,o)-.5)),l&&(i=re.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=k.css(e,t)),tt(0,n,l)}}})),k.cssHooks.marginLeft=Ue(g.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(We(e,"marginLeft"))||e.getBoundingClientRect().left-$e(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),k.each({margin:"",padding:"",border:"Width"},(function(e,t){k.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+ie[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(k.cssHooks[e+t].set=tt)})),k.fn.extend({css:function(e,t){return z(this,(function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Fe(e),i=t.length;a1)}}),k.Tween=it,it.prototype={constructor:it,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=it.propHooks[this.prop];return e&&e.get?e.get(this):it.propHooks._default.get(this)},run:function(e){var t,n=it.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):it.propHooks._default.set(this),this}},it.prototype.init.prototype=it.prototype,it.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||!k.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}},it.propHooks.scrollTop=it.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=it.prototype.init,k.fx.step={};var ot,at,st=/^(?:toggle|show|hide)$/,lt=/queueHooks$/;function ut(){at&&(!1===b.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(ut):n.setTimeout(ut,k.fx.interval),k.fx.tick())}function ct(){return n.setTimeout((function(){ot=void 0})),ot=Date.now()}function dt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ie[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ft(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each((function(){k.removeAttr(this,e)}))}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ht:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!g.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(I);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),ht={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),(function(e,t){var n=mt[t]||k.find.attr;mt[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=mt[a],mt[a]=i,i=null!=n(e,t,r)?a:null,mt[a]=o),i}}));var gt=/^(?:input|select|textarea|button)$/i,vt=/^(?:a|area)$/i;function yt(e){return(e.match(I)||[]).join(" ")}function bt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(I)||[]}k.fn.extend({prop:function(e,t){return z(this,k.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[k.propFix[e]||e]}))}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||vt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),g.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){k.propFix[this.toLowerCase()]=this})),k.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,l=0;if(v(e))return this.each((function(t){k(this).addClass(e.call(this,t,bt(this)))}));if((t=xt(e)).length)for(;n=this[l++];)if(i=bt(n),r=1===n.nodeType&&" "+yt(i)+" "){for(a=0;o=t[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=yt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,l=0;if(v(e))return this.each((function(t){k(this).removeClass(e.call(this,t,bt(this)))}));if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)for(;n=this[l++];)if(i=bt(n),r=1===n.nodeType&&" "+yt(i)+" "){for(a=0;o=t[a++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");i!==(s=yt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):v(e)?this.each((function(n){k(this).toggleClass(e.call(this,n,bt(this),t),t)})):this.each((function(){var t,i,o,a;if(r)for(i=0,o=k(this),a=xt(e);t=a[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||((t=bt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+yt(bt(n))+" ").indexOf(t)>-1)return!0;return!1}});var wt=/\r/g;k.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=v(e),this.each((function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,k(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=k.map(i,(function(e){return null==e?"":e+""}))),(t=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))}))):i?(t=k.valHooks[i.type]||k.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(wt,""):null==n?"":n:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:yt(k.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],l=a?o+1:i.length;for(r=o<0?l:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],(function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=k.inArray(k(e).val(),t)>-1}},g.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),g.focusin="onfocusin"in n;var _t=/^(?:focusinfocus|focusoutblur)$/,kt=function(e){e.stopPropagation()};k.extend(k.event,{trigger:function(e,t,r,i){var o,a,s,l,u,c,d,f,h=[r||b],m=p.call(e,"type")?e.type:e,g=p.call(e,"namespace")?e.namespace.split("."):[];if(a=f=s=r=r||b,3!==r.nodeType&&8!==r.nodeType&&!_t.test(m+k.event.triggered)&&(m.indexOf(".")>-1&&(g=m.split("."),m=g.shift(),g.sort()),u=m.indexOf(":")<0&&"on"+m,(e=e[k.expando]?e:new k.Event(m,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=g.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=r),t=null==t?[e]:k.makeArray(t,[e]),d=k.event.special[m]||{},i||!d.trigger||!1!==d.trigger.apply(r,t))){if(!i&&!d.noBubble&&!y(r)){for(l=d.delegateType||m,_t.test(l+m)||(a=a.parentNode);a;a=a.parentNode)h.push(a),s=a;s===(r.ownerDocument||b)&&h.push(s.defaultView||s.parentWindow||n)}for(o=0;(a=h[o++])&&!e.isPropagationStopped();)f=a,e.type=o>1?l:d.bindType||m,(c=(J.get(a,"events")||Object.create(null))[e.type]&&J.get(a,"handle"))&&c.apply(a,t),(c=u&&a[u])&&c.apply&&K(a)&&(e.result=c.apply(a,t),!1===e.result&&e.preventDefault());return e.type=m,i||e.isDefaultPrevented()||d._default&&!1!==d._default.apply(h.pop(),t)||!K(r)||u&&v(r[m])&&!y(r)&&((s=r[u])&&(r[u]=null),k.event.triggered=m,e.isPropagationStopped()&&f.addEventListener(m,kt),r[m](),e.isPropagationStopped()&&f.removeEventListener(m,kt),k.event.triggered=void 0,s&&(r[u]=s)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each((function(){k.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),g.focusin||k.each({focus:"focusin",blur:"focusout"},(function(e,t){var n=function(e){k.event.simulate(t,e.target,k.event.fix(e))};k.event.special[t]={setup:function(){var r=this.ownerDocument||this.document||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this.document||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}}));var Et=n.location,Ct={guid:Date.now()},St=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new n.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var Ot=/\[\]$/,Tt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,jt=/^(?:input|select|textarea|keygen)/i;function Pt(e,t,n,r){var i;if(Array.isArray(t))k.each(t,(function(t,i){n||Ot.test(e)?r(e,i):Pt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)}));else if(n||"object"!==_(t))r(e,t);else for(i in t)Pt(e+"["+i+"]",t[i],n,r)}k.param=function(e,t){var n,r=[],i=function(e,t){var n=v(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,(function(){i(this.name,this.value)}));else for(n in e)Pt(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&jt.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!me.test(e))})).map((function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,(function(e){return{name:t.name,value:e.replace(Tt,"\r\n")}})):{name:t.name,value:n.replace(Tt,"\r\n")}})).get()}});var At=/%20/g,Lt=/#.*$/,Dt=/([?&])_=[^&]*/,Mt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Rt=/^(?:GET|HEAD)$/,It=/^\/\//,qt={},Ht={},Bt="*/".concat("*"),Qt=b.createElement("a");function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(I)||[];if(v(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function $t(e,t,n,r){var i={},o=e===Ht;function a(s){var l;return i[s]=!0,k.each(e[s]||[],(function(e,s){var u=s(t,n,r);return"string"!=typeof u||o||i[u]?o?!(l=u):void 0:(t.dataTypes.unshift(u),a(u),!1)})),l}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}Qt.href=Et.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Bt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,k.ajaxSettings),t):zt(k.ajaxSettings,e)},ajaxPrefilter:Ft(qt),ajaxTransport:Ft(Ht),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,a,s,l,u,c,d,f,p=k.ajaxSetup({},t),h=p.context||p,m=p.context&&(h.nodeType||h.jquery)?k(h):k.event,g=k.Deferred(),v=k.Callbacks("once memory"),y=p.statusCode||{},x={},w={},_="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(u){if(!a)for(a={};t=Mt.exec(o);)a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return u?o:null},setRequestHeader:function(e,t){return null==u&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,x[e]=t),this},overrideMimeType:function(e){return null==u&&(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(u)E.always(e[E.status]);else for(t in e)y[t]=[y[t],e[t]];return this},abort:function(e){var t=e||_;return r&&r.abort(t),C(0,t),this}};if(g.promise(E),p.url=((e||p.url||Et.href)+"").replace(It,Et.protocol+"//"),p.type=t.method||t.type||p.method||p.type,p.dataTypes=(p.dataType||"*").toLowerCase().match(I)||[""],null==p.crossDomain){l=b.createElement("a");try{l.href=p.url,l.href=l.href,p.crossDomain=Qt.protocol+"//"+Qt.host!=l.protocol+"//"+l.host}catch(e){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=k.param(p.data,p.traditional)),$t(qt,p,t,E),u)return E;for(d in(c=k.event&&p.global)&&0==k.active++&&k.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Rt.test(p.type),i=p.url.replace(Lt,""),p.hasContent?p.data&&p.processData&&0===(p.contentType||"").indexOf("application/x-www-form-urlencoded")&&(p.data=p.data.replace(At,"+")):(f=p.url.slice(i.length),p.data&&(p.processData||"string"==typeof p.data)&&(i+=(St.test(i)?"&":"?")+p.data,delete p.data),!1===p.cache&&(i=i.replace(Dt,"$1"),f=(St.test(i)?"&":"?")+"_="+Ct.guid+++f),p.url=i+f),p.ifModified&&(k.lastModified[i]&&E.setRequestHeader("If-Modified-Since",k.lastModified[i]),k.etag[i]&&E.setRequestHeader("If-None-Match",k.etag[i])),(p.data&&p.hasContent&&!1!==p.contentType||t.contentType)&&E.setRequestHeader("Content-Type",p.contentType),E.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Bt+"; q=0.01":""):p.accepts["*"]),p.headers)E.setRequestHeader(d,p.headers[d]);if(p.beforeSend&&(!1===p.beforeSend.call(h,E,p)||u))return E.abort();if(_="abort",v.add(p.complete),E.done(p.success),E.fail(p.error),r=$t(Ht,p,t,E)){if(E.readyState=1,c&&m.trigger("ajaxSend",[E,p]),u)return E;p.async&&p.timeout>0&&(s=n.setTimeout((function(){E.abort("timeout")}),p.timeout));try{u=!1,r.send(x,C)}catch(e){if(u)throw e;C(-1,e)}}else C(-1,"No Transport");function C(e,t,a,l){var d,f,b,x,w,_=t;u||(u=!0,s&&n.clearTimeout(s),r=void 0,o=l||"",E.readyState=e>0?4:0,d=e>=200&&e<300||304===e,a&&(x=function(e,t,n){for(var r,i,o,a,s=e.contents,l=e.dataTypes;"*"===l[0];)l.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){l.unshift(i);break}if(l[0]in n)o=l[0];else{for(i in n){if(!l[0]||e.converters[i+" "+l[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==l[0]&&l.unshift(o),n[o]}(p,E,a)),!d&&k.inArray("script",p.dataTypes)>-1&&(p.converters["text script"]=function(){}),x=function(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(a=u[l+" "+o]||u["* "+o]))for(i in u)if((s=i.split(" "))[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){!0===a?a=u[i]:!0!==u[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}(p,x,E,d),d?(p.ifModified&&((w=E.getResponseHeader("Last-Modified"))&&(k.lastModified[i]=w),(w=E.getResponseHeader("etag"))&&(k.etag[i]=w)),204===e||"HEAD"===p.type?_="nocontent":304===e?_="notmodified":(_=x.state,f=x.data,d=!(b=x.error))):(b=_,!e&&_||(_="error",e<0&&(e=0))),E.status=e,E.statusText=(t||_)+"",d?g.resolveWith(h,[f,_,E]):g.rejectWith(h,[E,_,b]),E.statusCode(y),y=void 0,c&&m.trigger(d?"ajaxSuccess":"ajaxError",[E,p,d?f:b]),v.fireWith(h,[E,_]),c&&(m.trigger("ajaxComplete",[E,p]),--k.active||k.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],(function(e,t){k[t]=function(e,n,r,i){return v(n)&&(i=i||r,r=n,n=void 0),k.ajax(k.extend({url:e,type:t,dataType:i,data:n,success:r},k.isPlainObject(e)&&e))}})),k.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),k._evalUrl=function(e,t,n){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){k.globalEval(e,t,n)}})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return v(e)?this.each((function(t){k(this).wrapInner(e.call(this,t))})):this.each((function(){var t=k(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=v(e);return this.each((function(n){k(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){k(this).replaceWith(this.childNodes)})),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(e){}};var Wt={0:200,1223:204},Ut=k.ajaxSettings.xhr();g.cors=!!Ut&&"withCredentials"in Ut,g.ajax=Ut=!!Ut,k.ajaxTransport((function(e){var t,r;if(g.cors||Ut&&!e.crossDomain)return{send:function(i,o){var a,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(a in e.xhrFields)s[a]=e.xhrFields[a];for(a in e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)s.setRequestHeader(a,i[a]);t=function(e){return function(){t&&(t=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Wt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=t(),r=s.onerror=s.ontimeout=t("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&n.setTimeout((function(){t&&r()}))},t=t("abort");try{s.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}})),k.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),k.ajaxTransport("script",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(r,i){t=k(" - - - - - - - - - -
- - - - - -
-
-
- - - - -
-
-
-
- - - diff --git a/mix.exs b/mix.exs index e47f8038..ba7891fe 100644 --- a/mix.exs +++ b/mix.exs @@ -1,23 +1,24 @@ defmodule PaperTrail.Mixfile do use Mix.Project + @source_url "https://github.com/izelnakri/paper_trail" + @version "0.10.1" + def project do [ app: :paper_trail, - version: "0.10.1", + version: @version, elixir: "~> 1.11", description: description(), build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, elixirc_paths: elixirc_paths(Mix.env()), package: package(), - deps: deps() + deps: deps(), + docs: docs() ] end - # Configuration for the OTP application - # - # Type "mix help compile.app" for more information def application do [ applications: [:logger, :ecto, :ecto_sql, :runtime_tools] @@ -28,31 +29,45 @@ defmodule PaperTrail.Mixfile do [ {:ecto, ">= 3.4.6"}, {:ecto_sql, ">= 3.4.5"}, - {:ex_doc, ">= 0.23.0", only: :dev, runtime: false}, - {:postgrex, ">= 0.0.0", only: [:dev, :test]}, - {:jason, ">= 1.2.0", only: [:dev, :test]} + + {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, + {:jason, ">= 1.2.0", only: [:dev, :test]}, + {:postgrex, ">= 0.0.0", only: [:dev, :test]} ] end defp description do """ - Track and record all the changes in your database. Revert back to anytime in history. + Track and record all the changes in your database. Revert back to anytime + in history. """ end defp package do [ name: :paper_trail, - files: ["lib", "mix.exs", "README*", "LICENSE*"], + files: ["lib", "mix.exs", "README*", "LICENSE*", "CHANGELOG*"], maintainers: ["Izel Nakri"], licenses: ["MIT License"], links: %{ - "GitHub" => "https://github.com/izelnakri/paper_trail", - "Docs" => "https://hexdocs.pm/paper_trail/PaperTrail.html" + "Changelog" => "#{@source_url}/blob/master/CHANGELOG.md", + "GitHub" => @source_url } ] end + defp docs do + [ + main: "readme", + source_ref: "v#{@version}", + source_url: @source_url, + extras: [ + "README.md", + "CHANGELOG.md" + ] + ] + end + defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"] end