├── .gitignore ├── Gruntfile.js ├── README.md ├── coffee ├── config.coffee ├── lib │ ├── api.coffee │ ├── core.coffee │ ├── oauth.coffee │ ├── providers.coffee │ ├── request.coffee │ └── user.coffee ├── main.coffee └── tools │ ├── cache.coffee │ ├── location_operations.coffee │ ├── lstorage.coffee │ ├── sha1.coffee │ └── url.coffee ├── compile-jquery.sh ├── dist ├── oauth.js └── oauth.min.js ├── example ├── index.html ├── jquery-2.1.1.min.js └── jquery-2.1.1.min.map ├── js └── tools │ └── jquery-lite.js ├── package.json └── plugin.xml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | /js/* 4 | !/js/tools 5 | /js/tools/* 6 | !/js/tools/jquery-lite.js 7 | *sublime* 8 | .idea 9 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var package_info = require('./package.json'); 4 | var fs = require('fs'); 5 | 6 | 7 | module.exports = function(grunt) { 8 | // Project configuration. 9 | var gruntConf = { 10 | watch: { 11 | options: { 12 | nospawn: true 13 | }, 14 | default: { 15 | files: ['./**/*.coffee'], 16 | tasks: ['coffee', 'browserify'] 17 | } 18 | }, 19 | coffee: { 20 | default: { 21 | expand: true, 22 | cwd: 'coffee', 23 | src: ['**/*.coffee'], 24 | dest: 'js', 25 | ext: '.js', 26 | options: { 27 | bare: true 28 | } 29 | } 30 | }, 31 | concurrent: { 32 | server: { 33 | options: { 34 | logConcurrentOutput: true 35 | } 36 | } 37 | }, 38 | browserify: { 39 | dist: { 40 | files: { 41 | './dist/oauth.js': ['js/main.js'] 42 | }, 43 | options: { 44 | transform: [ 45 | [ 46 | 'envify', { 47 | oauthd_url: 'https://oauth.io', 48 | api_url: 'https://oauth.io/api', 49 | sdk_version: "phonegap-" + package_info.version 50 | } 51 | ] 52 | ], 53 | browserifyOptions: { 54 | standalone: 'oauthio-phonegap' 55 | } 56 | } 57 | } 58 | }, 59 | uglify: { 60 | my_target: { 61 | files: { 62 | './dist/oauth.min.js': ['dist/oauth.js'] 63 | } 64 | } 65 | }, 66 | jasmine_node: { 67 | 68 | options: { 69 | forceExit: true, 70 | match: '.', 71 | matchall: false, 72 | extensions: 'js', 73 | specNameMatcher: 'spec' 74 | }, 75 | all: ['tests/unit/spec/'] 76 | }, 77 | 78 | taskDefault: ['coffee', 'browserify', 'uglify'] 79 | }; 80 | 81 | grunt.initConfig(gruntConf); 82 | 83 | // These plugins provide necessary tasks. 84 | grunt.loadNpmTasks('grunt-contrib-watch'); 85 | grunt.loadNpmTasks('grunt-contrib-coffee'); 86 | grunt.loadNpmTasks('grunt-concurrent'); 87 | grunt.loadNpmTasks('grunt-browserify'); 88 | grunt.loadNpmTasks('grunt-contrib-uglify'); 89 | grunt.loadNpmTasks('grunt-jasmine-node'); 90 | 91 | grunt.registerTask('coverage', 'Creates a tests coverage report', function() { 92 | var exec = require('child_process').exec; 93 | var done = this.async(); 94 | exec('npm test', function(error, stdout, stderr) { 95 | console.log("Coverage report should be generated in ./coverage/lcov-report/index.html"); 96 | done(); 97 | }); 98 | }); 99 | 100 | // Default task. 101 | grunt.registerTask('default', gruntConf.taskDefault); 102 | 103 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OAuth.io Cordova/Phonegap SDK 2 | ======================= 3 | 4 | This is the Cordova/Phonegap SDK for [OAuth.io](https://oauth.io). OAuth.io allows you to integrate **100+ providers** really easily in your web app, without worrying about each provider's OAuth specific implementation. 5 | 6 | Installation 7 | ============ 8 | 9 | * This plugin is supported on PhoneGap (Cordova) v3.0.0 and above. 10 | 11 | OAuth.io Requirements and Set-Up 12 | -------------------------------- 13 | 14 | To use this plugin you will need to make sure you've registered your OAuth.io app and have a public key (please check https://oauth.io/docs). 15 | 16 | Getting the SDK 17 | --------------- 18 | 19 | Run the following command in your project directory. If you are using Phonegap, use the `phonegap` command. If you are using Cordova, use the `cordova` command. 20 | 21 | ```sh 22 | $ cordova plugin add https://github.com/oauth-io/oauth-phonegap 23 | ``` 24 | 25 | Whitelisting API URLs 26 | --------------------- 27 | 28 | OAuth.io will try to access various URLs, and their domains must be whitelisted in your `config.xml` in the `` tag's `origin` attribute : 29 | 30 | ```xml 31 | 32 | 33 | 34 | 35 | 36 | 37 | ``` 38 | 39 | 40 | You can either add each domain separately, depending on the providers you use: 41 | 42 | * graph.facebook.com 43 | * api.twitter.com 44 | * github.com 45 | * ... 46 | 47 | Or you can allow all domains with `*` like this : 48 | 49 | ```xml 50 | 51 | ``` 52 | 53 | 54 | Integrating in your project 55 | --------------------------- 56 | 57 | The `OAuth` object is automatically added to `window` when you include the plugin, so you don't need to add it yourself. 58 | 59 | In your JavaScript, add this line to initialize OAuth.js. You can get the public key of your app from your [OAuth.io dashboard](https://oauth.io/dashboard/apps). 60 | 61 | ```javascript 62 | OAuth.initialize('your_app_public_key'); 63 | ``` 64 | 65 | Usage 66 | ===== 67 | 68 | To connect your user using facebook (as an example): 69 | 70 | ```javascript 71 | //Using popup (option 1) 72 | OAuth.popup('facebook') 73 | .done(function(result) { 74 | //use result.access_token in your API request 75 | //or use result.get|post|put|del|patch|me methods (see below) 76 | }) 77 | .fail(function (err) { 78 | //handle error with err 79 | }); 80 | ``` 81 | 82 | Using the cache 83 | --------------- 84 | 85 | As of version `0.2.0`, you can use the cache feature. This prevents the user from having to log in to the provider through a popup everytime he wants to access the app. 86 | 87 | To use the cache, pass an options object to your popup method like this : 88 | 89 | ```javascript 90 | OAuth.popup('facebook', { 91 | cache: true 92 | }) 93 | .done(function(result) { 94 | //use result.access_token in your API request 95 | //or use result.get|post|put|del|patch|me methods (see below) 96 | }) 97 | .fail(function (err) { 98 | //handle error with err 99 | }); 100 | ``` 101 | 102 | That way, your user will have to login to the provider only if the request token has not been retrieved yet or has expired. 103 | 104 | Making requests 105 | --------------- 106 | 107 | You can make requests to the provider's API manually with the access token you got from the `popup` or `callback` methods, or use the request methods stored in the `result` object. 108 | 109 | **GET Request** 110 | 111 | To make a GET request, you have to call the `result.get` method like this : 112 | 113 | ```javascript 114 | //Let's say the /me endpoint on the provider API returns a JSON object 115 | //with the field "name" containing the name "John Doe" 116 | OAuth.popup(provider) 117 | .done(function(result) { 118 | result.get('/me') 119 | .done(function (response) { 120 | //this will display "John Doe" in the console 121 | console.log(response.name); 122 | }) 123 | .fail(function (err) { 124 | //handle error with err 125 | }); 126 | }) 127 | .fail(function (err) { 128 | //handle error with err 129 | }); 130 | ``` 131 | 132 | **POST Request** 133 | 134 | To make a POST request, you have to call the `result.post` method like this : 135 | 136 | ```javascript 137 | //Let's say the /message endpoint on the provider waits for 138 | //a POST request containing the fields "user_id" and "content" 139 | //and returns the field "id" containing the id of the sent message 140 | OAuth.popup(provider) 141 | .done(function(result) { 142 | result.post('/message', { 143 | data: { 144 | user_id: 93, 145 | content: 'Hello Mr. 93 !' 146 | } 147 | }) 148 | .done(function (response) { 149 | //this will display the id of the message in the console 150 | console.log(response.id); 151 | }) 152 | .fail(function (err) { 153 | //handle error with err 154 | }); 155 | }) 156 | .fail(function (err) { 157 | //handle error with err 158 | }); 159 | ``` 160 | 161 | **PUT Request** 162 | 163 | To make a PUT request, you have to call the `result.post` method like this : 164 | 165 | ```javascript 166 | //Let's say the /profile endpoint on the provider waits for 167 | //a PUT request to update the authenticated user's profile 168 | //containing the field "name" and returns the field "name" 169 | //containing the new name 170 | OAuth.popup(provider) 171 | .done(function(result) { 172 | result.put('/profile', { 173 | data: { 174 | name: "John Williams Doe III" 175 | } 176 | }) 177 | .done(function (response) { 178 | //this will display the new name in the console 179 | console.log(response.name); 180 | }) 181 | .fail(function (err) { 182 | //handle error with err 183 | }); 184 | }) 185 | .fail(function (err) { 186 | //handle error with err 187 | }); 188 | ``` 189 | 190 | **PATCH Request** 191 | 192 | To make a PATCH request, you have to call the `result.patch` method like this : 193 | 194 | ```javascript 195 | //Let's say the /profile endpoint on the provider waits for 196 | //a PATCH request to update the authenticated user's profile 197 | //containing the field "name" and returns the field "name" 198 | //containing the new name 199 | OAuth.popup(provider) 200 | .done(function(result) { 201 | result.patch('/profile', { 202 | data: { 203 | name: "John Williams Doe III" 204 | } 205 | }) 206 | .done(function (response) { 207 | //this will display the new name in the console 208 | console.log(response.name); 209 | }) 210 | .fail(function (err) { 211 | //handle error with err 212 | }); 213 | }) 214 | .fail(function (err) { 215 | //handle error with err 216 | }); 217 | ``` 218 | 219 | **DELETE Request** 220 | 221 | To make a DELETE request, you have to call the `result.del` method like this : 222 | 223 | ```javascript 224 | //Let's say the /picture?id=picture_id endpoint on the provider waits for 225 | //a DELETE request to delete a picture with the id "84" 226 | //and returns true or false depending on the user's rights on the picture 227 | OAuth.popup(provider) 228 | .done(function(result) { 229 | result.del('/picture?id=84') 230 | .done(function (response) { 231 | //this will display true if the user was authorized to delete 232 | //the picture 233 | console.log(response); 234 | }) 235 | .fail(function (err) { 236 | //handle error with err 237 | }); 238 | }) 239 | .fail(function (err) { 240 | //handle error with err 241 | }); 242 | ``` 243 | 244 | **Me() Request** 245 | 246 | The `me()` request is an OAuth.io feature that allows you, when the provider is supported, to retrieve a unified object describing the authenticated user. That can be very useful when you need to login a user via several providers, but don't want to handle a different response each time. 247 | 248 | To use the `me()` feature, do like the following (the example works for Facebook, Github, Twitter and many other providers in this case) : 249 | 250 | ```javascript 251 | //provider can be 'facebook', 'twitter', 'github', or any supported 252 | //provider that contain the fields 'firstname' and 'lastname' 253 | //or an equivalent (e.g. "FirstName" or "first-name") 254 | var provider = 'facebook'; 255 | 256 | OAuth.popup(provider) 257 | .done(function(result) { 258 | result.me() 259 | .done(function (response) { 260 | console.log('Firstname: ', response.firstname); 261 | console.log('Lastname: ', response.lastname); 262 | }) 263 | .fail(function (err) { 264 | //handle error with err 265 | }); 266 | }) 267 | .fail(function (err) { 268 | //handle error with err 269 | }); 270 | ``` 271 | 272 | *Filtering the results* 273 | 274 | You can filter the results of the `me()` method by passing an array of fields you need : 275 | 276 | ```javascript 277 | //... 278 | result.me(['firstname', 'lastname', 'email'/*, ...*/]) 279 | //... 280 | ``` 281 | 282 | 283 | Contributing 284 | ============ 285 | 286 | **Issues** 287 | 288 | Feel free to post issues if you have problems while using this SDK. 289 | 290 | **Pull requests** 291 | 292 | You are welcome to fork and make pull requests. We appreciate the time you spend working on this project and we will be happy to review your code and merge it if it brings nice improvements :) 293 | 294 | If you want to do a pull request, please mind these simple rules : 295 | 296 | - *One feature per pull request* 297 | - *Write lear commit messages* 298 | - *Unit test your feature* : if it's a bug fix for example, write a test that proves the bug exists and that your fix resolves it. 299 | - *Write a clear description of the pull request* 300 | 301 | If you do so, we'll be able to merge your pull request more quickly :) 302 | 303 | Testing the SDK 304 | =============== 305 | 306 | Unit Testing 307 | ------------ 308 | 309 | To test the SDK, you first need to install the npm modules `jasmine-node` and `istanbul` (to get the tests coverage) : 310 | 311 | ```sh 312 | $ sudo npm install -g jasmine-node@2.0.0 istanbul 313 | ``` 314 | 315 | Then you can run the testsuite from the SDK www directory : 316 | 317 | ```sh 318 | $ jasmine-node --verbose tests/unit/spec 319 | ``` 320 | 321 | Once you've installed `istanbul`, you can run the following command to get coverage information : 322 | 323 | ```sh 324 | $ npm test 325 | ``` 326 | 327 | The coverage report is generated in the `coverage` folder. You can have a nice HTML render of the report in `coverage/lcof-report/index.html` 328 | 329 | Running the included samples 330 | ------------------------ 331 | 332 | **Create a new project as described in the [PhoneGap documentation](http://docs.phonegap.com/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface). For example:** 333 | 334 | ```sh 335 | $ phonegap create oauthio-test com.example.oauthio-test OAuthioTest 336 | $ cd oauthio-test 337 | $ phonegap install android 338 | ``` 339 | 340 | **Install OAuth.io plugin into the project** 341 | 342 | ```sh 343 | $ phonegap local plugin add https://github.com/oauth-io/oauth-phonegap 344 | ``` 345 | 346 | **Replace the generated example `index.html` with the one included in the example folder, and copy jquery.** 347 | 348 | A valid key is provided, but you can do your own app on [OAuth.io](https://oauth.io/). Also, please check that your `config.xml` file contains `` or accept oauth.io and the provider's domain (e.g. graph.facebook.com). 349 | 350 | **Plug your phone & run it ! (or add --emulate)** 351 | 352 | ```sh 353 | $ phonegap run android 354 | ``` 355 | 356 | License 357 | ======= 358 | 359 | This SDK is published under the Apache2 License. 360 | 361 | 362 | 363 | More information in [oauth.io documentation](http://oauth.io/#/docs) 364 | -------------------------------------------------------------------------------- /coffee/config.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | oauthd_url: process.env.oauthd_url 3 | oauthd_api: process.env.api_url 4 | version: process.env.sdk_version 5 | options: {} -------------------------------------------------------------------------------- /coffee/lib/api.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | module.exports = (Materia) -> 4 | $ = Materia.getJquery() 5 | apiCall = (type, url, params) => 6 | defer = $.Deferred() 7 | base = Materia.getOAuthdURL() 8 | $.ajax( 9 | url: base + url 10 | type: type 11 | data: params 12 | ).then( 13 | ((data) => defer.resolve data), 14 | ((err) => defer.reject err && err.responseJSON) 15 | ) 16 | return defer.promise() 17 | 18 | return { 19 | get: (url, params) => apiCall 'get', url, params 20 | post: (url, params) => apiCall 'post', url, params 21 | put: (url, params) => apiCall 'put', url, params 22 | del: (url, params) => apiCall 'delete', url, params 23 | } 24 | -------------------------------------------------------------------------------- /coffee/lib/core.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | config = require('../config') 4 | Url = require("../tools/url") 5 | Location = require('../tools/location_operations') 6 | lstorage = require("../tools/lstorage") 7 | cache = require("../tools/cache") 8 | 9 | module.exports = (window, document, jquery, navigator) -> 10 | Url = Url(document) 11 | location_operations = Location document 12 | 13 | cache.init lstorage, config 14 | 15 | Materia = 16 | initialize: (public_key, options) -> 17 | config.key = public_key 18 | if options 19 | for i of options 20 | config.options[i] = options[i] 21 | return 22 | 23 | setOAuthdURL: (url) -> 24 | config.oauthd_url = url 25 | config.oauthd_base = Url.getAbsUrl(config.oauthd_url).match(/^.{2,5}:\/\/[^/]+/)[0] 26 | return 27 | 28 | getOAuthdURL: () -> return config.oauthd_url 29 | getVersion: () -> return config.version 30 | 31 | extend: (name, module) -> 32 | @[name] = module @ 33 | 34 | # private 35 | getConfig: () -> return config 36 | getWindow: () -> return window 37 | getDocument: () -> return document 38 | getNavigator: () -> return navigator 39 | getJquery: () -> return jquery 40 | getUrl: () -> return Url 41 | getCache: () -> return cache 42 | getStorage: () -> return lstorage 43 | getLocationOperations: () -> return location_operations 44 | 45 | return Materia 46 | -------------------------------------------------------------------------------- /coffee/lib/oauth.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | cookies = require("../tools/cookies") 4 | oauthio_requests = require("./request") 5 | sha1 = require("../tools/sha1") 6 | 7 | module.exports = (Materia) -> 8 | Url = Materia.getUrl() 9 | config = Materia.getConfig() 10 | document = Materia.getDocument() 11 | window = Materia.getWindow() 12 | $ = Materia.getJquery() 13 | cache = Materia.getCache() 14 | 15 | providers_api = require('./providers') Materia 16 | 17 | config.oauthd_base = Url.getAbsUrl(config.oauthd_url).match(/^.{2,5}:\/\/[^/]+/)[0] 18 | 19 | client_states = [] 20 | location_operations = Materia.getLocationOperations() 21 | oauthio = request: oauthio_requests(Materia, client_states, providers_api) 22 | 23 | oauth = { 24 | initialize: (public_key, options) -> return Materia.initialize public_key, options 25 | setOAuthdURL: (url) -> 26 | config.oauthd_url = url 27 | config.oauthd_base = Url.getAbsUrl(config.oauthd_url).match(/^.{2,5}:\/\/[^/]+/)[0] 28 | return 29 | create: (provider, tokens, request) -> 30 | return cache.tryCache(oauth, provider, true) unless tokens 31 | providers_api.fetchDescription provider if typeof request isnt "object" 32 | make_res = (method) -> 33 | oauthio.request.mkHttp provider, tokens, request, method 34 | 35 | make_res_endpoint = (method, url) -> 36 | oauthio.request.mkHttpEndpoint provider, tokens, request, method, url 37 | 38 | res = {} 39 | for i of tokens 40 | res[i] = tokens[i] 41 | 42 | res.toJson = -> 43 | a = {} 44 | a.access_token = res.access_token if res.access_token? 45 | a.oauth_token = res.oauth_token if res.oauth_token? 46 | a.oauth_token_secret = res.oauth_token_secret if res.oauth_token_secret? 47 | a.expires_in = res.expires_in if res.expires_in? 48 | a.token_type = res.token_type if res.token_type? 49 | a.id_token = res.id_token if res.id_token? 50 | a.provider = res.provider if res.provider? 51 | a.email = res.email if res.email? 52 | return a 53 | 54 | res.get = make_res("GET") 55 | res.post = make_res("POST") 56 | res.put = make_res("PUT") 57 | res.patch = make_res("PATCH") 58 | res.del = make_res("DELETE") 59 | res.me = oauthio.request.mkHttpMe provider, tokens, request, "GET" 60 | 61 | res 62 | 63 | popup: (provider, opts, callback) -> 64 | gotmessage = false 65 | getMessage = (e) -> 66 | console.log("going in callback") 67 | console.log(JSON.stringify(e)) 68 | if not gotmessage 69 | return if e.origin isnt config.oauthd_base 70 | gotmessage = true 71 | try 72 | wnd.close() 73 | opts.data = e.data 74 | oauthio.request.sendCallback opts, defer 75 | wnd = undefined 76 | frm = undefined 77 | wndTimeout = undefined 78 | defer = $.Deferred() 79 | opts = opts or {} 80 | unless config.key 81 | defer?.reject new Error("OAuth object must be initialized") 82 | if not callback? 83 | return defer.promise() 84 | else 85 | return callback(new Error("OAuth object must be initialized")) 86 | if arguments.length is 2 and typeof opts == 'function' 87 | callback = opts 88 | opts = {} 89 | if cache.cacheEnabled(opts.cache) 90 | res = cache.tryCache(oauth, provider, opts.cache) 91 | if res 92 | defer?.resolve res 93 | if callback 94 | return callback(null, res) 95 | else 96 | return defer.promise() 97 | unless opts.state 98 | opts.state = sha1.create_hash() 99 | opts.state_type = "client" 100 | client_states.push opts.state 101 | url = config.oauthd_url + "/auth/" + provider + "?k=" + config.key 102 | url += '&redirect_uri=http%3A%2F%2Flocalhost' 103 | url += "&opts=" + encodeURIComponent(JSON.stringify(opts)) if opts 104 | 105 | opts.provider = provider 106 | opts.cache = opts.cache 107 | 108 | wndTimeout = setTimeout(-> 109 | defer?.reject new Error("Authorization timed out") 110 | if opts.callback and typeof opts.callback == "function" 111 | opts.callback new Error("Authorization timed out") 112 | try 113 | wnd.close() 114 | return 115 | , 1200 * 1000) 116 | 117 | wnd = window.open(url, "_blank", 'toolbar=yes,closebuttoncaption=Back,presentationstyle=formsheet,toolbarposition=top,clearsessioncache=yes,clearcache=yes') 118 | 119 | wnd.addEventListener "loadstart", (ev) -> 120 | return if ev.url.substr(0, 17) isnt "http://localhost/" 121 | clearTimeout wndTimeout if wndTimeout 122 | results = /[\\#&]oauthio=([^&]*)/.exec(ev.url) 123 | gotmessage = true 124 | wnd.close() 125 | if results and results[1] 126 | opts.data = decodeURIComponent(results[1].replace(/\+/g, " ")) 127 | opts.callback = callback 128 | opts.provider = provider 129 | oauthio.request.sendCallback opts, defer 130 | else 131 | if opts.callback and typeof opts.callback == "function" 132 | opts.callback new Error("unable to receive token") 133 | defer?.reject new Error("unable to receive token") 134 | return 135 | wnd.addEventListener "exit", () -> 136 | if not gotmessage 137 | defer?.reject new Error("The popup was closed") 138 | opts.callback new Error("The popup was closed") if opts.callback and typeof opts.callback == "function" 139 | 140 | return defer?.promise() 141 | 142 | clearCache: (provider) -> 143 | cache.clearCache provider 144 | 145 | http_me: (opts) -> 146 | oauthio.request.http_me opts if oauthio.request.http_me 147 | return 148 | 149 | http: (opts) -> 150 | oauthio.request.http opts if oauthio.request.http 151 | return 152 | getVersion: () -> 153 | Materia.getVersion.apply this 154 | } 155 | return oauth 156 | -------------------------------------------------------------------------------- /coffee/lib/providers.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | config = require("../config") 4 | 5 | module.exports = (Materia) -> 6 | $ = Materia.getJquery() 7 | 8 | providers_desc = {} 9 | providers_cb = {} 10 | providers_api = 11 | execProvidersCb: (provider, e, r) -> 12 | if providers_cb[provider] 13 | cbs = providers_cb[provider] 14 | delete providers_cb[provider] 15 | 16 | for i of cbs 17 | cbs[i] e, r 18 | return 19 | 20 | fetchDescription: (provider) -> 21 | return if providers_desc[provider] 22 | providers_desc[provider] = true 23 | $.ajax( 24 | url: config.oauthd_api + "/providers/" + provider 25 | data: 26 | extend: true 27 | 28 | dataType: "json" 29 | ).done((data) -> 30 | providers_desc[provider] = data.data 31 | providers_api.execProvidersCb provider, null, data.data 32 | return 33 | ).always -> 34 | if typeof providers_desc[provider] isnt "object" 35 | delete providers_desc[provider] 36 | 37 | providers_api.execProvidersCb provider, new Error("Unable to fetch request description") 38 | return 39 | 40 | return 41 | 42 | getDescription: (provider, opts, callback) -> 43 | opts = opts or {} 44 | return callback(null, providers_desc[provider]) if typeof providers_desc[provider] is "object" 45 | providers_api.fetchDescription provider unless providers_desc[provider] 46 | return callback(null, {}) unless opts.wait 47 | providers_cb[provider] = providers_cb[provider] or [] 48 | providers_cb[provider].push callback 49 | return 50 | 51 | return providers_api 52 | -------------------------------------------------------------------------------- /coffee/lib/request.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | Url = require('../tools/url')() 4 | 5 | module.exports = (Materia, client_states, providers_api) -> 6 | $ = Materia.getJquery() 7 | config = Materia.getConfig() 8 | cache = Materia.getCache() 9 | extended_methods = [] 10 | 11 | fetched_methods = false 12 | retrieveMethods: () -> 13 | defer = $.Deferred() 14 | if not fetched_methods 15 | $.ajax(config.oauthd_url + '/api/extended-endpoints') 16 | .then (data) -> 17 | extended_methods = data.data 18 | fetched_methods = true 19 | defer.resolve() 20 | .fail (e) -> 21 | fetched_methods = true 22 | defer.reject(e) 23 | else 24 | defer.resolve extended_methods 25 | return defer.promise() 26 | 27 | generateMethods: (request_object, tokens, provider) -> 28 | if extended_methods? 29 | for v, k in extended_methods 30 | # v is a method to add 31 | name_array = v.name.split '.' 32 | pt = request_object 33 | for vv, kk in name_array 34 | if kk < name_array.length - 1 35 | if not pt[vv]? 36 | pt[vv] = {} 37 | pt = pt[vv] 38 | else 39 | pt[vv] = @mkHttpAll provider, tokens, v, arguments 40 | 41 | http: (opts) -> 42 | doRequest = -> 43 | request = options.oauthio.request or {} 44 | unless request.cors 45 | options.url = encodeURIComponent(options.url) 46 | options.url = "/" + options.url unless options.url[0] is "/" 47 | options.url = config.oauthd_url + "/request/" + options.oauthio.provider + options.url 48 | options.headers = options.headers or {} 49 | options.headers.oauthio = "k=" + config.key 50 | options.headers.oauthio += "&oauthv=1" if options.oauthio.tokens.oauth_token and options.oauthio.tokens.oauth_token_secret # make sure to use oauth 1 51 | for k of options.oauthio.tokens 52 | options.headers.oauthio += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(options.oauthio.tokens[k]) 53 | delete options.oauthio 54 | 55 | return $.ajax(options) 56 | if options.oauthio.tokens 57 | #Fetching the url if a common endpoint is called 58 | options.oauthio.tokens.token = options.oauthio.tokens.access_token if options.oauthio.tokens.access_token 59 | unless options.url.match(/^[a-z]{2,16}:\/\//) 60 | options.url = "/" + options.url if options.url[0] isnt "/" 61 | options.url = request.url + options.url 62 | options.url = Url.replaceParam(options.url, options.oauthio.tokens, request.parameters) 63 | if request.query 64 | qs = [] 65 | for i of request.query 66 | qs.push encodeURIComponent(i) + "=" + encodeURIComponent(Url.replaceParam(request.query[i], options.oauthio.tokens, request.parameters)) 67 | if "?" in options.url 68 | options.url += "&" + qs 69 | else 70 | options.url += "?" + qs 71 | if request.headers 72 | options.headers = options.headers or {} 73 | for i of request.headers 74 | options.headers[i] = Url.replaceParam(request.headers[i], options.oauthio.tokens, request.parameters) 75 | delete options.oauthio 76 | $.ajax options 77 | options = {} 78 | i = undefined 79 | for i of opts 80 | options[i] = opts[i] 81 | if not options.oauthio.request or options.oauthio.request is true 82 | desc_opts = wait: !!options.oauthio.request 83 | defer = $.Deferred() 84 | providers_api.getDescription options.oauthio.provider, desc_opts, (e, desc) -> 85 | return defer.reject(e) if e 86 | if options.oauthio.tokens.oauth_token and options.oauthio.tokens.oauth_token_secret 87 | options.oauthio.request = desc.oauth1 and desc.oauth1.request 88 | else 89 | options.oauthio.request = desc.oauth2 and desc.oauth2.request 90 | defer.resolve() 91 | return 92 | 93 | return defer.then(doRequest) 94 | else 95 | return doRequest() 96 | return 97 | 98 | http_me: (opts) -> 99 | doRequest = -> 100 | defer = $.Deferred() 101 | request = options.oauthio.request or {} 102 | options.url = config.oauthd_url + "/auth/" + options.oauthio.provider + "/me" 103 | options.headers = options.headers or {} 104 | options.headers.oauthio = "k=" + config.key 105 | options.headers.oauthio += "&oauthv=1" if options.oauthio.tokens.oauth_token and options.oauthio.tokens.oauth_token_secret # make sure to use oauth 1 106 | for k of options.oauthio.tokens 107 | options.headers.oauthio += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(options.oauthio.tokens[k]) 108 | delete options.oauthio 109 | 110 | promise = $.ajax(options) 111 | $.when(promise).done((data) -> 112 | defer.resolve data.data 113 | return 114 | ).fail (data) -> 115 | if data.responseJSON 116 | defer.reject data.responseJSON.data 117 | else 118 | defer.reject new Error("An error occured while trying to access the resource") 119 | return 120 | 121 | defer.promise() 122 | options = {} 123 | for k of opts 124 | options[k] = opts[k] 125 | if not options.oauthio.request or options.oauthio.request is true 126 | desc_opts = wait: !!options.oauthio.request 127 | defer = $.Deferred() 128 | providers_api.getDescription options.oauthio.provider, desc_opts, (e, desc) -> 129 | return defer.reject(e) if e 130 | if options.oauthio.tokens.oauth_token and options.oauthio.tokens.oauth_token_secret 131 | options.oauthio.request = desc.oauth1 and desc.oauth1.request 132 | else 133 | options.oauthio.request = desc.oauth2 and desc.oauth2.request 134 | defer.resolve() 135 | return 136 | 137 | return defer.then(doRequest) 138 | else 139 | return doRequest() 140 | return 141 | 142 | http_all: (options, endpoint_descriptor, parameters) -> 143 | doRequest = -> 144 | defer = $.Deferred() 145 | request = options.oauthio.request or {} 146 | options.headers = options.headers or {} 147 | options.headers.oauthio = "k=" + config.key 148 | options.headers.oauthio += "&oauthv=1" if options.oauthio.tokens.oauth_token and options.oauthio.tokens.oauth_token_secret # make sure to use oauth 1 149 | for k of options.oauthio.tokens 150 | options.headers.oauthio += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(options.oauthio.tokens[k]) 151 | delete options.oauthio 152 | 153 | 154 | promise = $.ajax(options) 155 | $.when(promise).done((data) -> 156 | 157 | if typeof data.data == 'string' 158 | try 159 | data.data = JSON.parse data.data 160 | catch error 161 | data.data = data.data 162 | finally 163 | defer.resolve data.data 164 | return 165 | ).fail (data) -> 166 | if data.responseJSON 167 | defer.reject data.responseJSON.data 168 | else 169 | defer.reject new Error("An error occured while trying to access the resource") 170 | return 171 | 172 | defer.promise() 173 | 174 | return doRequest() 175 | 176 | mkHttp: (provider, tokens, request, method) -> 177 | base = this 178 | (opts, opts2) -> 179 | options = {} 180 | if typeof opts is "string" 181 | if typeof opts2 is "object" 182 | for i of opts2 183 | options[i] = opts2[i] 184 | options.url = opts 185 | else if typeof opts is "object" 186 | for i of opts 187 | options[i] = opts[i] 188 | options.type = options.type or method 189 | options.oauthio = 190 | provider: provider 191 | tokens: tokens 192 | request: request 193 | 194 | base.http options 195 | 196 | mkHttpMe: (provider, tokens, request, method) -> 197 | base = this 198 | (filter) -> 199 | options = {} 200 | options.type = options.type or method 201 | options.oauthio = 202 | provider: provider 203 | tokens: tokens 204 | request: request 205 | 206 | options.data = options.data or {} 207 | options.data.filter = filter.join(",") if filter 208 | base.http_me options 209 | 210 | mkHttpAll: (provider, tokens, endpoint_descriptor) -> 211 | base = this 212 | () -> 213 | options = {} 214 | options.type = endpoint_descriptor.method 215 | options.url = config.oauthd_url + endpoint_descriptor.endpoint.replace ':provider', provider 216 | options.oauthio = 217 | provider: provider 218 | tokens: tokens 219 | options.data = {} 220 | for k, v of arguments 221 | th_param = endpoint_descriptor.params[k] 222 | if th_param? 223 | options.data[th_param.name] = v 224 | 225 | options.data = options.data or {} 226 | base.http_all options, endpoint_descriptor, arguments 227 | 228 | sendCallback: (opts, defer) -> 229 | base = this 230 | data = undefined 231 | err = undefined 232 | try 233 | data = JSON.parse(opts.data) 234 | catch e 235 | defer.reject new Error("Error while parsing result") 236 | return opts.callback(new Error("Error while parsing result")) 237 | return if not data or not data.provider 238 | if opts.provider and data.provider.toLowerCase() isnt opts.provider.toLowerCase() 239 | err = new Error("Returned provider name does not match asked provider") 240 | defer.reject err 241 | if opts.callback and typeof opts.callback == "function" 242 | return opts.callback(err) 243 | else 244 | return 245 | if data.status is "error" or data.status is "fail" 246 | err = new Error(data.message) 247 | err.body = data.data 248 | defer.reject err 249 | if opts.callback and typeof opts.callback == "function" 250 | return opts.callback(err) 251 | else 252 | return 253 | if data.status isnt "success" or not data.data 254 | err = new Error() 255 | err.body = data.data 256 | defer.reject err 257 | if opts.callback and typeof opts.callback == "function" 258 | return opts.callback(err) 259 | else 260 | return 261 | 262 | #checking if state is known 263 | data.state = data.state.replace(/\s+/g,"") 264 | i = 0 265 | while i < client_states.length 266 | client_states[i] = client_states[i].replace(/\s+/g,"") 267 | i++ 268 | 269 | if not data.state or client_states.indexOf(data.state) == -1 270 | defer.reject new Error("State is not matching") 271 | if opts.callback and typeof opts.callback == "function" 272 | return opts.callback(new Error("State is not matching")) 273 | else 274 | return 275 | data.data.provider = data.provider unless opts.provider 276 | res = data.data 277 | res.provider = data.provider.toLowerCase() 278 | if cache.cacheEnabled(opts.cache) and res 279 | if opts.expires && ! res.expires_in 280 | res.expires_in = opts.expires 281 | cache.storeCache data.provider, res 282 | request = res.request 283 | delete res.request 284 | 285 | tokens = undefined 286 | if res.access_token 287 | tokens = access_token: res.access_token 288 | else if res.oauth_token and res.oauth_token_secret 289 | tokens = 290 | oauth_token: res.oauth_token 291 | oauth_token_secret: res.oauth_token_secret 292 | unless request 293 | defer.resolve res 294 | if opts.callback and typeof opts.callback == "function" 295 | return opts.callback(null, res) 296 | else 297 | return 298 | if request.required 299 | for i of request.required 300 | tokens[request.required[i]] = res[request.required[i]] 301 | make_res = (method) -> 302 | base.mkHttp data.provider, tokens, request, method 303 | 304 | res.toJson = -> 305 | a = {} 306 | a.access_token = res.access_token if res.access_token? 307 | a.oauth_token = res.oauth_token if res.oauth_token? 308 | a.oauth_token_secret = res.oauth_token_secret if res.oauth_token_secret? 309 | a.expires_in = res.expires_in if res.expires_in? 310 | a.token_type = res.token_type if res.token_type? 311 | a.id_token = res.id_token if res.id_token? 312 | a.provider = res.provider if res.provider? 313 | a.email = res.email if res.email? 314 | return a 315 | 316 | res.get = make_res("GET") 317 | res.post = make_res("POST") 318 | res.put = make_res("PUT") 319 | res.patch = make_res("PATCH") 320 | res.del = make_res("DELETE") 321 | res.me = base.mkHttpMe(data.provider, tokens, request, "GET") 322 | 323 | @retrieveMethods() 324 | .then () => 325 | @generateMethods res, tokens, data.provider 326 | defer.resolve res 327 | if opts.callback and typeof opts.callback == "function" 328 | opts.callback null, res 329 | else 330 | return 331 | .fail (e) => 332 | console.log 'Could not retrieve methods', e 333 | defer.resolve res 334 | if opts.callback and typeof opts.callback == "function" 335 | opts.callback null, res 336 | else 337 | return 338 | -------------------------------------------------------------------------------- /coffee/lib/user.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | module.exports = (Materia) -> 4 | $ = Materia.getJquery() 5 | config = Materia.getConfig() 6 | storage = Materia.getStorage() 7 | 8 | lastSave = null 9 | 10 | class UserObject 11 | constructor: (data) -> 12 | @token = data.token 13 | @data = data.user 14 | @providers = data.providers 15 | lastSave = @getEditableData() 16 | 17 | getEditableData: () -> 18 | data = [] 19 | for key of @data 20 | if ['id', 'email'].indexOf(key) == -1 21 | data.push 22 | key: key 23 | value: @data[key] 24 | return data 25 | 26 | save: () -> 27 | #call to save on stormpath 28 | 29 | dataToSave = {} 30 | for d in lastSave 31 | dataToSave[d.key] = @data[d.key] if @data[d.key] != d.value 32 | delete @data[d.key] if @data[d.key] == null 33 | keyIsInLastSave = (key) -> 34 | for o in lastSave 35 | return true if o.key == key 36 | return false 37 | 38 | for d in @getEditableData() 39 | if !keyIsInLastSave d.key 40 | dataToSave[d.key] = @data[d.key] 41 | @saveLocal() 42 | return Materia.API.put '/api/usermanagement/user?k=' + config.key + '&token=' + @token, dataToSave 43 | 44 | ## todo select(provider) 45 | select: (provider) -> 46 | OAuthResult = null 47 | return OAuthResult 48 | 49 | saveLocal: () -> 50 | copy = token: @token, user: @data, providers: @providers 51 | storage.erase 'oio_auth' 52 | storage.create 'oio_auth', JSON.stringify(copy), 21600 53 | 54 | hasProvider: (provider) -> 55 | return @providers?.indexOf(provider) != -1 56 | 57 | getProviders: () -> 58 | defer = $.Deferred() 59 | Materia.API.get '/api/usermanagement/user/providers?k=' + config.key + '&token=' + @token 60 | .done (providers) => 61 | @providers = providers.data 62 | @saveLocal() 63 | defer.resolve @providers 64 | .fail (err) -> 65 | defer.reject err 66 | return defer.promise() 67 | 68 | addProvider: (oauthRes) -> 69 | defer = $.Deferred() 70 | oauthRes = oauthRes.toJson() if typeof oauthRes.toJson == 'function' 71 | oauthRes.email = @data.email 72 | @providers.push oauthRes.provider 73 | Materia.API.post '/api/usermanagement/user/providers?k=' + config.key + '&token=' + @token, oauthRes 74 | .done (res) => 75 | @data = res.data 76 | @saveLocal() 77 | defer.resolve() 78 | .fail (err) => 79 | @providers.splice @providers.indexOf(oauthRes.provider), 1 80 | defer.reject err 81 | return defer.promise() 82 | 83 | removeProvider: (provider) -> 84 | defer = $.Deferred() 85 | @providers.splice @providers.indexOf(provider), 1 86 | Materia.API.del '/api/usermanagement/user/providers/' + provider + '?k=' + config.key + '&token=' + @token 87 | .done (res) => 88 | @saveLocal() 89 | defer.resolve res 90 | .fail (err) => 91 | @providers.push provider 92 | defer.reject err 93 | return defer.promise() 94 | 95 | # todo - not working 96 | changePassword: (oldPassword, newPassword) -> 97 | return Materia.API.post '/api/usermanagement/user/password?k=' + config.key + '&token=' + @token, 98 | password: newPassword 99 | #oldPassword ? 100 | 101 | #### 0.5.0 => remove this method 102 | isLoggued: () -> 103 | return Materia.User.isLogged() 104 | ########### 105 | 106 | isLogged: () -> 107 | return Materia.User.isLogged() 108 | 109 | logout: () -> 110 | defer = $.Deferred() 111 | storage.erase 'oio_auth' 112 | Materia.API.post('/api/usermanagement/user/logout?k=' + config.key + '&token=' + @token) 113 | .done -> 114 | defer.resolve() 115 | .fail (err)-> 116 | defer.reject err 117 | 118 | return defer.promise() 119 | return { 120 | initialize: (public_key, options) -> return Materia.initialize public_key, options 121 | setOAuthdURL: (url) -> return Materia.setOAuthdURL url 122 | signup: (data) -> 123 | defer = $.Deferred() 124 | data = data.toJson() if typeof data.toJson == 'function' 125 | Materia.API.post '/api/usermanagement/signup?k=' + config.key, data 126 | .done (res) -> 127 | storage.create 'oio_auth', JSON.stringify(res.data), res.data.expires_in || 21600 128 | defer.resolve new UserObject(res.data) 129 | .fail (err) -> 130 | defer.reject err 131 | 132 | return defer.promise() 133 | 134 | signin: (email, password) -> 135 | defer = $.Deferred() 136 | if typeof email != "string" and not password 137 | # signin(OAuthRes) 138 | signinData = email 139 | signinData = signinData.toJson() if typeof signinData.toJson == 'function' 140 | Materia.API.post '/api/usermanagement/signin?k=' + config.key, signinData 141 | .done (res) -> 142 | storage.create 'oio_auth', JSON.stringify(res.data), res.data.expires_in || 21600 143 | defer.resolve new UserObject(res.data) 144 | .fail (err) -> 145 | defer.reject err 146 | else 147 | # signin(email, password) 148 | Materia.API.post('/api/usermanagement/signin?k=' + config.key, 149 | email: email 150 | password: password 151 | ).done((res) -> 152 | storage.create 'oio_auth', JSON.stringify(res.data), res.data.expires_in || 21600 153 | defer.resolve new UserObject(res.data) 154 | ).fail (err) -> 155 | defer.reject err 156 | return defer.promise() 157 | 158 | confirmResetPassword: (newPassword, sptoken) -> 159 | return Materia.API.post '/api/usermanagement/user/password?k=' + config.key, 160 | password: newPassword 161 | token: sptoken 162 | 163 | resetPassword: (email, callback) -> 164 | Materia.API.post '/api/usermanagement/user/password/reset?k=' + config.key, email: email 165 | 166 | refreshIdentity: () -> 167 | defer = $.Deferred() 168 | Materia.API.get('/api/usermanagement/user?k=' + config.key + '&token=' + JSON.parse(storage.read('oio_auth')).token) 169 | .done (res) -> 170 | defer.resolve new UserObject(res.data) 171 | .fail (err) -> 172 | defer.reject err 173 | return defer.promise() 174 | 175 | getIdentity: () -> 176 | user = storage.read 'oio_auth' 177 | return null if not user 178 | return new UserObject(JSON.parse(user)) 179 | 180 | isLogged: () -> 181 | a = storage.read 'oio_auth' 182 | return true if a 183 | return false 184 | } 185 | -------------------------------------------------------------------------------- /coffee/main.coffee: -------------------------------------------------------------------------------- 1 | do -> 2 | jquery = require('./tools/jquery-lite.js') 3 | 4 | Materia = require('./lib/core') window, document, jquery, navigator 5 | Materia.extend 'OAuth', require('./lib/oauth') 6 | Materia.extend 'API', require('./lib/api') 7 | Materia.extend 'User', require('./lib/user') 8 | 9 | if angular? 10 | angular.module 'oauthio', [] 11 | .factory 'Materia', [() -> 12 | return Materia 13 | ] 14 | .factory 'OAuth', [() -> 15 | return Materia.OAuth 16 | ] 17 | .factory 'User', [() -> 18 | return Materia.User 19 | ] 20 | 21 | window.Materia = exports.Materia = Materia 22 | window.User = exports.User = exports.Materia.User 23 | window.OAuth = exports.OAuth = exports.Materia.OAuth 24 | 25 | if (typeof define == 'function' && define.amd) 26 | define -> exports 27 | if (module?.exports) 28 | module.exports = exports 29 | 30 | return exports -------------------------------------------------------------------------------- /coffee/tools/cache.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | module.exports = 4 | init: (storage, config) -> 5 | @config = config 6 | @storage = storage 7 | tryCache: (OAuth, provider, cache) -> 8 | if @cacheEnabled(cache) 9 | cache = @storage.read("oauthio_provider_" + provider) 10 | return false unless cache 11 | cache = decodeURIComponent(cache) 12 | if typeof cache is "string" 13 | try cache = JSON.parse(cache) 14 | catch e 15 | return false 16 | if typeof cache is "object" 17 | res = {} 18 | for i of cache 19 | res[i] = cache[i] if i isnt "request" and typeof cache[i] isnt "function" 20 | return OAuth.create(provider, res, cache.request) 21 | false 22 | 23 | storeCache: (provider, cache) -> 24 | expires = 3600 25 | if cache.expires_in 26 | expires = cache.expires_in 27 | else if @config.options.expires || @config.options.expires == false 28 | expires = @config.options.expires 29 | 30 | @storage.create "oauthio_provider_" + provider, encodeURIComponent(JSON.stringify(cache)), expires 31 | return 32 | 33 | cacheEnabled: (cache) -> 34 | return @config.options.cache if typeof cache is "undefined" 35 | cache 36 | 37 | clearCache: (provider) -> 38 | if provider 39 | @storage.erase "oauthio_provider_" + provider 40 | else 41 | @storage.eraseFrom "oauthio_provider_" 42 | return 43 | -------------------------------------------------------------------------------- /coffee/tools/location_operations.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | module.exports = (document) -> 4 | return { 5 | reload: -> 6 | document.location.reload() 7 | getHash: -> 8 | return document.location.hash 9 | setHash: (newHash) -> 10 | document.location.hash = newHash 11 | changeHref: (newLocation) -> 12 | document.location.href = newLocation 13 | } -------------------------------------------------------------------------------- /coffee/tools/lstorage.coffee: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | useCache = (callback) -> 4 | cacheobj = localStorage.getItem('oauthio_cache') 5 | if cacheobj 6 | cacheobj = JSON.parse(cacheobj) 7 | else 8 | cacheobj = {} 9 | return callback cacheobj, -> 10 | localStorage.setItem('oauthio_cache', JSON.stringify(cacheobj)) 11 | 12 | 13 | module.exports = 14 | init: (config, document) -> 15 | @config = config 16 | @document = document 17 | 18 | active: -> localStorage? 19 | 20 | create: (name, value, expires) -> 21 | @erase name 22 | date = new Date() 23 | localStorage.setItem(name, value) 24 | useCache (cacheobj, cacheupdate) -> 25 | cacheobj[name] = expires ? date.getTime() + (expires or 1200) * 1000 : false 26 | cacheupdate() 27 | return 28 | 29 | read: (name) -> 30 | return useCache (cacheobj, cacheupdate) -> 31 | if ! cacheobj[name]? 32 | return null 33 | if cacheobj[name] == false 34 | return localStorage.getItem(name) 35 | else if (new Date()).getTime() < cacheobj[name] 36 | localStorage.removeItem(name) 37 | delete cacheobj[name] 38 | cacheupdate() 39 | return null 40 | else 41 | return localStorage.getItem(name) 42 | 43 | erase: (name) -> 44 | useCache (cacheobj, cacheupdate) -> 45 | localStorage.removeItem(name) 46 | delete cacheobj[name] 47 | cacheupdate() 48 | 49 | eraseFrom: (prefix) -> 50 | useCache (cacheobj, cacheupdate) -> 51 | cachenames = Object.keys(cacheobj) 52 | for name in cachenames 53 | if name.substr(0, prefix.length) == prefix 54 | localStorage.removeItem(name) 55 | delete cacheobj[name] 56 | cacheupdate() 57 | return -------------------------------------------------------------------------------- /coffee/tools/sha1.coffee: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined 4 | # * in FIPS 180-1 5 | # * Version 2.2 Copyright Paul Johnston 2000 - 2009. 6 | # * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 7 | # * Distributed under the BSD License 8 | # * See http://pajhome.org.uk/crypt/md5 for details. 9 | # 10 | 11 | # 12 | # * Configurable variables. You may need to tweak these to be compatible with 13 | # * the server-side, but the defaults work in most cases. 14 | # 15 | hexcase = 0 # hex output format. 0 - lowercase; 1 - uppercase 16 | b64pad = "" # base-64 pad character. "=" for strict RFC compliance 17 | 18 | # 19 | # * These are the functions you'll usually want to call 20 | # * They take string arguments and return either hex or base-64 encoded strings 21 | # 22 | ### istanbul ignore next ### 23 | module.exports = 24 | hex_sha1: (s) -> 25 | @rstr2hex @rstr_sha1(@str2rstr_utf8(s)) 26 | 27 | b64_sha1: (s) -> 28 | @rstr2b64 @rstr_sha1(@str2rstr_utf8(s)) 29 | 30 | any_sha1: (s, e) -> 31 | @rstr2any @rstr_sha1(@str2rstr_utf8(s)), e 32 | 33 | hex_hmac_sha1: (k, d) -> 34 | @rstr2hex @rstr_hmac_sha1(@str2rstr_utf8(k), @str2rstr_utf8(d)) 35 | 36 | b64_hmac_sha1: (k, d) -> 37 | @rstr2b64 @rstr_hmac_sha1(@str2rstr_utf8(k), @str2rstr_utf8(d)) 38 | 39 | any_hmac_sha1: (k, d, e) -> 40 | @rstr2any @rstr_hmac_sha1(@str2rstr_utf8(k), @str2rstr_utf8(d)), e 41 | 42 | 43 | # 44 | # * Perform a simple self-test to see if the VM is working 45 | # 46 | sha1_vm_test: -> 47 | thishex_sha1("abc").toLowerCase() is "a9993e364706816aba3e25717850c26c9cd0d89d" 48 | 49 | 50 | # 51 | # * Calculate the SHA1 of a raw string 52 | # 53 | rstr_sha1: (s) -> 54 | @binb2rstr @binb_sha1(@rstr2binb(s), s.length * 8) 55 | 56 | 57 | # 58 | # * Calculate the HMAC-SHA1 of a key and some data (raw strings) 59 | # 60 | rstr_hmac_sha1: (key, data) -> 61 | bkey = @rstr2binb(key) 62 | bkey = @binb_sha1(bkey, key.length * 8) if bkey.length > 16 63 | ipad = Array(16) 64 | opad = Array(16) 65 | i = 0 66 | 67 | while i < 16 68 | ipad[i] = bkey[i] ^ 0x36363636 69 | opad[i] = bkey[i] ^ 0x5C5C5C5C 70 | i++ 71 | hash = @binb_sha1(ipad.concat(@rstr2binb(data)), 512 + data.length * 8) 72 | @binb2rstr @binb_sha1(opad.concat(hash), 512 + 160) 73 | 74 | 75 | # 76 | # * Convert a raw string to a hex string 77 | # 78 | rstr2hex: (input) -> 79 | try 80 | hexcase 81 | catch e 82 | hexcase = 0 83 | hex_tab = (if hexcase then "0123456789ABCDEF" else "0123456789abcdef") 84 | output = "" 85 | x = undefined 86 | i = 0 87 | 88 | while i < input.length 89 | x = input.charCodeAt(i) 90 | output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F) 91 | i++ 92 | output 93 | 94 | 95 | # 96 | # * Convert a raw string to a base-64 string 97 | # 98 | rstr2b64: (input) -> 99 | try 100 | b64pad 101 | catch e 102 | b64pad = "" 103 | tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 104 | output = "" 105 | len = input.length 106 | i = 0 107 | 108 | while i < len 109 | triplet = (input.charCodeAt(i) << 16) | ((if i + 1 < len then input.charCodeAt(i + 1) << 8 else 0)) | ((if i + 2 < len then input.charCodeAt(i + 2) else 0)) 110 | j = 0 111 | 112 | while j < 4 113 | if i * 8 + j * 6 > input.length * 8 114 | output += b64pad 115 | else 116 | output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F) 117 | j++ 118 | i += 3 119 | output 120 | 121 | 122 | # 123 | # * Convert a raw string to an arbitrary string encoding 124 | # 125 | rstr2any: (input, encoding) -> 126 | divisor = encoding.length 127 | remainders = Array() 128 | i = undefined 129 | q = undefined 130 | x = undefined 131 | quotient = undefined 132 | 133 | # Convert to an array of 16-bit big-endian values, forming the dividend 134 | dividend = Array(Math.ceil(input.length / 2)) 135 | i = 0 136 | while i < dividend.length 137 | dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1) 138 | i++ 139 | 140 | # 141 | # * Repeatedly perform a long division. The binary array forms the dividend, 142 | # * the length of the encoding is the divisor. Once computed, the quotient 143 | # * forms the dividend for the next step. We stop when the dividend is zero. 144 | # * All remainders are stored for later use. 145 | # 146 | while dividend.length > 0 147 | quotient = Array() 148 | x = 0 149 | i = 0 150 | while i < dividend.length 151 | x = (x << 16) + dividend[i] 152 | q = Math.floor(x / divisor) 153 | x -= q * divisor 154 | quotient[quotient.length] = q if quotient.length > 0 or q > 0 155 | i++ 156 | remainders[remainders.length] = x 157 | dividend = quotient 158 | 159 | # Convert the remainders to the output string 160 | output = "" 161 | i = remainders.length - 1 162 | while i >= 0 163 | output += encoding.charAt(remainders[i]) 164 | i-- 165 | 166 | # Append leading zero equivalents 167 | full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))) 168 | i = output.length 169 | while i < full_length 170 | output = encoding[0] + output 171 | i++ 172 | output 173 | 174 | 175 | # 176 | # * Encode a string as utf-8. 177 | # * For efficiency, this assumes the input is valid utf-16. 178 | # 179 | str2rstr_utf8: (input) -> 180 | output = "" 181 | i = -1 182 | x = undefined 183 | y = undefined 184 | while ++i < input.length 185 | 186 | # Decode utf-16 surrogate pairs 187 | x = input.charCodeAt(i) 188 | y = (if i + 1 < input.length then input.charCodeAt(i + 1) else 0) 189 | if 0xD800 <= x and x <= 0xDBFF and 0xDC00 <= y and y <= 0xDFFF 190 | x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF) 191 | i++ 192 | 193 | # Encode output as utf-8 194 | if x <= 0x7F 195 | output += String.fromCharCode(x) 196 | else if x <= 0x7FF 197 | output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 0x80 | (x & 0x3F)) 198 | else if x <= 0xFFFF 199 | output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F)) 200 | else output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F)) if x <= 0x1FFFFF 201 | output 202 | 203 | 204 | # 205 | # * Encode a string as utf-16 206 | # 207 | str2rstr_utf16le: (input) -> 208 | output = "" 209 | i = 0 210 | 211 | while i < input.length 212 | output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF) 213 | i++ 214 | output 215 | 216 | str2rstr_utf16be: (input) -> 217 | output = "" 218 | i = 0 219 | 220 | while i < input.length 221 | output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF) 222 | i++ 223 | output 224 | 225 | 226 | # 227 | # * Convert a raw string to an array of big-endian words 228 | # * Characters >255 have their high-byte silently ignored. 229 | # 230 | rstr2binb: (input) -> 231 | output = Array(input.length >> 2) 232 | i = 0 233 | 234 | while i < output.length 235 | output[i] = 0 236 | i++ 237 | i = 0 238 | 239 | while i < input.length * 8 240 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32) 241 | i += 8 242 | output 243 | 244 | 245 | # 246 | # * Convert an array of big-endian words to a string 247 | # 248 | binb2rstr: (input) -> 249 | output = "" 250 | i = 0 251 | 252 | while i < input.length * 32 253 | output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF) 254 | i += 8 255 | output 256 | 257 | 258 | # 259 | # * Calculate the SHA-1 of an array of big-endian words, and a bit length 260 | # 261 | binb_sha1: (x, len) -> 262 | 263 | # append padding 264 | x[len >> 5] |= 0x80 << (24 - len % 32) 265 | x[((len + 64 >> 9) << 4) + 15] = len 266 | w = Array(80) 267 | a = 1732584193 268 | b = -271733879 269 | c = -1732584194 270 | d = 271733878 271 | e = -1009589776 272 | i = 0 273 | 274 | while i < x.length 275 | olda = a 276 | oldb = b 277 | oldc = c 278 | oldd = d 279 | olde = e 280 | j = 0 281 | 282 | while j < 80 283 | if j < 16 284 | w[j] = x[i + j] 285 | else 286 | w[j] = @bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1) 287 | t = @safe_add(@safe_add(@bit_rol(a, 5), @sha1_ft(j, b, c, d)), @safe_add(@safe_add(e, w[j]), @sha1_kt(j))) 288 | e = d 289 | d = c 290 | c = @bit_rol(b, 30) 291 | b = a 292 | a = t 293 | j++ 294 | a = @safe_add(a, olda) 295 | b = @safe_add(b, oldb) 296 | c = @safe_add(c, oldc) 297 | d = @safe_add(d, oldd) 298 | e = @safe_add(e, olde) 299 | i += 16 300 | Array a, b, c, d, e 301 | 302 | 303 | # 304 | # * Perform the appropriate triplet combination function for the current 305 | # * iteration 306 | # 307 | sha1_ft: (t, b, c, d) -> 308 | return (b & c) | ((~b) & d) if t < 20 309 | return b ^ c ^ d if t < 40 310 | return (b & c) | (b & d) | (c & d) if t < 60 311 | b ^ c ^ d 312 | 313 | 314 | # 315 | # * Determine the appropriate additive constant for the current iteration 316 | # 317 | sha1_kt: (t) -> 318 | (if (t < 20) then 1518500249 else (if (t < 40) then 1859775393 else (if (t < 60) then -1894007588 else -899497514))) 319 | 320 | 321 | # 322 | # * Add integers, wrapping at 2^32. This uses 16-bit operations internally 323 | # * to work around bugs in some JS interpreters. 324 | # 325 | safe_add: (x, y) -> 326 | lsw = (x & 0xFFFF) + (y & 0xFFFF) 327 | msw = (x >> 16) + (y >> 16) + (lsw >> 16) 328 | (msw << 16) | (lsw & 0xFFFF) 329 | 330 | 331 | # 332 | # * Bitwise rotate a 32-bit number to the left. 333 | # 334 | bit_rol: (num, cnt) -> 335 | (num << cnt) | (num >>> (32 - cnt)) 336 | 337 | create_hash: -> 338 | hash = @b64_sha1((new Date()).getTime() + ":" + Math.floor(Math.random() * 9999999)) 339 | hash.replace(/\+/g, "-").replace(/\//g, "_").replace /\=+$/, "" 340 | -------------------------------------------------------------------------------- /coffee/tools/url.coffee: -------------------------------------------------------------------------------- 1 | module.exports = (document) -> 2 | getAbsUrl: (url) -> 3 | return url if url.match(/^.{2,5}:\/\//) 4 | return document.location.protocol + "//" + document.location.host + url if url[0] is "/" 5 | base_url = document.location.protocol + "//" + document.location.host + document.location.pathname 6 | return base_url + "/" + url if base_url[base_url.length - 1] isnt "/" and url[0] isnt "#" 7 | base_url + url 8 | 9 | replaceParam: (param, rep, rep2) -> 10 | param = param.replace(/\{\{(.*?)\}\}/g, (m, v) -> 11 | rep[v] or "" 12 | ) 13 | if rep2 14 | param = param.replace(/\{(.*?)\}/g, (m, v) -> 15 | rep2[v] or "" 16 | ) 17 | param 18 | -------------------------------------------------------------------------------- /compile-jquery.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # In the jquery sources folder, you have to: 3 | # 4 | # git clone git@github.com:jquery/jquery.git 5 | # git checkout 2.1.1 6 | # npm install 7 | # 8 | # Make sure to have grunt-cli installed with 9 | # npm install -g grunt-cli 10 | 11 | OAUTHJS_PATH=`pwd` 12 | JQUERY_PATH="../jquery" 13 | 14 | cd $JQUERY_PATH 15 | grunt custom:-attributes,-attributes/attr,-attributes/classes,-attributes/prop,-attributes/support,-attributes/val,-attributes,-css/addGetHookIf,-css/curCSS,-css/defaultDisplay,-css/hiddenVisibleSelectors,-css/support,-css/swap,-css/var,-css/var/cssExpand,-css/var/getStyles,-css/var/isHidden,-css/var/rmargin,-css/var/rnumnonpx,-css,-data/var/data_user,-deprecated,-dimensions,-effects,-effects/animatedSelector,-effects/Tween,-event/alias,-event/support,-intro,-manipulation/_evalUrl,-manipulation/support,-manipulation/var,-manipulation/var/rcheckableType,-manipulation,-offset,-outro,-queue,-queue/delay,-selector-native,-selector-sizzle,-sizzle,-sizzle/dist,-sizzle/dist/sizzle,-sizzle/test,-traversing,-traversing/findFilter,-traversing/var,-traversing/var/rneedsContext,-wrap,-exports,-exports/global,-exports/amd 16 | cat ./dist/jquery.js | head -n $((`cat ./dist/jquery.js | wc -l`-2)) > ./dist/jquery-lite.js 17 | LASTLINES=`cat ./dist/jquery.js | tail -n 1` 18 | echo 'return jQuery;' >> ./dist/jquery-lite.js 19 | echo $LASTLINES >> ./dist/jquery-lite.js 20 | 21 | cd $OAUTHJS_PATH 22 | cp $JQUERY_PATH/dist/jquery-lite.js ./js/tools/jquery-lite.js && echo "copied jquery to oauth-js" 23 | grunt && echo "compiled oauth-js" 24 | -------------------------------------------------------------------------------- /dist/oauth.min.js: -------------------------------------------------------------------------------- 1 | !function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.oauthioPhonegap=a()}}(function(){var a;return function b(a,c,d){function e(g,h){if(!c[g]){if(!a[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};a[g][0].call(k.exports,function(b){var c=a[g][1][b];return e(c?c:b)},k,k.exports,b,a,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gb;b++)if(b in this&&this[b]===a)return b;return-1};d=a("../tools/url")(),b.exports=function(a,b,c){var f,g,h,i,j;return f=a.getJquery(),h=a.getConfig(),g=a.getCache(),i=[],j=!1,{retrieveMethods:function(){var a;return a=f.Deferred(),j?a.resolve(i):f.ajax(h.oauthd_url+"/api/extended-endpoints").then(function(b){return i=b.data,j=!0,a.resolve()}).fail(function(b){return j=!0,a.reject(b)}),a.promise()},generateMethods:function(a,b,c){var d,e,f,g,h,j,k,l,m;if(null!=i){for(k=[],e=d=0,g=i.length;g>d;e=++d)l=i[e],h=l.name.split("."),j=a,k.push(function(){var a,d,e;for(e=[],f=a=0,d=h.length;d>a;f=++a)m=h[f],f=0?k.url+="&"+c:k.url+="?"+c}if(g.headers){k.headers=k.headers||{};for(a in g.headers)k.headers[a]=d.replaceParam(g.headers[a],k.oauthio.tokens,g.parameters)}return delete k.oauthio,f.ajax(k)}},k={},j=void 0;for(j in a)k[j]=a[j];return k.oauthio.request&&k.oauthio.request!==!0?i():(g={wait:!!k.oauthio.request},b=f.Deferred(),c.getDescription(k.oauthio.provider,g,function(a,c){return a?b.reject(a):(k.oauthio.tokens.oauth_token&&k.oauthio.tokens.oauth_token_secret?k.oauthio.request=c.oauth1&&c.oauth1.request:k.oauthio.request=c.oauth2&&c.oauth2.request,void b.resolve())}),b.then(i))},http_me:function(a){var b,d,e,g,i;e=function(){var a,b,c,d;a=f.Deferred(),d=i.oauthio.request||{},i.url=h.oauthd_url+"/auth/"+i.oauthio.provider+"/me",i.headers=i.headers||{},i.headers.oauthio="k="+h.key,i.oauthio.tokens.oauth_token&&i.oauthio.tokens.oauth_token_secret&&(i.headers.oauthio+="&oauthv=1");for(b in i.oauthio.tokens)i.headers.oauthio+="&"+encodeURIComponent(b)+"="+encodeURIComponent(i.oauthio.tokens[b]);return delete i.oauthio,c=f.ajax(i),f.when(c).done(function(b){a.resolve(b.data)}).fail(function(b){b.responseJSON?a.reject(b.responseJSON.data):a.reject(new Error("An error occured while trying to access the resource"))}),a.promise()},i={};for(g in a)i[g]=a[g];return i.oauthio.request&&i.oauthio.request!==!0?e():(d={wait:!!i.oauthio.request},b=f.Deferred(),c.getDescription(i.oauthio.provider,d,function(a,c){return a?b.reject(a):(i.oauthio.tokens.oauth_token&&i.oauthio.tokens.oauth_token_secret?i.oauthio.request=c.oauth1&&c.oauth1.request:i.oauthio.request=c.oauth2&&c.oauth2.request,void b.resolve())}),b.then(e))},http_all:function(a,b,c){var d;return(d=function(){var b,c,d,e;b=f.Deferred(),e=a.oauthio.request||{},a.headers=a.headers||{},a.headers.oauthio="k="+h.key,a.oauthio.tokens.oauth_token&&a.oauthio.tokens.oauth_token_secret&&(a.headers.oauthio+="&oauthv=1");for(c in a.oauthio.tokens)a.headers.oauthio+="&"+encodeURIComponent(c)+"="+encodeURIComponent(a.oauthio.tokens[c]);return delete a.oauthio,d=f.ajax(a),f.when(d).done(function(a){var c;if("string"==typeof a.data)try{a.data=JSON.parse(a.data)}catch(d){c=d,a.data=a.data}finally{b.resolve(a.data)}}).fail(function(a){a.responseJSON?b.reject(a.responseJSON.data):b.reject(new Error("An error occured while trying to access the resource"))}),b.promise()})()},mkHttp:function(a,b,c,d){var e;return e=this,function(f,g){var h,i;if(i={},"string"==typeof f){if("object"==typeof g)for(h in g)i[h]=g[h];i.url=f}else if("object"==typeof f)for(h in f)i[h]=f[h];return i.type=i.type||d,i.oauthio={provider:a,tokens:b,request:c},e.http(i)}},mkHttpMe:function(a,b,c,d){var e;return e=this,function(f){var g;return g={},g.type=g.type||d,g.oauthio={provider:a,tokens:b,request:c},g.data=g.data||{},f&&(g.data.filter=f.join(",")),e.http_me(g)}},mkHttpAll:function(a,b,c){var d;return d=this,function(){var e,f,g,i;f={},f.type=c.method,f.url=h.oauthd_url+c.endpoint.replace(":provider",a),f.oauthio={provider:a,tokens:b},f.data={};for(e in arguments)i=arguments[e],g=c.params[e],null!=g&&(f.data[g.name]=i);return f.data=f.data||{},d.http_all(f,c,arguments)}},sendCallback:function(a,c){var d,e,f,h,i,j,k,l,m;d=this,e=void 0,h=void 0;try{e=JSON.parse(a.data)}catch(n){return f=n,c.reject(new Error("Error while parsing result")),a.callback(new Error("Error while parsing result"))}if(e&&e.provider){if(a.provider&&e.provider.toLowerCase()!==a.provider.toLowerCase())return h=new Error("Returned provider name does not match asked provider"),c.reject(h),a.callback&&"function"==typeof a.callback?a.callback(h):void 0;if("error"===e.status||"fail"===e.status)return h=new Error(e.message),h.body=e.data,c.reject(h),a.callback&&"function"==typeof a.callback?a.callback(h):void 0;if("success"!==e.status||!e.data)return h=new Error,h.body=e.data,c.reject(h),a.callback&&"function"==typeof a.callback?a.callback(h):void 0;for(e.state=e.state.replace(/\s+/g,""),i=0;if;f++)b=e[f],this.data[b.key]!==b.value&&(c[b.key]=this.data[b.key]),null===this.data[b.key]&&delete this.data[b.key];for(h=function(a){var b,c,d;for(b=0,c=e.length;c>b;b++)if(d=e[b],d.key===a)return!0;return!1},k=this.getEditableData(),g=0,j=k.length;j>g;g++)b=k[g],h(b.key)||(c[b.key]=this.data[b.key]);return this.saveLocal(),a.API.put("/api/usermanagement/user?k="+d.key+"&token="+this.token,c)},c.prototype.select=function(a){var b;return b=null},c.prototype.saveLocal=function(){var a;return a={token:this.token,user:this.data,providers:this.providers},f.erase("oio_auth"),f.create("oio_auth",JSON.stringify(a),21600)},c.prototype.hasProvider=function(a){var b;return-1!==(null!=(b=this.providers)?b.indexOf(a):void 0)},c.prototype.getProviders=function(){var c;return c=b.Deferred(),a.API.get("/api/usermanagement/user/providers?k="+d.key+"&token="+this.token).done(function(a){return function(b){return a.providers=b.data,a.saveLocal(),c.resolve(a.providers)}}(this)).fail(function(a){return c.reject(a)}),c.promise()},c.prototype.addProvider=function(c){var e;return e=b.Deferred(),"function"==typeof c.toJson&&(c=c.toJson()),c.email=this.data.email,this.providers.push(c.provider),a.API.post("/api/usermanagement/user/providers?k="+d.key+"&token="+this.token,c).done(function(a){return function(b){return a.data=b.data,a.saveLocal(),e.resolve()}}(this)).fail(function(a){return function(b){return a.providers.splice(a.providers.indexOf(c.provider),1),e.reject(b)}}(this)),e.promise()},c.prototype.removeProvider=function(c){var e;return e=b.Deferred(),this.providers.splice(this.providers.indexOf(c),1),a.API.del("/api/usermanagement/user/providers/"+c+"?k="+d.key+"&token="+this.token).done(function(a){return function(b){return a.saveLocal(),e.resolve(b)}}(this)).fail(function(a){return function(b){return a.providers.push(c),e.reject(b)}}(this)),e.promise()},c.prototype.changePassword=function(b,c){return a.API.post("/api/usermanagement/user/password?k="+d.key+"&token="+this.token,{password:c})},c.prototype.isLoggued=function(){return a.User.isLogged()},c.prototype.isLogged=function(){return a.User.isLogged()},c.prototype.logout=function(){var c;return c=b.Deferred(),f.erase("oio_auth"),a.API.post("/api/usermanagement/user/logout?k="+d.key+"&token="+this.token).done(function(){return c.resolve()}).fail(function(a){return c.reject(a)}),c.promise()},c}(),{initialize:function(b,c){return a.initialize(b,c)},setOAuthdURL:function(b){return a.setOAuthdURL(b)},signup:function(e){var g;return g=b.Deferred(),"function"==typeof e.toJson&&(e=e.toJson()),a.API.post("/api/usermanagement/signup?k="+d.key,e).done(function(a){return f.create("oio_auth",JSON.stringify(a.data),a.data.expires_in||21600),g.resolve(new c(a.data))}).fail(function(a){return g.reject(a)}),g.promise()},signin:function(e,g){var h,i;return h=b.Deferred(),"string"==typeof e||g?a.API.post("/api/usermanagement/signin?k="+d.key,{email:e,password:g}).done(function(a){return f.create("oio_auth",JSON.stringify(a.data),a.data.expires_in||21600),h.resolve(new c(a.data))}).fail(function(a){return h.reject(a)}):(i=e,"function"==typeof i.toJson&&(i=i.toJson()),a.API.post("/api/usermanagement/signin?k="+d.key,i).done(function(a){return f.create("oio_auth",JSON.stringify(a.data),a.data.expires_in||21600),h.resolve(new c(a.data))}).fail(function(a){return h.reject(a)})),h.promise()},confirmResetPassword:function(b,c){return a.API.post("/api/usermanagement/user/password?k="+d.key,{password:b,token:c})},resetPassword:function(b,c){return a.API.post("/api/usermanagement/user/password/reset?k="+d.key,{email:b})},refreshIdentity:function(){var e;return e=b.Deferred(),a.API.get("/api/usermanagement/user?k="+d.key+"&token="+JSON.parse(f.read("oio_auth")).token).done(function(a){return e.resolve(new c(a.data))}).fail(function(a){return e.reject(a)}),e.promise()},getIdentity:function(){var a;return a=f.read("oio_auth"),a?new c(JSON.parse(a)):null},isLogged:function(){var a;return a=f.read("oio_auth"),a?!0:!1}}}},{}],8:[function(b,c,d){!function(){var e,f;return f=b("./tools/jquery-lite.js"),e=b("./lib/core")(window,document,f,navigator),e.extend("OAuth",b("./lib/oauth")),e.extend("API",b("./lib/api")),e.extend("User",b("./lib/user")),"undefined"!=typeof angular&&null!==angular&&angular.module("oauthio",[]).factory("Materia",[function(){return e}]).factory("OAuth",[function(){return e.OAuth}]).factory("User",[function(){return e.User}]),window.Materia=d.Materia=e,window.User=d.User=d.Materia.User,window.OAuth=d.OAuth=d.Materia.OAuth,"function"==typeof a&&a.amd&&a(function(){return d}),("undefined"!=typeof c&&null!==c?c.exports:void 0)&&(c.exports=d),d}()},{"./lib/api":2,"./lib/core":3,"./lib/oauth":4,"./lib/user":7,"./tools/jquery-lite.js":11}],9:[function(a,b,c){"use strict";b.exports={init:function(a,b){return this.config=b,this.storage=a},tryCache:function(a,b,c){var d,e,f;if(this.cacheEnabled(c)){if(c=this.storage.read("oauthio_provider_"+b),!c)return!1;c=decodeURIComponent(c)}if("string"==typeof c)try{c=JSON.parse(c)}catch(g){return d=g,!1}if("object"==typeof c){f={};for(e in c)"request"!==e&&"function"!=typeof c[e]&&(f[e]=c[e]);return a.create(b,f,c.request)}return!1},storeCache:function(a,b){var c;c=3600,b.expires_in?c=b.expires_in:(this.config.options.expires||this.config.options.expires===!1)&&(c=this.config.options.expires),this.storage.create("oauthio_provider_"+a,encodeURIComponent(JSON.stringify(b)),c)},cacheEnabled:function(a){return"undefined"==typeof a?this.config.options.cache:a},clearCache:function(a){a?this.storage.erase("oauthio_provider_"+a):this.storage.eraseFrom("oauthio_provider_")}}},{}],10:[function(a,b,c){"use strict";b.exports={init:function(a,b){return this.config=a,this.document=b},create:function(a,b,c){var d;this.erase(a),d=new Date,c?d.setTime(d.getTime()+1e3*(c||1200)):d.setFullYear(d.getFullYear()+3),c="; expires="+d.toGMTString(),this.document.cookie=a+"="+b+c+"; path=/"},read:function(a){var b,c,d,e;for(e=a+"=",c=this.document.cookie.split(";"),d=0;de;e++)c=d[e],b=c.split("=")[0].trim(),b.substr(0,a.length)===a&&this.erase(b)}}},{}],11:[function(a,b,c){!function(a,c){"object"==typeof b&&"object"==typeof b.exports?b.exports=a.document?c(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return c(a)}:c(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b=a.length,c=B.type(a);return"function"===c||B.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a){var b=L[a]={};return B.each(a.match(K)||[],function(a,c){b[c]=!0}),b}function e(){z.removeEventListener("DOMContentLoaded",e,!1),a.removeEventListener("load",e,!1),B.ready()}function f(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=B.expando+Math.random()}function g(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?B.parseJSON(c):c}catch(e){}data_user.set(a,b,c)}else c=void 0;return c}function h(){return!0}function i(){return!1}function j(){try{return z.activeElement}catch(a){}}function k(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(B.isFunction(c))for(;d=f[e++];)"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function l(a,b,c,d){function e(h){var i;return f[h]=!0,B.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||g||f[j]?g?!(i=j):void 0:(b.dataTypes.unshift(j),e(j),!1)}),i}var f={},g=a===ga;return e(b.dataTypes[0])||!f["*"]&&e("*")}function m(a,b){var c,d,e=B.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&B.extend(!0,a,d),a}function n(a,b,c){for(var d,e,f,g,h=a.contents,i=a.dataTypes;"*"===i[0];)i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function o(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];for(f=k.shift();f;)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}function p(a,b,c,d){var e;if(B.isArray(b))B.each(b,function(b,e){c||ka.test(a)?d(a,e):p(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==B.type(b))d(a,b);else for(e in b)p(a+"["+e+"]",b[e],c,d)}var q=[],r=q.slice,s=q.concat,t=q.push,u=q.indexOf,v={},w=v.toString,x=v.hasOwnProperty,y={},z=a.document,A="2.1.1 -attributes,-attributes/attr,-attributes/classes,-attributes/prop,-attributes/support,-attributes/val,-css/addGetHookIf,-css/curCSS,-css/defaultDisplay,-css/hiddenVisibleSelectors,-css/support,-css/swap,-css/var,-css/var/cssExpand,-css/var/getStyles,-css/var/isHidden,-css/var/rmargin,-css/var/rnumnonpx,-css,-effects,-effects/Tween,-effects/animatedSelector,-dimensions,-offset,-data/var/data_user,-deprecated,-event/alias,-event/support,-intro,-manipulation/_evalUrl,-manipulation/support,-manipulation/var,-manipulation/var/rcheckableType,-manipulation,-outro,-queue,-queue/delay,-selector-native,-selector-sizzle,-sizzle/dist,-sizzle/dist/sizzle,-sizzle/dist/min,-sizzle/test,-sizzle/test/jquery,-traversing,-traversing/findFilter,-traversing/var/rneedsContext,-traversing/var,-wrap,-exports,-exports/amd",B=function(a,b){return new B.fn.init(a,b)},C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,D=/^-ms-/,E=/-([\da-z])/gi,F=function(a,b){return b.toUpperCase()};B.fn=B.prototype={jquery:A,constructor:B,selector:"",length:0,toArray:function(){return r.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:r.call(this)},pushStack:function(a){var b=B.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return B.each(this,a,b)},map:function(a){return this.pushStack(B.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(r.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:t,sort:q.sort,splice:q.splice},B.extend=B.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||B.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(B.isPlainObject(d)||(e=B.isArray(d)))?(e?(e=!1,f=c&&B.isArray(c)?c:[]):f=c&&B.isPlainObject(c)?c:{},g[b]=B.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},B.extend({expando:"jQuery"+(A+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===B.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!B.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==B.type(a)||a.nodeType||B.isWindow(a)?!1:a.constructor&&!x.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?v[w.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=B.trim(a),a&&(1===a.indexOf("use strict")?(b=z.createElement("script"),b.text=a,z.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(D,"ms-").replace(E,F)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,d){var e,f=0,g=a.length,h=c(a);if(d){if(h)for(;g>f&&(e=b.apply(a[f],d),e!==!1);f++);else for(f in a)if(e=b.apply(a[f],d),e===!1)break}else if(h)for(;g>f&&(e=b.call(a[f],f,a[f]),e!==!1);f++);else for(f in a)if(e=b.call(a[f],f,a[f]),e===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(C,"")},makeArray:function(a,b){var d=b||[];return null!=a&&(c(Object(a))?B.merge(d,"string"==typeof a?[a]:a):t.call(d,a)),d},inArray:function(a,b,c){return null==b?-1:u.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,d){var e,f=0,g=a.length,h=c(a),i=[];if(h)for(;g>f;f++)e=b(a[f],f,d),null!=e&&i.push(e);else for(f in a)e=b(a[f],f,d),null!=e&&i.push(e);return s.apply([],i)},guid:1,proxy:function(a,b){var c,d,e;return"string"==typeof b&&(c=a[b],b=a,a=c),B.isFunction(a)?(d=r.call(arguments,2),e=function(){return a.apply(b||this,d.concat(r.call(arguments)))},e.guid=a.guid=a.guid||B.guid++,e):void 0},now:Date.now,support:y}),B.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){v["[object "+b+"]"]=b.toLowerCase()});var G,H=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,I=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,J=B.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:I.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||G).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof B?b[0]:b,B.merge(this,B.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),H.test(c[1])&&B.isPlainObject(b))for(c in b)B.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=z.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):B.isFunction(a)?"undefined"!=typeof G.ready?G.ready(a):a(B):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),B.makeArray(a,this))};J.prototype=B.fn,G=B(z);var K=/\S+/g,L={};B.Callbacks=function(a){a="string"==typeof a?L[a]||d(a):B.extend({},a);var b,c,e,f,g,h,i=[],j=!a.once&&[],k=function(d){for(b=a.memory&&d,c=!0,h=f||0,f=0,g=i.length,e=!0;i&&g>h;h++)if(i[h].apply(d[0],d[1])===!1&&a.stopOnFalse){b=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):b?i=[]:l.disable())},l={add:function(){if(i){var c=i.length;!function d(b){B.each(b,function(b,c){var e=B.type(c);"function"===e?a.unique&&l.has(c)||i.push(c):c&&c.length&&"string"!==e&&d(c)})}(arguments),e?g=i.length:b&&(f=c,k(b))}return this},remove:function(){return i&&B.each(arguments,function(a,b){for(var c;(c=B.inArray(b,i,c))>-1;)i.splice(c,1),e&&(g>=c&&g--,h>=c&&h--)}),this},has:function(a){return a?B.inArray(a,i)>-1:!(!i||!i.length)},empty:function(){return i=[],g=0,this},disable:function(){return i=j=b=void 0,this},disabled:function(){return!i},lock:function(){return j=void 0,b||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return!i||c&&!j||(b=b||[],b=[a,b.slice?b.slice():b],e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!c}};return l},B.extend({Deferred:function(a){var b=[["resolve","done",B.Callbacks("once memory"),"resolved"],["reject","fail",B.Callbacks("once memory"),"rejected"],["notify","progress",B.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return B.Deferred(function(c){B.each(b,function(b,f){var g=B.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&B.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?B.extend(a,d):d}},e={};return d.pipe=d.then,B.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b,c,d,e=0,f=r.call(arguments),g=f.length,h=1!==g||a&&B.isFunction(a.promise)?g:0,i=1===h?a:B.Deferred(),j=function(a,c,d){return function(e){c[a]=this,d[a]=arguments.length>1?r.call(arguments):e,d===b?i.notifyWith(c,d):--h||i.resolveWith(c,d)}};if(g>1)for(b=new Array(g),c=new Array(g),d=new Array(g);g>e;e++)f[e]&&B.isFunction(f[e].promise)?f[e].promise().done(j(e,d,f)).fail(i.reject).progress(j(e,c,b)):--h;return h||i.resolveWith(d,f),i.promise()}});var M;B.fn.ready=function(a){return B.ready.promise().done(a),this},B.extend({isReady:!1, 2 | readyWait:1,holdReady:function(a){a?B.readyWait++:B.ready(!0)},ready:function(a){(a===!0?--B.readyWait:B.isReady)||(B.isReady=!0,a!==!0&&--B.readyWait>0||(M.resolveWith(z,[B]),B.fn.triggerHandler&&(B(z).triggerHandler("ready"),B(z).off("ready"))))}}),B.ready.promise=function(b){return M||(M=B.Deferred(),"complete"===z.readyState?setTimeout(B.ready):(z.addEventListener("DOMContentLoaded",e,!1),a.addEventListener("load",e,!1))),M.promise(b)},B.ready.promise();var N=B.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===B.type(c)){e=!0;for(h in c)B.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,B.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(B(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};B.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType},f.uid=1,f.accepts=B.acceptData,f.prototype={key:function(a){if(!f.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=f.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,B.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(B.isEmptyObject(f))B.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,B.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{B.isArray(b)?d=b.concat(b.map(B.camelCase)):(e=B.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(K)||[])),c=d.length;for(;c--;)delete g[d[c]]}},hasData:function(a){return!B.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var O=new f,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/([A-Z])/g;B.extend({hasData:function(a){return data_user.hasData(a)||O.hasData(a)},data:function(a,b,c){return data_user.access(a,b,c)},removeData:function(a,b){data_user.remove(a,b)},_data:function(a,b,c){return O.access(a,b,c)},_removeData:function(a,b){O.remove(a,b)}}),B.fn.extend({data:function(a,b){var c,d,e,f=this[0],h=f&&f.attributes;if(void 0===a){if(this.length&&(e=data_user.get(f),1===f.nodeType&&!O.get(f,"hasDataAttrs"))){for(c=h.length;c--;)h[c]&&(d=h[c].name,0===d.indexOf("data-")&&(d=B.camelCase(d.slice(5)),g(f,d,e[d])));O.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){data_user.set(this,a)}):N(this,function(b){var c,d=B.camelCase(a);if(f&&void 0===b){if(c=data_user.get(f,a),void 0!==c)return c;if(c=data_user.get(f,d),void 0!==c)return c;if(c=g(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=data_user.get(this,d);data_user.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&data_user.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){data_user.remove(this,a)})}});var R=(/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,"undefined"),S=/^key/,T=/^(?:mouse|pointer|contextmenu)|click/,U=/^(?:focusinfocus|focusoutblur)$/,V=/^([^.]*)(?:\.(.+)|)$/;B.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=O.get(a);if(q)for(c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=B.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return typeof B!==R&&B.event.triggered!==b.type?B.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;j--;)h=V.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=B.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=B.event.special[n]||{},k=B.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&B.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),B.event.global[n]=!0)},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=O.hasData(a)&&O.get(a);if(q&&(i=q.events)){for(b=(b||"").match(K)||[""],j=b.length;j--;)if(h=V.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){for(l=B.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;f--;)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||B.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)B.event.remove(a,n+b[j],c,d,!0);B.isEmptyObject(i)&&(delete q.handle,O.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,j,k,l,m=[d||z],n=x.call(b,"type")?b.type:b,o=x.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!U.test(n+B.event.triggered)&&(n.indexOf(".")>=0&&(o=n.split("."),n=o.shift(),o.sort()),j=n.indexOf(":")<0&&"on"+n,b=b[B.expando]?b:new B.Event(n,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=o.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:B.makeArray(c,[b]),l=B.event.special[n]||{},e||!l.trigger||l.trigger.apply(d,c)!==!1)){if(!e&&!l.noBubble&&!B.isWindow(d)){for(i=l.delegateType||n,U.test(i+n)||(g=g.parentNode);g;g=g.parentNode)m.push(g),h=g;h===(d.ownerDocument||z)&&m.push(h.defaultView||h.parentWindow||a)}for(f=0;(g=m[f++])&&!b.isPropagationStopped();)b.type=f>1?i:l.bindType||n,k=(O.get(g,"events")||{})[b.type]&&O.get(g,"handle"),k&&k.apply(g,c),k=j&&g[j],k&&k.apply&&B.acceptData(g)&&(b.result=k.apply(g,c),b.result===!1&&b.preventDefault());return b.type=n,e||b.isDefaultPrevented()||l._default&&l._default.apply(m.pop(),c)!==!1||!B.acceptData(d)||j&&B.isFunction(d[n])&&!B.isWindow(d)&&(h=d[j],h&&(d[j]=null),B.event.triggered=n,d[n](),B.event.triggered=void 0,h&&(d[j]=h)),b.result}},dispatch:function(a){a=B.event.fix(a);var b,c,d,e,f,g=[],h=r.call(arguments),i=(O.get(this,"events")||{})[a.type]||[],j=B.event.special[a.type]||{};if(h[0]=a,a.delegateTarget=this,!j.preDispatch||j.preDispatch.call(this,a)!==!1){for(g=B.event.handlers.call(this,a,i),b=0;(e=g[b++])&&!a.isPropagationStopped();)for(a.currentTarget=e.elem,c=0;(f=e.handlers[c++])&&!a.isImmediatePropagationStopped();)(!a.namespace_re||a.namespace_re.test(f.namespace))&&(a.handleObj=f,a.data=f.data,d=((B.event.special[f.origType]||{}).handle||f.handler).apply(e.elem,h),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()));return j.postDispatch&&j.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?B(e,this).index(i)>=0:B.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h0?4:0,i=a>=200&&300>a||304===a,c&&(u=n(m,y,c)),u=o(m,u,y,i),i?(m.ifModified&&(v=y.getResponseHeader("Last-Modified"),v&&(B.lastModified[e]=v),v=y.getResponseHeader("etag"),v&&(B.etag[e]=v)),204===a||"HEAD"===m.type?x="nocontent":304===a?x="notmodified":(x=u.state,k=u.data,l=u.error,i=!l)):(l=x,(a||!x)&&(x="error",0>a&&(a=0))),y.status=a,y.statusText=(b||x)+"",i?r.resolveWith(p,[k,x,y]):r.rejectWith(p,[y,x,l]),y.statusCode(t),t=void 0,j&&q.trigger(i?"ajaxSuccess":"ajaxError",[y,m,i?k:l]),s.fireWith(p,[y,x]),j&&(q.trigger("ajaxComplete",[y,m]),--B.active||B.event.trigger("ajaxStop")))}"object"==typeof a&&(b=a,a=void 0),b=b||{};var d,e,f,g,h,i,j,k,m=B.ajaxSetup({},b),p=m.context||m,q=m.context&&(p.nodeType||p.jquery)?B(p):B.event,r=B.Deferred(),s=B.Callbacks("once memory"),t=m.statusCode||{},u={},v={},w=0,x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(2===w){if(!g)for(g={};b=aa.exec(f);)g[b[1].toLowerCase()]=b[2];b=g[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===w?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return w||(a=v[c]=v[c]||a,u[a]=b),this},overrideMimeType:function(a){return w||(m.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>w)for(b in a)t[b]=[t[b],a[b]];else y.always(a[y.status]);return this},abort:function(a){var b=a||x;return d&&d.abort(b),c(0,b),this}};if(r.promise(y).complete=s.add,y.success=y.done,y.error=y.fail,m.url=((a||m.url||Z)+"").replace($,"").replace(da,Y[1]+"//"),m.type=b.method||b.type||m.method||m.type,m.dataTypes=B.trim(m.dataType||"*").toLowerCase().match(K)||[""],null==m.crossDomain&&(i=ea.exec(m.url.toLowerCase()),m.crossDomain=!(!i||i[1]===Y[1]&&i[2]===Y[2]&&(i[3]||("http:"===i[1]?"80":"443"))===(Y[3]||("http:"===Y[1]?"80":"443")))),m.data&&m.processData&&"string"!=typeof m.data&&(m.data=B.param(m.data,m.traditional)),l(fa,m,b,y),2===w)return y;j=m.global,j&&0===B.active++&&B.event.trigger("ajaxStart"),m.type=m.type.toUpperCase(),m.hasContent=!ca.test(m.type),e=m.url,m.hasContent||(m.data&&(e=m.url+=(X.test(e)?"&":"?")+m.data,delete m.data),m.cache===!1&&(m.url=_.test(e)?e.replace(_,"$1_="+W++):e+(X.test(e)?"&":"?")+"_="+W++)),m.ifModified&&(B.lastModified[e]&&y.setRequestHeader("If-Modified-Since",B.lastModified[e]),B.etag[e]&&y.setRequestHeader("If-None-Match",B.etag[e])),(m.data&&m.hasContent&&m.contentType!==!1||b.contentType)&&y.setRequestHeader("Content-Type",m.contentType),y.setRequestHeader("Accept",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+("*"!==m.dataTypes[0]?", "+ha+"; q=0.01":""):m.accepts["*"]);for(k in m.headers)y.setRequestHeader(k,m.headers[k]);if(m.beforeSend&&(m.beforeSend.call(p,y,m)===!1||2===w))return y.abort();x="abort";for(k in{success:1,error:1,complete:1})y[k](m[k]);if(d=l(ga,m,b,y)){y.readyState=1,j&&q.trigger("ajaxSend",[y,m]),m.async&&m.timeout>0&&(h=setTimeout(function(){y.abort("timeout")},m.timeout));try{w=1,d.send(u,c)}catch(z){if(!(2>w))throw z;c(-1,z)}}else c(-1,"No Transport");return y},getJSON:function(a,b,c){return B.get(a,b,c,"json")},getScript:function(a,b){return B.get(a,void 0,b,"script")}}),B.each(["get","post"],function(a,b){B[b]=function(a,c,d,e){return B.isFunction(c)&&(e=e||d,d=c,c=void 0),B.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),B.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){B.fn[b]=function(a){return this.on(b,a)}});var ja=/%20/g,ka=/\[\]$/,la=/\r?\n/g,ma=/^(?:submit|button|image|reset|file)$/i,na=/^(?:input|select|textarea|keygen)/i;B.param=function(a,b){var c,d=[],e=function(a,b){b=B.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=B.ajaxSettings&&B.ajaxSettings.traditional),B.isArray(a)||a.jquery&&!B.isPlainObject(a))B.each(a,function(){e(this.name,this.value)});else for(c in a)p(c,a[c],b,e);return d.join("&").replace(ja,"+")},B.fn.extend({serialize:function(){return B.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=B.prop(this,"elements");return a?B.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!B(this).is(":disabled")&&na.test(this.nodeName)&&!ma.test(a)&&(this.checked||!rcheckableType.test(a))}).map(function(a,b){var c=B(this).val();return null==c?null:B.isArray(c)?B.map(c,function(a){return{name:b.name,value:a.replace(la,"\r\n")}}):{name:b.name,value:c.replace(la,"\r\n")}}).get()}}),B.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var oa=0,pa={},qa={0:200,1223:204},ra=B.ajaxSettings.xhr();a.ActiveXObject&&B(a).on("unload",function(){for(var a in pa)pa[a]()}),y.cors=!!ra&&"withCredentials"in ra,y.ajax=ra=!!ra,B.ajaxTransport(function(a){var b;return y.cors||ra&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++oa;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete pa[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(qa[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=pa[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),B.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return B.globalEval(a),a}}}),B.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),B.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=B(" 21 | 22 | 23 | 24 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /example/jquery-2.1.1.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ 2 | !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) 3 | },_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("