summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-11-04 18:55:36 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-11-04 18:55:36 +0100
commitb6707c3bb53c931e9ec3c5c6630149b7121bbcf5 (patch)
tree2d9c880bb21242c3fb4619977fe9a71658b3d06e
parent2a067f08a4582cdff841dc27b661a9e48fac419a (diff)
Removed mongoose due to restricted license and webserver wip till code is restructured (nw)
-rw-r--r--3rdparty/mongoose/LICENSE16
-rw-r--r--3rdparty/mongoose/README.md78
-rw-r--r--3rdparty/mongoose/docs/API.md249
-rw-r--r--3rdparty/mongoose/docs/AndroidBuild.md27
-rw-r--r--3rdparty/mongoose/docs/BasicWebsite.md34
-rw-r--r--3rdparty/mongoose/docs/Embed.md173
-rw-r--r--3rdparty/mongoose/docs/FAQ.md45
-rw-r--r--3rdparty/mongoose/docs/FileSharing.md18
-rw-r--r--3rdparty/mongoose/docs/Internals.md44
-rw-r--r--3rdparty/mongoose/docs/Options.md154
-rw-r--r--3rdparty/mongoose/docs/PhpWebsite.md49
-rw-r--r--3rdparty/mongoose/docs/ReleaseNotes.md218
-rw-r--r--3rdparty/mongoose/docs/SSL.md70
-rw-r--r--3rdparty/mongoose/docs/Usage.md86
-rw-r--r--3rdparty/mongoose/examples/.gitignore1
-rw-r--r--3rdparty/mongoose/examples/Makefile20
-rw-r--r--3rdparty/mongoose/examples/array_vars/Makefile21
-rw-r--r--3rdparty/mongoose/examples/array_vars/array_vars.c45
-rw-r--r--3rdparty/mongoose/examples/big_upload/Makefile12
-rw-r--r--3rdparty/mongoose/examples/big_upload/big_upload.c84
-rw-r--r--3rdparty/mongoose/examples/cookie_authentication/Makefile12
-rw-r--r--3rdparty/mongoose/examples/cookie_authentication/cookie_auth.c97
-rw-r--r--3rdparty/mongoose/examples/cookie_authentication/index.html33
-rw-r--r--3rdparty/mongoose/examples/cookie_authentication/login.html44
-rw-r--r--3rdparty/mongoose/examples/csharp/example.cs43
-rw-r--r--3rdparty/mongoose/examples/csharp/mongoose.cs68
-rw-r--r--3rdparty/mongoose/examples/digest_authentication/Makefile12
-rw-r--r--3rdparty/mongoose/examples/digest_authentication/digest_auth.c36
-rw-r--r--3rdparty/mongoose/examples/file_upload/Makefile20
-rw-r--r--3rdparty/mongoose/examples/file_upload/file_upload.c61
-rw-r--r--3rdparty/mongoose/examples/form_submit/Makefile12
-rw-r--r--3rdparty/mongoose/examples/form_submit/form_submit.c62
-rw-r--r--3rdparty/mongoose/examples/hello_world/Makefile21
-rw-r--r--3rdparty/mongoose/examples/hello_world/hello_world.c38
-rw-r--r--3rdparty/mongoose/examples/http_client/Makefile12
-rw-r--r--3rdparty/mongoose/examples/http_client/http_client.c82
-rw-r--r--3rdparty/mongoose/examples/mjpg_streamer/Makefile12
-rw-r--r--3rdparty/mongoose/examples/mjpg_streamer/mjpg_streamer.c105
-rw-r--r--3rdparty/mongoose/examples/multi_threaded_server/Makefile12
-rw-r--r--3rdparty/mongoose/examples/multi_threaded_server/multi_threaded_server.c40
-rw-r--r--3rdparty/mongoose/examples/proxy_server/Makefile13
-rw-r--r--3rdparty/mongoose/examples/proxy_server/proxy_server.c202
-rw-r--r--3rdparty/mongoose/examples/proxy_server/proxy_web_root/app1/index.html23
-rw-r--r--3rdparty/mongoose/examples/proxy_server/proxy_web_root/app2/index.html37
-rw-r--r--3rdparty/mongoose/examples/proxy_server/proxy_web_root/index.html29
-rw-r--r--3rdparty/mongoose/examples/proxy_server/ssl_cert.pem50
-rw-r--r--3rdparty/mongoose/examples/restful_api/Makefile12
-rw-r--r--3rdparty/mongoose/examples/restful_api/index.html66
-rw-r--r--3rdparty/mongoose/examples/restful_api/restful_api.c51
-rw-r--r--3rdparty/mongoose/examples/send_file/Makefile21
-rw-r--r--3rdparty/mongoose/examples/send_file/send_file.c27
-rw-r--r--3rdparty/mongoose/examples/web_server/Makefile30
-rw-r--r--3rdparty/mongoose/examples/web_server/certs/cert.pem46
-rw-r--r--3rdparty/mongoose/examples/web_server/web_server.c490
-rw-r--r--3rdparty/mongoose/examples/websocket_chat/Makefile12
-rw-r--r--3rdparty/mongoose/examples/websocket_chat/index.html98
-rw-r--r--3rdparty/mongoose/examples/websocket_chat/websocket_chat.c83
-rw-r--r--3rdparty/mongoose/examples/websocket_echo_server/Makefile12
-rw-r--r--3rdparty/mongoose/examples/websocket_echo_server/index.html46
-rw-r--r--3rdparty/mongoose/examples/websocket_echo_server/websocket_echo_server.c61
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile27
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem49
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem49
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h253
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c123
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h34
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c182
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html50
-rw-r--r--3rdparty/mongoose/jni/Android.mk8
-rw-r--r--3rdparty/mongoose/mongoose.c5520
-rw-r--r--3rdparty/mongoose/mongoose.h158
-rw-r--r--3rdparty/mongoose/scripts/embed_binary_files.pl53
-rw-r--r--3rdparty/mongoose/test/Makefile21
-rw-r--r--3rdparty/mongoose/test/unit_test.c533
-rw-r--r--scripts/src/3rdparty.lua40
-rw-r--r--scripts/src/emu.lua2
-rw-r--r--scripts/src/main.lua1
-rw-r--r--src/emu/debug/debugcpu.c2
-rw-r--r--src/emu/emuopts.c4
-rw-r--r--src/emu/emuopts.h10
-rw-r--r--src/emu/luaengine.c5
-rw-r--r--src/emu/machine.c2
-rw-r--r--src/emu/mame.c6
-rw-r--r--src/emu/mame.h4
-rw-r--r--src/emu/ui/ui.c1
-rw-r--r--src/emu/webengine.c545
-rw-r--r--src/emu/webengine.h48
-rw-r--r--web/css/images/ajax-loader.gifbin7825 -> 0 bytes
-rw-r--r--web/css/images/icons-18-black.pngbin1968 -> 0 bytes
-rw-r--r--web/css/images/icons-18-white.pngbin1988 -> 0 bytes
-rw-r--r--web/css/images/icons-36-black.pngbin3859 -> 0 bytes
-rw-r--r--web/css/images/icons-36-white.pngbin3861 -> 0 bytes
-rw-r--r--web/css/jquery.mobile.css12
-rw-r--r--web/favicon.icobin2238 -> 0 bytes
-rw-r--r--web/images/logo-mame-small.pngbin25705 -> 0 bytes
-rw-r--r--web/index.html917
-rw-r--r--web/js/jquery.js6
-rw-r--r--web/js/jquery.mobile.js9
102 files changed, 2 insertions, 12527 deletions
diff --git a/3rdparty/mongoose/LICENSE b/3rdparty/mongoose/LICENSE
deleted file mode 100644
index feb3592d180..00000000000
--- a/3rdparty/mongoose/LICENSE
+++ /dev/null
@@ -1,16 +0,0 @@
-Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
-Copyright (c) 2013-2015 Cesanta Software Limited
-All rights reserved
-
-This code is dual-licensed: you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation. For the terms of this
-license, see <http://www.gnu.org/licenses>.
-
-You are free to use this code under the terms of the GNU General
-Public License, but WITHOUT ANY WARRANTY; without even the implied
-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
-
-Alternatively, you can license this code under a commercial
-license, as set out in <http://cesanta.com/>.
diff --git a/3rdparty/mongoose/README.md b/3rdparty/mongoose/README.md
deleted file mode 100644
index 4b4fc3219ba..00000000000
--- a/3rdparty/mongoose/README.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# <img src="http://cesanta.com/images/mongoose_logo.png" width="64" height="64"> Mongoose Web Server
-
-[![Join the chat at https://gitter.im/cesanta/mongoose](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cesanta/mongoose?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-Mongoose is the most easy to use web server on the planet. A web server of choice for Web developers (PHP, Ruby, Python, etc) and Web designers.
-
-Mongoose is built on top of Libmongoose embedded library, which can turn
-anything into a web server in 5 minutes worth of effort and few lines of code.
-Libmongoose is used to serve Web GUI on embedded devices, implement RESTful
-services, RPC frameworks (e.g. JSON-RPC), handle telemetry data exchange, and
-perform many other tasks in various different industries including aerospace,
-manufacturing, finance, research, automotive, gaming, IT.
-
-
- * [Mailing list](http://groups.google.com/group/mongoose-users)
- * [Downloads](http://cesanta.com/products.shtml)
- * [Documentation](http://cesanta.com/docs.shtml)
-
-Check out Fossa - our [embedded multi-protocol library](https://github.com/cesanta/fossa) with TCP,UDP,HTTP,Websocket,MQTT,DNS support, designed for Internet Of Things!
-
-# Features
-
-- Works on Windows, Mac, UNIX/Linux, iPhone, Android eCos, QNX
-and many other platforms
-- CGI, SSI, SSL, Digest auth, Websocket, WEbDAV, Resumed download,
- URL rewrite, file blacklist
-- Custom error pages, Virtual hosts, IP-based ACL, Windows service,
- HTTP/HTTPS client
-- Simple and clean
- [embedding API](https://github.com/cesanta/mongoose/blob/master/mongoose.h).
- The source is in single
- [mongoose.c](https://github.com/cesanta/mongoose/blob/master/mongoose.c) file
- to make embedding easy
-- Extremely lightweight, has a core of under 40kB and tiny runtime footprint
-- Asynchronous, non-blocking core supporting single- or multi-threaded usage
-- On the market since 2004 with over 1 million cumulative downloads
-- Stable, mature and tested, has several man-years invested
- in continuous improvement and refinement
-
-# Screenshots
-
-Download, double-click to start, run browser -- that's all!
-
-![shot1](http://cesanta.com/images/tut_sharing/tut1.png)
-![shot2](http://cesanta.com/images/tut_sharing/tut2.png)
-
-![shot3](http://cesanta.com/images/tut_sharing/tut3.png)
-![shot4](http://cesanta.com/images/tut_sharing/tut4.png)
-
-# Contributions
-
-People who have agreed to the
-[Cesanta CLA](http://cesanta.com/contributors_la.html)
-can make contributions. Note that the CLA isn't a copyright
-_assigment_ but rather a copyright _license_.
-You retain the copyright on your contributions.
-
-# Licensing
-
-Mongoose is released under commercial and
-[GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open
-source licenses. The GPLv2 open source License does not generally permit
-incorporating this software into non-open source programs.
-For those customers who do not wish to comply with the GPLv2 open
-source license requirements,
-[Cesanta](http://cesanta.com) offers a full,
-royalty-free commercial license and professional support
-without any of the GPL restrictions.
-
-# Other products by Cesanta
-
-- [Fossa](http://github.com/cesanta/fossa) - Multi-protocol networking library
-- [SSL Wrapper](https://github.com/cesanta/ssl_wrapper) - application to
- secure network communications
-- [Frozen](https://github.com/cesanta/frozen) - JSON parser and generator
-- [SLRE](https://github.com/cesanta/slre) - Super Light Regular Expression
- library
-- [V7](https://github.com/cesanta/v7) - Embedded JavaScript engine
diff --git a/3rdparty/mongoose/docs/API.md b/3rdparty/mongoose/docs/API.md
deleted file mode 100644
index faf93daaaae..00000000000
--- a/3rdparty/mongoose/docs/API.md
+++ /dev/null
@@ -1,249 +0,0 @@
-# Mongoose API Reference
-
- struct mg_server *mg_create_server(void *server_param, mg_handler_t handler);
-
-Creates web server instance. Returns opaque instance pointer, or NULL if
-there is not enough memory. `server_param`: Could be any pointer, or NULL.
-This pointer will be passed
-to the callback functions as `struct mg_connection::server_param` field.
-A common use case is to pass `this` pointer of the C++ wrapper class
-as `user_param`, to let the callback get the pointer to the C++ object.
-
-Note that this function doesn't make the
-server instance to serve. Serving is done by `mg_poll_server()` function.
-Mongoose has single-threaded, event-driven, asynchronous, non-blocking core.
-When server instance is created, it contains an information about
-the configuration and the state of each connection.
-Server instance is capable on listening on only one port. After creation,
-`struct mg_server` has a list
-of active connections and configuration parameters.
-
-Side-effect: on UNIX, `mg_create_server()` ignores SIGPIPE signals. If custom
-processing is required SIGPIPE, signal handler must be set up after
-calling `mg_create_server()`.
-
-Important: Mongoose does not install `SIGCHLD` handler. If CGI is used,
-`SIGCHLD` handler must be set up to reap CGI zombie processes.
-
-
- void mg_destroy_server(struct mg_server **server);
-
-Deallocates web server instance, closes all pending connections, and makes
-server pointer a NULL pointer.
-
- const char mg_set_option(struct mg_server *server, const char *name,
- const char *value);
-
-Sets a particular server option. Note that at least one option,
-`listening_port`, must be specified. To serve static files, `document_root`
-must be specified too. If `document_root` option is left unset, Mongoose
-will not access filesystem at all. `mg_set_option()` returns NULL if option was
-set successfully, otherwise it returns human-readable error string. It is
-allowed to call `mg_set_option()` by the same thread that does
-`mg_poll_server()` (Mongoose thread) and change server configuration while it
-is serving, in between `mg_poll_server()` calls.
-
- int mg_poll_server(struct mg_server *server, int milliseconds);
-
-Performs one iteration of IO loop by iterating over all
-active connections, performing `select()` syscall on all sockets with a timeout
-of `milliseconds`. When `select()` returns, Mongoose
-does an IO for each socket that has data to be sent or received. Application
-code must call `mg_poll_server()` in a loop. It is an error to have more then
-one thread calling `mg_poll_server()`, `mg_set_option()` or any other function
-that take `struct mg_server *` parameter. Mongoose does not
-mutex-protect `struct mg_server *`, therefore only single thread
-(Mongoose thread) should make Mongoose calls.
-
-`mg_poll_server()` calls user-specified event handler when certain events
-occur. Sequence of events for the accepted connection is this:
-
- * `MG_AUTH` - Mongoose asks whether this connection is authorized. If event
- handler returns `MG_FALSE`, then Mongoose does not serve the request but
- sends authorization request to the client. If `MG_TRUE` is returned,
- then Mongoose continues on with the request.
- * `MG_REQUEST` - Mongoose asks event handler to serve the request. If
- event handler serves the request by sending a reply,
- it should return `MG_TRUE`. Otherwise,
- it should return `MG_FALSE` which tells Mongoose that request is not
- served and Mongoose should serve it. For example, event handler might
- choose to serve only RESTful API requests with URIs that start with
- certain prefix, and let Mongoose serve all static files.
- If event handler decides to serve the request, but doesn't have
- all the data at the moment, it should return `MG_MORE`. That tells
- Mongoose to keep the connection open after callback returns.
-
- `mg_connection::connection_param` pointer is a placeholder to keep
- user-specific data. For example, handler could decide to open a DB
- connection and store DB connection handle in `connection_param`.
- * `MG_POLL` is sent to every connection on every iteration of
- `mg_poll_server()`. Event handler should return `MG_FALSE` to ignore
- this event. If event handler returns `MG_TRUE`, then Mongoose assumes
- that event handler has finished sending data, and Mongoose will
- close the connection.
- * `MG_HTTP_ERROR` sent when Mongoose is about to send HTTP error back
- to the client. Event handler can choose to send a reply itself, in which
- case event handler must return `MG_TRUE`. Otherwise, event handler must
- return `MG_FALSE`.
- * `MG_CLOSE` is sent when the connection is closed. This event is used
- to cleanup per-connection state stored in `connection_param`
- if it was allocated. Event handler return value is ignored.
-
-Sequence of events for the client connection is this:
-
- * `MG_CONNECT` sent when Mongoose has connected to the remote host.
- This event is sent to the connection initiated by `mg_connect()` call.
- Connection status is held in `mg_connection::status_code`: if zero,
- then connection was successful, otherwise connection was not established.
- User should send a request upon successful connection.
- Event handler should return `MG_TRUE` if connection was successful and
- HTTP request has been sent. Otherwise, it should send `MG_FALSE`.
- * `MG_REPLY` is sent when response has been received from the remote host.
- If event handler sends another request, then it should return `MG_TRUE`.
- Otherwise it should return `MG_FALSE` and Mongoose will close the connection.
- * `MG_CLOSE` same as for the accepted connection.
-
-
-When mongoose buffers in HTTP request and successfully parses it, it sends
-`MG_REQUEST` event for GET requests immediately. For POST requests,
-Mongoose delays the call until the whole POST request is buffered in memory.
-POST data is available to the callback as `struct mg_connection::content`,
-and POST data length is in `struct mg_connection::content_len`.
-
-Note that websocket connections are treated the same way. Mongoose buffers
-websocket frame in memory, and calls event handler when frame is fully
-buffered. Frame data is available `struct mg_connection::content`, and
-data length is in `struct mg_connection::content_len`, i.e. very similar to
-the POST request. `struct mg_connection::is_websocket` flag indicates
-whether the request is websocket or not. Also, for websocket requests,
-there is `struct mg_connection::wsbits` field which contains first byte
-of the websocket frame which URI handler can examine. Note that to
-reply to the websocket client, `mg_websocket_write()` should be used.
-To reply to the plain HTTP client, `mg_write_data()` should be used.
-
-Return value: number of active connections.
-
-
- const char **mg_get_valid_option_names(void);
-
-Returns a NULL-terminated array of option names and their default values.
-There are two entries per option in an array: an option name followed by a
-default value. A default value could be NULL. A NULL name indicates an end
-of the array.
-
- const char *mg_get_option(const struct mg_server *server, const char *name);
-
-Returns the value of particular configuration parameter. If
-given parameter name is not valid, NULL is returned. For valid names, return
-value is guaranteed to be non-NULL. If parameter is not set, zero-length string
-is returned.
-
- void mg_wakeup_server_ex(struct mg_server *, mg_handler_t func,
- const char *fmt, ...);
-
-Sends string message to a server. Function `func` is called for every active
-connection. String message is passed in `struct mg_connection::callback_param`.
-This function is designed to push data to the connected clients, and
-can be called from any thread. There is a limitation on the length of
-the message, currently at 8 kilobytes.
-
- void mg_send_status(struct mg_connection *, int status_code);
- void mg_send_header(struct mg_connection *, const char *name,
- const char *value);
- void mg_send_data(struct mg_connection *, const void *data, int data_len);
- void mg_printf_data(struct mg_connection *, const char *format, ...);
-
-These functions are used to construct a response to the client. HTTP response
-consists of three parts: a status line, zero or more HTTP headers,
-a response body. Mongoose provides functions for all three parts:
- * `mg_send_status()` is used to create status line. This function can be
- called zero or once. If `mg_send_status()` is not called, then Mongoose
- will send status 200 (success) implicitly.
- * `mg_send_header()` adds HTTP header to the response. This function could
- be called zero or more times.
- * `mg_send_data()` and `mg_printf_data()` are used to send data to the
- client. Note that Mongoose adds `Transfer-Encoding: chunked` header
- implicitly, and sends data in chunks. Therefore, it is not necessary to
- set `Content-Length` header. Note that `mg_send_data()` and
- `mg_printf_data()` do not send data immediately. Instead, they spool
- data in memory, and Mongoose sends that data later after URI handler
- returns. If data to be sent is huge, an URI handler might
- send data in pieces by saving state in
- `struct mg_connection::connection_param` variable and returning `0`. Then
- Mongoose will call a handler repeatedly after each socket write.
-
-<!-- -->
-
- void mg_send_file(struct mg_connection *, const char *path);
-
-Tells Mongoose to serve given file. Mongoose handles file according to
-it's extensions, i.e. Mongoose will invoke CGI script if `path` has CGI
-extension, it'll render SSI file if `path` has SSI extension, etc. If `path`
-points to a directory, Mongoose will show directory listing. If this function
-is used, no calls to `mg_send*` or `mg_printf*` functions must be made, and
-event handler must return `MG_MORE`.
-
- size_t mg_websocket_write(struct mg_connection* conn, int opcode,
- const char *data, size_t data_len);
- size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
- const char *fmt, ...);
-
-
-Similar to `mg_write()` and `mg_printf()`, but wraps the data into a
-websocket frame with a given websocket `opcode`.
-
- const char *mg_get_header(const struct mg_connection *, const char *name);
-
-Get the value of particular HTTP header. This is a helper function.
-It traverses http_headers array, and if the header is present in the array,
-returns its value. If it is not present, NULL is returned.
-
-
- int mg_get_var(const struct mg_connection *conn, const char *var_name,
- char *buf, size_t buf_len);
-
-Gets HTTP form variable. Both POST buffer and query string are inspected.
-Form variable is url-decoded and written to the buffer. On success, this
-function returns the length of decoded variable. On error, -1 is returned if
-variable not found, and -2 is returned if destination buffer is too small
-to hold the variable. Destination buffer is guaranteed to be
-'\0' - terminated if it is not NULL or zero length.
-
- int mg_parse_header(const char *hdr, const char *var_name, char *buf,
- size_t buf_size);
-
-This function parses HTTP header and fetches given variable's value in a buffer.
-A header should be like `x=123, y=345, z="other value"`. This function is
-designed to parse Cookie headers, Authorization headers, and similar. Returns
-the length of the fetched value, or 0 if variable not found.
-
- int mg_modify_passwords_file(const char *passwords_file_name,
- const char *domain,
- const char *user,
- const char *password);
-
-Add, edit or delete the entry in the passwords file.
-This function allows an application to manipulate .htpasswd files on the
-fly by adding, deleting and changing user records. This is one of the
-several ways of implementing authentication on the server side.
-If password is not NULL, entry is added (or modified if already exists).
-If password is NULL, entry is deleted.
-Return: 1 on success, 0 on error.
-
-
- int mg_parse_multipart(const char *buf, int buf_len,
- char *var_name, int var_name_len,
- char *file_name, int file_name_len,
- const char **data, int *data_len);
-
-Parses a buffer that contains multipart form data. Stores chunk name
-in a `var_name` buffer. If chunk is an uploaded file, then `file_name`
-will have a file name. `data` and `data_len` will point to the chunk data.
-Returns number of bytes to skip to the next chunk.
-
- struct mg_connection *mg_connect(struct mg_server *server,
- const char *host, int port, int use_ssl);
-
-Create connection to the remote host. Returns `NULL` on error, non-null
-if the connection has been scheduled for connection. Upon a connection,
-Mongoose will send `MG_CONNECT` event to the event handler.
diff --git a/3rdparty/mongoose/docs/AndroidBuild.md b/3rdparty/mongoose/docs/AndroidBuild.md
deleted file mode 100644
index afd21522f55..00000000000
--- a/3rdparty/mongoose/docs/AndroidBuild.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Mongoose Build on Android
-
-This is a small guide to help you run mongoose on Android. Currently it is
-tested on the HTC Wildfire. If you have managed to run it on other devices
-as well, please comment or drop an email in the mailing list.
-Note : You dont need root access to run mongoose on Android.
-
-- Clone Mongoose Git repo
-- Download the Android NDK from [http://developer.android.com/tools/sdk/ndk/index.html](http://developer.android.com/tools/sdk/ndk/index.html)
-- Run `/path-to-ndk/ndk-build -C /path/to/mongoose`
- That should generate mongoose/lib/armeabi/mongoose
-- Using the adb tool (you need to have Android SDK installed for that),
- push the generated mongoose binary to `/data/local` folder on device.
-- From adb shell, navigate to `/data/local` and execute `./mongoose`.
-- To test if the server is running fine, visit your web-browser and
- navigate to `http://127.0.0.1:8080` You should see the `Index of /` page.
-
-![screenshot](http://cesanta.com/images/android_build.png)
-
-
-Notes:
-
-- `jni` stands for Java Native Interface. Read up on Android NDK if you want
- to know how to interact with the native C functions of mongoose in Android
- Java applications.
-- TODO: A Java application that interacts with the native binary or a
- shared library.
diff --git a/3rdparty/mongoose/docs/BasicWebsite.md b/3rdparty/mongoose/docs/BasicWebsite.md
deleted file mode 100644
index c5c93c7760d..00000000000
--- a/3rdparty/mongoose/docs/BasicWebsite.md
+++ /dev/null
@@ -1,34 +0,0 @@
-How To Create Basic Website With Mongoose
-===========================================
-
-## 1. Create a directory which will contain your website files. For example, on drive `C:\`, create a directory called `my_website`:
-
-![screenshot](http://cesanta.com/images/tut_basic/tut1.png)
-
-## 2. Inside `my_website` directory, create a new file called "index". This will be the default web page shown when the website is visited.
-
-![screenshot](http://cesanta.com/images/tut_basic/tut2.png)
-
-## 3. Open index file with your favorite editor (for example, Notepad) and enter some HTML code:
-
-![screenshot](http://cesanta.com/images/tut_basic/tut3.png)
-
-## 4. Save this file as `index.html`:
-
-![screenshot](http://cesanta.com/images/tut_basic/tut4.png)
-
-
-## 5. Download Mongoose executable from http://cesanta.com/mongoose.shtml and copy the executable inside `my_website` directory:
-
-![screenshot](http://cesanta.com/images/tut_basic/tut5.png)
-
-## 6. Double-click mongoose executable. An icon will appear on a system tray in the bottom right corner of the desktop:
-
-![screenshot](http://cesanta.com/images/tut_basic/tut6.png)
-
-## 7. Click on the mongoose icon and choose "Go to my address" menu:
-![screenshot](http://cesanta.com/images/tut_basic/tut7.png)
-
-## 8. A browser will popup displaying `index.html` file. Now, you can expand your website by adding more content.
-
-![screenshot](http://cesanta.com/images/tut_basic/tut8.png)
diff --git a/3rdparty/mongoose/docs/Embed.md b/3rdparty/mongoose/docs/Embed.md
deleted file mode 100644
index 8e6dfbf5669..00000000000
--- a/3rdparty/mongoose/docs/Embed.md
+++ /dev/null
@@ -1,173 +0,0 @@
-# Mongoose Embedding Guide
-
-Embedding Mongoose is done in two steps:
-
- 1. Copy
- [mongoose.c](https://raw.github.com/cesanta/mongoose/master/mongoose.c) and
- [mongoose.h](https://raw.github.com/cesanta/mongoose/master/mongoose.h)
- to your application's source tree and include them in the build.
- 2. Somewhere in the application code, call `mg_create_server()` to create
- a server, configure it with `mg_set_option()` and loop with
- `mg_poll_server()` until done. Call `mg_destroy_server()` to cleanup.
-
-Here's a minimal application `app.c` that embeds mongoose:
-
- #include "mongoose.h"
-
- int main(void) {
- struct mg_server *server = mg_create_server(NULL, NULL);
- mg_set_option(server, "document_root", "."); // Serve current directory
- mg_set_option(server, "listening_port", "8080"); // Open port 8080
-
- for (;;) {
- mg_poll_server(server, 1000); // Infinite loop, Ctrl-C to stop
- }
- mg_destroy_server(&server);
-
- return 0;
- }
-
-To compile it, put `mongoose.c`, `mongoose.h` and `app.c` into one
-folder, start terminal on UNIX or Visual Studio command line prompt on Windows,
-and run the following command:
-
- cc app.c mongoose.c -pthread -o app # on Unix
- cl.exe app.c mongoose.c /TC /MD # on Windows
-
-When run, this simple application opens port 8080 and serves static files,
-CGI files and lists directory content in the current working directory.
-
-It is possible to generate HTML page content. Mongoose can call user-defined
-function when certain events occur.
-That function is called _an event handler_, and it is the second parameter
-to `mg_create_server()` function. Here is the example event handler function:
-
- int event_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return MG_TRUE;
- default: return MG_FALSE;
- }
- }
-
-Event handler is called by Mongoose with `struct mg_connection *`
-pointer and an event number. `struct mg_connection *conn`
-has all information about the request: HTTP headers, POST or websocket
-data buffer, etcetera. `enum mg_event ev` tells which exactly event is sent.
-For each event, an event handler returns a value which tells Mongoose how
-to behave.
-
-The sequence of events for every connection is this:
-
- * `MG_AUTH` - Mongoose asks whether this connection is authorized. If event
- handler returns `MG_FALSE`, then Mongoose does not serve the request but
- sends authorization request to the client. If `MG_TRUE` is returned,
- then Mongoose continues on with the request.
- * `MG_REQUEST` - Mongoose asks event handler to serve the request. If
- event handler serves the request by sending a reply,
- it should return `MG_TRUE`. Otherwise,
- it should return `MG_FALSE` which tells Mongoose that request is not
- served and Mongoose should serve it. For example, event handler might
- choose to serve only RESTful API requests with URIs that start with
- certain prefix, and let Mongoose serve all static files.
- If event handler decides to serve the request, but doesn't have
- all the data at the moment, it should return `MG_MORE`. That tells
- Mongoose to keep the connection open after callback returns.
-
- `mg_connection::connection_param` pointer is a placeholder to keep
- user-specific data. For example, handler could decide to open a DB
- connection and store DB connection handle in `connection_param`.
- * `MG_POLL` is sent to every connection on every iteration of
- `mg_poll_server()`. Event handler should return `MG_FALSE` to ignore
- this event. If event handler returns `MG_TRUE`, then Mongoose assumes
- that event handler has finished sending data, and Mongoose will
- close the connection.
- * `MG_HTTP_ERROR` sent when Mongoose is about to send HTTP error back
- to the client. Event handler can choose to send a reply itself, in which
- case event handler must return `MG_TRUE`. Otherwise, event handler must
- return `MG_FALSE`
- * `MG_CLOSE` is sent when the connection is closed. This event is used
- to cleanup per-connection state stored in `connection_param`
- if it was allocated.
-
-Let's extend our minimal application example and
-create an URI that will be served by user's C code. The app will handle
-`/hello` URI by showing a hello message. So, when app is run,
-http://127.0.0.1:8080/hello will say hello, and here's the code:
-
- #include <string.h>
- #include "mongoose.h"
-
- static int event_handler(struct mg_connection *conn, enum mg_event ev) {
- if (ev == MG_AUTH) {
- return MG_TRUE; // Authorize all requests
- } else if (ev == MG_REQUEST && !strcmp(conn->uri, "/hello")) {
- mg_printf_data(conn, "%s", "Hello world");
- return MG_TRUE; // Mark as processed
- } else {
- return MG_FALSE; // Rest of the events are not processed
- }
- }
-
- int main(void) {
- struct mg_server *server = mg_create_server(NULL, event_handler);
- mg_set_option(server, "document_root", ".");
- mg_set_option(server, "listening_port", "8080");
-
- for (;;) {
- mg_poll_server(server, 1000); // Infinite loop, Ctrl-C to stop
- }
- mg_destroy_server(&server);
-
- return 0;
- }
-
-## Example code
-
-Mongoose source code contains number of examples, located in the
-[examples](https://github.com/cesanta/mongoose/blob/master/examples/) directory.
-To build any example, go to the respective directory and run `make`.
-
-## Compilation flags
-
-Below is the list of compilation flags that enable or disable certain
-features. By default, some features are enabled, and could be disabled
-by setting appropriate `NO_*` flag. Features that are disabled by default
-could be enabled by setting appropriate `USE_*` flag. Bare bones Mongoose
-is quite small, about 30 kilobytes of compiled x86 code. Each feature adds
-a couple of kilobytes to the executable size, and also has some runtime penalty.
-
-Note that some flags start with `NS_` prefix. This is because Mongoose uses
-[Net Skeleton](http://github.com/cesanta/net_skeleton) as a low-level
-networking engine. If user code has `#include <net_skeleton.h>`, then
-all Net Skeleton functions will be available too.
-
-
- -DMONGOOSE_NO_AUTH Disable MD5 authorization support
- -DMONGOOSE_NO_CGI Disable CGI support
- -DMONGOOSE_NO_DAV Disable WebDAV support
- (PUT, DELETE, MKCOL, PROPFIND methods)
- -DMONGOOSE_NO_DIRECTORY_LISTING Disable directory listing
- -DMONGOOSE_NO_FILESYSTEM Disables all file IO, serving from memory only
- -DMONGOOSE_NO_LOGGING Disable access/error logging
- -DMONGOOSE_ENABLE_THREADS Enable mg_start_thread() function
- -DMONGOOSE_NO_WEBSOCKET Disable WebSocket support
- -DMONGOOSE_NO_USER No concept of a user on used platform.
- (Platform does not provide getpwnam, setgid or setuid)
-
- -DMONGOOSE_USE_IDLE_TIMEOUT_SECONDS=X Idle connection timeout, default is 30
- -DMONGOOSE_USE_LUA Enable Lua scripting
- -DMONGOOSE_USE_LUA_SQLITE3 Enable sqlite3 binding for Lua
- -DMONGOOSE_USE_POST_SIZE_LIMIT=X POST requests larger than X will be
- rejected, not set by default
- -DMONGOOSE_USE_EXTRA_HTTP_HEADERS=X Append X to the HTTP headers
- for static files, empty by default
-
- -DNS_ENABLE_DEBUG Enables debug messages on stdout, very noisy
- -DNS_ENABLE_SSL Enable SSL
- -DNS_ENABLE_IPV6 Enable IPv6 support
- -DNS_ENABLE_HEXDUMP Enables hexdump of sent and received traffic
- -DNS_STACK_SIZE=X Sets stack size to X for ns_start_thread()
- -DNS_DISABLE_THREADS Disable threads support
- -DNS_DISABLE_SOCKETPAIR For systems without loopback interface
- -DMONGOOSE_SEND_NS_EVENTS Send Net Skeleton events to the event handler
- in addition to the Mongoose events
diff --git a/3rdparty/mongoose/docs/FAQ.md b/3rdparty/mongoose/docs/FAQ.md
deleted file mode 100644
index 5648f5a1242..00000000000
--- a/3rdparty/mongoose/docs/FAQ.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Mongoose FAQ
-
-## My Antivirus Software reports Mongoose as a security threat
-
-Mongoose doesn't contain any malicious logic. Antivirus reports a
-[false positive](http://en.wikipedia.org/wiki/Type_I_and_type_II_errors#False_positive_error).
-This is when certain byte sequence in Mongoose accidentally matches
-virus signature in the Antivirus database.
-
-## Download page doesn't work
-
-Please make sure Javascript is enabled in your browser, and that the
-antivirus software is not blocking the download.
-
-
-## MacOS message: "Mongoose.app is damaged and can’t be opened. You should move it to the Trash"
-
-This happens on newer MacOS systems. The reason for the message
-is the fact Mongoose.app is not digitally signed.
-Mongoose download procedure changes the app on the fly by injecting
-user information in the binary, making any prior digital signature void.
-Open "System Preferences" -> "Security" and set "Allow apps downloaded from"
-to "Anywhere". Revert the settings once Mongoose is installed.
-
-## PHP doesn't work: getting empty page, or 'File not found' error
-
-The reason for that is wrong paths to the interpreter. Remember that with PHP,
-correct interpreter is `php-cgi.exe` (`php-cgi` on UNIX). Solution: specify
-full path to the PHP interpreter, e.g.:
-
- mongoose -cgi_interpreter /full/path/to/php-cgi
-
-## Mongoose fails to start
-
-If Mongoose exits immediately when run, this
-usually indicates a syntax error in the configuration file
-(named `mongoose.conf` by default) or the command-line arguments.
-Syntax checking is omitted from Mongoose to keep its size low. However,
-the Manual should be of help. Note: the syntax changes from time to time,
-so updating the config file might be necessary after executable update.
-
-### Embedding with OpenSSL on Windows might fail because of calling convention
-
-To force Mongoose to use `__stdcall` convention, add `/Gz` compilation
-flag to the Visual Studio project settings.
diff --git a/3rdparty/mongoose/docs/FileSharing.md b/3rdparty/mongoose/docs/FileSharing.md
deleted file mode 100644
index e21750a2e65..00000000000
--- a/3rdparty/mongoose/docs/FileSharing.md
+++ /dev/null
@@ -1,18 +0,0 @@
-How To Share Files With Mongoose
-===========================================
-
-## 1. Download Mongoose executable from http://cesanta.com/mongoose.shtml and copy the executable inside the directory you want to share:
-
-![screenshot](http://cesanta.com/images/tut_sharing/tut1.png)
-
-## 2. Double-click mongoose executable. A browser will start automatically, an icon will appear on a system tray in the bottom right corner of the desktop:
-
-![screenshot](http://cesanta.com/images/tut_sharing/tut2.png)
-
-## 3. Click on the mongoose icon
-![screenshot](http://cesanta.com/images/tut_sharing/tut3.png)
-
-
-## 4. Click on "Go to my address" to launch a browser locally. Or, to access a folder from another machine, launch a browser and type in the URL:
-
-![screenshot](http://cesanta.com/images/tut_sharing/tut4.png)
diff --git a/3rdparty/mongoose/docs/Internals.md b/3rdparty/mongoose/docs/Internals.md
deleted file mode 100644
index 2ecde5c849a..00000000000
--- a/3rdparty/mongoose/docs/Internals.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Mongoose Internals
-
-Mongoose has single-threaded, event-driven, asynchronous, non-blocking core.
-`mg_create_server()` creates a web server instance. An instance is a container
-for the config options and list of active connections. To do the actual
-serving, user must call `mg_poll_server()`, which iterates over all
-active connections, performing `select()` syscall on all sockets with a
-timeout of specified number of milliseconds. When `select()` returns, Mongoose
-does an IO for each socket that has data to be sent or received. Application
-code must call `mg_poll_server()` in a loop.
-
-Mongoose server instance is designed to be used by a single thread.
-It is an error to have more then
-one thread calling `mg_poll_server()`, `mg_set_option()` or any other function
-that take `struct mg_server *` parameter. Mongoose does not
-mutex-protect `struct mg_server *`, therefore the best practice is
-to call server management functions from the same thread (an IO thread).
-On a multi-core systems, many server instances can be created, sharing the
-same listening socket and managed by separate threads (see [multi_threaded.c](https://github.com/cesanta/mongoose/blob/master/examples/multi_threaded.c))
-example.
-
-It is an error to pass and store `struct mg_connection *` pointers for
-later use to send data. The reason is that they can be invalidated by the
-next `mg_poll_server()` call. For such a task,
-there is `mg_iterate_over_connections()` API
-exists, which sends a callback function to the IO thread, then IO thread
-calls specified function for all active connection.
-
-When mongoose buffers in HTTP request and successfully parses it, it calls
-appropriate URI handler immediately for GET requests. For POST requests,
-Mongoose delays the call until the whole POST request is buffered in memory.
-POST data is available to the callback as `struct mg_connection::content`,
-and POST data length is in `struct mg_connection::content_len`.
-
-Note that websocket connections are treated the same way. Mongoose buffers
-websocket frame in memory, and calls URI handler when frame is fully
-buffered. Frame data is available `struct mg_connection::content`, and
-data length is in `struct mg_connection::content_len`, i.e. very similar to
-the POST request. `struct mg_connection::is_websocket` flag indicates
-whether the request is websocket or not. Also, for websocket requests,
-there is `struct mg_connection::wsbits` field which contains first byte
-of the websocket frame which URI handler can examine. Note that to
-reply to the websocket client, `mg_websocket_write()` should be used.
-To reply to the plain HTTP client, `mg_write()` should be used.
diff --git a/3rdparty/mongoose/docs/Options.md b/3rdparty/mongoose/docs/Options.md
deleted file mode 100644
index 116c61fb9e4..00000000000
--- a/3rdparty/mongoose/docs/Options.md
+++ /dev/null
@@ -1,154 +0,0 @@
-# Mongoose Configuration Options
-
-### access\_control\_list
-An Access Control List (ACL) allows restrictions to be put on the list of IP
-addresses which have access to the web server. In the case of the Mongoose
-web server, the ACL is a comma separated list of IP subnets, where each
-subnet is prepended by either a `-` or a `+` sign. A plus sign means allow,
-where a minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
-this means to deny only that single IP address.
-
-Subnet masks may vary from 0 to 32, inclusive. The default setting is to allow
-all accesses. On each request the full list is traversed, and
-the last match wins. Example: `$ mongoose -access_control_list -0.0.0.0/0,+192.168/16` to deny all acccesses except those from `192.168/16` subnet. Note that if the option is set, then all accesses are forbidden
-by default. Thus in a previous example, `-0.0.0.0` part is not necessary.
-For example, `$mongoose access_control_list +10.0.0.0/8`
-means disallow all, allow subnet 10/8 only.
-
-To learn more about subnet masks, see the
-[Wikipedia page on Subnetwork](http://en.wikipedia.org/wiki/Subnetwork)
-
-Default: not set, all accesses are allowed.
-
-### access\_log\_file
-Path to a file for access logs. Either full path, or relative to the
-mongoose executable. Default: not set, no query logging is done.
-
-### auth_domain
-Authorization realm used in `.htpasswd` authorization. Default: `mydomain.com`
-
-### cgi_interpreter
-Path to an executable to be used use as an interpreter for __all__ CGI scripts
-regardless script extension. Default: not set, Mongoose looks at
-[shebang line](http://en.wikipedia.org/wiki/Shebang_(Unix\).
-
-For example, if both PHP and perl CGIs are used, then
-`#!/path/to/php-cgi.exe` and `#!/path/to/perl.exe` must be first lines of the
-respective CGI scripts. Note that paths should be either full file paths,
-or file paths relative to the directory where mongoose executable is located.
-
-If all CGIs use the same interpreter, for example they are all PHP, then
-`cgi_interpreter` option can be set to the path to `php-cgi.exe` executable and
-shebang line in the CGI scripts can be omitted.
-**Note**: PHP scripts must use `php-cgi.exe`, not `php.exe`.
-
-### cgi_pattern
-All files that match `cgi_pattern` are treated as CGI files. Default pattern
-allows CGI files be anywhere. To restrict CGIs to a certain directory,
-use `/path/to/cgi-bin/**.cgi` as a pattern. Note that **full file path** is
-matched against the pattern, not the URI.
-
-When Mongoose starts CGI program, it creates new environment for it (in
-contrast, usually child program inherits the environment from parent). Several
-environment variables however are inherited from Mongoose's environment,
-they are: `PATH`, `TMP`, `TEMP`, `TMPDIR`, `PERLLIB`, `MONGOOSE_CGI`. On UNIX
-it is also `LD_LIBRARY_PATH`. On Windows it is also `COMSPEC`, `SYSTEMROOT`,
-`SystemDrive`, `ProgramFiles`, `ProgramFiles(x86)`, `CommonProgramFiles(x86)`.
-
-Default: `**.cgi$|**.pl$|**.php$`
-
-### dav\_auth\_file
-Authentication file for WebDAV mutation requests: `PUT`, `DELETE`, `MKCOL`.
-The format of that file is the same as for the `.htpasswd` file
-used for digest authentication. It can be created and managed by
-`mongoose -A` command. Default: not set, WebDAV mutations are disallowed.
-
-### document_root
-A directory to serve. Default: current working directory.
-
-### enable\_directory\_listing
-Enable directory listing, either `yes` or `no`. Default: `yes`.
-
-### enable\_proxy
-Enable proxy functionality, either `yes` or `no`. If set to `yes`, then
-browsers can be configured to use Mongoose as a proxy. Default: `no`.
-
-
-### extra\_mime\_types
-Extra mime types to recognize, in form `extension1=type1,extension2=type2,...`.
-Extension must include dot. Example:
-`mongoose -extra_mime_types .cpp=plain/text,.java=plain/text`. Default: not set.
-
-
-### global\_auth\_file
-Path to a global passwords file, either full path or relative to the mongoose
-executable. If set, per-directory `.htpasswd` files are ignored,
-and all requests are authorised against that file. Use `mongoose -A` to
-manage passwords, or third party utilities like
-[htpasswd-generator](http://www.askapache.com/online-tools/htpasswd-generator).
-Default: not set, per-directory `.htpasswd` files are respected.
-
-### hide\_files\_patterns
-A pattern for the files to hide. Files that match the pattern will not
-show up in directory listing and return `404 Not Found` if requested. Pattern
-must be for a file name only, not including directory name, e.g.
-`mongoose -hide_files_patterns secret.txt|even_more_secret.txt`. Default:
-not set.
-
-### index_files
-Comma-separated list of files to be treated as directory index
-files. Default: `index.html,index.htm,index.cgi,index.shtml,index.php`
-
-### listening_port
-Port to listen on. Port could be prepended by the specific IP address to bind
-to, e.g. `mongoose -listening_port 127.0.0.1:8080`. Otherwise Mongoose
-will bind to all addresses. To enable SSL, build Mongoose with
-`-DNS_ENABLE_SSL` compilation option, and specify `listening_port` as
-`ssl://PORT:SSL_CERTIFICATE.PEM`. Example SSL listener:
-`mongoose -listening_port ssl://8043:ssl_cert.pem`. Note that PEM file should
-be in PEM format, and must have both certificate and private key in it,
-concatenated together. More than one listening port can be specified,
-separated by comma,
-for example `mongoose -listening_port 8080,8000`. Default: 8080.
-
-### run\_as\_user
-Switch to given user credentials after startup. UNIX-only. This option is
-required when mongoose needs to bind on privileged port on UNIX, e.g.
-
- $ sudo mongoose -listening_port 80 -run_as_user nobody
-
-Default: not set.
-
-### url\_rewrites
-Comma-separated list of URL rewrites in the form of
-`uri_pattern=file_or_directory_path`. When Mongoose receives the request,
-it constructs the file name to show by combining `document_root` and the URI.
-However, if the rewrite option is used and `uri_pattern` matches the
-requested URI, then `document_root` is ignored. Instead,
-`file_or_directory_path` is used, which should be a full path name or
-a path relative to the web server's current working directory. Note that
-`uri_pattern`, as all mongoose patterns, is a prefix pattern. If `uri_pattern`
-is a number, then it is treated as HTTP error code, and `file_or_directory_path`
-should be an URI to redirect to. Mongoose will issue `302` temporary redirect
-to the specified URI with following parameters:
-`?code=HTTP_ERROR_CODE&orig_uri=ORIGINAL_URI&query_string=QUERY_STRING`.
-
-If `uri_pattern` starts with `@` symbol, then Mongoose compares
-it with the `HOST` header of the request. If they are equal, Mongoose sets
-document root to `file_or_directory_path`, implementing virtual hosts support.
-
-Examples:
-
- # Redirect all accesses to `.doc` files to a special script
- mongoose -url_rewrites **.doc$=/path/to/cgi-bin/handle_doc.cgi
-
- # Implement user home directories support
- mongoose -url_rewrites /~joe/=/home/joe/,/~bill=/home/bill/
-
- # Redirect 404 errors to a specific error page
- mongoose -url_rewrites 404=/cgi-bin/error.cgi
-
- # Virtual hosts example: serve foo.com domain from different directory
- mongoose -url_rewrites @foo.com=/var/www/foo.com
-
-Default: not set.
diff --git a/3rdparty/mongoose/docs/PhpWebsite.md b/3rdparty/mongoose/docs/PhpWebsite.md
deleted file mode 100644
index 3b503c64c2a..00000000000
--- a/3rdparty/mongoose/docs/PhpWebsite.md
+++ /dev/null
@@ -1,49 +0,0 @@
-How To Create A PHP Website With Mongoose
-===========================================
-
-## 1. Create a directory which will contain your website files. For example, on drive `C:\`, create a directory called `my_website`:
-
-![screenshot](http://cesanta.com/images/tut_php/tut1.png)
-
-## 2. Inside `my_website` directory, create a new file called "index". This will be the default web page shown when the website is visited.
-
-![screenshot](http://cesanta.com/images/tut_php/tut2.png)
-
-## 3. Open index file with your favorite editor (for example, Notepad) and enter some HTML / PHP code:
-
-![screenshot](http://cesanta.com/images/tut_php/tut3.png)
-
-## 4. Save this file as `index.php`:
-
-![screenshot](http://cesanta.com/images/tut_php/tut4.png)
-
-
-## 5. Download Mongoose executable from http://cesanta.com/mongoose.shtml and copy the executable inside `my_website` directory:
-
-![screenshot](http://cesanta.com/images/tut_php/tut5.png)
-
-## 6. Double-click mongoose executable. An icon will appear on a system tray in the bottom right corner of the desktop:
-
-![screenshot](http://cesanta.com/images/tut_php/tut6.png)
-
-## 7. Download PHP 5.3 zip (do NOT download PHP 5.5 cause you might have missing DLLs problem) from http://windows.php.net/download and extract it to `C:\php5` directory:
-![screenshot](http://cesanta.com/images/tut_php/tut7.png)
-
-## 8. Click on the mongoose icon and choose "Edit Settings" menu.:
-![screenshot](http://cesanta.com/images/tut_php/tut8.png)
-
-## 9. A settings dialog will appear. Click on `cgi_interpreter` button:
-
-![screenshot](http://cesanta.com/images/tut_php/tut9.png)
-
-## 10. Choose `C:\php5\php-cgi.exe` and click "Save Settings":
-
-![screenshot](http://cesanta.com/images/tut_php/tut10.png)
-
-## 11. Click on the mongoose icon and choose "Go to my address" menu:
-![screenshot](http://cesanta.com/images/tut_php/tut11.png)
-
-
-## 12. A browser will popup displaying `index.php`.
-
-![screenshot](http://cesanta.com/images/tut_php/tut12.png)
diff --git a/3rdparty/mongoose/docs/ReleaseNotes.md b/3rdparty/mongoose/docs/ReleaseNotes.md
deleted file mode 100644
index 10fd4592609..00000000000
--- a/3rdparty/mongoose/docs/ReleaseNotes.md
+++ /dev/null
@@ -1,218 +0,0 @@
-# Mongoose Release Notes
-
-## Release 5.6, 2015-03-17
-
-Changes in Libmongoose library:
-
-- Added `-dav_root` configuration option that gives an ability to mount
- a different root directory (not document_root)
-- Fixes for build under Win23 and MinGW
-- Bugfix: Double dots removal
-- Bugfix: final chunked response double-send
-- Fixed compilation in 64-bit environments
-- Added OS/2 compatibility
-- Added `getaddrinfo()` call and `NS_ENABLE_GETADDRINFO`
-- Various SSL-related fixes
-- Added integer overflow protection in `iobuf_append()` and `deliver_websocket_frame()`
-- Fixed NetBSD build
-- Enabled `NS_ENABLE_IPV6` build for Visual Studio 2008+
-- Enhanced comma detection in `parse_header()`
-- Fixed unchanged memory accesses on ARM
-- Added ability to use custom memory allocator through NS_MALLOC, NS_FREE, NS_REALLOC
-
-Changes in Mongoose binary:
-
-- Added `-start_browser` option to disable automatic browser launch
-- Added experimental SSL support. To listen on HTTPS port, use `ssl://PORT:SSL_CERT` format. For example, to listen on HTTP port 8080 and HTTPS port 8043, use `-listening_port 8080,ssl://8043:ssl_cert.pem`
-
-## Release 5.5, October 28 2014
-
-Changes in Libmongoose library:
-
-- Added new API function: `mg_forward()` for proxying functionality
-- Added new API function: `mg_send_file_data()` for sending file data
-- Added new utility API functions: `mg_mmap() and mg_munmap()`
-- Changed the way SSL settings are handled: removed `ssl_certificate` and
- `ssl_ca_certificate` options, and instead made `listening_port` accept
- `ssl://PORT:SSL_CERT:CA_CERT` notation
-- Added ability to listen on multiple ports, see `listening_port` documentation
-- Added `enable_proxy` option
-- Added [cookie_authentication](https://github.com/cesanta/mongoose/tree/master/examples/cookie_authentication) example
-- Added [websocket\_ssl\_proxy](https://github.com/cesanta/mongoose/tree/master/examples/websocket_ssl_proxy) example
-- Added [http_client](https://github.com/cesanta/mongoose/tree/master/examples/http_client) example
-- Increased default 'idle connection' timeout from 30 to 300 seconds
-- Fixed MinGW build
-- Refactored all examples, put each in it's own directory with dedicated build
-- Many smaller bugfixed, including SSL, CGI, API, proxy, etc
-
-Changes in pre-compiled binaries:
-
-- Support for multiple listening ports
-- Fixed CGI handling for scripts that specify interpreter in the hashbang line
-
-## Release 5.4, July 28 2014
-
-Changes in Libmongoose library:
-
-- Added `hexdump_file` option for low-level request/reply debugging
-- Added `mg_template()` API function for generating HTML pages from
- templates with expansions
-- Fixed `struct mg_connection::local_ip` handling, `mg_set_option()`
- behavior with NULL values
-- Added `mg_send_file()` call to send arbitrary file to the client
-- Added `mg_terminate_ssl()` for SSL termination functionality
-- Added HTTP proxy support, `enable_proxy` config option
-- Added `mg_next()` for iterating over existing active connections
-- Added client-side SSL auth, `ssl_ca_certificate` option
-- Added `mg_wakeup_server_ex()` for pushing messages to existing connections
-- Added `MG_WS_HANDSHAKE` and `MG_WS_CONNECT` events that are sent on
- Websocket handshake is connection establishment, respectively
-- Removed server-side Lua support
-- Filesystem access, reading from socket/SSL performance improvements
-- DAV PROPFIND memory leak fixed
-- Added `big_upload.c` and enhanced `upload.c` example
-- Added `proxy.c` example that demonstrates proxy functionality and SSE pushes
-- Added `websocket2.c` example that shows simple web chat implementation
- over websockets
-- Various minor fixes
-
-
-Changes in pre-compiled binaries:
-
-- Created HTML administration console
-- When server is started, browser is started automatically
-- Fixed directory listing bug when directory contains `#` character
-- Removed built-in Lua Server Pages in the binary, and instead
- added Mongoose + Lua developer bundle which has Lua Server Pages support.
- That also solves external Lua modules loading problem.
-
-
-## Release 5.3, March 10 2014
-
-Changes in Libmongoose library:
-
- * Moved to the evented API. Updated API documentation is at
- http://cesanta.com/docs/Embed.shtml
- http://cesanta.com/docs/API.shtml
- * Added `MG_LUA` event for exporting custom variables to the Lua environment
- * Added virtual hosts capability, see `url_rewrites` option description at
- http://cesanta.com/docs/Options.shtml
- * Added mjpg serving example
- * Cleaned up and documented HTTP client API, with unit tests
- * Added `mg_wakeup_server()` to awaken `mg_poll_server()`
- from another thread
- * Moved Mongoose IO core to [https://github.com/cesanta/net_skeleton](Net Skeleton)
- * Added connection hexdump functionality for developers
- * Bug fixes
-
-Changes in pre-compiled binaries:
-
- * New awesome Mongoose logos by our designer Katrin - thanks Katrin!
- Check them out at http://cesanta.com/products.shtml
- * Added Lua Server Pages support to the free version, quick intro is at
- http://cesanta.com/docs/Lua.shtml
- * Added quick "Set shared directory" menu item to set `document_root`
- * Added SSI support to the Pro version
- * Removed SSL support from the Pro version
-
-## Release 5.2, Feb 1 2014
-
- * Windows binary made fully UNICODE aware. In previous versions,
- the presence of non-ASCII chars in document root, CGI script name,
- or directory name might have broken Mongoose as stand-alone
- or as Windows service. Now Mongoose works with non-ASCII paths properly.
- Internally, Mongoose uses UTF8 encoding. When making WinAPI calls,
- mongoose converts UTF8 strings to wide chars and calls UNICODE API.
- * Enhanced authorization API by providing `mg_set_auth_handler()` and
- `mg_authorize_digest()`
- * Removed `mg_add_uri_handler()`, added `mg_set_request_handler()`.
- There is only oneURI handler that handles all requests, just like in 4.x.
- The reason for this change is to provide an ability to catch all URIs,
- and at the same time signal Mongoose to continue handling specific URIs.
- * Added `mg_parse_multipart()` API for file uploads.
- Note that the restriction on uploading huge files still exists,
- and will be eliminated in the next release.
- * Allowing mongoose to bind to port 0, in which case it'll bind to any
- random unused port.
- * Moved `idle_timeout_ms` run-time option to compile-time flag
- * Added asynchronous HTTP client, not documented yet. Documentation and
- examples are coming in the next couple of weeks. Async Websocket client
- is scheduled for the next release. See usage examples at `unit_test.c`
- * Windows and MacOS pre-built binaries are now split to free and paid ones,
- paid binaries include CGI, SSL, Lua, Sqlite, support and updates.
- Linux pre-built binary includes all functionality and is free, and will
- continue to be free. Source code for Windows and MacOS GUI is closed.
- Disclaimer: source code for the command line stand-alone server,
- as well as Mongoose library itself, will never be closed.
- * Multiple bug fixes and minor enhancements
-
-## Release 5.1, Jan 10 2014
-
- * CGI-related bugs where fixed, primarily for Windows platform
- * Bugs on Windows related to UNICODE support were fixed
- * Added a feature to support "error pages" through redirect.
- Done using `-url_redirects` option, details are on
- http://cesanta.com/docs/Options.shtml
-
-## Release 5.0, Jan 6 2014
-
- * Internal core has been changed from blocking, thread-per-connection to
- non-blocking, asynchronous, one thread for all.
- * API modification for server creation and response creation. That allowed
- keep-alive support for dynamic requests, boosting the embedded performance
- to 100+ thousands requests per second on a single core
- (as measured on my development MacBook laptop)
- * Unified handling of POST requests and Websocket requests by putting a
- payload into `conn->content`, `conn->content_len` attributes.
- That simplified user code and eliminated the need of `mg_read()`,
- since mongoose buffers all data prior to calling the callback
- * keep-alive support is the default
- * Dropped SSI support and throttling support
- * Several configuration parameters are gone:
- * `cgi_environment` (replaced with MONGOOSE_CGI),
- * `protect_uri` (not useful)
- * `ssi_pattern` (SSI support is gone)
- * `throttle` (throttling support is gone)
- * `error_log_file` (not used)
- * `enable_keep_alive` (enabled by default)
- * `listening_ports` (renamed to listening_port)
- * `num_threads` (core has changed to single thread)
- * `put_delete_auth_file` (renamed to dav_auth_file)
- * `authentication_domain` (renamed to auth_domain)
- * Due to the async, non-blocking nature of the core, few restrictions
- are now in place:
- * user callbacks must not block
- * POST and Websocket data are now buffered, and cannot be huge
- * mongoose is now capable on listening on only one port
-
-## Release 4.1, Oct 2013
-## Release 4.0, Oct 2013
-## Release 3.8, Sep 2013
-
-## Release 3.7, Feb 2 2013
-
- * Added "redirect to SSL port" functionality, e.g. if you specify
- `-listening_ports 8080r,8043s`
- then all requests to HTTP port 8080 will be redirected to HTTPS port 8043
- * Added `mg_download()` API, an HTTP client interface!
- * Lua server pages now must output HTTP headers -- full control for Lua
- * Added pre-built binary for MacOS, with initial GUI support
- * API change: got rid of events, moved to struct `mg_callbacks`
- * Bugfixes, thanks to contributors
-
-
-## Release 3.7, Jan 18 2013
- * Fixed source code archive (main.c was missing)
- * Extended Windows GUI functionality:
- * Added "Start browser" systray popup menu item
- * Enhanced configuration editor
- * Renamed config options:
- * `put_delete_passwords_file` -> `put_delete_auth_file`
- * `global_passwords_file` -> `global_auth_file`
- * `select()` changed to `poll()`, to avoid big file descriptor
- `FD_SET` problem on UNIX
- * Couple of bugfixes, thanks to contributors
-
-
-Earlier release notes could be found by searching
-[Mongoose mailing list](https://groups.google.com/forum/#!forum/mongoose-users)
diff --git a/3rdparty/mongoose/docs/SSL.md b/3rdparty/mongoose/docs/SSL.md
deleted file mode 100644
index 09f16e9e756..00000000000
--- a/3rdparty/mongoose/docs/SSL.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# Mongoose SSL guide
-
-SSL is a protocol that makes web communication secure. To enable SSL
-in mongoose, 2 steps are required:
-
- 1. Create valid SSL certificate file
- 2. Append SSL certificate file path to the `listening_ports` option
-
-Below is the `mongoose.conf` file snippet for typical SSL setup:
-
- document_root www_root # Serve files in www_root directory
- listening_ports 80,443:cert.pem # Listen on ports 80 and 443
-
-## How to create SSL certificate file
-
-SSL certificate file is a text file that must contain at least two
-sections:
-
- 1. A private key
- 2. A certificate
-
-Both sections should be chunks of text in PEM format. When PEM file is
-opened in a text editor, it looks like this:
-
- -----BEGIN RSA PRIVATE KEY-----
- MIIEogIBAAKCAQEAwONaLOP7EdegqjRuQKSDXzvHmFMZfBufjhELhNjo5KsL4ieH
- hYN0Zii2yTb63jGxKY6gH1R/r9dL8kXaJmcZrfSa3AgywnteJWg=
- -----END RSA PRIVATE KEY-----
- -----BEGIN CERTIFICATE-----
- MIIDBjCCAe4CCQCX05m0b053QzANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJB
- SEGI4JSxV56lYg==
- -----END CERTIFICATE-----
-
-Two aforementioned sections are clearly seen. Typically, those section
-are bigger then in the example shown. The text between the `BEGIN` and
-`END` is the text representation of binary data, a private key and a
-certificate. Therefore, in order to create a certificate file,
-
- * private key must be converted to PEM format
- * certificate must be converted to PEM format
- * those two should be concatenated into a single file
-
-If the certificate chain in used, a chain file also needs to be
-converted into PEM format and appended to the certificate file.
-
-## How SSL works
-
-SSL is a protocol that can encrypt communication between two parties. If third
-party observes all messages passed by, it would be very
-hard for the third party (though not impossible) to decrypt the communication.
-
-The idea is based on so-called public key encryption. Communicating parties
-have two keys: a public key and a private key. A public key is advertised
-to everybody, and it is contained in a certificate. A private key is kept
-secret. Security algorithm works in a way that anybody can encrypt
-a message using public key, and only private key can decrypt it.
-
-This is why web server needs both private key and certificate: private key
-is used to decrypt incoming messages, and certificate is used to tell the
-public key to the other party. When communication starts, parties exchange
-their public keys, and keep private keys to themselves. Man-in-the-middle
-who observes the communication is unable to decrypt the messages cause
-private keys are required for decryption.
-
-Encryption algorithms are built on top of hard mathematical problem, which
-makes it very expensive for man-in-the-middle to compute private keys.
-For example, RSA algorithm is based on a mathematical problem of factorization.
-It is easy to generate two very large prime numbers `P` and `Q` and make
-a product `P * Q`. But given a product, it is very hard to recover these
-two prime numbers - this is called factorization.
diff --git a/3rdparty/mongoose/docs/Usage.md b/3rdparty/mongoose/docs/Usage.md
deleted file mode 100644
index b9f7052fa09..00000000000
--- a/3rdparty/mongoose/docs/Usage.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Mongoose User Guide
-
-Mongoose is small and easy to use web server built on top of
-mongoose library. It is designed with maximum simplicity in mind. For example,
-to share any directory, just drop mongoose executable in that directory,
-double-click it (on UNIX, run it from shell) and launch a browser at
-[http://localhost:8080](http://localhost:8080) Note that 'localhost' should
-be changed to a machine's name if a folder is accessed from other computer.
-
-On Windows and Mac, Mongoose iconifies itself to the system tray when started.
-Right-click on the icon to pop up a menu, where it is possible to stop
-mongoose, or configure it.
-
-On UNIX, `mongoose` is a command line utility. Running `mongoose` in
-terminal, optionally followed by configuration parameters
-(`mongoose [OPTIONS]`) or configuration file name
-(`mongoose [config_file_name]`) starts the
-web server:
-
- $ mongoose -document_root /var/www # Running mongoose with cmdline options
- $ mongoose /etc/my_config.txt # Running mongoose with config file
- $ mongoose # Running with no parameters. This will
- # serve current directory on port 8080
-
-Mongoose does not detach from terminal. Pressing `Ctrl-C` keys
-stops the server.
-
-When started, mongoose first searches for the configuration file.
-If configuration file is specified explicitly in the command line, then
-specified configuration file is used.
-Otherwise, mongoose would search for file `mongoose.conf` in the same directory
-where binary is located, and use it. Configuration file can be absent.
-
-Configuration file is a sequence of lines, each line containing
-command line argument name and it's value. Empty lines and lines beginning
-with `#` are ignored. Here is the example of `mongoose.conf` file:
-
- # This is a comment
- document_root C:\www
- listening_port 80
- ssl_certificate C:\mongoose\ssl_cert.pem
-
-Command line arguments are highest priority and can override
-configuration file settings. For example, if `mongoose.conf` has line
-`document_root /var/www`, and mongoose has been started as
-`mongoose -document_root /etc`, then `/etc` directory will be used as
-document root.
-
-Note that configuration options on the command line must start with `-`,
-and their names are the same as in the config file. Exampli gratia,
-the following two setups are equivalent:
-
- $ mongoose -listening_port 1234 -document_root /var/www
-
- $ cat > mongoose.conf
- listening_ports 1234
- document_root /var/www
- ^D
- $ mongoose
-
-Mongoose can also be used to modify `.htpasswd` passwords file:
-
- $ mongoose -A .htpasswd mydomain.com user_name user_password
-
-Unlike other web servers, mongoose does not require CGI scripts be located in
-a special directory. CGI scripts can be anywhere. CGI (and SSI) files are
-recognized by the file name pattern. Mongoose uses shell-like glob
-patterns. Pattern match starts at the beginning of the string, so essentially
-patterns are prefix patterns. Syntax is as follows:
-
- ** Matches everything
- * Matches everything but slash character, '/'
- ? Matches any character
- $ Matches the end of the string
- | Matches if pattern on the left side or the right side matches.
-
-All other characters in the pattern match themselves. Examples:
-
- # Pattern Meaning
- **.cgi$ Any string that ends with .cgi
- /foo Any string that begins with /foo
- **a$|**b$ Any string that ends with a or b
-
-To restrict CGI files only to `/cgi-bin/` directory, use this setting:
-
- $ mongoose -cgi_pattern /cgi-bin/*.cgi # Emulate /cgi-bin/ restriction
diff --git a/3rdparty/mongoose/examples/.gitignore b/3rdparty/mongoose/examples/.gitignore
deleted file mode 100644
index b883f1fdc6d..00000000000
--- a/3rdparty/mongoose/examples/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.exe
diff --git a/3rdparty/mongoose/examples/Makefile b/3rdparty/mongoose/examples/Makefile
deleted file mode 100644
index 43483c3f860..00000000000
--- a/3rdparty/mongoose/examples/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-SUBDIRS = $(sort $(filter-out csharp/, $(dir $(wildcard */))))
-X = $(SUBDIRS)
-ifdef WINDIR
- # appending the Winsock2 library at the end of the compiler
- # invocation
- CFLAGS_EXTRA += -lws2_32
-endif
-
-.PHONY: $(SUBDIRS)
-
-all: $(SUBDIRS)
-
-$(SUBDIRS):
- @$(MAKE) CFLAGS_EXTRA="$(CFLAGS_EXTRA)" -C $@
-
-clean:
- for d in $(SUBDIRS) ; do $(MAKE) -C $$d clean ; done
diff --git a/3rdparty/mongoose/examples/array_vars/Makefile b/3rdparty/mongoose/examples/array_vars/Makefile
deleted file mode 100644
index 5ce2d1db6cb..00000000000
--- a/3rdparty/mongoose/examples/array_vars/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = array_vars
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-all: $(PROG)
-
-run: $(PROG)
- ./$(PROG)
-
-$(PROG): $(SOURCES) Makefile
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-win:
- wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /I../.. /Fe$(PROG).exe
- wine $(PROG).exe
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
diff --git a/3rdparty/mongoose/examples/array_vars/array_vars.c b/3rdparty/mongoose/examples/array_vars/array_vars.c
deleted file mode 100644
index d631a7b0c79..00000000000
--- a/3rdparty/mongoose/examples/array_vars/array_vars.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2014 Cesanta Software
-// All rights reserved
-//
-// This example demostrates how to use array get variables using mg_get_n_var
-// $Date: 2014-09-09 22:20:23 UTC $
-
-#include <stdio.h>
-#include <string.h>
-#include "mongoose.h"
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return MG_TRUE;
- case MG_REQUEST:
- {
- mg_printf_data(conn, "Hello! Requested URI is [%s] ", conn->uri);
- char buffer[1024];
- int i, ret;
- for(i=0; (ret = mg_get_var_n(conn, "foo[]", buffer, 1024, i)) > 0; i++)
- mg_printf_data(conn, "\nfoo[%d] = %s", i, buffer);
-
- return MG_TRUE;
- }
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server;
-
- // Create and configure the server
- server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8080");
-
- // Serve request. Hit Ctrl-C to terminate the program
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
-
- // Cleanup, and free server instance
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/big_upload/Makefile b/3rdparty/mongoose/examples/big_upload/Makefile
deleted file mode 100644
index a47d188489f..00000000000
--- a/3rdparty/mongoose/examples/big_upload/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = big_upload
-CFLAGS = -W -Wall -pthread -I../.. -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/big_upload/big_upload.c b/3rdparty/mongoose/examples/big_upload/big_upload.c
deleted file mode 100644
index a756ddd3a07..00000000000
--- a/3rdparty/mongoose/examples/big_upload/big_upload.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "mongoose.h"
-
-static int handle_request(struct mg_connection *conn) {
- if (strcmp(conn->uri, "/upload") == 0) {
- FILE *fp = (FILE *) conn->connection_param;
- if (fp != NULL) {
- fwrite(conn->content, 1, conn->content_len, fp); // Write last bits
- mg_printf(conn, "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain\r\n"
- "Connection: close\r\n\r\n"
- "Written %ld of POST data to a temp file:\n\n",
- (long) ftell(fp));
-
- // Temp file will be destroyed after fclose(), do something with the
- // data here -- for example, parse it and extract uploaded files.
- // As an example, we just echo the whole POST buffer back to the client.
- rewind(fp);
- mg_send_file_data(conn, fileno(fp));
- return MG_MORE; // Tell Mongoose reply is not completed yet
- } else {
- mg_printf_data(conn, "%s", "Had no data to write...");
- return MG_TRUE; // Tell Mongoose we're done with this request
- }
- } else {
- mg_printf_data(conn, "%s",
- "<html><body>Upload example."
- "<form method=\"POST\" action=\"/upload\" "
- " enctype=\"multipart/form-data\">"
- "<input type=\"file\" name=\"file\" /> <br/>"
- "<input type=\"submit\" value=\"Upload\" />"
- "</form></body></html>");
- return MG_TRUE; // Tell mongoose to close this connection
- }
-}
-
-// Mongoose sends MG_RECV for every received POST chunk.
-// When last POST chunk is received, Mongoose sends MG_REQUEST, then MG_CLOSE.
-static int handle_recv(struct mg_connection *conn) {
- FILE *fp = (FILE *) conn->connection_param;
-
- // Open temporary file where we going to write data
- if (fp == NULL && ((conn->connection_param = fp = tmpfile())) == NULL) {
- return -1; // Close connection on error
- }
-
- // Return number of bytes written to a temporary file: that is how many
- // bytes we want to discard from the receive buffer
- return fwrite(conn->content, 1, conn->content_len, fp);
-}
-
-// Make sure we free all allocated resources
-static int handle_close(struct mg_connection *conn) {
- if (conn->connection_param != NULL) {
- fclose((FILE *) conn->connection_param);
- conn->connection_param = NULL;
- }
- return MG_TRUE;
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return MG_TRUE;
- case MG_REQUEST: return handle_request(conn);
- case MG_RECV: return handle_recv(conn);
- case MG_CLOSE: return handle_close(conn);
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8080");
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
-
- for (;;) {
- mg_poll_server(server, 1000);
- }
-
- mg_destroy_server(&server);
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/cookie_authentication/Makefile b/3rdparty/mongoose/examples/cookie_authentication/Makefile
deleted file mode 100644
index 1eb0652b961..00000000000
--- a/3rdparty/mongoose/examples/cookie_authentication/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = cookie_auth
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/cookie_authentication/cookie_auth.c b/3rdparty/mongoose/examples/cookie_authentication/cookie_auth.c
deleted file mode 100644
index c35e0445ef2..00000000000
--- a/3rdparty/mongoose/examples/cookie_authentication/cookie_auth.c
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2014 Cesanta Software
-// All rights reserved
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include "mongoose.h"
-
-static const char *s_login_uri = "/login.html";
-static const char *s_secret = ":-)"; // Must be known only to server
-
-static void generate_ssid(const char *user_name, const char *expiration_date,
- char *ssid, size_t ssid_size) {
- char hash[33];
- mg_md5(hash, user_name, ":", expiration_date, ":", s_secret, NULL);
- snprintf(ssid, ssid_size, "%s|%s|%s", user_name, expiration_date, hash);
-}
-
-static int check_auth(struct mg_connection *conn) {
- char ssid[100], calculated_ssid[100], name[100], expire[100];
-
- // Always authenticate requests to login page
- if (strcmp(conn->uri, s_login_uri) == 0) {
- return MG_TRUE;
- }
-
- // Look for session ID in the Cookie.
- // That session ID can be validated against the database that stores
- // current active sessions.
- mg_parse_header(mg_get_header(conn, "Cookie"), "ssid", ssid, sizeof(ssid));
- if (sscanf(ssid, "%[^|]|%[^|]|", name, expire) == 2) {
- generate_ssid(name, expire, calculated_ssid, sizeof(calculated_ssid));
- if (strcmp(ssid, calculated_ssid) == 0) {
- return MG_TRUE; // Authenticate
- }
- }
-
- // Auth failed, do NOT authenticate, redirect to login page
- mg_printf(conn, "HTTP/1.1 302 Moved\r\nLocation: %s\r\n\r\n", s_login_uri);
- return MG_FALSE;
-}
-
-static int check_login_form_submission(struct mg_connection *conn) {
- char name[100], password[100], ssid[100], expire[100], expire_epoch[100];
-
- mg_get_var(conn, "name", name, sizeof(name));
- mg_get_var(conn, "password", password, sizeof(password));
-
- // A real authentication mechanism should be employed here.
- // Also, the whole site should be served through HTTPS.
- if (strcmp(name, "Joe") == 0 && strcmp(password, "Doe") == 0) {
- // Generate expiry date
- time_t t = time(NULL) + 3600; // Valid for 1 hour
- snprintf(expire_epoch, sizeof(expire_epoch), "%lu", (unsigned long) t);
- strftime(expire, sizeof(expire), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
- generate_ssid(name, expire_epoch, ssid, sizeof(ssid));
- // Set "session id" cookie, there could be some data encoded in it.
- mg_printf(conn,
- "HTTP/1.1 302 Moved\r\n"
- "Set-Cookie: ssid=%s; expire=\"%s\"; http-only; HttpOnly;\r\n"
- "Content-Length: 0\r\n"
- "Location: /\r\n\r\n",
- ssid, expire);
- return MG_TRUE;
- }
- return MG_FALSE;
-}
-
-static int serve_request(struct mg_connection *conn) {
- if (strcmp(conn->uri, s_login_uri) == 0 &&
- strcmp(conn->request_method, "POST") == 0) {
- return check_login_form_submission(conn);
- }
- return MG_FALSE; // Serve files in the document_root
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return check_auth(conn);
- case MG_REQUEST: return serve_request(conn);
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8080");
- mg_set_option(server, "document_root", ".");
-
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/cookie_authentication/index.html b/3rdparty/mongoose/examples/cookie_authentication/index.html
deleted file mode 100644
index fc992fd03de..00000000000
--- a/3rdparty/mongoose/examples/cookie_authentication/index.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8" />
- <title>WebSocket Test</title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style type="text/css">
- body {
- background-color: #cde; margin: 0;
- padding: 0; font: 14px Helvetica, Arial, sans-serif;
- }
- * { outline: none; }
- div.content {
- width: 800px; margin: 2em auto; padding: 20px 50px;
- background-color: #fff; border-radius: 1em;
- }
- label { display: inline-block; min-width: 7em; }
- input { border: 1px solid #ccc; padding: 0.4em; margin: 0 0 10px 0; }
- a:link, a:visited { color: #69c; text-decoration: none; }
- @media (max-width: 700px) {
- body { background-color: #fff; }
- div.content {
- width: auto; margin: 0 auto; border-radius: 0; padding: 1em;
- }
- }
-</style>
-
-<body>
- <div class="content">
- <h1>Mongoose Cookie Base Authentication</h1>
- <p>This is an index page. Authentication succeeded.</p>
-</body>
-</html> \ No newline at end of file
diff --git a/3rdparty/mongoose/examples/cookie_authentication/login.html b/3rdparty/mongoose/examples/cookie_authentication/login.html
deleted file mode 100644
index d3ff7056573..00000000000
--- a/3rdparty/mongoose/examples/cookie_authentication/login.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8" />
- <title>WebSocket Test</title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style type="text/css">
- body {
- background-color: #cde; margin: 0;
- padding: 0; font: 14px Helvetica, Arial, sans-serif;
- }
- * { outline: none; }
- div.content {
- width: 800px; margin: 2em auto; padding: 20px 50px;
- background-color: #fff; border-radius: 1em;
- }
- label { display: inline-block; min-width: 7em; }
- input { border: 1px solid #ccc; padding: 0.4em; margin: 0 0 10px 0; }
- a:link, a:visited { color: #69c; text-decoration: none; }
- @media (max-width: 700px) {
- body { background-color: #fff; }
- div.content {
- width: auto; margin: 0 auto; border-radius: 0; padding: 1em;
- }
- }
-</style>
-
-<body>
- <div class="content">
- <h1>Mongoose Cookie Based Authentication</h1>
- <p>Use name "Joe", password "Doe" to login.</p>
- <form method="POST">
- <div>
- <label>Name:</label>
- <input type="text" name="name"/>
- </div><div>
- <label>Password:</label>
- <input type="password" name="password"/>
- </div><div>
- <input type="submit" value="Login"/>
- </div>
- </form>
-</body>
-</html> \ No newline at end of file
diff --git a/3rdparty/mongoose/examples/csharp/example.cs b/3rdparty/mongoose/examples/csharp/example.cs
deleted file mode 100644
index 9736c6b991d..00000000000
--- a/3rdparty/mongoose/examples/csharp/example.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is part of mongoose web server project,
-// https://github.com/cesanta/mongoose
-
-using System;
-
-public class Program {
- static private int EventHandler(IntPtr conn_ptr, int ev) {
- MongooseConnection conn = (MongooseConnection)
- System.Runtime.InteropServices.Marshal.PtrToStructure(
- conn_ptr , typeof(MongooseConnection));
-
- if (ev == 102) {
- // MG_AUTH
- return 1;
- } else if (ev == 103) {
- // MG_REQUEST
- Mongoose.send_data(conn_ptr, "Hello from C#!\n");
- Mongoose.send_data(conn_ptr, "URI: " + conn.uri + "\n");
- Mongoose.send_data(conn_ptr, "HTTP Headers:\n");
-
- for (int i = 0; i < conn.num_headers; i++) {
- IntPtr name = conn.http_headers[i].name;
- IntPtr val = conn.http_headers[i].value;
- System.Runtime.InteropServices.Marshal.PtrToStringAnsi(name);
- Mongoose.send_data(conn_ptr, " " +
- System.Runtime.InteropServices.Marshal.PtrToStringAnsi(name) + ": " +
- System.Runtime.InteropServices.Marshal.PtrToStringAnsi(val) + "\n");
- }
- return 1;
- }
- return 0;
- }
-
- static void Main() {
- Mongoose web_server = new Mongoose(".", "9001",
- new MongooseEventHandler(EventHandler));
-
- Console.WriteLine("Mongoose started, press Ctrl-C to exit.");
- for (;;) {
- web_server.poll(1000);
- }
- }
-}
diff --git a/3rdparty/mongoose/examples/csharp/mongoose.cs b/3rdparty/mongoose/examples/csharp/mongoose.cs
deleted file mode 100644
index f0953d22d58..00000000000
--- a/3rdparty/mongoose/examples/csharp/mongoose.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// This file is part of mongoose web server project,
-// https://github.com/cesanta/mongoose
-
-using System;
-using System.Runtime.InteropServices;
-
-[StructLayout(LayoutKind.Sequential)] public struct MongooseHeader {
- [MarshalAs(UnmanagedType.LPTStr)] public IntPtr name;
- [MarshalAs(UnmanagedType.LPTStr)] public IntPtr value;
-};
-
-// mongoose.h :: struct mg_connection
-[StructLayout(LayoutKind.Sequential)] public struct MongooseConnection {
- [MarshalAs(UnmanagedType.LPTStr)] public string request_method;
- [MarshalAs(UnmanagedType.LPTStr)] public string uri;
- [MarshalAs(UnmanagedType.LPTStr)] public string http_version;
- [MarshalAs(UnmanagedType.LPTStr)] public string query_string;
-
- [MarshalAs(UnmanagedType.ByValArray,SizeConst=48)] public char[] remote_ip;
- [MarshalAs(UnmanagedType.LPTStr)] public string local_ip;
- [MarshalAs(UnmanagedType.U2)] public short remote_port;
- [MarshalAs(UnmanagedType.U2)] public short local_port;
-
- [MarshalAs(UnmanagedType.SysInt)] public int num_headers;
- [MarshalAs(UnmanagedType.ByValArray,SizeConst=30)]
- public MongooseHeader[] http_headers;
-
- [MarshalAs(UnmanagedType.LPTStr)] public IntPtr content;
- [MarshalAs(UnmanagedType.SysInt)] public int content_len;
-
- [MarshalAs(UnmanagedType.SysInt)] public int is_websocket;
- [MarshalAs(UnmanagedType.SysInt)] public int status_code;
- [MarshalAs(UnmanagedType.SysInt)] public int wsbits;
-};
-
-public delegate int MongooseEventHandler(IntPtr c, int ev);
-
-public class Mongoose {
- public const string dll_ = "mongoose";
- private IntPtr server_;
-
- [DllImport(dll_)] private static extern IntPtr
- mg_create_server(IntPtr user_data, MongooseEventHandler eh);
- [DllImport(dll_)] private static extern int
- mg_poll_server(IntPtr server, int milli);
- [DllImport(dll_)] private static extern IntPtr
- mg_set_option(IntPtr server, string name, string value);
- [DllImport(dll_)] public static extern int
- mg_send_data(IntPtr conn, string data, int length);
-
- public Mongoose(string document_root,
- string listening_port,
- MongooseEventHandler event_handler) {
- server_ = mg_create_server(IntPtr.Zero, event_handler);
- mg_set_option(server_, "document_root", document_root);
- mg_set_option(server_, "listening_port", listening_port);
- }
-
- public static int send_data(IntPtr conn, string data) {
- return mg_send_data(conn, data, data.Length);
- }
-
- public void poll(int milli) {
- mg_poll_server(server_, milli);
- }
-
- // TODO: add destructor and call mg_destroy_server()
-}
diff --git a/3rdparty/mongoose/examples/digest_authentication/Makefile b/3rdparty/mongoose/examples/digest_authentication/Makefile
deleted file mode 100644
index 86cd30db1d7..00000000000
--- a/3rdparty/mongoose/examples/digest_authentication/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = digest_auth
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/digest_authentication/digest_auth.c b/3rdparty/mongoose/examples/digest_authentication/digest_auth.c
deleted file mode 100644
index 18835c729c7..00000000000
--- a/3rdparty/mongoose/examples/digest_authentication/digest_auth.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "mongoose.h"
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
-
- if (ev == MG_AUTH) {
- int result = MG_FALSE; // Not authorized
- FILE *fp;
-
- // To populate passwords file, do
- // mongoose -A my_passwords.txt mydomain.com admin admin
- if ((fp = fopen("my_passwords.txt", "r")) != NULL) {
- result = mg_authorize_digest(conn, fp);
- fclose(fp);
- }
-
- return result;
- }
-
- return MG_FALSE;
-}
-
-int main(void) {
- struct mg_server *server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8080");
- mg_set_option(server, "document_root", ".");
-
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/file_upload/Makefile b/3rdparty/mongoose/examples/file_upload/Makefile
deleted file mode 100644
index bf1e51dfc90..00000000000
--- a/3rdparty/mongoose/examples/file_upload/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = file_upload
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-all: $(PROG)
-
-run: $(PROG)
- ./$(PROG)
-
-$(PROG): $(SOURCES) Makefile
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-win:
- wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /I../.. /Fe$(PROG).exe
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
diff --git a/3rdparty/mongoose/examples/file_upload/file_upload.c b/3rdparty/mongoose/examples/file_upload/file_upload.c
deleted file mode 100644
index eedfc837c57..00000000000
--- a/3rdparty/mongoose/examples/file_upload/file_upload.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2004-2012 Sergey Lyubka
-// This file is a part of mongoose project, http://github.com/valenok/mongoose
-
-#include <stdio.h>
-#include <string.h>
-#include "mongoose.h"
-
-static int send_index_page(struct mg_connection *conn) {
- const char *data;
- int data_len, n1, n2;
- char var_name[100], file_name[100];
-
- mg_printf_data(conn, "%s",
- "<html><body>Upload example."
- "<form method=\"POST\" action=\"/handle_post_request\" "
- " enctype=\"multipart/form-data\">"
- "<input type=\"file\" name=\"file1\" /> <br/>"
- "<input type=\"file\" name=\"file2\" /> <br/>"
- "<input type=\"submit\" value=\"Upload\" />"
- "</form>");
-
- n1 = n2 = 0;
- while ((n2 = mg_parse_multipart(conn->content + n1, conn->content_len - n1,
- var_name, sizeof(var_name), file_name,
- sizeof(file_name), &data, &data_len)) > 0) {
- mg_printf_data(conn, "var: %s, file_name: %s, size: %d bytes<br>",
- var_name, file_name, data_len);
- n1 += n2;
- }
-
- mg_printf_data(conn, "%s", "</body></html>");
-
- return MG_TRUE;
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return MG_TRUE;
- case MG_REQUEST: return send_index_page(conn);
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server;
-
- // Create and configure the server
- server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8080");
-
- // Serve request. Hit Ctrl-C to terminate the program
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
-
- // Cleanup, and free server instance
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/form_submit/Makefile b/3rdparty/mongoose/examples/form_submit/Makefile
deleted file mode 100644
index b233f285774..00000000000
--- a/3rdparty/mongoose/examples/form_submit/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = form_submit
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/form_submit/form_submit.c b/3rdparty/mongoose/examples/form_submit/form_submit.c
deleted file mode 100644
index f6893114d7f..00000000000
--- a/3rdparty/mongoose/examples/form_submit/form_submit.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "mongoose.h"
-
-static const char *html_form =
- "<html><body>POST example."
- "<form method=\"POST\" action=\"/handle_post_request\">"
- "Input 1: <input type=\"text\" name=\"input_1\" /> <br/>"
- "Input 2: <input type=\"text\" name=\"input_2\" /> <br/>"
- "<input type=\"submit\" />"
- "</form></body></html>";
-
-static void send_reply(struct mg_connection *conn) {
- char var1[500], var2[500];
-
- if (strcmp(conn->uri, "/handle_post_request") == 0) {
- // User has submitted a form, show submitted data and a variable value
- // Parse form data. var1 and var2 are guaranteed to be NUL-terminated
- mg_get_var(conn, "input_1", var1, sizeof(var1));
- mg_get_var(conn, "input_2", var2, sizeof(var2));
-
- // Send reply to the client, showing submitted form values.
- // POST data is in conn->content, data length is in conn->content_len
- mg_send_header(conn, "Content-Type", "text/plain");
- mg_printf_data(conn,
- "Submitted data: [%.*s]\n"
- "Submitted data length: %d bytes\n"
- "input_1: [%s]\n"
- "input_2: [%s]\n",
- conn->content_len, conn->content,
- conn->content_len, var1, var2);
- } else {
- // Show HTML form.
- mg_send_data(conn, html_form, strlen(html_form));
- }
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- if (ev == MG_REQUEST) {
- send_reply(conn);
- return MG_TRUE;
- } else if (ev == MG_AUTH) {
- return MG_TRUE;
- } else {
- return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server = mg_create_server(NULL, ev_handler);
-
- mg_set_option(server, "listening_port", "8080");
-
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
-
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/hello_world/Makefile b/3rdparty/mongoose/examples/hello_world/Makefile
deleted file mode 100644
index d1384e01723..00000000000
--- a/3rdparty/mongoose/examples/hello_world/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = hello_world
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-all: $(PROG)
-
-run: $(PROG)
- ./$(PROG)
-
-$(PROG): $(SOURCES) Makefile
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-win:
- wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /I../.. /Fe$(PROG).exe
- wine $(PROG).exe
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
diff --git a/3rdparty/mongoose/examples/hello_world/hello_world.c b/3rdparty/mongoose/examples/hello_world/hello_world.c
deleted file mode 100644
index 95056895d02..00000000000
--- a/3rdparty/mongoose/examples/hello_world/hello_world.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2014 Cesanta Software
-// All rights reserved
-//
-// This example demostrates basic use of Mongoose embedded web server.
-// $Date: 2014-09-09 22:20:23 UTC $
-
-#include <stdio.h>
-#include <string.h>
-#include "mongoose.h"
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return MG_TRUE;
- case MG_REQUEST:
- mg_printf_data(conn, "Hello! Requested URI is [%s]", conn->uri);
- return MG_TRUE;
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server;
-
- // Create and configure the server
- server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8080");
-
- // Serve request. Hit Ctrl-C to terminate the program
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
-
- // Cleanup, and free server instance
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/http_client/Makefile b/3rdparty/mongoose/examples/http_client/Makefile
deleted file mode 100644
index 5769babf0f7..00000000000
--- a/3rdparty/mongoose/examples/http_client/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = http_client
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-unix: $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp *.o *.lib
diff --git a/3rdparty/mongoose/examples/http_client/http_client.c b/3rdparty/mongoose/examples/http_client/http_client.c
deleted file mode 100644
index 41eac581e90..00000000000
--- a/3rdparty/mongoose/examples/http_client/http_client.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2014 Cesanta Software
-// All rights reserved
-//
-// This example demostrates how to connect to the remote Web server,
-// download data, process it and send back a reply.
-
-#include <signal.h>
-#include <stdlib.h>
-
-#include "mongoose.h"
-
-static int s_received_signal = 0;
-static struct mg_server *s_server = NULL;
-static const char *s_remote_addr = "glosbe.com:80";
-
-static void signal_handler(int sig_num) {
- signal(sig_num, signal_handler);
- s_received_signal = sig_num;
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- struct mg_connection *client, *orig;
-
- switch (ev) {
- case MG_AUTH:
- return MG_TRUE;
-
- case MG_CONNECT:
- // Send request to the remote host.
- // TODO(lsm): handle connect error here.
- mg_printf(conn, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n",
- "/gapi/translate?from=eng&dest=fra&format=json&phrase=cat",
- s_remote_addr);
- return MG_TRUE;
-
- case MG_REPLY:
- // Send reply to the original connection
- orig = (struct mg_connection *) conn->connection_param;
- mg_send_status(orig, conn->status_code);
- mg_send_header(orig, "Content-Type", "text/plain");
- mg_send_data(orig, conn->content, conn->content_len);
- mg_send_data(orig, "", 0); // Last chunk: mark the end of reply
-
- // Disconnect connections
- orig->connection_param = NULL;
- conn->connection_param = NULL;
- return MG_TRUE;
-
- case MG_REQUEST:
- if ((client = mg_connect(s_server, s_remote_addr)) != NULL) {
- // Interconnect requests
- client->connection_param = conn;
- conn->connection_param = client;
- return MG_MORE;
- } else {
- mg_printf_data(conn, "%s", "cannot send API request");
- return MG_TRUE;
- }
-
- default:
- return MG_FALSE;
- }
-}
-
-int main(void) {
- s_server = mg_create_server(NULL, ev_handler);
-
- mg_set_option(s_server, "listening_port", "8080");
-
- // Setup signal handlers
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
-
- printf("Listening on port %s\n", mg_get_option(s_server, "listening_port"));
- while (s_received_signal == 0) {
- mg_poll_server(s_server, 1000);
- }
- mg_destroy_server(&s_server);
- printf("Existing on signal %d\n", s_received_signal);
-
- return EXIT_SUCCESS;
-}
diff --git a/3rdparty/mongoose/examples/mjpg_streamer/Makefile b/3rdparty/mongoose/examples/mjpg_streamer/Makefile
deleted file mode 100644
index 35946c0a477..00000000000
--- a/3rdparty/mongoose/examples/mjpg_streamer/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = mjpg_streamer
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/mjpg_streamer/mjpg_streamer.c b/3rdparty/mongoose/examples/mjpg_streamer/mjpg_streamer.c
deleted file mode 100644
index 4bac6c14838..00000000000
--- a/3rdparty/mongoose/examples/mjpg_streamer/mjpg_streamer.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include <sys/stat.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include "mongoose.h"
-
-static void send_file(struct mg_connection *conn, const char *path) {
- char buf[1024];
- struct stat st;
- int n;
- FILE *fp;
-
- if (stat(path, &st) == 0 && (fp = fopen(path, "rb")) != NULL) {
- mg_printf(conn, "--w00t\r\nContent-Type: image/jpeg\r\n"
- "Content-Length: %lu\r\n\r\n", (unsigned long) st.st_size);
- while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
- mg_write(conn, buf, n);
- }
- fclose(fp);
- mg_write(conn, "\r\n", 2);
- }
-}
-
-struct conn_state {
- int file_index;
- time_t last_poll;
-};
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- const char **file_names = (const char **) conn->server_param;
- struct conn_state *state;
- time_t now = time(NULL);
-
- switch (ev) {
-
- case MG_AUTH:
- return MG_TRUE;
-
- case MG_REQUEST:
- if (strcmp(conn->uri, "/stream") != 0) {
- mg_send_header(conn, "Content-Type", "text/html");
- mg_printf_data(conn, "%s",
- "Go to <a href=/stream>/stream</a> for MJPG stream");
- return MG_TRUE;
- }
-
- mg_printf(conn, "%s",
- "HTTP/1.0 200 OK\r\n" "Cache-Control: no-cache\r\n"
- "Pragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT\r\n"
- "Connection: close\r\nContent-Type: multipart/x-mixed-replace; "
- "boundary=--w00t\r\n\r\n");
-
- send_file(conn, file_names[0]);
-
- state = (struct conn_state *) malloc(sizeof(*state));
- conn->connection_param = state;
- state->file_index = 1; // First file is already sent
- state->last_poll = time(NULL);
- return MG_MORE;
-
- case MG_POLL:
- state = (struct conn_state *) conn->connection_param;
-
- if (state != NULL && now > state->last_poll) {
- if (file_names[state->file_index] != NULL) {
- send_file(conn, file_names[state->file_index]);
- state->file_index++;
- if (file_names[state->file_index] == NULL) {
- return MG_TRUE; // No more images, close connection
- }
- }
- state->last_poll = now;
- }
- return MG_FALSE;
-
- case MG_CLOSE:
- free(conn->connection_param);
- conn->connection_param = NULL;
- return MG_FALSE;
-
- default:
- return MG_FALSE;
- }
-}
-
-int main(int argc, char *argv[]) {
- struct mg_server *server;
-
- if (argc < 3) {
- printf("Usage: %s image1.jpg image2.jpg ...\n", argv[0]);
- return 1;
- }
-
- server = mg_create_server(&argv[1], ev_handler);
- mg_set_option(server, "listening_port", "8080");
-
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/multi_threaded_server/Makefile b/3rdparty/mongoose/examples/multi_threaded_server/Makefile
deleted file mode 100644
index 2b08db12c77..00000000000
--- a/3rdparty/mongoose/examples/multi_threaded_server/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = multi_threaded_server
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/multi_threaded_server/multi_threaded_server.c b/3rdparty/mongoose/examples/multi_threaded_server/multi_threaded_server.c
deleted file mode 100644
index 30af3f10807..00000000000
--- a/3rdparty/mongoose/examples/multi_threaded_server/multi_threaded_server.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "mongoose.h"
-
-// Start a browser and hit refresh couple of times. The replies will
-// come from both server instances.
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- if (ev == MG_REQUEST) {
- mg_send_header(conn, "Content-Type", "text/plain");
- mg_printf_data(conn, "This is a reply from server instance # %s",
- (char *) conn->server_param);
- return MG_TRUE;
- } else if (ev == MG_AUTH) {
- return MG_TRUE;
- } else {
- return MG_FALSE;
- }
-}
-
-static void *serve(void *server) {
- for (;;) mg_poll_server((struct mg_server *) server, 1000);
- return NULL;
-}
-
-int main(void) {
- struct mg_server *server1, *server2;
-
- server1 = mg_create_server((void *) "1", ev_handler);
- server2 = mg_create_server((void *) "2", ev_handler);
-
- // Make both server1 and server2 listen on the same sockets
- mg_set_option(server1, "listening_port", "8080");
- mg_copy_listeners(server1, server2);
-
- // server1 goes to separate thread, server 2 runs in main thread.
- // IMPORTANT: NEVER LET DIFFERENT THREADS HANDLE THE SAME SERVER.
- mg_start_thread(serve, server1);
- mg_start_thread(serve, server2);
- getchar();
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/proxy_server/Makefile b/3rdparty/mongoose/examples/proxy_server/Makefile
deleted file mode 100644
index 7a5d2f7d41a..00000000000
--- a/3rdparty/mongoose/examples/proxy_server/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = proxy_server
-FLAGS = -I../.. -DNS_ENABLE_SSL
-CFLAGS = -W -Wall -g -O0 -pthread -lssl -DMONGOOSE_ENABLE_THREADS $(FLAGS) $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-unix: $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/proxy_server/proxy_server.c b/3rdparty/mongoose/examples/proxy_server/proxy_server.c
deleted file mode 100644
index cef0f24c9bb..00000000000
--- a/3rdparty/mongoose/examples/proxy_server/proxy_server.c
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (c) 2014 Cesanta Software Limited
-// All rights reserved
-//
-// To build and run this example:
-// git clone https://github.com/cesanta/net_skeleton.git
-// git clone https://github.com/cesanta/mongoose.git
-// cd mongoose/examples
-// make proxy
-// ./proxy
-//
-// Configure your browser to use localhost:2014 as a proxy for all protocols
-// Then, navigate to https://cesanta.com
-
-#include <sys/stat.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#ifdef _WIN32
-#define sleep(x) Sleep((x) * 1000)
-#else
-#include <unistd.h>
-#endif
-
-#include "mongoose.h"
-
-static int s_received_signal = 0;
-static struct mg_server *s_server = NULL;
-
-#define SSE_CONNECTION ((void *) 1)
-
-static void elog(int do_exit, const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fputc('\n', stderr);
- if (do_exit) exit(EXIT_FAILURE);
-}
-
-static void signal_handler(int sig_num) {
- signal(sig_num, signal_handler);
- s_received_signal = sig_num;
-}
-
-static int sse_push(struct mg_connection *conn, enum mg_event ev) {
- if (ev == MG_POLL && conn->connection_param == SSE_CONNECTION) {
- mg_printf(conn, "data: %s\r\n\r\n", (const char *) conn->callback_param);
- }
- return MG_TRUE;
-}
-
-static void *sse_pusher_thread_func(void *param) {
- while (s_received_signal == 0) {
- mg_wakeup_server_ex(s_server, sse_push, "%lu %s",
- (unsigned long) time(NULL), (const char *) param);
- sleep(1);
- }
- return NULL;
-}
-
-// Return: 1 if regular file, 2 if directory, 0 if not found
-static int exists(const char *path) {
- struct stat st;
- return stat(path, &st) != 0 ? 0 : S_ISDIR(st.st_mode) == 0 ? 1 : 2;
-}
-
-// Return: 1 if regular file, 2 if directory, 0 if not found
-static int is_local_file(const char *uri, char *path, size_t path_len) {
- snprintf(path, path_len, "%s/%s",
- mg_get_option(s_server, "document_root"), uri);
- return exists(path);
-}
-
-static int try_to_serve_locally(struct mg_connection *conn) {
- char path[500], buf[2000];
- int n, res;
- FILE *fp = NULL;
-
- if ((res = is_local_file(conn->uri, path, sizeof(path))) == 2) {
- strncat(path, "/index.html", sizeof(path) - strlen(path) - 1);
- res = exists(path);
- printf("PATH: [%s]\n", path);
- }
- if (res == 0) return MG_FALSE;
-
- if ((fp = fopen(path, "rb")) != NULL) {
- printf("Serving [%s] locally \n", path);
- mg_send_header(conn, "Connection", "close");
- mg_send_header(conn, "Content-Type", mg_get_mime_type(path, "text/plain"));
- while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
- mg_send_data(conn, buf, n);
- }
- mg_send_data(conn, "", 0);
- fclose(fp);
- }
- return fp == NULL ? MG_FALSE : MG_TRUE;
-}
-
-static int is_resource_present_locally(const char *uri) {
- char path[500];
- return is_local_file(uri, path, sizeof(path)) || strcmp(uri, "/api/sse") == 0;
-}
-
-static int proxy_event_handler(struct mg_connection *conn, enum mg_event ev) {
- static const char target_url[] = "http://cesanta.com";
- static int target_url_size = sizeof(target_url) - 1;
- const char *host;
-
- switch (ev) {
- case MG_REQUEST:
- host = mg_get_header(conn, "Host");
- printf("[%s] [%s] [%s]\n", conn->request_method, conn->uri,
- host == NULL ? "" : host);
- if (strstr(conn->uri, "/qqq") != NULL) s_received_signal = SIGTERM;
-
- // Proxied HTTPS requests use "CONNECT foo.com:443"
- // Proxied HTTP requests use "GET http://..... "
- // Serve requests for target_url from the local FS.
- if (memcmp(conn->uri, target_url, target_url_size) == 0 &&
- is_resource_present_locally(conn->uri + target_url_size)) {
- conn->uri += target_url_size; // Leave only path in the URI
- }
-
- if (strcmp(conn->uri, "/api/sse") == 0) {
- conn->connection_param = SSE_CONNECTION;
- mg_printf(conn, "%s", "HTTP/1.0 200 OK\r\n"
- "Content-Type: text/event-stream\r\n"
- "Cache-Control: no-cache\r\n\r\n");
- return MG_MORE;
- }
-
- if (host != NULL && strstr(host, "cesanta") != NULL) {
- return try_to_serve_locally(conn);
- }
-
- // Enable man-in-the-middle SSL mode for oracle.com
- if (!strcmp(conn->request_method, "CONNECT") &&
- !strcmp(host, "oracle.com")) {
- mg_terminate_ssl(conn, "ssl_cert.pem"); // MUST return MG_MORE after
- return MG_MORE;
- }
-
- return MG_FALSE;
- case MG_AUTH:
- return MG_TRUE;
- default:
- return MG_FALSE;
- }
-}
-
-static void setopt(struct mg_server *s, const char *opt, const char *val) {
- const char *err_msg = mg_set_option(s, opt, val);
- if (err_msg != NULL) {
- elog(1, "Error setting [%s]: [%s]", opt, err_msg);
- }
-}
-
-int main(int argc, char *argv[]) {
- const char *port = "2014", *dump = NULL, *root = "proxy_web_root";
- int i;
-
- // Parse command line options
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-port") == 0 && i + 1 < argc) {
- port = argv[++i];
- } else if (strcmp(argv[i], "-root") == 0 && i + 1 < argc) {
- root = argv[++i];
- } else if (strcmp(argv[i], "-dump") == 0 && i + 1 < argc) {
- dump = argv[++i];
- } else {
- elog(1, "Usage: %s [-cert FILE] [-ca_cert FILE] [-port PORT]", argv[0]);
- }
- }
-
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
-
- // Create and configure proxy server
- s_server = mg_create_server(NULL, &proxy_event_handler);
- setopt(s_server, "enable_proxy", "yes");
- setopt(s_server, "document_root", root);
- setopt(s_server, "listening_port", port);
- setopt(s_server, "hexdump_file", dump);
-
- // Start two SSE pushing threads
- mg_start_thread(sse_pusher_thread_func, (void *) "sse_pusher_thread_1");
- mg_start_thread(sse_pusher_thread_func, (void *) "sse_pusher_thread_2");
-
- // Start serving in the main thread
- printf("Starting on port %s\n", mg_get_option(s_server, "listening_port"));
- while (s_received_signal == 0) {
- mg_poll_server(s_server, 1000);
- }
- printf("Existing on signal %d\n", s_received_signal);
- mg_destroy_server(&s_server);
-
- return EXIT_SUCCESS;
-}
diff --git a/3rdparty/mongoose/examples/proxy_server/proxy_web_root/app1/index.html b/3rdparty/mongoose/examples/proxy_server/proxy_web_root/app1/index.html
deleted file mode 100644
index 5b5c81677f2..00000000000
--- a/3rdparty/mongoose/examples/proxy_server/proxy_web_root/app1/index.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<html>
-<head>
- <title>App1 Index</title>
- <style>
- img { height: 40px; }
- </style>
-</head>
-<body>
-
- <h1>App1 index page. Served locally from the the proxy server filesystem</h1>
-
- <p>image that references non-existent local resource. Forwarded to
- the 'real' proxy target:</p>
- <img src="http://cesanta.com/images/logo.png" />
-
- <p>Google logo via HTTPS (external resource, served by remote host):</p>
- <img src="https://www.google.ie/images/srpr/logo11w.png" />
-
- <p>Same image via HTTP:</p>
- <img src="http://www.google.ie/images/srpr/logo11w.png" />
-
-</body>
-</html>
diff --git a/3rdparty/mongoose/examples/proxy_server/proxy_web_root/app2/index.html b/3rdparty/mongoose/examples/proxy_server/proxy_web_root/app2/index.html
deleted file mode 100644
index 28d4beadcdb..00000000000
--- a/3rdparty/mongoose/examples/proxy_server/proxy_web_root/app2/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<html>
-<head>
- <title>App2 Index</title>
- <meta charset="utf-8">
- <script>
- window.onload = function() {
- // Using secure websocket connection, wss://
- var ws = new WebSocket('wss://echo.websocket.org');
- var div = document.getElementById('events');
- ws.onmessage = function(ev) {
- var el = document.createElement('div');
- el.innerHTML = 'websocket message: ' + ev.data;
- div.appendChild(el);
- // Keep only last 5 messages in the list
- while (div.childNodes.length > 5) div.removeChild(div.firstChild);
- };
-
- // Send random stuff to the websocket connection periodically.
- // websocket server much echo that stuff back.
- window.setInterval(function() {
- var d = new Date();
- ws.send(d.toString());
- }, 1000);
- };
- </script>
-</head>
-<body>
- <h1>App2 index page. Served locally from the
- the proxy's filesystem.</h1>
- <p>
- Following div shows proxy forwarding of websocket connection, served by
- ws://echo.websocket.org:
- </p>
-
- <div id="events"></div>
-</body>
-</html>
diff --git a/3rdparty/mongoose/examples/proxy_server/proxy_web_root/index.html b/3rdparty/mongoose/examples/proxy_server/proxy_web_root/index.html
deleted file mode 100644
index d8343bf3b71..00000000000
--- a/3rdparty/mongoose/examples/proxy_server/proxy_web_root/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<html>
-<head>
- <title> proxy index </title>
- <script type="text/javascript">
- window.onload = function() {
- var es = new EventSource("/api/sse");
- var div = document.getElementById('events');
- es.onmessage = function(ev) {
- var el = document.createElement('div');
- el.innerHTML = 'sse message: ' + ev.data;
- div.appendChild(el);
- // Keep only last 5 messages in the list
- while (div.childNodes.length > 5) div.removeChild(div.firstChild);
- };
- };
- </script>
-</head>
-<body>
- <h1> proxy index page.</h1>
- <ul>
- <li><a href="app1">App1</a> - App1 root</li>
- <li><a href="app2">App2</a> - App2 root</li>
- </ul>
-
- <h2>SSE pushes, done by separate threads at random times:</h2>
- <div id="events"></div>
-
-</body>
-</html>
diff --git a/3rdparty/mongoose/examples/proxy_server/ssl_cert.pem b/3rdparty/mongoose/examples/proxy_server/ssl_cert.pem
deleted file mode 100644
index e6045389a1a..00000000000
--- a/3rdparty/mongoose/examples/proxy_server/ssl_cert.pem
+++ /dev/null
@@ -1,50 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAwONaLOP7EdegqjRuQKSDXzvHmFMZfBufjhELhNjo5KsL4ieH
-hMSGCcSV6y32hzhqR5lvTViaQez+xhc58NZRu+OUgEhodRBW/vAOjpz/xdMz5HaC
-EhP3E9W1pkitVseS8B5rrgJo1BfCGai1fPav1nutPq2Kj7vMy24+g460Lonf6ln1
-di4aTIRtAqXtUU6RFpPJP35PkCXbTK65O8HJSxxt/XtfoezHCU5+UIwmZGYx46UB
-Wzg3IfK6bGPSiHU3pdiTol0uMPt/GUK+x4NyZJ4/ImsNAicRwMBdja4ywHKXJehH
-gXBthsVIHbL21x+4ibsg9eVM/XioTV6tW3IrdwIDAQABAoIBACFfdLutmkQFBcRN
-HAJNNHmmsyr0vcUOVnXTFyYeDXV67qxrYHQlOHe6LqIpKq1Mon7O2kYMnWvooFAP
-trOnsS6L+qaTYJdYg2TKjgo4ubw1hZXytyB/mdExuaMSkgMgtpia+tB5lD+V+LxN
-x1DesZ+veFMO3Zluyckswt4qM5yVa04YFrt31H0E1rJfIen61lidXIKYmHHWuRxK
-SadjFfbcqJ6P9ZF22BOkleg5Fm5NaxJmyQynOWaAkSZa5w1XySFfRjRfsbDr64G6
-+LSG8YtRuvfxnvUNhynVPHcpE40eiPo6v8Ho6yZKXpV5klCKciodXAORsswSoGJa
-N3nnu/ECgYEA6Yb2rM3QUEPIALdL8f/OzZ1GBSdiQB2WSAxzl9pR/dLF2H+0pitS
-to0830mk92ppVmRVD3JGxYDRZQ56tlFXyGaCzJBMRIcsotAhBoNbjV0i9n5bLJYf
-BmjU9yvWcgsTt0tr3B0FrtYyp2tCvwHqlxvFpFdUCj2oRw2uGpkhmNkCgYEA03M6
-WxFhsix3y6eVCVvShfbLBSOqp8l0qiTEty+dgVQcWN4CO/5eyaZXKxlCG9KMmKxy
-Yx+YgxZrDhfaZ0cxhHGPRKEAxM3IKwT2C8/wCaSiLWXZZpTifnSD99vtOt4wEfrG
-+AghNd5kamFiM9tU0AyvhJc2vdJFuXrfeC7ntM8CgYBGDA+t4cZcbRhu7ow/OKYF
-kulP3nJgHP/Y+LMrl3cEldZ2jEfZmCElVNQvfd2XwTl7injhOzvzPiKRF3jDez7D
-g8w0JAxceddvttJRK9GoY4l7OoeKpjUELSnEQkf+yUfOsTbXPXVY7jMfeNL6jE6b
-qN7t3qv8rmXtejMBE3G6cQKBgGR5W2BMiRSlxqKx1cKlrApV87BUe1HRCyuR3xuA
-d6Item7Lx1oEi7vb242yKdSYnpApWQ06xTh83Y/Ly87JaIEbiM0+h+P8OEIg0F1a
-iB+86AcUX1I8KseVy+Np0HbpfwP8GrFfA5DaRPK7pXMopEtby8cAJ1XZZaI1/ZvZ
-BebHAoGAcQU9WvCkT+nIp9FpXfBybYUsvgkaizMIqp66/l3GYgYAq8p1VLGvN4v5
-ec0dW58SJrCpqsM3NP78DtEzQf9OOsk+FsjBFzDU2RkeUreyt2/nQBj/2mN/+hEy
-hYN0Zii2yTb63jGxKY6gH1R/r9dL8kXaJmcZrfSa3AgywnteJWg=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIDBjCCAe4CCQCX05m0b053QzANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJB
-VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
-cyBQdHkgTHRkMB4XDTA4MTIwNzEwMjUyMloXDTE4MTIwNTEwMjUyMlowRTELMAkG
-A1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0
-IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AMDjWizj+xHXoKo0bkCkg187x5hTGXwbn44RC4TY6OSrC+Inh4TEhgnElest9oc4
-akeZb01YmkHs/sYXOfDWUbvjlIBIaHUQVv7wDo6c/8XTM+R2ghIT9xPVtaZIrVbH
-kvAea64CaNQXwhmotXz2r9Z7rT6tio+7zMtuPoOOtC6J3+pZ9XYuGkyEbQKl7VFO
-kRaTyT9+T5Al20yuuTvByUscbf17X6HsxwlOflCMJmRmMeOlAVs4NyHyumxj0oh1
-N6XYk6JdLjD7fxlCvseDcmSePyJrDQInEcDAXY2uMsBylyXoR4FwbYbFSB2y9tcf
-uIm7IPXlTP14qE1erVtyK3cCAwEAATANBgkqhkiG9w0BAQQFAAOCAQEAW4yZdqpB
-oIdiuXRosr86Sg9FiMg/cn+2OwQ0QIaA8ZBwKsc+wIIHEgXCS8J6316BGQeUvMD+
-plNe0r4GWzzmlDMdobeQ5arPRB89qd9skE6pAMdLg3FyyfEjz3A0VpskolW5VBMr
-P5R7uJ1FLgH12RyAjZCWYcCRqEMOffqvyMCH6oAjyDmQOA5IssRKX/HsHntSH/HW
-W7slTcP45ty1b44Nq22/ubYk0CJRQgqKOIQ3cLgPomN1jNFQbAbfVTaK1DpEysrQ
-5V8a8gNW+3sVZmV6d1Mj3pN2Le62wUKuV2g6BNU7iiwcoY8HI68aRxz2hVMS+t5f
-SEGI4JSxV56lYg==
------END CERTIFICATE-----
------BEGIN DH PARAMETERS-----
-MEYCQQD+ef8hZ4XbdoyIpJyCTF2UrUEfX6mYDvxuS5O1UNYcslUqlj6JkA11e/yS
-6DK8Z86W6mSj5CEk4IjbyEOECXH7AgEC
------END DH PARAMETERS-----
diff --git a/3rdparty/mongoose/examples/restful_api/Makefile b/3rdparty/mongoose/examples/restful_api/Makefile
deleted file mode 100644
index 97fcf3f93db..00000000000
--- a/3rdparty/mongoose/examples/restful_api/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = restful_api
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/restful_api/index.html b/3rdparty/mongoose/examples/restful_api/index.html
deleted file mode 100644
index 9051ff08ceb..00000000000
--- a/3rdparty/mongoose/examples/restful_api/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8" />
- <title>RESTful API demo</title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style type="text/css">
- * { outline: none; font: 16px/1.4 Helvetica, Arial, sans-serif; }
- body {
- background-color: #cde; margin: 0;
- padding: 0; font: 16px/1.4 Helvetica, Arial, sans-serif;
- }
- div.content {
- width: 800px; margin: 2em auto; padding: 20px 50px;
- background-color: #fff; border-radius: 1em;
- }
- label { display: inline-block; min-width: 7em; }
- input { border: 1px solid #ccc; padding: 0.2em; }
- a:link, a:visited { color: #69c; text-decoration: none; }
- @media (max-width: 700px) {
- body { background-color: #fff; }
- div.content { width: auto; margin: 0 auto; padding: 1em; }
- }
-</style>
-
-<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
-<script language="javascript" type="text/javascript">
- jQuery(function() {
-
- $(document).on('keyup', '#n1, #n2', function() {
- $.ajax({
- url: '/api/sum',
- method: 'POST',
- dataType: 'json',
- data: { n1: $('#n1').val(), n2: $('#n2').val() },
- success: function(json) {
- $('#result').html(json.result);
- }
- });
- });
-
- });
-</script>
-</head>
-<body>
- <div class="content">
- <h1>RESTful API demo.</h1>
-
- <p>
- This page demonstrates how Mongoose web server could be used to implement
- RESTful APIs. Enter numbers below, and press Submit. Browser will send
- two numbers to <tt>/api/sum</tt> URI, Mongoose calclulates the sum of
- two and returns the result.
- </p>
-
- <div>
- <label>Number 1:</label> <input type="text" id="n1" />
- </div><div>
- <label>Number 2:</label> <input type="text" id="n2" />
- </div><div>
- <label>Result:</label> <span id="result">&nbsp;</span>
- </div><div>
-
- </div>
-</body>
-</html>
diff --git a/3rdparty/mongoose/examples/restful_api/restful_api.c b/3rdparty/mongoose/examples/restful_api/restful_api.c
deleted file mode 100644
index ff0ac83a9f3..00000000000
--- a/3rdparty/mongoose/examples/restful_api/restful_api.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "mongoose.h"
-
-static const char *s_no_cache_header =
- "Cache-Control: max-age=0, post-check=0, "
- "pre-check=0, no-store, no-cache, must-revalidate\r\n";
-
-static void handle_restful_call(struct mg_connection *conn) {
- char n1[100], n2[100];
-
- // Get form variables
- mg_get_var(conn, "n1", n1, sizeof(n1));
- mg_get_var(conn, "n2", n2, sizeof(n2));
-
- mg_printf_data(conn, "{ \"result\": %lf }", strtod(n1, NULL) + strtod(n2, NULL));
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return MG_TRUE;
- case MG_REQUEST:
- if (!strcmp(conn->uri, "/api/sum")) {
- handle_restful_call(conn);
- return MG_TRUE;
- }
- mg_send_file(conn, "index.html", s_no_cache_header);
- return MG_MORE;
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server;
-
- // Create and configure the server
- server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8000");
-
- // Serve request. Hit Ctrl-C to terminate the program
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 1000);
- }
-
- // Cleanup, and free server instance
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/send_file/Makefile b/3rdparty/mongoose/examples/send_file/Makefile
deleted file mode 100644
index 4c20d6ac4b6..00000000000
--- a/3rdparty/mongoose/examples/send_file/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = send_file
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-all: $(PROG)
-
-run: $(PROG)
- ./$(PROG)
-
-$(PROG): $(SOURCES) Makefile
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-win:
- wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /I../.. /Fe$(PROG).exe
- wine $(PROG).exe
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
diff --git a/3rdparty/mongoose/examples/send_file/send_file.c b/3rdparty/mongoose/examples/send_file/send_file.c
deleted file mode 100644
index 345c3af694b..00000000000
--- a/3rdparty/mongoose/examples/send_file/send_file.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2014 Cesanta Software
-// All rights reserved
-//
-// This example demostrates how to send arbitrary files to the client.
-
-#include "mongoose.h"
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_REQUEST:
- mg_send_file(conn, "send_file.c", NULL); // Also could be a dir, or CGI
- return MG_MORE; // It is important to return MG_MORE after mg_send_file!
- case MG_AUTH: return MG_TRUE;
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server = mg_create_server(NULL, ev_handler);
- mg_set_option(server, "listening_port", "8080");
-
- printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) mg_poll_server(server, 1000);
- mg_destroy_server(&server);
-
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/web_server/Makefile b/3rdparty/mongoose/examples/web_server/Makefile
deleted file mode 100644
index 4f9eacb6d06..00000000000
--- a/3rdparty/mongoose/examples/web_server/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = web_server
-CFLAGS = -W -Wall -I../.. -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-OPENSSL_FLAGS = -DNS_ENABLE_SSL -lssl
-
-# PolarSSL paths and flags
-POLARSSL_PATH = /usr/local
-POLARSSLCOMPAT_PATH = ./../../../polar
-SOURCES_POLAR = $(SOURCES) $(POLARSSLCOMPAT_PATH)/polarssl_compat.c
-INCDIR_POLAR = -I$(POLARSSLCOMPAT_PATH) -I$(POLARSSL_PATH)/include
-LDFLAGS_POLAR = -L$(POLARSSL_PATH)/lib -lmbedtls
-CFLAGS_POLAR = $(CFLAGS) $(INCDIR_POLAR) -DNS_ENABLE_SSL
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-$(PROG).exe: $(SOURCES)
- cl -Fo $(PROG) $(SOURCES) -nologo -MD -I../..
-
-openssl:
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS) $(OPENSSL_FLAGS)
-
-polarssl:
- $(CC) -o $(PROG) $(SOURCES_POLAR) $(LDFLAGS_POLAR) $(CFLAGS_POLAR)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/web_server/certs/cert.pem b/3rdparty/mongoose/examples/web_server/certs/cert.pem
deleted file mode 100644
index f191e3c10a6..00000000000
--- a/3rdparty/mongoose/examples/web_server/certs/cert.pem
+++ /dev/null
@@ -1,46 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC+zCCAeOgAwIBAgIJAPhB8jbL+G82MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
-BAMMCTEyNy4wLjAuMTAeFw0xNTAzMDYxMjQzMzNaFw0yNTAzMDMxMjQzMzNaMBQx
-EjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBALi3b3daMgzUEROKob1Caf68i+//cTRkPdBJv2cOBak21CdQzY0Nvx73GLzf
-5TKB347BCHNbYRKGJXDbYdmFp20/WeBHkY7RS3Ad2Q5lzyx66u9PxNx7hJIiqBgF
-58VU+E3o/I+o8QNIoOT+wtCiq3Nwkp+zGBJmS32rzMEV9bcKxSzMrkfRhF+XAREd
-DwM9vfPg6WRb/b+vv06uvVwcw390RprLautGfBdaRddVYkIAKJGRRTqZAvTRFW1J
-FcIVOxlN+iA7qP7xjr3tUP78qMmlu0MXsHrUR2cgfveZK2sdUW5G804yHsU5sC8l
-FbtLKMEOyLsk2bEIScOXgum7g2sCAwEAAaNQME4wHQYDVR0OBBYEFHtLzUqAsXkH
-Il8S5sMhJuVhRJLdMB8GA1UdIwQYMBaAFHtLzUqAsXkHIl8S5sMhJuVhRJLdMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEzHc0AOr+qs0OFvWMfcSMi7
-O/aYlLS6f7Sos+lli69+61EcmCTJVarVeAVUsAoqmzBKDbeOpAK1hGX6/GGcXjR2
-BmuU0hUKyX9l1lwdMKU45BayH/riElwnvAyj2GxKoPpdIjlHns4SAITOCUx9NfpM
-agd7kjolton0ZQ5DI/2a43PkqHv1lY4Dp60wJlxit9U68bsGOycCJ/BsAyrPROb2
-D1MkpMBIdfHc8uxRywM3/l9buFX8yrrMUGOYKgfjDwdzbj0iwIixoGpHL7IfeBtu
-dvGO/g2rEhbtAP+xIgOR3GvzqjZh30er3no7zjDMn65tTME18Aq3tBQY7vPDKms=
------END CERTIFICATE-----
------BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4t293WjIM1BET
-iqG9Qmn+vIvv/3E0ZD3QSb9nDgWpNtQnUM2NDb8e9xi83+Uygd+OwQhzW2EShiVw
-22HZhadtP1ngR5GO0UtwHdkOZc8seurvT8Tce4SSIqgYBefFVPhN6PyPqPEDSKDk
-/sLQoqtzcJKfsxgSZkt9q8zBFfW3CsUszK5H0YRflwERHQ8DPb3z4OlkW/2/r79O
-rr1cHMN/dEaay2rrRnwXWkXXVWJCACiRkUU6mQL00RVtSRXCFTsZTfogO6j+8Y69
-7VD+/KjJpbtDF7B61EdnIH73mStrHVFuRvNOMh7FObAvJRW7SyjBDsi7JNmxCEnD
-l4Lpu4NrAgMBAAECggEAaFuqbAHXOQwuwZ2XFzgIblTTsrncmT7w9VZU/sIbTKif
-X771AnX7vmDX5w2PjeN2DE7emV3NEAwd5w7qz1wFZWFfQ6jrgYaZWjRixxGZ5IVl
-aeLlU7OtCGrwEPJ1KTWCO3IgDoHh+Hr1+6o7Imhk+QlmrTcfqHWGvO9s9MGVWt2S
-RLAnSTFiOe5brdJnmlqq1sKZmnLmpydBaPUOYpZGAgRasrjdMZB+lZOazd1x23/5
-GAcm0rDREMnO9b2Jt+TNEZHT6d5KpVoExztZEZj8QCLXoic/SpFIqHGtpNlQXa+d
-BVqgQbIYjO8ldldxZ8YIyJDVF+9e/uBBwu6jBIIsEQKBgQDspEHCyyuh4LG+7BbZ
-eXlsfCxPTM6K9w31ZwHAwRtAuGqrOrE+pFJG9CEsFZbAI1aOGmZZdjexuSMcOlXl
-TIVJTQHoFtoGEsanYEXO4O1t02Ab/DCYSpXusXUraRBRPpsTC77Sh5mxLUNd23d9
-NhnDBuwChAmC+IYexjkXeqPYFwKBgQDH08PEd+2PVo4MD8UVKUlEcgoyCr6ESiyp
-HfYyhhfd5x3DbZLoKCkunDfBs/hakQk8DA2nn4tl4ZjfmzXmX0EBx+E5YTdYshW7
-ZcjN5x64B5PEOAR/NZA6agNlp3XGXXXgX+gnN6pgE49eVU22nZ4G+QBKD6NcCviB
-LBPUxMbvzQKBgHgZYRqonGtaqzsXfP1AjmSFnMNeWtDiU95BOf2Gw/sT3WcrsXr2
-UJ+cFR3XkxvOk4YpVdp/igKT0ILqBGAMdvTdtWMB/gLpEpMt5B/7veRoS7XIRy1z
-ZSawP6QZfWOOX4vKAT29/j2SmEcRNFKC245EfBFGy8EBuqfxuFX3MyJfAoGBAJ0y
-tjsErVmpma1baosvI3g4zlR3p1CimWehLmCopHXorr1iocMIdP0535L+ZU258y3N
-vaA0HpFTW9PsYgaMwLMJ7uAY3lVkIzx84e849i2HqHMgLkl0dbW+WFXL2xblxylv
-yU2wuNNED/EB4lTawcpycAvTKYvrBXt4lVE4S9exAoGAGl6vZV3zyw4jpIw4uDfk
-LTPYUrghFDDGKExyeOnC/W9pqR2veqzfBz02C3jqwhewoqgAcnNc2sg0rJmM+6Oz
-Z2mmGZTHO9xR++7+W7e8AkQBbS6TB8a+7yNcM4USLP+b9sX5N+8gFhFs9tG7j/no
-G44qLsJ/yve7/QsOA37uEMs=
------END PRIVATE KEY-----
diff --git a/3rdparty/mongoose/examples/web_server/web_server.c b/3rdparty/mongoose/examples/web_server/web_server.c
deleted file mode 100644
index 4d256a8fedf..00000000000
--- a/3rdparty/mongoose/examples/web_server/web_server.c
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright (c) 2004-2013 Sergey Lyubka
-// Copyright (c) 2013-2014 Cesanta Software Limited
-
-#undef UNICODE // Use ANSI WinAPI functions
-#undef _UNICODE // Use multibyte encoding on Windows
-#define _MBCS // Use multibyte encoding on Windows
-#define _WIN32_WINNT 0x500 // Enable MIIM_BITMAP
-#define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005
-#define _XOPEN_SOURCE 600 // For PATH_MAX on linux
-#undef WIN32_LEAN_AND_MEAN // Let windows.h always include winsock2.h
-
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <time.h>
-
-#include "mongoose.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#include <direct.h> // For chdir()
-#include <winsvc.h>
-#include <shlobj.h>
-
-#ifndef PATH_MAX
-#define PATH_MAX MAX_PATH
-#endif
-
-#ifndef S_ISDIR
-#define S_ISDIR(x) ((x) & _S_IFDIR)
-#endif
-
-#define DIRSEP '\\'
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#ifndef sleep
-#define sleep(x) Sleep((x) * 1000)
-#endif
-#define abs_path(rel, abs, abs_size) _fullpath((abs), (rel), (abs_size))
-#define SIGCHLD 0
-typedef struct _stat file_stat_t;
-#define stat(x, y) _stat((x), (y))
-#else
-typedef struct stat file_stat_t;
-#include <sys/wait.h>
-#include <unistd.h>
-
-#ifdef IOS
-#include <ifaddrs.h>
-#endif
-
-#define DIRSEP '/'
-#define __cdecl
-#define abs_path(rel, abs, abs_size) realpath((rel), (abs))
-#endif // _WIN32
-
-#define MAX_OPTIONS 100
-#define MAX_CONF_FILE_LINE_SIZE (8 * 1024)
-
-#ifndef MVER
-#define MVER MONGOOSE_VERSION
-#endif
-
-static int exit_flag;
-static char server_name[50]; // Set by init_server_name()
-static char s_config_file[PATH_MAX]; // Set by process_command_line_arguments
-static struct mg_server *server; // Set by start_mongoose()
-static const char *s_default_document_root = ".";
-static const char *s_default_listening_port = "8080";
-static char **s_argv = { NULL };
-
-static void set_options(char *argv[]);
-
-#if !defined(CONFIG_FILE)
-#define CONFIG_FILE "mongoose.conf"
-#endif /* !CONFIG_FILE */
-
-static void __cdecl signal_handler(int sig_num) {
- // Reinstantiate signal handler
- signal(sig_num, signal_handler);
-
-#ifndef _WIN32
- // Do not do the trick with ignoring SIGCHLD, cause not all OSes (e.g. QNX)
- // reap zombies if SIGCHLD is ignored. On QNX, for example, waitpid()
- // fails if SIGCHLD is ignored, making system() non-functional.
- if (sig_num == SIGCHLD) {
- do {} while (waitpid(-1, &sig_num, WNOHANG) > 0);
- } else
-#endif
- { exit_flag = sig_num; }
-}
-
-static void vnotify(const char *fmt, va_list ap, int must_exit) {
- vfprintf(stderr, fmt, ap);
- fputc('\n', stderr);
- if (must_exit) {
- exit(EXIT_FAILURE);
- }
-}
-
-static void notify(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- vnotify(fmt, ap, 0);
- va_end(ap);
-}
-
-static void die(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- vnotify(fmt, ap, 1);
- va_end(ap);
-}
-
-static void show_usage_and_exit(void) {
- const char **names;
- int i;
-
- fprintf(stderr, "Mongoose version %s (c) Sergey Lyubka, built on %s\n",
- MVER, __DATE__);
- fprintf(stderr, "Usage:\n");
-#if !defined(MONGOOSE_NO_AUTH) && !defined(MONGOOSE_NO_FILESYSTEM)
- fprintf(stderr, " mongoose -A <htpasswd_file> <realm> <user> <passwd>\n");
-#endif
- fprintf(stderr, " mongoose [config_file]\n");
- fprintf(stderr, " mongoose [-option value ...]\n");
- fprintf(stderr, "\nOPTIONS:\n");
-
- names = mg_get_valid_option_names();
- for (i = 0; names[i] != NULL; i += 2) {
- fprintf(stderr, " -%s %s\n",
- names[i], names[i + 1] == NULL ? "<empty>" : names[i + 1]);
- }
- exit(EXIT_FAILURE);
-}
-
-#define EV_HANDLER NULL
-
-static char *sdup(const char *str) {
- char *p;
- if ((p = (char *) malloc(strlen(str) + 1)) != NULL) {
- strcpy(p, str);
- }
- return p;
-}
-
-static void set_option(char **options, const char *name, const char *value) {
- int i;
-
- for (i = 0; i < MAX_OPTIONS - 3; i++) {
- if (options[i] == NULL) {
- options[i] = sdup(name);
- options[i + 1] = sdup(value);
- options[i + 2] = NULL;
- break;
- } else if (!strcmp(options[i], name)) {
- free(options[i + 1]);
- options[i + 1] = sdup(value);
- break;
- }
- }
-
- if (i == MAX_OPTIONS - 3) {
- die("%s", "Too many options specified");
- }
-}
-
-static void process_command_line_arguments(char *argv[], char **options) {
- char line[MAX_CONF_FILE_LINE_SIZE], opt[sizeof(line)], val[sizeof(line)],
- *p, cpath[PATH_MAX];
- FILE *fp = NULL;
- size_t i, cmd_line_opts_start = 1, line_no = 0;
-
- // Should we use a config file ?
- if (argv[1] != NULL && argv[1][0] != '-') {
- snprintf(cpath, sizeof(cpath), "%s", argv[1]);
- cmd_line_opts_start = 2;
- } else if ((p = strrchr(argv[0], DIRSEP)) == NULL) {
- // No command line flags specified. Look where binary lives
- snprintf(cpath, sizeof(cpath), "%s", CONFIG_FILE);
- } else {
- snprintf(cpath, sizeof(cpath), "%.*s%c%s",
- (int) (p - argv[0]), argv[0], DIRSEP, CONFIG_FILE);
- }
- abs_path(cpath, s_config_file, sizeof(s_config_file));
-
- fp = fopen(s_config_file, "r");
-
- // If config file was set in command line and open failed, die
- if (cmd_line_opts_start == 2 && fp == NULL) {
- die("Cannot open config file %s: %s", s_config_file, strerror(errno));
- }
-
- // Load config file settings first
- if (fp != NULL) {
- fprintf(stderr, "Loading config file %s\n", s_config_file);
-
- // Loop over the lines in config file
- while (fgets(line, sizeof(line), fp) != NULL) {
- line_no++;
-
- // Ignore empty lines and comments
- for (i = 0; isspace(* (unsigned char *) &line[i]); ) i++;
- if (line[i] == '#' || line[i] == '\0') {
- continue;
- }
-
- if (sscanf(line, "%s %[^\r\n#]", opt, val) != 2) {
- printf("%s: line %d is invalid, ignoring it:\n %s",
- s_config_file, (int) line_no, line);
- } else {
- set_option(options, opt, val);
- }
- }
-
- fclose(fp);
- }
-
- // If we're under MacOS and started by launchd, then the second
- // argument is process serial number, -psn_.....
- // In this case, don't process arguments at all.
- if (argv[1] == NULL || memcmp(argv[1], "-psn_", 5) != 0) {
- // Handle command line flags.
- // They override config file and default settings.
- for (i = cmd_line_opts_start; argv[i] != NULL; i += 2) {
- if (argv[i][0] != '-' || argv[i + 1] == NULL) {
- show_usage_and_exit();
- }
- set_option(options, &argv[i][1], argv[i + 1]);
- }
- }
-}
-
-static void init_server_name(void) {
- const char *descr = "";
- snprintf(server_name, sizeof(server_name), "Mongoose web server v.%s%s",
- MVER, descr);
-}
-
-static int is_path_absolute(const char *path) {
-#ifdef _WIN32
- return path != NULL &&
- ((path[0] == '\\' && path[1] == '\\') || // UNC path, e.g. \\server\dir
- (isalpha(path[0]) && path[1] == ':' && path[2] == '\\')); // E.g. X:\dir
-#else
- return path != NULL && path[0] == '/';
-#endif
-}
-
-static char *get_option(char **options, const char *option_name) {
- int i;
-
- for (i = 0; options[i] != NULL; i++)
- if (!strcmp(options[i], option_name))
- return options[i + 1];
-
- return NULL;
-}
-
-static void *serving_thread_func(void *param) {
- struct mg_server *srv = (struct mg_server *) param;
- while (exit_flag == 0) {
- mg_poll_server(srv, 1000);
- }
- return NULL;
-}
-
-static int path_exists(const char *path, int is_dir) {
- file_stat_t st;
- return path == NULL || (stat(path, &st) == 0 &&
- ((S_ISDIR(st.st_mode) ? 1 : 0) == is_dir));
-}
-
-static void verify_existence(char **options, const char *name, int is_dir) {
- const char *path = get_option(options, name);
- if (!path_exists(path, is_dir)) {
- notify("Invalid path for %s: [%s]: (%s). Make sure that path is either "
- "absolute, or it is relative to mongoose executable.",
- name, path, strerror(errno));
- }
-}
-
-static void set_absolute_path(char *options[], const char *option_name) {
- char path[PATH_MAX], abs[PATH_MAX], *option_value;
- const char *p;
-
- // Check whether option is already set
- option_value = get_option(options, option_name);
-
- // If option is already set and it is an absolute path,
- // leave it as it is -- it's already absolute.
- if (option_value != NULL && !is_path_absolute(option_value)) {
- // Not absolute. Use the directory where mongoose executable lives
- // be the relative directory for everything.
- // Extract mongoose executable directory into path.
- if ((p = strrchr(s_config_file, DIRSEP)) == NULL) {
- getcwd(path, sizeof(path));
- } else {
- snprintf(path, sizeof(path), "%.*s", (int) (p - s_config_file),
- s_config_file);
- }
-
- strncat(path, "/", sizeof(path) - 1);
- strncat(path, option_value, sizeof(path) - 1);
-
- // Absolutize the path, and set the option
- abs_path(path, abs, sizeof(abs));
- set_option(options, option_name, abs);
- }
-}
-
-#if !defined(MONGOOSE_NO_AUTH) && !defined(MONGOOSE_NO_FILESYSTEM)
-int modify_passwords_file(const char *fname, const char *domain,
- const char *user, const char *pass) {
- int found;
- char line[512], u[512], d[512], ha1[33], tmp[PATH_MAX];
- FILE *fp, *fp2;
-
- found = 0;
- fp = fp2 = NULL;
-
- // Regard empty password as no password - remove user record.
- if (pass != NULL && pass[0] == '\0') {
- pass = NULL;
- }
-
- (void) snprintf(tmp, sizeof(tmp), "%s.tmp", fname);
-
- // Create the file if does not exist
- if ((fp = fopen(fname, "a+")) != NULL) {
- fclose(fp);
- }
-
- // Open the given file and temporary file
- if ((fp = fopen(fname, "r")) == NULL) {
- return 0;
- } else if ((fp2 = fopen(tmp, "w+")) == NULL) {
- fclose(fp);
- return 0;
- }
-
- // Copy the stuff to temporary file
- while (fgets(line, sizeof(line), fp) != NULL) {
- if (sscanf(line, "%[^:]:%[^:]:%*s", u, d) != 2) {
- continue;
- }
-
- if (!strcmp(u, user) && !strcmp(d, domain)) {
- found++;
- if (pass != NULL) {
- mg_md5(ha1, user, ":", domain, ":", pass, NULL);
- fprintf(fp2, "%s:%s:%s\n", user, domain, ha1);
- }
- } else {
- fprintf(fp2, "%s", line);
- }
- }
-
- // If new user, just add it
- if (!found && pass != NULL) {
- mg_md5(ha1, user, ":", domain, ":", pass, NULL);
- fprintf(fp2, "%s:%s:%s\n", user, domain, ha1);
- }
-
- // Close files
- fclose(fp);
- fclose(fp2);
-
- // Put the temp file in place of real file
- remove(fname);
- rename(tmp, fname);
-
- return 1;
-}
-#endif
-
-static void start_mongoose(int argc, char *argv[]) {
- s_argv = argv;
- if ((server = mg_create_server(NULL, EV_HANDLER)) == NULL) {
- die("%s", "Failed to start Mongoose.");
- }
-
-#if !defined(MONGOOSE_NO_AUTH) && !defined(MONGOOSE_NO_FILESYSTEM)
- // Edit passwords file if -A option is specified
- if (argc > 1 && !strcmp(argv[1], "-A")) {
- if (argc != 6) {
- show_usage_and_exit();
- }
- exit(modify_passwords_file(argv[2], argv[3], argv[4], argv[5]) ?
- EXIT_SUCCESS : EXIT_FAILURE);
- }
-#endif
-
- // Show usage if -h or --help options are specified
- if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) {
- show_usage_and_exit();
- }
- set_options(argv);
-}
-
-static void set_options(char *argv[]) {
- char *options[MAX_OPTIONS];
- int i;
-
- options[0] = NULL;
- set_option(options, "document_root", s_default_document_root);
- set_option(options, "listening_port", s_default_listening_port);
-
- // Update config based on command line arguments
- process_command_line_arguments(argv, options);
-
- // Make sure we have absolute paths for files and directories
- // https://github.com/valenok/mongoose/issues/181
- set_absolute_path(options, "document_root");
- set_absolute_path(options, "dav_auth_file");
- set_absolute_path(options, "cgi_interpreter");
- set_absolute_path(options, "access_log_file");
- set_absolute_path(options, "global_auth_file");
- set_absolute_path(options, "ssl_certificate");
-
- if (!path_exists(get_option(options, "document_root"), 1)) {
- set_option(options, "document_root", s_default_document_root);
- set_absolute_path(options, "document_root");
- notify("Setting document_root to [%s]",
- mg_get_option(server, "document_root"));
- }
-
- // Make extra verification for certain options
- verify_existence(options, "document_root", 1);
- verify_existence(options, "cgi_interpreter", 0);
- verify_existence(options, "ssl_certificate", 0);
-
- for (i = 0; options[i] != NULL; i += 2) {
- const char *msg = mg_set_option(server, options[i], options[i + 1]);
- if (msg != NULL) {
- notify("Failed to set option [%s] to [%s]: %s",
- options[i], options[i + 1], msg);
- if (!strcmp(options[i], "listening_port")) {
- mg_set_option(server, "listening_port", s_default_listening_port);
- notify("Setting %s to [%s]", options[i], s_default_listening_port);
- }
- }
- free(options[i]);
- free(options[i + 1]);
- }
-
- // Change current working directory to document root. This way,
- // scripts can use relative paths.
- chdir(mg_get_option(server, "document_root"));
-
-#if 0
- // Add an ability to pass listening socket to mongoose
- {
- const char *env = getenv("MONGOOSE_LISTENING_SOCKET");
- if (env != NULL && atoi(env) > 0 ) {
- mg_set_listening_socket(server, atoi(env));
- }
- }
-#endif
-
- // Setup signal handler: quit on Ctrl-C
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
-#ifndef _WIN32
- signal(SIGCHLD, signal_handler);
-#endif
-}
-
-int main(int argc, char *argv[]) {
- init_server_name();
- start_mongoose(argc, argv);
- printf("%s serving [%s] on port %s\n",
- server_name, mg_get_option(server, "document_root"),
- mg_get_option(server, "listening_port"));
- fflush(stdout); // Needed, Windows terminals might not be line-buffered
- serving_thread_func(server);
- printf("Exiting on signal %d ...", exit_flag);
- fflush(stdout);
- mg_destroy_server(&server);
- printf("%s\n", " done.");
-
- return EXIT_SUCCESS;
-}
diff --git a/3rdparty/mongoose/examples/websocket_chat/Makefile b/3rdparty/mongoose/examples/websocket_chat/Makefile
deleted file mode 100644
index 780276ef46b..00000000000
--- a/3rdparty/mongoose/examples/websocket_chat/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = websocket_chat
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/websocket_chat/index.html b/3rdparty/mongoose/examples/websocket_chat/index.html
deleted file mode 100644
index 5da84d30775..00000000000
--- a/3rdparty/mongoose/examples/websocket_chat/index.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8" />
- <title>WebSocket Test</title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style type="text/css">
- body {
- background-color: #cde; margin: 0;
- padding: 0; font: 14px Helvetica, Arial, sans-serif;
- }
- div.content {
- width: 800px; margin: 2em auto; padding: 20px 50px;
- background-color: #fff; border-radius: 1em;
- }
- #messages {
- border: 2px solid #fec; border-radius: 1em;
- height: 10em; overflow: scroll; padding: 0.5em 1em;
- }
- a:link, a:visited { color: #69c; text-decoration: none; }
- @media (max-width: 700px) {
- body { background-color: #fff; }
- div.content {
- width: auto; margin: 0 auto; border-radius: 0;
- padding: 1em;
- }
- }
-</style>
-
-<script language="javascript" type="text/javascript">
-
- var rooms = [];
- var ws = new WebSocket('ws://' + location.host + '/ws');
-
- if (!window.console) { window.console = { log: function() {} } };
-
- ws.onopen = function(ev) { console.log(ev); };
- ws.onerror = function(ev) { console.log(ev); };
- ws.onclose = function(ev) { console.log(ev); };
- ws.onmessage = function(ev) {
- console.log(ev);
- var m = (ev.data || '').match(/^(\S+) (.+)/);
- if (m[1] == 'id') {
- document.getElementById('my_id').innerText = m[2];
- } else if (m[1] == 'msg') {
- var div = document.createElement('div');
- div.innerHTML = m[2];
- document.getElementById('messages').appendChild(div);
- }
- };
-
- window.onload = function() {
- document.getElementById('send_button').onclick = function(ev) {
- var msg = document.getElementById('send_input').value;
- ws.send('msg ' + msg);
- };
- document.getElementById('room_sel').onchange = function(ev) {
- var roomName = this.value || '?';
- ws.send('join ' + roomName);
- };
- };
-</script>
-</head>
-<body>
- <div class="content">
- <h1>Websocket PubSub Demonstration</h1>
-
- <p>
- This page demonstrates how Mongoose web server could be used to implement
- <a href="http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">
- publish–subscribe pattern</a>. Open this page in several browser
- windows. Each window initiates persistent
- <a href="http://en.wikipedia.org/wiki/WebSocket">WebSocket</a>
- connection with Mongoose, making each browser window a websocket client.
- Join a room, send messages, and see messages sent by other clients.
- </p>
-
- <p>
- My ID: <b><span id="my_id"></b></span>
- </p>
- <p>
- Join room: <select id="room_sel">
- <option value="">-- select room -- </option>
- <option>A</option>
- <option>B</option>
- </select>
- </p>
-
- <div id="messages">
- </div>
-
- <p>
- <input type="text" id="send_input" />
- <button id="send_button">Send Message</button>
- </p>
- </div>
-</body>
-</html>
diff --git a/3rdparty/mongoose/examples/websocket_chat/websocket_chat.c b/3rdparty/mongoose/examples/websocket_chat/websocket_chat.c
deleted file mode 100644
index 5ba53801017..00000000000
--- a/3rdparty/mongoose/examples/websocket_chat/websocket_chat.c
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2013-2014 Cesanta Software Limited
-// $Date: 2014-09-09 17:07:55 UTC $
-
-#include <string.h>
-#include <time.h>
-#include <signal.h>
-#include <stdlib.h>
-#include "mongoose.h"
-
-static int s_signal_received = 0;
-static struct mg_server *s_server = NULL;
-
-// Data associated with each websocket connection
-struct conn_data {
- int room;
-};
-
-static void signal_handler(int sig_num) {
- signal(sig_num, signal_handler); // Reinstantiate signal handler
- s_signal_received = sig_num;
-}
-
-static void handle_websocket_message(struct mg_connection *conn) {
- struct conn_data *d = (struct conn_data *) conn->connection_param;
- struct mg_connection *c;
-
- printf("[%.*s]\n", (int) conn->content_len, conn->content);
- if (conn->content_len > 5 && !memcmp(conn->content, "join ", 5)) {
- // Client joined new room
- d->room = conn->content[5];
- } else if (conn->content_len > 4 && !memcmp(conn->content, "msg ", 4) &&
- d->room != 0 && d->room != '?') {
- // Client has sent a message. Push this message to all clients
- // that are subscribed to the same room as client
- for (c = mg_next(s_server, NULL); c != NULL; c = mg_next(s_server, c)) {
- struct conn_data *d2 = (struct conn_data *) c->connection_param;
- if (!c->is_websocket || d2->room != d->room) continue;
- mg_websocket_printf(c, WEBSOCKET_OPCODE_TEXT, "msg %c %p %.*s",
- (char) d->room, conn,
- conn->content_len - 4, conn->content + 4);
- }
- }
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_REQUEST:
- if (conn->is_websocket) {
- handle_websocket_message(conn);
- return MG_TRUE;
- } else {
- mg_send_file(conn, "index.html", NULL); // Return MG_MORE after!
- return MG_MORE;
- }
- case MG_WS_CONNECT:
- // New websocket connection. Send connection ID back to the client.
- conn->connection_param = calloc(1, sizeof(struct conn_data));
- mg_websocket_printf(conn, WEBSOCKET_OPCODE_TEXT, "id %p", conn);
- return MG_FALSE;
- case MG_CLOSE:
- free(conn->connection_param);
- return MG_TRUE;
- case MG_AUTH:
- return MG_TRUE;
- default:
- return MG_FALSE;
- }
-}
-
-int main(void) {
- s_server = mg_create_server(NULL, ev_handler);
- mg_set_option(s_server, "listening_port", "8080");
-
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
-
- printf("Started on port %s\n", mg_get_option(s_server, "listening_port"));
- while (s_signal_received == 0) {
- mg_poll_server(s_server, 100);
- }
- mg_destroy_server(&s_server);
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/websocket_echo_server/Makefile b/3rdparty/mongoose/examples/websocket_echo_server/Makefile
deleted file mode 100644
index f6b132dc9c6..00000000000
--- a/3rdparty/mongoose/examples/websocket_echo_server/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = websocket_echo_server
-CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c ../../mongoose.c
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/websocket_echo_server/index.html b/3rdparty/mongoose/examples/websocket_echo_server/index.html
deleted file mode 100644
index 84e7078a7cb..00000000000
--- a/3rdparty/mongoose/examples/websocket_echo_server/index.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8" />
-<title>WebSocket Test</title>
-<script language="javascript" type="text/javascript">
-
- var out = function(message) {
- var div = document.createElement('div');
- div.innerHTML = message;
- document.getElementById('output').appendChild(div);
- };
-
- window.onload = function() {
- var url = 'ws://' + location.host + '/ws';
- var num_messages = 0;
-
- websocket = new WebSocket(url);
- websocket.onopen = function(ev) {
- out('CONNECTED');
- var msg = 'Не всё подчиняется разуму. Но всё подчиняется упорству. ';
- out('SENT: ' + msg);
- websocket.send(msg);
- };
- websocket.onclose = function(ev) {
- out('DISCONNECTED');
- };
- websocket.onmessage = function(ev) {
- if (!ev.data) {
- out('<span style="color: blue;">PING... </span>');
- } else {
- out('<span style="color: blue;">RESPONSE: ' + ev.data + ' </span>');
- num_messages++;
- }
- if (num_messages > 3) {
- websocket.send('exit');
- }
- };
- websocket.onerror = function(ev) {
- out('<span style="color: red; ">ERROR: </span> ' + ev.data);
- };
- };
-</script>
-<style> div {font: small Verdana; } </style>
-<h2>Mongoose WebSocket Test</h2>
-
-<div id="output"></div>
-</html>
diff --git a/3rdparty/mongoose/examples/websocket_echo_server/websocket_echo_server.c b/3rdparty/mongoose/examples/websocket_echo_server/websocket_echo_server.c
deleted file mode 100644
index 9001a8a4c23..00000000000
--- a/3rdparty/mongoose/examples/websocket_echo_server/websocket_echo_server.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2013-2014 Cesanta Software Limited
-// $Date: 2014-09-09 17:07:55 UTC $
-
-#include <string.h>
-#include <time.h>
-#include "mongoose.h"
-
-static void push_message(struct mg_server *server, time_t current_time) {
- struct mg_connection *c;
- char buf[20];
- int len = sprintf(buf, "%lu", (unsigned long) current_time);
-
- // Iterate over all connections, and push current time message to websocket ones.
- for (c = mg_next(server, NULL); c != NULL; c = mg_next(server, c)) {
- if (c->is_websocket) {
- mg_websocket_write(c, 1, buf, len);
- }
- }
-}
-
-static int send_reply(struct mg_connection *conn) {
- if (conn->is_websocket) {
- // This handler is called for each incoming websocket frame, one or more
- // times for connection lifetime.
- // Echo websocket data back to the client.
- mg_websocket_write(conn, 1, conn->content, conn->content_len);
- return conn->content_len == 4 && !memcmp(conn->content, "exit", 4) ?
- MG_FALSE : MG_TRUE;
- } else {
- mg_send_file(conn, "index.html", NULL);
- return MG_MORE;
- }
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH: return MG_TRUE;
- case MG_REQUEST: return send_reply(conn);
- default: return MG_FALSE;
- }
-}
-
-int main(void) {
- struct mg_server *server = mg_create_server(NULL, ev_handler);
- time_t current_timer = 0, last_timer = time(NULL);
-
- mg_set_option(server, "listening_port", "8080");
-
- printf("Started on port %s\n", mg_get_option(server, "listening_port"));
- for (;;) {
- mg_poll_server(server, 100);
- current_timer = time(NULL);
- if (current_timer - last_timer > 0) {
- last_timer = current_timer;
- push_message(server, current_timer);
- }
- }
-
- mg_destroy_server(&server);
- return 0;
-}
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile b/3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile
deleted file mode 100644
index 968f1aca066..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = ws_ssl
-CFLAGS = -W -Wall -I../.. -I. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS -DNS_ENABLE_SSL -DSSL_WRAPPER_USE_AS_LIBRARY $(CFLAGS_EXTRA)
-LDFLAGS = -lssl
-SOURCES = ws_ssl.c ../../mongoose.c ssl_wrapper.c
-
-# PolarSSL paths and flags
-POLARSSL_PATH = /usr/local
-POLARSSLCOMPAT_PATH = ./../../../polar
-SOURCES_POLAR = $(SOURCES) $(POLARSSLCOMPAT_PATH)/polarssl_compat.c
-INCDIR_POLAR = -I$(POLARSSLCOMPAT_PATH) -I$(POLARSSL_PATH)/include
-LDFLAGS_POLAR = -L$(POLARSSL_PATH)/lib -lmbedtls
-CFLAGS_POLAR = $(CFLAGS) $(INCDIR_POLAR)
-#
-
-all: $(PROG)
-
-$(PROG): $(SOURCES)
- $(CC) -o $(PROG) $(SOURCES) $(LDFLAGS) $(CFLAGS)
-
-polarssl: $(SOURCES_POLAR)
- $(CC) -o $(PROG) $(SOURCES_POLAR) $(LDFLAGS_POLAR) $(CFLAGS_POLAR)
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem
deleted file mode 100644
index ebc7d8fd5eb..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem
+++ /dev/null
@@ -1,49 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAwizPnrCx+/kPSdEeSJFLDXrBH+cSQsSLrCm99G1hCjzqSlIk
-1BhkZMEHxBaiVLky4+M/nwhjwwRHI10h6U2Or3tbPLv7z94cPf+uCx1aF7TE3Fm3
-6YnDk+CjrYVFN5GRPGOPPdFxGoc+vFvQJyAAimvchnS1ZoEQFvermwzOnKspA6gc
-Px+7wnOeju9TyJuDr5ngtDXFnkcpkBNPxz3En4MJY4xJiaueafh9pIES2vSl7uP0
-J/qot9v2rdiL7nt1H1vwseeEkZhQ+NLB5e2z4psyktJcwDX7wQ6j7JnKfHeP+ixO
-TUORgV4foBMVOqo//Guo92Q5HoLNK77V0y4+ZQIDAQABAoIBAGEsx+LlDs3JQQty
-KjOq8uKWElyC6bKcZkIMydGvg6b6AU6ceW3jnyqFJ/vMUAUSghNmQQq3yiVo2Kks
-DLKTa9sKYwisE0NeJsgoUtOhJttCTlrwU4f+t/AjtgY68f7zTLnqIV+Ql4ftM0pU
-sIFEFMExZbWsZrQb1w+Hd0wrRqNEbSOfSjHeigvuw1T3GH2tSBUTGTpcoewCzy7U
-PKS5pkYyiKySQQNqZTac3NHPjxdK6xxzwURZp1irKdiPdt04KHLVLX8KXelt/J0k
-AeYkVbpFIeQ9rNBerMEp6uRBt+nE5mvP+xx1XPqKRxuxbMyTnBXeOM2zS/a/dBiz
-fwokwcECgYEA9RSsv9AQ/AR8tt+aPEQvjhJ5pn/YbCb1DA9IDXpaq3tzacGd8JHj
-3kUtb79nosu85LvSkAYmtzgfJs6xZyUkscra6q+xlsJ12QRxLzqfxcp9Y0wsdqM4
-AcOwuiPKrjkWxOQpyWPWRwbmAefLfRMekHt4Y/QY0CwhslpnsOsj3O0CgYEAytOE
-8I4GBfSQfSjXwfrso++Oi75VSsl5ZeiMGihfEhYFTE8/3rEZf7nf9iFSkN3TT+7f
-pFqQzddzPBZXlpVM6k1jcEjdpJizbeR8DmICpABFrZvKz1o8pQ2Yw+FYI86ih0x4
-806snMNgg/RgcVijXKFrC5joJOI+DVgwWoQyMFkCgYBxt4MkiV2oIkjf7ca6GgVa
-zbXGjOGV5Umkq96J6nDxyplVw/IN8xOhScX4aP6kahaep4vfKguCzjaeIh/stS5e
-lLqZVKZ5Roe6B7ag7HnAI+GkVm73KWrOXse8xui/iFvJRfkhqgJ9+HR3A9/GjD2N
-Ws0Uy+lLhn6oLAya6bA9TQKBgAVfZP4aRP6TY+Bs3Io+41XUWqpI+GlqvNR+PHfU
-6e/ItYs37jEv78T6X3xdlZpQxfAwG6x22a8aLetBjEBo5Aiw1Bl9VKGvidE3ZDHd
-VsSRXUckAVNMyJ52pb1KktMf/h4nYGzRgLEGW+Ai8QsPlgQ2ImfEPSH8/DfORjmf
-ltTBAoGBAMxIZ52DrJvuxogSOfA1MoCD6a90trkXCquvi+A/fXojZ8BHmMQshvhK
-rAO7SDIV1i1Nh3jQ/oFWE8KOprqrOLO6jNTyF65vh+zk7ztGsEME9FkDhHasUiXf
-t5PE9KeTChHRvIa4FGCl9We9GftE5Ii77LWMOIq22pyxYbvHQFEf
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIJAIOoO+AapJ5WMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNV
-BAMTA3dzMTEMMAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVi
-bGluMB4XDTE0MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMD
-d3MxMQwwCgYDVQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZEdWJsaW4w
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCLM+esLH7+Q9J0R5IkUsN
-esEf5xJCxIusKb30bWEKPOpKUiTUGGRkwQfEFqJUuTLj4z+fCGPDBEcjXSHpTY6v
-e1s8u/vP3hw9/64LHVoXtMTcWbfpicOT4KOthUU3kZE8Y4890XEahz68W9AnIACK
-a9yGdLVmgRAW96ubDM6cqykDqBw/H7vCc56O71PIm4OvmeC0NcWeRymQE0/HPcSf
-gwljjEmJq55p+H2kgRLa9KXu4/Qn+qi32/at2Ivue3UfW/Cx54SRmFD40sHl7bPi
-mzKS0lzANfvBDqPsmcp8d4/6LE5NQ5GBXh+gExU6qj/8a6j3ZDkegs0rvtXTLj5l
-AgMBAAGjgZwwgZkwHQYDVR0OBBYEFL54xAgtJTW6US4Mbr4QG0yKzvaxMGoGA1Ud
-IwRjMGGAFL54xAgtJTW6US4Mbr4QG0yKzvaxoT6kPDA6MQwwCgYDVQQDEwN3czEx
-DDAKBgNVBAoTA3dzMTELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpboIJAIOo
-O+AapJ5WMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJz/RzMa9Wa2
-eEXed7ijH1gcWtgVsVT1xZo0ksFl+QJ5Be1AJpOIe8nKdzYjxPWUkofIoaGHdMLL
-Uc/udRzsXncup+0mD+Yos6Cqyo9yHq7L1HbXfKYZtBXIjWHdF2+RP8j9tHfITXYI
-Pb2zsQ+A6PYpp5OLGZTDAnI2qffqsmwXFNhPfFhOANrGlOjsvy1P7JDzvymj/90m
-NomlO3vjxLHOf6MvedTgCB0dRcAoUWPgbxPWifjBmGBjQjA4ukMQ58wbBQgvIoCW
-obrXmLCNZIkpWTw4gMRYquY880IYK/OuFNJH/dawxx/WzuVr7IdLmbFY15zf5TUb
-ZpIpwqRCysg=
------END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem
deleted file mode 100644
index 82e99504cb8..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem
+++ /dev/null
@@ -1,45 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEAwOp1RS9RnE8L5TszDPIOmpf/1pqb+ki99l/sGhqB/KZBKCuq
-uoCc2VPK3PCByBE15/xJ7t691FnJfForI9DO5p2R0FPD6o357hqRsh0dJNBm0VgG
-iNtLQ8lyYoE72HJbkgCAUZW4N0OBibOmvp/s3Fmr7rEjW5LmZxOtX+iULKIUZ0w6
-gJlM8G5QA1SuqndN0PbPx+RZKSXZCoJj+Nboqw03nyJUexzs+lynR9ITMziUaaVM
-4rzG+P6joQAnUkDNydxo/d4tj4xaioZdKxWLYEbj2BUtOlJJydotWo2wcG85ONrT
-Gw0ltR1vku1hidMm2QL30uGIL5SeqyE8TqWk4QIDAQABAoIBAQCxHtKauc45MA4g
-4hCGAzvLTmETnRI2YlEfAoTYlpvf5pkOE8GFyI25r4gjACJ4GO0gWG9dBF7Pt7wZ
-EwRmttEvxV3aIv5OvRnKNdSs7rQSV9D+xc4CGy1oSG1f6X2TxbMzQoiN32OqQa2O
-S0Z94IFs8lu8JCDtc9tcqiFVXEmnC3RvJZOShWpsCsbmh5ue1Xed0MQQ47vt7Zt7
-I0cutvwSFJMsZkZUJp5+KjVNYo9TEJxVD3m2NJNJxBfBoRVHXNii3hUEHcTIdIAz
-omtRwBU8AKgJirGIRo1h2ZFyubI8ScGOJWIiWMQvQqTHKiOaz3yUar1NSG+kFn0U
-cj7s3FhdAoGBAOQbx8Jwhtp4iOkP6aW1nVTgiaTj4LMlyJZioFwgPFRIcA3oRHt9
-5SRetmgFZNvcuNw1udfeaObKmlzxwUruprwOpihgAQWJFTtOjQNrt2gsYuX4l3W6
-T46dO2W1pV+mW4A5gt0aqhLv7pCS4lpreNAqyHSPqcQWcCeiTzmp/LfDAoGBANiB
-FQOTyMElR9OzKwmcGfIvnhUfJQwi5qNE3R+xXiP5x36a9HQBey5ri2lnBle0Ksr/
-G+RKoflmk1eFXVHN0w35yw0dVco//WE4vOknldNEnIT85k02ld8lDTa2Q/EJZtPH
-un6zeU0Q2/4SZ/GXPssEZPlpPM7WtQzztlH3+sqLAoGBAKnhppvAgi4ippQsLa4j
-29BiiSAsNiQ1d3XIbfUubL+4UvuIh7gQwp6biu1dVwgHEgWuXYHPOgDn0p51zaao
-pbRYlJZtKVWeChnpHkv15NnIdL8grGwZHTbxElNlPIxHsM2GB1fzi8YeumUhf0In
-2AnwUum8NIq8yzo5PxeK6ZNRAoGBAIEA2Q6ankJH/nZsCbbeJq+iI+Wd+ysyGI8s
-Vz2tJ9Tz3iTYG9SLlWRhfF4/nw3fMqhmPa5Xsg+zSRQbSTGXHKz1LEISOq4aVtX5
-QscCaUnLVh//uRJE9iRSJX92NyGGYpjKJ5ubQSnkY9EOEpVnc2jwo2HhjPQKBzNC
-fF53Dh5lAoGALwTN5uxrBZLPu4DtZkOosKkv4l+kzFoOjLJR4vA7ONBx2CSe9G7F
-tSsH7lZS3b0mxBWjO90WhaSvtMWWrfqq8vrqmoTE795fYxNoLfCLK13W31aTDUsI
-pQRJIL30MPvASbcFHN2MD2dXz2nQzY8C9lvtvap/krYiDKDU2L7+iP8=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIC7DCCAdQCBRQHBXNHMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMTEM
-MAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
-MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMDd3MxMQwwCgYD
-VQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA6nVFL1GcTwvlOzMM8g6al//Wmpv6SL32
-X+waGoH8pkEoK6q6gJzZU8rc8IHIETXn/Enu3r3UWcl8Wisj0M7mnZHQU8Pqjfnu
-GpGyHR0k0GbRWAaI20tDyXJigTvYcluSAIBRlbg3Q4GJs6a+n+zcWavusSNbkuZn
-E61f6JQsohRnTDqAmUzwblADVK6qd03Q9s/H5FkpJdkKgmP41uirDTefIlR7HOz6
-XKdH0hMzOJRppUzivMb4/qOhACdSQM3J3Gj93i2PjFqKhl0rFYtgRuPYFS06UknJ
-2i1ajbBwbzk42tMbDSW1HW+S7WGJ0ybZAvfS4YgvlJ6rITxOpaThAgMBAAEwDQYJ
-KoZIhvcNAQEFBQADggEBABPLmq6zKOMY0WRjtBoSymq6f+vXeEwtWCfVejdG6RlG
-/PTdCKNvp3OL7FDnmQQ+r5rMs4+Os4fX/g315QFKXu01rqxmFb2XVNhhaECdUWtK
-QP6ZoVZviUiDjhK6a+05aerPCJpkGy/lz0W6gmj4qhuAQbobxb6UbzqTRYY+ZwGk
-+SI3TAVCdmXFlxN/M9b0DbmkseRG8GGFmyRYyRb84vbV6zemFI++5ROUT9zXT7ey
-nYfFJvAAk5jJhY5UP2aMlVWYYa4jUZrrPLoiBLUuRrp67EKGebCH9mgCIf8ztNJF
-fpuvcz++LUeRyTlAGDefe+FyHGIwFzIfZn39D7CaRvM=
------END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem
deleted file mode 100644
index 93ef657ec6f..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem
+++ /dev/null
@@ -1,45 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAyal0BZKRYd+Wpxv4MB8LjjgXv/MxSN5oSAKThlCZ/AWG0FEP
-d4nrBACT2xUxwo+xbYl3joiwL/eCPAp6QNKRGhvXVOnSIFVSjKZWbdX+toqK9pDS
-QMDTL4ZJvK6pLZXknyHjEr0PxZh22F7iS1+C8HxBPj0Xgg/u5/+jPhFPPZ1d5elv
-4cm/z+xy6RjFlA80aIeK7dcWssOsOIPjUNFfmoYgR63ScZIlUZj6j8VX9oX7fJID
-jumGajDxgD2nBWFbHcGKin6bz/wZ+OIhXOCDdY7oKuMW4JiBwbfBtedkQuQYS11s
-PRFFYDLoZH59Ivcu0c4F2tomE86qM8THsI910wIDAQABAoIBAG55FAQRfO8/C0rU
-eavy9eOdOvV+hltC66G3N5X3BcQYSvhHz89OkJ6KqnT0MWRCT5KQIhzFKK++SWwW
-2U41jCPfaKEtzlzEIQrH/MUC3Byn3OSiBWxPteFtEWv5ytgcKzg52iljxQYcNc7m
-e9WKpzKS/zLXSM+JZvlVA9p2pRA88kUZ/EE5H+FW3kHj5eGNqX+cxUVpL0VKTiLv
-aXWjYotpmDJW/Rn9wRQethm6Gdx3bvo+LEVlJRELNq8NM5H/tZIVRzudJOgzsw5v
-3OQGhfKB6Eg/vqSFoZxX6ApXDxmtaSO83B0kK550bDVv4sBnOExGjKCzybt04tet
-KtLPPoECgYEA5WUD+mFL99sCX6pzIyUVlxp9eUhVy5nvhoF6u3mvhay2XsZUY0wy
-+/qVqYSZTvuvJ6JSXc4iVIX8u/gj7914805AwujepIF/8E0AaXLBMndzDE4ze5S5
-2RHI7Cy4/3AWOcQ9wFFmUdSs7/6oAkcQtvzP40hGg3J2jAEhIdCqmbMCgYEA4Q0G
-BYP9XeTdh0C+BcP9B5VUEC0jerYS8VqVqriB+9JfT3InI7K08sOG2DiQQBhAHuzL
-RhCECU2a9j0+u5F5JNeY5m3IhU73Lw+lOlUkMaAO6x7JJEzhXhonE7Kv8fWygr/0
-OB7yzqz+YsWdQ2VOPZ88ntlAYE65vzcaVswZY2ECgYEAr7Gt2VA6Ei0A5Wq0Yr+d
-iKz2WzUG2TkelqOG8B4kTDrbNz2qFp+fERV9GWgAz9i+75lIgqZF7vzsdL96LtYv
-NBLEUURwegjhh5hCb4E/7bpFOLCQh9+CdHpFrHYYfzRHIZlnPmxZ9OTyS6J85bmu
-WKjLRKXvs++wUkzvJmoesDcCgYEAkTOB6xUZ5/a+J4HSGI43NylVr4owFgBbgHVd
-k2SwGPXGoM+aCSJINUmKOv9jsrbyyAEntfD5/7aegLlLPGHDs82WzTWP5tLoEOkb
-ReOhEpOejHy0ckNYNQrSo5bqhkZsAogu3fa52jcrejbeHJnEPWX8CtFJA9pHZeP7
-jnzo9IECgYBefHg0dymSj2xxN0XmC+S5cvQu2K/NYUpatoWvHnPiQ87wIM0AWz0O
-D0ghEI+Ze57NbtSrrcTE7hY/LHrAqXGAB9XNIM5g9Pp/lM+XjzKVr1FMf4xpuHf1
-VJJRHrOU14CvMvKbgbPrL6B0d5yrYmeex7GxNw0ZVvtjCa502Eck+w==
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIC7DCCAdQCBRQHBXNGMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMTEM
-MAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
-MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMDd3MxMQwwCgYD
-VQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJqXQFkpFh35anG/gwHwuOOBe/8zFI3mhI
-ApOGUJn8BYbQUQ93iesEAJPbFTHCj7FtiXeOiLAv94I8CnpA0pEaG9dU6dIgVVKM
-plZt1f62ior2kNJAwNMvhkm8rqktleSfIeMSvQ/FmHbYXuJLX4LwfEE+PReCD+7n
-/6M+EU89nV3l6W/hyb/P7HLpGMWUDzRoh4rt1xayw6w4g+NQ0V+ahiBHrdJxkiVR
-mPqPxVf2hft8kgOO6YZqMPGAPacFYVsdwYqKfpvP/Bn44iFc4IN1jugq4xbgmIHB
-t8G152RC5BhLXWw9EUVgMuhkfn0i9y7RzgXa2iYTzqozxMewj3XTAgMBAAEwDQYJ
-KoZIhvcNAQEFBQADggEBAE20gAykuuaCoP49GnZ/Z6ZItFry4Fl6iCWBDdEsWI9R
-wRNYumeaeejdFPXfSJdTT7UlrVK1WWGLQLq+ixHRDX+V9T67ou85F92H/OxbUoPr
-iz/TZAEBTC1GvTJl49lsfPl1dTWH8T4Ej2hxCUvIJrkCkI2Ov4Wwef6A26USrwBt
-S/CPInjCe6qkE5E8xfTDl8k5IIgMadTPhi5sbV2piBJoN4floJPqR0hdDKbgUymn
-5WNSiRkuI6UIDZwQEp+A8TmFBHbSwfTGt2Sz5iI27P8J6pFvR5eRA1k57dRUWNXC
-WAU1nqteP3QAjj9L3o8IO0T62scaiJX8x01gTmVVe2I=
------END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem
deleted file mode 100644
index 9345a94a60a..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem
+++ /dev/null
@@ -1,49 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAwXIMpHuTNsro2pxe6y1mu27md2Olhvfx26rO3maO0/stIC2z
-G/xQatFDLIWzfKFYOT0iSEj252ENFDCw6aDRKpiaUFtXcMAWkNkkKntEyoEgE45k
-rTrvpay0v0B+ojwjA1Jz/9v35cgvDwTs3vNFno5HhI0m2YF4ocTmeHJ6u0xRL/qy
-atfKsfuVq5s5CXOYCXp3Ux6kJ1c22J0EdZMvS75SVjAZgRkqQpqt9L3e2ZBCEgUr
-w0KwlERvpeJF+sJJOshXjfrDzvwL8IpPnGZLJNINFbSJMk5MFGcMyq/28pSZLB9E
-Dh8vk5D5gUnxM60ONUy2nYPcYr5p1PLDiC8hfQIDAQABAoIBAB0Twpi6xn8W8vdh
-R9c75NRJsDTD8q6d+GnXe+7sJY3xlG/gzqpnO8NCn0FC+57BNdystsl8xjgzW17s
-jrsfZDFt7MwlXrhg90NgkFIeY1G5JRQrdDChykHx+t1AmYhTV8P5EdykuNd+RqyQ
-RfahRJa3tkJTYUKSdoqCaU4zjwU2CSxltuJx24V+WoZE12EwewJ8HPg2XTnbsGE7
-Fnx5s29O4ItM70CC0536AY/OgfuPix5z573VQiilqqfOQkVkKa1fHd6tGpWU+3kH
-X9FnhEBf9cN9tVgmaB0sCSVVrfgqSXg1EwKHqe/+FCumuesA68Q35+/K3b+QrNiR
-ka2yliECgYEA+V/4pbgG/lPYvTwWhKxGXXdJmrSPgZC0mwE+fRuYkeptbIkS0pwt
-/UDTXk9nttj1f1ZJ3NgQbT/1w8jpXfsCJ8VeGzL9+ADhRKWVFRlu/nyFCMXawLEV
-rot7SEr8BW/m8moHgY5lYipM3dXJPk0F+KLrN60U/aNmFUtPGW802BkCgYEAxpWy
-FGL2sEQ0QaRDTcqqF5faVqw+5rVGvN+EX5o26E0QWWnoo3L2c2/5X93iBl+Fqtnm
-9jSIQUC3rYOawKnZ/HcIE2ergFit/p6JaV9NiLDRtDUmSzlffEGVCj0neYFsnWp5
-zcmkUyZ6fr19EmKQWfdteNBlXue32TjVlFbfUQUCgYAfMbgi0sBdNBPaqBeRBRPQ
-QUm9xnRlGrrc4Oz2LWuKZS7G8uad3deK5H8MPxaUMtOS2DJpI8X6RJPzp8A5d1qv
-quq4sEpAqauEMMpTV1khEGZ70HQqwnwZ12zWgDrCW1siW80QkcVw4CW5YjLITk4+
-6fJOhqInkDcG1uLQJa8QkQKBgQCfs8l4DbJ4RRGFbLXXvNGXkb68j18yqLxPrq3F
-OL9JiJhKYBsAP7clVPrG9ykLmQxlP0I35D1jxMkymLD+mlo9Z/itqmTJHggnyZWW
-kVdIQ3MSKuA2BNjek9tpVY8Gb2hLHFMChVRKrpo6jOclvvB5+bsnOukbLtyyq7tP
-xaFohQKBgByCmlltjOBWZLFLeA1x8j3inm9zM/FAJuANbHUOZ1RwrRcNFbDv/FXm
-rLPnPCaH5AwAWhVRJcNHo37Ee0s/xqe+Q4dG4xL943k+6KlopAw1SXhuXF6PnBfF
-y+ArVlh9d2oWN5cBEzRddnWnKJuMi70kMzYf6dIW9s/dHbq/gFDy
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIJAJDtcXU2wiJIMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNV
-BAMTA3dzMjEMMAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVi
-bGluMB4XDTE0MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMD
-d3MyMQwwCgYDVQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZEdWJsaW4w
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBcgyke5M2yujanF7rLWa7
-buZ3Y6WG9/Hbqs7eZo7T+y0gLbMb/FBq0UMshbN8oVg5PSJISPbnYQ0UMLDpoNEq
-mJpQW1dwwBaQ2SQqe0TKgSATjmStOu+lrLS/QH6iPCMDUnP/2/flyC8PBOze80We
-jkeEjSbZgXihxOZ4cnq7TFEv+rJq18qx+5WrmzkJc5gJendTHqQnVzbYnQR1ky9L
-vlJWMBmBGSpCmq30vd7ZkEISBSvDQrCURG+l4kX6wkk6yFeN+sPO/Avwik+cZksk
-0g0VtIkyTkwUZwzKr/bylJksH0QOHy+TkPmBSfEzrQ41TLadg9xivmnU8sOILyF9
-AgMBAAGjgZwwgZkwHQYDVR0OBBYEFLK4flD5QD/mRufsPx63xlEKM8pwMGoGA1Ud
-IwRjMGGAFLK4flD5QD/mRufsPx63xlEKM8pwoT6kPDA6MQwwCgYDVQQDEwN3czIx
-DDAKBgNVBAoTA3dzMjELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpboIJAJDt
-cXU2wiJIMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEYD+CReikYr
-Rzvk+/Vdi/7IcaH9CFknIdtineSIw1y98nxnbnNJqxwfNaRblbYvg6OFdUI3POuI
-+rdYLCFl8z3tWqRHLkGqHSJA9xcng3jLJxz0+ctiVcekJvXaB3O6eSZjhGbmmI/s
-CQhdy2zpEIVOeUq50DrSJp9CknyGu/IkaGx5GOZtkiHMrpig50CRjX1lS6qrMNYp
-vB8gfuqpjsL4Ar3vg+lgMSwNWXBNHrIRPHB5VEzBEdmLFZlvueR0ooEMCklpwX/a
-lFImVc6JcY1pBEkHTiTLGMpGAHG3I1aVUaWb3L+V+2ym/KNRNL5C2+1eiqql5u8m
-HUaOcNC90ew=
------END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem
deleted file mode 100644
index 8021de3c8a3..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem
+++ /dev/null
@@ -1,45 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA0ucemqFwBFziVOgTgx4mZII4WnGDpA/rWAGHvUZOqy2dQ3Pz
-woGKxBaVPAl5kxEosROVGa7dTuq5yFZ4XIGvwCKxF30vCmdGCytqq6MMp904jG32
-KikkmjCApIMGxMO4eoBHZZxiyVvKTbg9M2CRXErwnYWhFH/qGdPnuo0CEaHJA4VK
-A9incT9dpeEhU30R6ajAe/je9rCj2OMLMFSMfd51L/VYfO60zDwUNY7YVIghQZgJ
-e44EVGsp1pXaqaD6o3PvGY3ohw2aZjJzlJ7MJHbKV9lft98R3pklbpBzMH849cEy
-Q/51L/rlfTUgCpTy7wEZpWHQNtHfu/1rhJjpNQIDAQABAoIBAQCUNIHXG/dBuZv7
-GpMLotZL7w520Co30lAJqhmfMpb5x7YpvoPffXTsUwpQBECAzqAPv7kZMT6nxF8F
-n245Y5EDrd1QqlGyN9yK4Nm2/39XPygL1wITopHsIIVmFgVdpEQxIZAKoZjx8yT4
-9K1dO1Eq0CbCKzOE2lbCC51eBNUdWZIMxwC6O/j/KoIkZ/HwlG2hpUuXg8x/XawA
-ZJDCoTcWHCjYP10FxKVN3vAyWM2IM44o9IbsAGEOswR4gUwRsgq6Ehc1U59XUHi+
-x30oda55I1/8xD+SfP/zk2dDPHkv/hq5+258GU/THsw2+AAexocvSIS/g9EppTEg
-biFaDKzJAoGBAPqey10JeyiOlHbBjoSSa7lJYUjocQANFQ4ayOAgfNX72iyabrKF
-p9sVAeO/nM00+DPrm2wWws03ScsPeh+9BDJMPRBUHfSNp7+F+oyj7PWHBEFHbyO9
-5HnYZP+1vhdG2dYPIY2gRSFXpiGn3j0M1D0w9c7Ilm8ee3krdR4E/mw3AoGBANdu
-EfS1dK3+m7sEgc2+3U32z83GpuCHeUIKGPYMLI0fIb1CPpboHU9YjOFJZH9iIIdl
-00JC963O3+pqLe0XbMOmBVt9QjZfhfB+AY+JHtbPgoQVLtq9X/WvW7h3xn6S971r
-Crkhqay3Cs4BzsgYDYraQCTw3oq4twR9Nuy4etfzAoGAXOsG5wWe3diO/sCggFJx
-Eg88vHVBgA1ZoxMXKtGgtw1bRHI1XIblRvqw6qmeDw72fvl5dEe0DbXT7C9ezemc
-ZrGRaj5lpMfoS7/2trIIJrfaQgGkGRJMZUhvmcbeJW8lUJHnlMS5HLWMaKn+YZAi
-GFXQrMv9ylD44mHUWD7tvV0CgYBNctPfvvCQsQ05ofgsiKa1Jbs1hmpuJCYy2MB6
-jIvjvEJ78PnhdNc8tGAJikIoDZYWN0RI+RxkDxCvDLcwGpDOkbwxVQnd1F+pwxM6
-kBhXL8kDRT5QA28hO4bk/aKN1LZeEcKMJg8C+ddXkozNoOAVgDs5TKMlCh057u41
-EmmPgwKBgQDOlYi7fPYOCy0yjHMxSrp2SZOS06AMWGbbCoGkjRtvuP+FmKSNB+LZ
-pOSEPJgzjsRutKjneww4LpV6dViAyTcP5JoeQpokHf7UVo7yq2QH/iwF3zJwsC/S
-OuVLkqpZzWuye/QCH5NOTfw27ye8jG8VcQW2QPbcbkLXLM7zg2yX7g==
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIC7DCCAdQCBRQHBXNJMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMjEM
-MAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
-MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMDd3MyMQwwCgYD
-VQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDS5x6aoXAEXOJU6BODHiZkgjhacYOkD+tY
-AYe9Rk6rLZ1Dc/PCgYrEFpU8CXmTESixE5UZrt1O6rnIVnhcga/AIrEXfS8KZ0YL
-K2qrowyn3TiMbfYqKSSaMICkgwbEw7h6gEdlnGLJW8pNuD0zYJFcSvCdhaEUf+oZ
-0+e6jQIRockDhUoD2KdxP12l4SFTfRHpqMB7+N72sKPY4wswVIx93nUv9Vh87rTM
-PBQ1jthUiCFBmAl7jgRUaynWldqpoPqjc+8ZjeiHDZpmMnOUnswkdspX2V+33xHe
-mSVukHMwfzj1wTJD/nUv+uV9NSAKlPLvARmlYdA20d+7/WuEmOk1AgMBAAEwDQYJ
-KoZIhvcNAQEFBQADggEBACCCAJypO9DFU6GeOH+FwE0JCLTypHoIwERWxNL7xfjg
-rwVqIxwAEo+fJjL+QY7JbAb/eqKaXIBYkAF2lFc4iEmecXX/A3Aqw95AYi78o7HD
-MwRPqJha9mxLcCWwjX8XK8pT152BvYFPNhi+6jd++rDRxKDfmNvgdUQ2/YW6a5Wv
-zEmLDPUWRIuMQIEmOa2/JhlllDviMExTw51nbqYgCghycRvDACyQAuu8re7P6gcg
-bXObNlfxcU/8Ph6MFI+2S9ODtQ4BHyuKd4kRNsYn8vV42a0h3bCYSGPk3kSIgxd7
-XijwHT/o8E9ddH2BvDv+6Nhno9C6/MbezEOIs4nlhRk=
------END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem
deleted file mode 100644
index b6b48ef23f4..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem
+++ /dev/null
@@ -1,45 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEA29iFnMf4pjty6knOt4wT0joPUlU2dGCFWxQ5Eg77Yx3Lou2a
-FOzNGp7zLYH8gauOK+mgY+B9cBv8PvVtUQQKB0SKTTV8ZNKVyP3O5F2gRSJ+tHtT
-FqaPfG0WPOn/f02YbOpAe6Rk+NnlJoeuBxG4uapUSq7r0mTGJQe+52y1LcMs23ID
-ENBfDoUMVt5vCnF+cYK5ndeFVLyPO3JjohDH1zv3a9ECG28rtjKHLpNYFDsPJaD7
-UPuyyk3hIvfPCZoJOUlEVfpLT/lM+9oCPnq9PwIp5NqYofkuc3eKooCo7N4r4IlP
-Ajktaao6b0ScNwNQB3leOIdEUFSIYy8N1JszVwIDAQABAoIBAFlIvjrGG/2m9yyf
-fQyeHw6p9b8CTHNHH+G1fNgQrZe7ahBpXsJQyZueIjTBLcOb4MmEwFbPvSHiu7b2
-Bcd5VHlPJLvmlPZ9b8eJDJVCUOzC7aJu03fHfU6THwzuG42f/d9942JTiY5nL+FO
-CSdl0xfUTRdnou53buFrG+TxCUPj13HP1HY6DAVzEIq1H4TZwIZo7KRRTIYpTB3P
-6yvr9xsISLlnmfQ4tp2pApl5o+bHJEhr1VO6SAT/pSyShi79KmMMqYtyTmOMz7w6
-VJkre5ybnXBDN6tfMHWqdobJ4gRWK9rqf+LIZig5XQnyzkue8k+I7aPgO4xNFh56
-dkejQcECgYEA9MDCWViqpfvof+epiKzccqnIRnz1EfHdRQjiKsKGRe39+K+pyaqJ
-FOOPFy3aOw6M4cFWwcdMYzKTItvzyLVhDqMzT5eup/NVqo5tPoy93XPf2qRYiTl4
-2j5wvm0RVkYEONd3pk2lbfbUmn7XQXj0+AG60SvsqErF/UhIBGec/xsCgYEA5fLC
-EdiiC98kr4sVaE8G854WI+aAkStqO5YXyrnsMzRsqk8KVVYE1yCC9rYyymDBYmlx
-uEW+vbWqLc8PO3v4ty3o5ff303lPMWIrvKiUldjqMjS6ncWxsQjU0bygGVgOgHO7
-c8rjiDH5M0JgWSREYUVFT5mW/5+Y1LVT8mYNlHUCgYEAhMSX6N23XGkFW3Twu2qB
-/1Vohgw86OoaDNvfzDBPpFmQ3rlz0ijHSeSTd5BxBH5FICXACUgygNErjcphOSxj
-JQyUxgVTQlo2y1mNm1O/nwS/lxx1xqK9ky4x/Kqvr+w1WBxSFI2kQr2V4OUTobma
-sXpGvDcmnrhJJLd0EaefO6cCgYEA3Xw/S9tC8nZjqqYn34nHI16Q6tF54tpTf8Np
-dT4x8Xw8cqqhRGMPVHsfSi1irKYXfwgbnienuqlBmtAHVv9pKF+TJfb7gXkmO2XY
-xOYIAHGn2uYJHjCun9vmyYKLHv4/MaDH3Jd/I88mviXgEdyp9Js5UJua4utB1Rg3
-HJMJ34UCgYEAr0PpHEBMbZXZBybNU96+jRTgkrNeJpzlnMy7et2IsRAtLjZ0mpbn
-NaX8i8eO+ubweqFdhOvbh7Hd0zr7BzrYcUG1e3njhtxJE1MgWL5plnLVUbIyDAm3
-iBpIHIBASNCN3sqeq+VqXvavRmeZh5O0vyLP46/kxZx0rzR/NCi9xxU=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIC7DCCAdQCBRQHBXNIMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMjEM
-MAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
-MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMDd3MyMQwwCgYD
-VQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb2IWcx/imO3LqSc63jBPSOg9SVTZ0YIVb
-FDkSDvtjHcui7ZoU7M0anvMtgfyBq44r6aBj4H1wG/w+9W1RBAoHRIpNNXxk0pXI
-/c7kXaBFIn60e1MWpo98bRY86f9/TZhs6kB7pGT42eUmh64HEbi5qlRKruvSZMYl
-B77nbLUtwyzbcgMQ0F8OhQxW3m8KcX5xgrmd14VUvI87cmOiEMfXO/dr0QIbbyu2
-Mocuk1gUOw8loPtQ+7LKTeEi988Jmgk5SURV+ktP+Uz72gI+er0/Aink2pih+S5z
-d4qigKjs3ivgiU8COS1pqjpvRJw3A1AHeV44h0RQVIhjLw3UmzNXAgMBAAEwDQYJ
-KoZIhvcNAQEFBQADggEBALi/RmqeXGazT/WRj9+ZqdcnbcHwK5wwr2/YkpFPJ0Hf
-ZDm+2vgjDdTT6cJS6fau0M5nliYdz89aQQo1j9RSRZnzlc/2YCFXyRLCOJYaINbj
-1MEUAvNDGL7xTpepK9hVkXASRkbyNXERXRKFI1N+vpKu6UorT6/osEV/qM+MFJ3s
-24xE8/J3J4MirVQVt6eY6Jb+tkliOPMIugr6YQlLsqJygEWATP8Qsr81XSfcZhVq
-rXzVt7QV8dO0nStMjKK5omrtEAhVnASk7w1tFHkpBF1rqXGoo9ML40RnFZ+E5zqi
-iZtzp+NzzLnEnWMNs+fJpPJ96P0kbq2bQzuSBcUynq0=
------END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h b/3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h
deleted file mode 100644
index 4d1c33fc820..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2014 Cesanta Software Limited
-// All rights reserved
-//
-// This software is dual-licensed: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation. For the terms of this
-// license, see <http://www.gnu.org/licenses/>.
-//
-// You are free to use this software under the terms of the GNU General
-// Public License, but WITHOUT ANY WARRANTY; without even the implied
-// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU General Public License for more details.
-//
-// Alternatively, you can license this software under a commercial
-// license, as set out in <http://cesanta.com/>.
-//
-// $Date: 2014-09-28 05:04:41 UTC $
-
-#ifndef NS_SKELETON_HEADER_INCLUDED
-#define NS_SKELETON_HEADER_INCLUDED
-
-#define NS_SKELETON_VERSION "2.1.0"
-
-#undef UNICODE // Use ANSI WinAPI functions
-#undef _UNICODE // Use multibyte encoding on Windows
-#define _MBCS // Use multibyte encoding on Windows
-#define _INTEGRAL_MAX_BITS 64 // Enable _stati64() on Windows
-#define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005+
-#undef WIN32_LEAN_AND_MEAN // Let windows.h always include winsock2.h
-#define _XOPEN_SOURCE 600 // For flockfile() on Linux
-#define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
-#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
-#ifndef _LARGEFILE_SOURCE
-#define _LARGEFILE_SOURCE // Enable fseeko() and ftello() functions
-#endif
-#define _FILE_OFFSET_BITS 64 // Enable 64-bit file offsets
-
-#ifdef _MSC_VER
-#pragma warning (disable : 4127) // FD_SET() emits warning, disable it
-#pragma warning (disable : 4204) // missing c99 support
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <signal.h>
-
-#ifdef _WIN32
-#ifdef _MSC_VER
-#pragma comment(lib, "ws2_32.lib") // Linking with winsock library
-#endif
-#include <windows.h>
-#include <process.h>
-#ifndef EINPROGRESS
-#define EINPROGRESS WSAEINPROGRESS
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif
-#ifndef __func__
-#define STRX(x) #x
-#define STR(x) STRX(x)
-#define __func__ __FILE__ ":" STR(__LINE__)
-#endif
-#ifndef va_copy
-#define va_copy(x,y) x = y
-#endif // MINGW #defines va_copy
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define sleep(x) Sleep((x) * 1000)
-#define to64(x) _atoi64(x)
-typedef int socklen_t;
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-typedef unsigned short uint16_t;
-typedef unsigned __int64 uint64_t;
-typedef __int64 int64_t;
-typedef SOCKET sock_t;
-typedef struct _stati64 ns_stat_t;
-#ifndef S_ISDIR
-#define S_ISDIR(x) ((x) & _S_IFDIR)
-#endif
-#else
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <arpa/inet.h> // For inet_pton() when NS_ENABLE_IPV6 is defined
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#define closesocket(x) close(x)
-#define __cdecl
-#define INVALID_SOCKET (-1)
-#define to64(x) strtoll(x, NULL, 10)
-typedef int sock_t;
-typedef struct stat ns_stat_t;
-#endif
-
-#ifdef NS_ENABLE_DEBUG
-#define DBG(x) do { printf("%-20s ", __func__); printf x; putchar('\n'); \
- fflush(stdout); } while(0)
-#else
-#define DBG(x)
-#endif
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-#endif
-
-#ifdef NS_ENABLE_SSL
-#ifdef __APPLE__
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-#include <openssl/ssl.h>
-#else
-typedef void *SSL;
-typedef void *SSL_CTX;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-union socket_address {
- struct sockaddr sa;
- struct sockaddr_in sin;
-#ifdef NS_ENABLE_IPV6
- struct sockaddr_in6 sin6;
-#else
- struct sockaddr sin6;
-#endif
-};
-
-// Describes chunk of memory
-struct ns_str {
- const char *p;
- size_t len;
-};
-
-// IO buffers interface
-struct iobuf {
- char *buf;
- size_t len;
- size_t size;
-};
-
-void iobuf_init(struct iobuf *, size_t initial_size);
-void iobuf_free(struct iobuf *);
-size_t iobuf_append(struct iobuf *, const void *data, size_t data_size);
-void iobuf_remove(struct iobuf *, size_t data_size);
-void iobuf_resize(struct iobuf *, size_t new_size);
-
-// Callback function (event handler) prototype, must be defined by user.
-// Net skeleton will call event handler, passing events defined above.
-struct ns_connection;
-typedef void (*ns_callback_t)(struct ns_connection *, int event_num, void *evp);
-
-// Events. Meaning of event parameter (evp) is given in the comment.
-#define NS_POLL 0 // Sent to each connection on each call to ns_mgr_poll()
-#define NS_ACCEPT 1 // New connection accept()-ed. union socket_address *addr
-#define NS_CONNECT 2 // connect() succeeded or failed. int *success_status
-#define NS_RECV 3 // Data has benn received. int *num_bytes
-#define NS_SEND 4 // Data has been written to a socket. int *num_bytes
-#define NS_CLOSE 5 // Connection is closed. NULL
-
-
-struct ns_mgr {
- struct ns_connection *active_connections;
- const char *hexdump_file; // Debug hexdump file path
- sock_t ctl[2]; // Socketpair for mg_wakeup()
- void *user_data; // User data
-};
-
-
-struct ns_connection {
- struct ns_connection *next, *prev; // ns_mgr::active_connections linkage
- struct ns_connection *listener; // Set only for accept()-ed connections
- struct ns_mgr *mgr;
-
- sock_t sock; // Socket
- union socket_address sa; // Peer address
- struct iobuf recv_iobuf; // Received data
- struct iobuf send_iobuf; // Data scheduled for sending
- SSL *ssl;
- SSL_CTX *ssl_ctx;
- void *user_data; // User-specific data
- void *proto_data; // Application protocol-specific data
- time_t last_io_time; // Timestamp of the last socket IO
- ns_callback_t callback; // Event handler function
-
- unsigned int flags;
-#define NSF_FINISHED_SENDING_DATA (1 << 0)
-#define NSF_BUFFER_BUT_DONT_SEND (1 << 1)
-#define NSF_SSL_HANDSHAKE_DONE (1 << 2)
-#define NSF_CONNECTING (1 << 3)
-#define NSF_CLOSE_IMMEDIATELY (1 << 4)
-#define NSF_WANT_READ (1 << 5)
-#define NSF_WANT_WRITE (1 << 6)
-#define NSF_LISTENING (1 << 7)
-#define NSF_UDP (1 << 8)
-
-#define NSF_USER_1 (1 << 20)
-#define NSF_USER_2 (1 << 21)
-#define NSF_USER_3 (1 << 22)
-#define NSF_USER_4 (1 << 23)
-#define NSF_USER_5 (1 << 24)
-#define NSF_USER_6 (1 << 25)
-};
-
-void ns_mgr_init(struct ns_mgr *, void *user_data);
-void ns_mgr_free(struct ns_mgr *);
-time_t ns_mgr_poll(struct ns_mgr *, int milli);
-void ns_broadcast(struct ns_mgr *, ns_callback_t, void *, size_t);
-
-struct ns_connection *ns_next(struct ns_mgr *, struct ns_connection *);
-struct ns_connection *ns_add_sock(struct ns_mgr *, sock_t,
- ns_callback_t, void *);
-struct ns_connection *ns_bind(struct ns_mgr *, const char *,
- ns_callback_t, void *);
-struct ns_connection *ns_connect(struct ns_mgr *, const char *,
- ns_callback_t, void *);
-
-int ns_send(struct ns_connection *, const void *buf, int len);
-int ns_printf(struct ns_connection *, const char *fmt, ...);
-int ns_vprintf(struct ns_connection *, const char *fmt, va_list ap);
-
-// Utility functions
-void *ns_start_thread(void *(*f)(void *), void *p);
-int ns_socketpair(sock_t [2]);
-int ns_socketpair2(sock_t [2], int sock_type); // SOCK_STREAM or SOCK_DGRAM
-void ns_set_close_on_exec(sock_t);
-void ns_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
-int ns_hexdump(const void *buf, int len, char *dst, int dst_len);
-int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
-int ns_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // NS_SKELETON_HEADER_INCLUDED
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c b/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c
deleted file mode 100644
index 969aa979345..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2014 Cesanta Software Limited
-// All rights reserved
-//
-// This software is dual-licensed: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation. For the terms of this
-// license, see <http://www.gnu.org/licenses/>.
-//
-// You are free to use this software under the terms of the GNU General
-// Public License, but WITHOUT ANY WARRANTY; without even the implied
-// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU General Public License for more details.
-//
-// Alternatively, you can license this software under a commercial
-// license, as set out in <http://cesanta.com/products.html>.
-//
-// $Date$
-
-#include "net_skeleton.h"
-#include "ssl_wrapper.h"
-
-static void ev_handler(struct ns_connection *nc, int ev, void *p) {
- const char *target_addr = (const char *) nc->mgr->user_data;
- struct ns_connection *pc = (struct ns_connection *) nc->user_data;
- struct iobuf *io = &nc->recv_iobuf;
-
- (void) p;
- switch (ev) {
- case NS_ACCEPT:
- // Create a connection to the target, and interlink both connections
- nc->user_data = ns_connect(nc->mgr, target_addr, ev_handler, nc);
- if (nc->user_data == NULL) {
- nc->flags |= NSF_CLOSE_IMMEDIATELY;
- }
- break;
-
- case NS_CLOSE:
- // If either connection closes, unlink them and shedule closing
- if (pc != NULL) {
- pc->flags |= NSF_FINISHED_SENDING_DATA;
- pc->user_data = NULL;
- }
- nc->user_data = NULL;
- break;
-
- case NS_RECV:
- // Forward arrived data to the other connection, and discard from buffer
- if (pc != NULL) {
- ns_send(pc, io->buf, io->len);
- iobuf_remove(io, io->len);
- }
- break;
-
- default:
- break;
- }
-}
-
-void *ssl_wrapper_init(const char *local_addr, const char *target_addr,
- const char **err_msg) {
- struct ns_mgr *mgr = (struct ns_mgr *) calloc(1, sizeof(mgr[0]));
- *err_msg = NULL;
-
- if (mgr == NULL) {
- *err_msg = "malloc failed";
- } else {
- ns_mgr_init(mgr, (void *) target_addr);
- if (ns_bind(mgr, local_addr, ev_handler, NULL) == NULL) {
- *err_msg = "ns_bind() failed: bad listening_port";
- ns_mgr_free(mgr);
- free(mgr);
- mgr = NULL;
- }
- }
-
- return mgr;
-}
-
-void ssl_wrapper_serve(void *param, volatile int *quit) {
- struct ns_mgr *mgr = (struct ns_mgr *) param;
-
- while (*quit == 0) {
- ns_mgr_poll(mgr, 1000);
- }
- ns_mgr_free(mgr);
- free(mgr);
-}
-
-#ifndef SSL_WRAPPER_USE_AS_LIBRARY
-static int s_received_signal = 0;
-
-static void signal_handler(int sig_num) {
- signal(sig_num, signal_handler);
- s_received_signal = sig_num;
-}
-
-static void show_usage_and_exit(const char *prog) {
- fprintf(stderr, "Usage: %s <listening_address> <target_address>\n", prog);
- exit(EXIT_FAILURE);
-}
-
-int main(int argc, char *argv[]) {
- void *wrapper;
- const char *err_msg;
-
- if (argc != 3) {
- show_usage_and_exit(argv[0]);
- }
-
- // Setup signal handlers
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
- signal(SIGPIPE, SIG_IGN);
-
- if ((wrapper = ssl_wrapper_init(argv[1], argv[2], &err_msg)) == NULL) {
- fprintf(stderr, "Error: %s\n", err_msg);
- exit(EXIT_FAILURE);
- }
- ssl_wrapper_serve(wrapper, &s_received_signal);
-
- return EXIT_SUCCESS;
-}
-#endif // SSL_WRAPPER_USE_AS_LIBRARY
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h b/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h
deleted file mode 100644
index ccdf780556c..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2014 Cesanta Software Limited
-// All rights reserved
-//
-// This software is dual-licensed: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation. For the terms of this
-// license, see <http://www.gnu.org/licenses/>.
-//
-// You are free to use this software under the terms of the GNU General
-// Public License, but WITHOUT ANY WARRANTY; without even the implied
-// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU General Public License for more details.
-//
-// Alternatively, you can license this software under a commercial
-// license, as set out in <http://cesanta.com/products.html>.
-//
-// $Date$
-
-#ifndef SSL_WRAPPER_HEADER_INCLUDED
-#define SSL_WRAPPER_HEADER_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-void *ssl_wrapper_init(const char *listen_addr, const char *target_addr,
- const char **err_msg);
-void ssl_wrapper_serve(void *, volatile int *stop_marker);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // SSL_WRAPPER_HEADER_INCLUDED
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c b/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c
deleted file mode 100644
index d2fceee650e..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2014 Cesanta Software
-// All rights reserved
-//
-// This example demostrates proxying of WebSocket traffic, regardless of the
-// protocol (ws:// or wss://).
-// To use this example:
-// 1. configure your browser to use a proxy on port 2014
-// 2. import certs/ws1_ca.pem and certs/ws2_ca.pem into the trusted
-// certificates list on your browser
-// 3. make && ./ws_ssl
-// 4. Point your browser to http://ws_ssl.com
-// A page with 4 sections should appear, showing websocket echoes
-
-#include "net_skeleton.h"
-#include "mongoose.h"
-#include "ssl_wrapper.h"
-
-#define S1_PEM "certs/ws1_server.pem"
-#define C1_PEM "certs/ws1_client.pem"
-#define CA1_PEM "certs/ws1_ca.pem"
-#define S2_PEM "certs/ws2_server.pem"
-#define C2_PEM "certs/ws2_client.pem"
-#define CA2_PEM "certs/ws2_ca.pem"
-
-struct config {
- const char *uri;
- const char *wrapper_server_addr;
- const char *wrapper_client_addr;
- const char *target_addr;
-};
-
-static struct config s_wrappers[] = {
- {
- "ws1:80",
- "tcp://127.0.0.1:7001",
- "tcp://127.0.0.1:7001",
- "tcp://127.0.0.1:9001"
- },
- {
- "ws1:443",
- "ssl://127.0.0.1:7002:" S1_PEM,
- "tcp://127.0.0.1:7002",
- "tcp://127.0.0.1:9001"
- },
- {
- "ws2:80",
- "tcp://127.0.0.1:7003",
- "tcp://127.0.0.1:7003",
- "ssl://127.0.0.1:9002:" C2_PEM ":" CA2_PEM
- },
- {
- "ws2:443",
- "ssl://127.0.0.1:7004:" S2_PEM,
- "tcp://127.0.0.1:7004",
- "ssl://127.0.0.1:9002:" C2_PEM ":" CA2_PEM
- },
-};
-
-static int s_received_signal = 0;
-
-static void signal_handler(int sig_num) {
- signal(sig_num, signal_handler);
- s_received_signal = sig_num;
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- int i;
-
- switch (ev) {
- case MG_AUTH:
- return MG_TRUE;
-
- case MG_REQUEST:
- printf("==> [%s] [%s]\n", conn->request_method, conn->uri);
-
- if (strcmp(conn->request_method, "CONNECT") == 0) {
- // Iterate over configured wrappers, see if we can use one of them
- for (i = 0; i < (int) ARRAY_SIZE(s_wrappers); i++) {
- if (strcmp(conn->uri, s_wrappers[i].uri) == 0) {
- mg_forward(conn, s_wrappers[i].wrapper_client_addr);
- return MG_MORE;
- }
- }
-
- // No suitable wrappers found. Disallow that CONNECT request.
- mg_send_status(conn, 405);
- return MG_TRUE;
- }
-
- // Not a CONNECT request, serve HTML file.
- mg_send_file(conn, "ws_ssl.html", NULL);
- return MG_MORE;
-
- default:
- return MG_FALSE;
- }
-}
-
-static int ws_handler(struct mg_connection *conn, enum mg_event ev) {
- switch (ev) {
- case MG_AUTH:
- return MG_TRUE;
- case MG_REQUEST:
- if (conn->is_websocket) {
- // Simple websocket echo server
- mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT,
- conn->content, conn->content_len);
- } else {
- mg_printf_data(conn, "%s", "websocket connection expected");
- }
- return MG_TRUE;
- default:
- return MG_FALSE;
- }
-}
-
-static void *serve_thread_func(void *param) {
- struct mg_server *server = (struct mg_server *) param;
- printf("Listening on port %s\n", mg_get_option(server, "listening_port"));
- while (s_received_signal == 0) {
- mg_poll_server(server, 1000);
- }
- mg_destroy_server(&server);
- return NULL;
-}
-
-static void *wrapper_thread_func(void *param) {
- struct config *c = (struct config *) param;
- const char *err_msg;
- void *wrapper;
-
- wrapper = ssl_wrapper_init(c->wrapper_server_addr, c->target_addr, &err_msg);
- if (wrapper == NULL) {
- fprintf(stderr, "Error: %s\n", err_msg);
- exit(EXIT_FAILURE);
- }
- //((struct ns_mgr *) wrapper)->hexdump_file = "/dev/stderr";
- ssl_wrapper_serve(wrapper, &s_received_signal);
-
- return NULL;
-}
-
-int main(void) {
- struct mg_server *proxy_server = mg_create_server(NULL, ev_handler);
- struct mg_server *ws1_server = mg_create_server(NULL, ws_handler);
- struct mg_server *ws2_server = mg_create_server(NULL, ws_handler);
- size_t i;
-
- ((struct ns_mgr *) proxy_server)->hexdump_file = "/dev/stderr";
-
- // Configure proxy server to listen on port 2014
- mg_set_option(proxy_server, "listening_port", "2014");
- //mg_set_option(proxy_server, "enable_proxy", "yes");
-
- // Configure two websocket echo servers:
- // ws1 is WS, listening on 9001
- // ws2 is WSS, listening on 9002
- // Note that HTML page thinks that ws1 is WSS, and ws2 is WS,
- // where in reality it is vice versa and proxy server makes the decision.
- mg_set_option(ws1_server, "listening_port", "tcp://127.0.0.1:9001");
- mg_set_option(ws2_server, "listening_port",
- "ssl://127.0.0.1:9002:" S2_PEM ":" CA2_PEM);
-
- // Setup signal handlers
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
-
- // Start SSL wrappers, each in it's own thread
- for (i = 0; i < ARRAY_SIZE(s_wrappers); i++) {
- ns_start_thread(wrapper_thread_func, &s_wrappers[i]);
- }
-
- // Start websocket servers in separate threads
- mg_start_thread(serve_thread_func, ws1_server);
- mg_start_thread(serve_thread_func, ws2_server);
-
- // Finally, start proxy server in this thread: this call blocks
- serve_thread_func(proxy_server);
-
- printf("Existing on signal %d\n", s_received_signal);
- return EXIT_SUCCESS;
-}
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html b/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html
deleted file mode 100644
index 23ab2506145..00000000000
--- a/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<html>
-<head>
- <title>Websocket Proxy SSL Test</title>
- <meta charset="utf-8">
- <script>
- window.onload = function() {
- var protocols = ['ws://', 'wss://'];
- var websocketServers = ['ws1', 'ws2'];
- //protocols = ['wss://'];
- //websocketServers = ['ws1']
-
- var createWebsocketConnection = function(proto, server) {
- var conn = new WebSocket(proto + server);
-
- var div = document.createElement('div');
- var h2 = document.createElement('h2');
- h2.innerHTML = 'Connection to ' + proto + server;
- document.body.appendChild(h2);
- document.body.appendChild(div);
-
- conn.onmessage = function(ev) {
- var el = document.createElement('div');
- el.innerHTML = 'websocket message: ' + ev.data;
- div.appendChild(el);
- // Keep only last 5 messages in the list
- while (div.childNodes.length > 5) div.removeChild(div.firstChild);
- };
-
- // Send some string to the websocket connection periodically.
- // websocket server much echo it back.
- window.setInterval(function() { conn.send(Math.random()); }, 1000);
- };
-
- for (var i = 0; i < protocols.length; i++) {
- for (var j = 0; j < websocketServers.length; j++) {
- createWebsocketConnection(protocols[i], websocketServers[j]);
- }
- }
- };
- </script>
- <style>
- body > div {
- border: 1px solid #ccc; background: #f0f0f0; padding: 0 1em;
- margin: 0 2em; min-height: 4em; max-width: 40em;
- }
- </style>
-</head>
-<body>
-</body>
-</html> \ No newline at end of file
diff --git a/3rdparty/mongoose/jni/Android.mk b/3rdparty/mongoose/jni/Android.mk
deleted file mode 100644
index 3a7daa061c1..00000000000
--- a/3rdparty/mongoose/jni/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-LOCAL_PATH := $(call my-dir)/..
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS := -std=c99 -O2 -W -Wall -pthread -pipe $(COPT)
-LOCAL_MODULE := mongoose
-LOCAL_SRC_FILES := examples/web_server/web_server.c mongoose.c
-
-include $(BUILD_EXECUTABLE)
diff --git a/3rdparty/mongoose/mongoose.c b/3rdparty/mongoose/mongoose.c
deleted file mode 100644
index 3fc2b63fd0a..00000000000
--- a/3rdparty/mongoose/mongoose.c
+++ /dev/null
@@ -1,5520 +0,0 @@
-// Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
-// Copyright (c) 2013-2014 Cesanta Software Limited
-// All rights reserved
-//
-// This library is dual-licensed: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation. For the terms of this
-// license, see <http://www.gnu.org/licenses/>.
-//
-// You are free to use this library under the terms of the GNU General
-// Public License, but WITHOUT ANY WARRANTY; without even the implied
-// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU General Public License for more details.
-//
-// Alternatively, you can license this library under a commercial
-// license, as set out in <http://cesanta.com/>.
-
-#ifdef NOEMBED_NET_SKELETON
-#include "net_skeleton.h"
-#else
-// net_skeleton start
-// Copyright (c) 2014 Cesanta Software Limited
-// All rights reserved
-//
-// This software is dual-licensed: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation. For the terms of this
-// license, see <http://www.gnu.org/licenses/>.
-//
-// You are free to use this software under the terms of the GNU General
-// Public License, but WITHOUT ANY WARRANTY; without even the implied
-// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU General Public License for more details.
-//
-// Alternatively, you can license this software under a commercial
-// license, as set out in <http://cesanta.com/>.
-
-#ifndef NS_SKELETON_HEADER_INCLUDED
-#define NS_SKELETON_HEADER_INCLUDED
-
-#define NS_SKELETON_VERSION "2.1.0"
-
-#undef UNICODE // Use ANSI WinAPI functions
-#undef _UNICODE // Use multibyte encoding on Windows
-#define _MBCS // Use multibyte encoding on Windows
-#define _INTEGRAL_MAX_BITS 64 // Enable _stati64() on Windows
-#ifndef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005+
-#endif
-#undef WIN32_LEAN_AND_MEAN // Let windows.h always include winsock2.h
-#ifdef __Linux__
-#define _XOPEN_SOURCE 600 // For flockfile() on Linux
-#endif
-#define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
-#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
-#ifndef _LARGEFILE_SOURCE
-#define _LARGEFILE_SOURCE // Enable fseeko() and ftello() functions
-#endif
-#define _FILE_OFFSET_BITS 64 // Enable 64-bit file offsets
-
-#ifdef _MSC_VER
-#pragma warning (disable : 4127) // FD_SET() emits warning, disable it
-#pragma warning (disable : 4204) // missing c99 support
-#endif
-
-#if defined(_WIN32) && !defined(MONGOOSE_NO_CGI) && !defined(MONGOOSE_ENABLE_THREADS)
-#define MONGOOSE_ENABLE_THREADS /* Windows uses stdio threads for CGI */
-#endif
-
-#ifndef MONGOOSE_ENABLE_THREADS
-#define NS_DISABLE_THREADS
-#endif
-
-#ifdef __OS2__
-#define _MMAP_DECLARED // Prevent dummy mmap() declaration in stdio.h
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <signal.h>
-
-#ifdef _WIN32
-#ifdef _MSC_VER
-#pragma comment(lib, "ws2_32.lib") // Linking with winsock library
-#include <BaseTsd.h>
-typedef SSIZE_T ssize_t;
-#endif
-#ifndef FD_SETSIZE
-#define FD_SETSIZE 1024
-#endif
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <windows.h>
-#include <process.h>
-#ifndef EINPROGRESS
-#define EINPROGRESS WSAEINPROGRESS
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif
-#ifndef __func__
-#define STRX(x) #x
-#define STR(x) STRX(x)
-#define __func__ __FILE__ ":" STR(__LINE__)
-#endif
-#ifndef va_copy
-#define va_copy(x,y) x = y
-#endif // MINGW #defines va_copy
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define sleep(x) Sleep((x) * 1000)
-#define to64(x) _atoi64(x)
-typedef int socklen_t;
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-typedef unsigned short uint16_t;
-typedef unsigned __int64 uint64_t;
-typedef __int64 int64_t;
-typedef SOCKET sock_t;
-typedef struct _stati64 ns_stat_t;
-#ifndef S_ISDIR
-#define S_ISDIR(x) ((x) & _S_IFDIR)
-#endif
-#else
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <arpa/inet.h> // For inet_pton() when NS_ENABLE_IPV6 is defined
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#define closesocket(x) close(x)
-#ifndef __OS2__
-#define __cdecl
-#else
-#include <sys/time.h>
-typedef int socklen_t;
-#endif
-#define INVALID_SOCKET (-1)
-#define to64(x) strtoll(x, NULL, 10)
-typedef int sock_t;
-typedef struct stat ns_stat_t;
-#endif
-
-#ifdef NS_ENABLE_DEBUG
-#define DBG(x) do { printf("%-20s ", __func__); printf x; putchar('\n'); \
- fflush(stdout); } while(0)
-#else
-#define DBG(x)
-#endif
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-#endif
-
-#ifdef NS_ENABLE_SSL
-#ifdef __APPLE__
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-#include <openssl/ssl.h>
-#else
-typedef void *SSL;
-typedef void *SSL_CTX;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-union socket_address {
- struct sockaddr sa;
- struct sockaddr_in sin;
-#ifdef NS_ENABLE_IPV6
- struct sockaddr_in6 sin6;
-#else
- struct sockaddr sin6;
-#endif
-};
-
-// Describes chunk of memory
-struct ns_str {
- const char *p;
- size_t len;
-};
-
-// IO buffers interface
-struct iobuf {
- char *buf;
- size_t len;
- size_t size;
-};
-
-void iobuf_init(struct iobuf *, size_t initial_size);
-void iobuf_free(struct iobuf *);
-size_t iobuf_append(struct iobuf *, const void *data, size_t data_size);
-void iobuf_remove(struct iobuf *, size_t data_size);
-void iobuf_resize(struct iobuf *, size_t new_size);
-
-// Callback function (event handler) prototype, must be defined by user.
-// Net skeleton will call event handler, passing events defined above.
-struct ns_connection;
-typedef void (*ns_callback_t)(struct ns_connection *, int event_num, void *evp);
-
-// Events. Meaning of event parameter (evp) is given in the comment.
-#define NS_POLL 0 // Sent to each connection on each call to ns_mgr_poll()
-#define NS_ACCEPT 1 // New connection accept()-ed. union socket_address *addr
-#define NS_CONNECT 2 // connect() succeeded or failed. int *success_status
-#define NS_RECV 3 // Data has benn received. int *num_bytes
-#define NS_SEND 4 // Data has been written to a socket. int *num_bytes
-#define NS_CLOSE 5 // Connection is closed. NULL
-
-
-struct ns_mgr {
- struct ns_connection *active_connections;
- const char *hexdump_file; // Debug hexdump file path
- sock_t ctl[2]; // Socketpair for mg_wakeup()
- void *user_data; // User data
-};
-
-
-struct ns_connection {
- struct ns_connection *next, *prev; // ns_mgr::active_connections linkage
- struct ns_connection *listener; // Set only for accept()-ed connections
- struct ns_mgr *mgr;
-
- sock_t sock; // Socket
- union socket_address sa; // Peer address
- size_t recv_iobuf_limit; /* Max size of recv buffer */
- struct iobuf recv_iobuf; // Received data
- struct iobuf send_iobuf; // Data scheduled for sending
- SSL *ssl;
- SSL_CTX *ssl_ctx;
- void *user_data; // User-specific data
- void *proto_data; // Application protocol-specific data
- time_t last_io_time; // Timestamp of the last socket IO
- ns_callback_t callback; // Event handler function
-
- unsigned int flags;
-#define NSF_FINISHED_SENDING_DATA (1 << 0)
-#define NSF_BUFFER_BUT_DONT_SEND (1 << 1)
-#define NSF_SSL_HANDSHAKE_DONE (1 << 2)
-#define NSF_CONNECTING (1 << 3)
-#define NSF_CLOSE_IMMEDIATELY (1 << 4)
-#define NSF_WANT_READ (1 << 5)
-#define NSF_WANT_WRITE (1 << 6)
-#define NSF_LISTENING (1 << 7)
-#define NSF_UDP (1 << 8)
-#define NSF_DISCARD (1 << 9)
-
-#define NSF_USER_1 (1 << 20)
-#define NSF_USER_2 (1 << 21)
-#define NSF_USER_3 (1 << 22)
-#define NSF_USER_4 (1 << 23)
-#define NSF_USER_5 (1 << 24)
-#define NSF_USER_6 (1 << 25)
-};
-
-void ns_mgr_init(struct ns_mgr *, void *user_data);
-void ns_mgr_free(struct ns_mgr *);
-time_t ns_mgr_poll(struct ns_mgr *, int milli);
-void ns_broadcast(struct ns_mgr *, ns_callback_t, void *, size_t);
-
-struct ns_connection *ns_next(struct ns_mgr *, struct ns_connection *);
-struct ns_connection *ns_add_sock(struct ns_mgr *, sock_t,
- ns_callback_t, void *);
-struct ns_connection *ns_bind(struct ns_mgr *, const char *,
- ns_callback_t, void *);
-struct ns_connection *ns_connect(struct ns_mgr *, const char *,
- ns_callback_t, void *);
-
-int ns_send(struct ns_connection *, const void *buf, size_t len);
-int ns_printf(struct ns_connection *, const char *fmt, ...);
-int ns_vprintf(struct ns_connection *, const char *fmt, va_list ap);
-
-// Utility functions
-void *ns_start_thread(void *(*f)(void *), void *p);
-int ns_socketpair(sock_t [2]);
-int ns_socketpair2(sock_t [2], int sock_type); // SOCK_STREAM or SOCK_DGRAM
-void ns_set_close_on_exec(sock_t);
-void ns_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
-int ns_hexdump(const void *buf, int len, char *dst, int dst_len);
-int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
-int ns_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // NS_SKELETON_HEADER_INCLUDED
-// Copyright (c) 2014 Cesanta Software Limited
-// All rights reserved
-//
-// This software is dual-licensed: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation. For the terms of this
-// license, see <http://www.gnu.org/licenses/>.
-//
-// You are free to use this software under the terms of the GNU General
-// Public License, but WITHOUT ANY WARRANTY; without even the implied
-// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU General Public License for more details.
-//
-// Alternatively, you can license this software under a commercial
-// license, as set out in <http://cesanta.com/>.
-//
-// $Date: 2014-09-28 05:04:41 UTC $
-
-
-#ifndef NS_MALLOC
-#define NS_MALLOC malloc
-#endif
-
-#ifndef NS_REALLOC
-#define NS_REALLOC realloc
-#endif
-
-#ifndef NS_FREE
-#define NS_FREE free
-#endif
-
-#ifndef NS_CALLOC
-#define NS_CALLOC calloc
-#endif
-
-#define NS_MAX_SOCKETPAIR_ATTEMPTS 10
-#define NS_CTL_MSG_MESSAGE_SIZE (8 * 1024)
-#define NS_READ_BUFFER_SIZE 2048
-#define NS_UDP_RECEIVE_BUFFER_SIZE 2000
-#define NS_VPRINTF_BUFFER_SIZE 500
-
-struct ctl_msg {
- ns_callback_t callback;
- char message[NS_CTL_MSG_MESSAGE_SIZE];
-};
-
-void iobuf_resize(struct iobuf *io, size_t new_size) {
- char *p;
- if ((new_size > io->size || (new_size < io->size && new_size >= io->len)) &&
- (p = (char *) NS_REALLOC(io->buf, new_size)) != NULL) {
- io->size = new_size;
- io->buf = p;
- }
-}
-
-void iobuf_init(struct iobuf *iobuf, size_t initial_size) {
- iobuf->len = iobuf->size = 0;
- iobuf->buf = NULL;
- iobuf_resize(iobuf, initial_size);
-}
-
-void iobuf_free(struct iobuf *iobuf) {
- if (iobuf != NULL) {
- if (iobuf->buf != NULL) NS_FREE(iobuf->buf);
- iobuf_init(iobuf, 0);
- }
-}
-
-size_t iobuf_append(struct iobuf *io, const void *buf, size_t len) {
- char *p = NULL;
-
- assert(io != NULL);
- assert(io->len <= io->size);
-
- /* check overflow */
- if (len > ~(size_t)0 - (size_t)(io->buf + io->len)) {
- return 0;
- }
-
- if (len <= 0) {
- } else if (io->len + len <= io->size) {
- memcpy(io->buf + io->len, buf, len);
- io->len += len;
- } else if ((p = (char *) NS_REALLOC(io->buf, io->len + len)) != NULL) {
- io->buf = p;
- memcpy(io->buf + io->len, buf, len);
- io->len += len;
- io->size = io->len;
- } else {
- len = 0;
- }
-
- return len;
-}
-
-void iobuf_remove(struct iobuf *io, size_t n) {
- if (n > 0 && n <= io->len) {
- memmove(io->buf, io->buf + n, io->len - n);
- io->len -= n;
- }
-}
-
-static size_t ns_out(struct ns_connection *nc, const void *buf, size_t len) {
- if (nc->flags & NSF_UDP) {
- long n = sendto(nc->sock, (const char *) buf, len, 0, &nc->sa.sa,
- sizeof(nc->sa.sin));
- DBG(("%p %d send %ld (%d %s)", nc, nc->sock, n, errno, strerror(errno)));
- return n < 0 ? 0 : n;
- } else {
- return iobuf_append(&nc->send_iobuf, buf, len);
- }
-}
-
-#ifndef NS_DISABLE_THREADS
-void *ns_start_thread(void *(*f)(void *), void *p) {
-#ifdef _WIN32
- return (void *) _beginthread((void (__cdecl *)(void *)) f, 0, p);
-#else
- pthread_t thread_id = (pthread_t) 0;
- pthread_attr_t attr;
-
- (void) pthread_attr_init(&attr);
- (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-#if defined(NS_STACK_SIZE) && NS_STACK_SIZE > 1
- (void) pthread_attr_setstacksize(&attr, NS_STACK_SIZE);
-#endif
-
- pthread_create(&thread_id, &attr, f, p);
- pthread_attr_destroy(&attr);
-
- return (void *) thread_id;
-#endif
-}
-#endif // NS_DISABLE_THREADS
-
-static void ns_add_conn(struct ns_mgr *mgr, struct ns_connection *c) {
- c->next = mgr->active_connections;
- mgr->active_connections = c;
- c->prev = NULL;
- if (c->next != NULL) c->next->prev = c;
-}
-
-static void ns_remove_conn(struct ns_connection *conn) {
- if (conn->prev == NULL) conn->mgr->active_connections = conn->next;
- if (conn->prev) conn->prev->next = conn->next;
- if (conn->next) conn->next->prev = conn->prev;
-}
-
-// Print message to buffer. If buffer is large enough to hold the message,
-// return buffer. If buffer is to small, allocate large enough buffer on heap,
-// and return allocated buffer.
-int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap) {
- va_list ap_copy;
- int len;
-
- va_copy(ap_copy, ap);
- len = vsnprintf(*buf, size, fmt, ap_copy);
- va_end(ap_copy);
-
- if (len < 0) {
- // eCos and Windows are not standard-compliant and return -1 when
- // the buffer is too small. Keep allocating larger buffers until we
- // succeed or out of memory.
- *buf = NULL;
- while (len < 0) {
- if (*buf) NS_FREE(*buf);
- size *= 2;
- if ((*buf = (char *) NS_MALLOC(size)) == NULL) break;
- va_copy(ap_copy, ap);
- len = vsnprintf(*buf, size, fmt, ap_copy);
- va_end(ap_copy);
- }
- } else if (len > (int) size) {
- // Standard-compliant code path. Allocate a buffer that is large enough.
- if ((*buf = (char *) NS_MALLOC(len + 1)) == NULL) {
- len = -1;
- } else {
- va_copy(ap_copy, ap);
- len = vsnprintf(*buf, len + 1, fmt, ap_copy);
- va_end(ap_copy);
- }
- }
-
- return len;
-}
-
-int ns_vprintf(struct ns_connection *nc, const char *fmt, va_list ap) {
- char mem[NS_VPRINTF_BUFFER_SIZE], *buf = mem;
- int len;
-
- if ((len = ns_avprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
- ns_out(nc, buf, len);
- }
- if (buf != mem && buf != NULL) {
- NS_FREE(buf);
- }
-
- return len;
-}
-
-int ns_printf(struct ns_connection *conn, const char *fmt, ...) {
- int len;
- va_list ap;
- va_start(ap, fmt);
- len = ns_vprintf(conn, fmt, ap);
- va_end(ap);
- return len;
-}
-
-static void hexdump(struct ns_connection *nc, const char *path,
- int num_bytes, int ev) {
- const struct iobuf *io = ev == NS_SEND ? &nc->send_iobuf : &nc->recv_iobuf;
- FILE *fp;
- char *buf, src[60], dst[60];
- int buf_size = num_bytes * 5 + 100;
-
- if ((fp = fopen(path, "a")) != NULL) {
- ns_sock_to_str(nc->sock, src, sizeof(src), 3);
- ns_sock_to_str(nc->sock, dst, sizeof(dst), 7);
- fprintf(fp, "%lu %p %s %s %s %d\n", (unsigned long) time(NULL),
- nc->user_data, src,
- ev == NS_RECV ? "<-" : ev == NS_SEND ? "->" :
- ev == NS_ACCEPT ? "<A" : ev == NS_CONNECT ? "C>" : "XX",
- dst, num_bytes);
- if (num_bytes > 0 && (buf = (char *) NS_MALLOC(buf_size)) != NULL) {
- ns_hexdump(io->buf + (ev == NS_SEND ? 0 : io->len) -
- (ev == NS_SEND ? 0 : num_bytes), num_bytes, buf, buf_size);
- fprintf(fp, "%s", buf);
- NS_FREE(buf);
- }
- fclose(fp);
- }
-}
-
-static void ns_call(struct ns_connection *nc, int ev, void *p) {
- if (nc->mgr->hexdump_file != NULL && ev != NS_POLL) {
- int len = (ev == NS_RECV || ev == NS_SEND) ? * (int *) p : 0;
- hexdump(nc, nc->mgr->hexdump_file, len, ev);
- }
-
- nc->callback(nc, ev, p);
-}
-
-static void ns_destroy_conn(struct ns_connection *conn) {
- closesocket(conn->sock);
- iobuf_free(&conn->recv_iobuf);
- iobuf_free(&conn->send_iobuf);
-#ifdef NS_ENABLE_SSL
- if (conn->ssl != NULL) {
- SSL_free(conn->ssl);
- }
- if (conn->ssl_ctx != NULL) {
- SSL_CTX_free(conn->ssl_ctx);
- }
-#endif
- NS_FREE(conn);
-}
-
-static void ns_close_conn(struct ns_connection *conn) {
- DBG(("%p %d", conn, conn->flags));
- ns_call(conn, NS_CLOSE, NULL);
- ns_remove_conn(conn);
- ns_destroy_conn(conn);
-}
-
-void ns_set_close_on_exec(sock_t sock) {
-#ifdef _WIN32
- (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
-#else
- fcntl(sock, F_SETFD, FD_CLOEXEC);
-#endif
-}
-
-static void ns_set_non_blocking_mode(sock_t sock) {
-#ifdef _WIN32
- unsigned long on = 1;
- ioctlsocket(sock, FIONBIO, &on);
-#else
- int flags = fcntl(sock, F_GETFL, 0);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-#endif
-}
-
-#ifndef NS_DISABLE_SOCKETPAIR
-int ns_socketpair2(sock_t sp[2], int sock_type) {
- union socket_address sa;
- sock_t sock;
- socklen_t len = sizeof(sa.sin);
- int ret = 0;
-
- sp[0] = sp[1] = INVALID_SOCKET;
-
- (void) memset(&sa, 0, sizeof(sa));
- sa.sin.sin_family = AF_INET;
- sa.sin.sin_port = htons(0);
- sa.sin.sin_addr.s_addr = htonl(0x7f000001);
-
- if ((sock = socket(AF_INET, sock_type, 0)) != INVALID_SOCKET &&
- !bind(sock, &sa.sa, len) &&
- (sock_type == SOCK_DGRAM || !listen(sock, 1)) &&
- !getsockname(sock, &sa.sa, &len) &&
- (sp[0] = socket(AF_INET, sock_type, 0)) != INVALID_SOCKET &&
- !connect(sp[0], &sa.sa, len) &&
- (sock_type == SOCK_STREAM ||
- (!getsockname(sp[0], &sa.sa, &len) && !connect(sock, &sa.sa, len))) &&
- (sp[1] = (sock_type == SOCK_DGRAM ? sock :
- accept(sock, &sa.sa, &len))) != INVALID_SOCKET) {
- ns_set_close_on_exec(sp[0]);
- ns_set_close_on_exec(sp[1]);
- ret = 1;
- } else {
- if (sp[0] != INVALID_SOCKET) closesocket(sp[0]);
- if (sp[1] != INVALID_SOCKET) closesocket(sp[1]);
- sp[0] = sp[1] = INVALID_SOCKET;
- }
- if (sock_type != SOCK_DGRAM) closesocket(sock);
-
- return ret;
-}
-
-int ns_socketpair(sock_t sp[2]) {
- return ns_socketpair2(sp, SOCK_STREAM);
-}
-#endif // NS_DISABLE_SOCKETPAIR
-
-// TODO(lsm): use non-blocking resolver
-static int ns_resolve2(const char *host, struct in_addr *ina) {
-#ifdef NS_ENABLE_GETADDRINFO
- int rv = 0;
- struct addrinfo hints, *servinfo, *p;
- struct sockaddr_in *h = NULL;
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
-
- if((rv = getaddrinfo(host, NULL , NULL, &servinfo)) != 0) {
- DBG(("getaddrinfo(%s) failed: %s", host, strerror(errno)));
- return 0;
- }
-
- for(p = servinfo; p != NULL; p = p->ai_next) {
- memcpy(&h, &p->ai_addr, sizeof(struct sockaddr_in *));
- memcpy(ina, &h->sin_addr, sizeof(ina));
- }
-
- freeaddrinfo(servinfo);
- return 1;
-#else
- struct hostent *he;
- if ((he = gethostbyname(host)) == NULL) {
- DBG(("gethostbyname(%s) failed: %s", host, strerror(errno)));
- } else {
- memcpy(ina, he->h_addr_list[0], sizeof(*ina));
- return 1;
- }
- return 0;
-#endif
-}
-
-// Resolve FDQN "host", store IP address in the "ip".
-// Return > 0 (IP address length) on success.
-int ns_resolve(const char *host, char *buf, size_t n) {
- struct in_addr ad;
- return ns_resolve2(host, &ad) ? snprintf(buf, n, "%s", inet_ntoa(ad)) : 0;
-}
-
-// Address format: [PROTO://][IP_ADDRESS:]PORT[:CERT][:CA_CERT]
-static int ns_parse_address(const char *str, union socket_address *sa,
- int *proto, int *use_ssl, char *cert, char *ca) {
- unsigned int a, b, c, d, port;
- int n = 0, len = 0;
- char host[200];
-#ifdef NS_ENABLE_IPV6
- char buf[100];
-#endif
-
- // MacOS needs that. If we do not zero it, subsequent bind() will fail.
- // Also, all-zeroes in the socket address means binding to all addresses
- // for both IPv4 and IPv6 (INADDR_ANY and IN6ADDR_ANY_INIT).
- memset(sa, 0, sizeof(*sa));
- sa->sin.sin_family = AF_INET;
-
- *proto = SOCK_STREAM;
- *use_ssl = 0;
- cert[0] = ca[0] = '\0';
-
- if (memcmp(str, "ssl://", 6) == 0) {
- str += 6;
- *use_ssl = 1;
- } else if (memcmp(str, "udp://", 6) == 0) {
- str += 6;
- *proto = SOCK_DGRAM;
- } else if (memcmp(str, "tcp://", 6) == 0) {
- str += 6;
- }
-
- if (sscanf(str, "%u.%u.%u.%u:%u%n", &a, &b, &c, &d, &port, &len) == 5) {
- // Bind to a specific IPv4 address, e.g. 192.168.1.5:8080
- sa->sin.sin_addr.s_addr = htonl((a << 24) | (b << 16) | (c << 8) | d);
- sa->sin.sin_port = htons((uint16_t) port);
-#ifdef NS_ENABLE_IPV6
- } else if (sscanf(str, "[%99[^]]]:%u%n", buf, &port, &len) == 2 &&
- inet_pton(AF_INET6, buf, &sa->sin6.sin6_addr)) {
- // IPv6 address, e.g. [3ffe:2a00:100:7031::1]:8080
- sa->sin6.sin6_family = AF_INET6;
- sa->sin6.sin6_port = htons((uint16_t) port);
-#endif
- } else if (sscanf(str, "%199[^ :]:%u%n", host, &port, &len) == 2) {
- sa->sin.sin_port = htons((uint16_t) port);
- ns_resolve2(host, &sa->sin.sin_addr);
- } else if (sscanf(str, "%u%n", &port, &len) == 1) {
- // If only port is specified, bind to IPv4, INADDR_ANY
- sa->sin.sin_port = htons((uint16_t) port);
- }
-
- if (*use_ssl && (sscanf(str + len, ":%99[^:,]:%99[^:,]%n", cert, ca, &n) == 2 ||
- sscanf(str + len, ":%99[^:,]%n", cert, &n) == 1)) {
- len += n;
- }
-
- return port < 0xffff && str[len] == '\0' ? len : 0;
-}
-
-// 'sa' must be an initialized address to bind to
-static sock_t ns_open_listening_socket(union socket_address *sa, int proto) {
- socklen_t sa_len = (sa->sa.sa_family == AF_INET) ?
- sizeof(sa->sin) : sizeof(sa->sin6);
- sock_t sock = INVALID_SOCKET;
-#ifndef _WIN32
- int on = 1;
-#endif
-
- if ((sock = socket(sa->sa.sa_family, proto, 0)) != INVALID_SOCKET &&
-#ifndef _WIN32
- // SO_RESUSEADDR is not enabled on Windows because the semantics of
- // SO_REUSEADDR on UNIX and Windows is different. On Windows,
- // SO_REUSEADDR allows to bind a socket to a port without error even if
- // the port is already open by another program. This is not the behavior
- // SO_REUSEADDR was designed for, and leads to hard-to-track failure
- // scenarios. Therefore, SO_REUSEADDR was disabled on Windows.
- !setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)) &&
-#endif
- !bind(sock, &sa->sa, sa_len) &&
- (proto == SOCK_DGRAM || listen(sock, SOMAXCONN) == 0)) {
- ns_set_non_blocking_mode(sock);
- // In case port was set to 0, get the real port number
- (void) getsockname(sock, &sa->sa, &sa_len);
- } else if (sock != INVALID_SOCKET) {
- closesocket(sock);
- sock = INVALID_SOCKET;
- }
-
- return sock;
-}
-
-#ifdef NS_ENABLE_SSL
-// Certificate generation script is at
-// https://github.com/cesanta/net_skeleton/blob/master/scripts/gen_certs.sh
-
-static int ns_use_ca_cert(SSL_CTX *ctx, const char *cert) {
- if (ctx == NULL) {
- return -1;
- } else if (cert == NULL || cert[0] == '\0') {
- return 0;
- }
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
- return SSL_CTX_load_verify_locations(ctx, cert, NULL) == 1 ? 0 : -2;
-}
-
-static int ns_use_cert(SSL_CTX *ctx, const char *pem_file) {
- if (ctx == NULL) {
- return -1;
- } else if (pem_file == NULL || pem_file[0] == '\0') {
- return 0;
- } else if (SSL_CTX_use_certificate_file(ctx, pem_file, 1) == 0 ||
- SSL_CTX_use_PrivateKey_file(ctx, pem_file, 1) == 0) {
- return -2;
- } else {
- SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
- SSL_CTX_use_certificate_chain_file(ctx, pem_file);
- return 0;
- }
-}
-#endif // NS_ENABLE_SSL
-
-struct ns_connection *ns_bind(struct ns_mgr *srv, const char *str,
- ns_callback_t callback, void *user_data) {
- union socket_address sa;
- struct ns_connection *nc = NULL;
- int use_ssl, proto;
- char cert[100], ca_cert[100];
- sock_t sock;
-
- ns_parse_address(str, &sa, &proto, &use_ssl, cert, ca_cert);
- if (use_ssl && cert[0] == '\0') return NULL;
-
- if ((sock = ns_open_listening_socket(&sa, proto)) == INVALID_SOCKET) {
- } else if ((nc = ns_add_sock(srv, sock, callback, NULL)) == NULL) {
- closesocket(sock);
- } else {
- nc->sa = sa;
- nc->flags |= NSF_LISTENING;
- nc->user_data = user_data;
- nc->callback = callback;
-
- if (proto == SOCK_DGRAM) {
- nc->flags |= NSF_UDP;
- }
-
-#ifdef NS_ENABLE_SSL
- if (use_ssl) {
- nc->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
- if (ns_use_cert(nc->ssl_ctx, cert) != 0 ||
- ns_use_ca_cert(nc->ssl_ctx, ca_cert) != 0) {
- ns_close_conn(nc);
- nc = NULL;
- }
- }
-#endif
-
- DBG(("%p sock %d/%d ssl %p %p", nc, sock, proto, nc->ssl_ctx, nc->ssl));
- }
-
- return nc;
-}
-
-static struct ns_connection *accept_conn(struct ns_connection *ls) {
- struct ns_connection *c = NULL;
- union socket_address sa;
- socklen_t len = sizeof(sa);
- sock_t sock = INVALID_SOCKET;
-
- // NOTE(lsm): on Windows, sock is always > FD_SETSIZE
- if ((sock = accept(ls->sock, &sa.sa, &len)) == INVALID_SOCKET) {
- } else if ((c = ns_add_sock(ls->mgr, sock, ls->callback,
- ls->user_data)) == NULL) {
- closesocket(sock);
-#ifdef NS_ENABLE_SSL
- } else if (ls->ssl_ctx != NULL &&
- ((c->ssl = SSL_new(ls->ssl_ctx)) == NULL ||
- SSL_set_fd(c->ssl, sock) != 1)) {
- DBG(("SSL error"));
- ns_close_conn(c);
- c = NULL;
-#endif
- } else {
- c->listener = ls;
- c->proto_data = ls->proto_data;
- ns_call(c, NS_ACCEPT, &sa);
- DBG(("%p %d %p %p", c, c->sock, c->ssl_ctx, c->ssl));
- }
-
- return c;
-}
-
-static int ns_is_error(int n) {
- return n == 0 ||
- (n < 0 && errno != EINTR && errno != EINPROGRESS &&
- errno != EAGAIN && errno != EWOULDBLOCK
-#ifdef _WIN32
- && WSAGetLastError() != WSAEINTR && WSAGetLastError() != WSAEWOULDBLOCK
-#endif
- )
-#ifdef NS_ENABLE_SSL
- /*
- * OpenSSL can return an error when the peer is closing the socket.
- * We don't encounter this error with openssl actually, but it's returned
- * by our polarssl <-> openssl wrapper who tries to speak the openssl API
- * as we understood it.
- */
- || n == SSL_AD_CLOSE_NOTIFY
-#endif
- ;
-}
-
-void ns_sock_to_str(sock_t sock, char *buf, size_t len, int flags) {
- union socket_address sa;
- socklen_t slen = sizeof(sa);
-
- if (buf != NULL && len > 0) {
- buf[0] = '\0';
- memset(&sa, 0, sizeof(sa));
- if (flags & 4) {
- getpeername(sock, &sa.sa, &slen);
- } else {
- getsockname(sock, &sa.sa, &slen);
- }
- if (flags & 1) {
-#if defined(NS_ENABLE_IPV6)
- inet_ntop(sa.sa.sa_family, sa.sa.sa_family == AF_INET ?
- (void *) &sa.sin.sin_addr :
- (void *) &sa.sin6.sin6_addr, buf, len);
-#elif defined(_WIN32)
- // Only Windoze Vista (and newer) have inet_ntop()
- strncpy(buf, inet_ntoa(sa.sin.sin_addr), len);
-#else
- inet_ntop(sa.sa.sa_family, (void *) &sa.sin.sin_addr, buf,(socklen_t)len);
-#endif
- }
- if (flags & 2) {
- snprintf(buf + strlen(buf), len - (strlen(buf) + 1), "%s%d",
- flags & 1 ? ":" : "", (int) ntohs(sa.sin.sin_port));
- }
- }
-}
-
-int ns_hexdump(const void *buf, int len, char *dst, int dst_len) {
- const unsigned char *p = (const unsigned char *) buf;
- char ascii[17] = "";
- int i, idx, n = 0;
-
- for (i = 0; i < len; i++) {
- idx = i % 16;
- if (idx == 0) {
- if (i > 0) n += snprintf(dst + n, dst_len - n, " %s\n", ascii);
- n += snprintf(dst + n, dst_len - n, "%04x ", i);
- }
- n += snprintf(dst + n, dst_len - n, " %02x", p[i]);
- ascii[idx] = p[i] < 0x20 || p[i] > 0x7e ? '.' : p[i];
- ascii[idx + 1] = '\0';
- }
-
- while (i++ % 16) n += snprintf(dst + n, dst_len - n, "%s", " ");
- n += snprintf(dst + n, dst_len - n, " %s\n\n", ascii);
-
- return n;
-}
-
-#ifdef NS_ENABLE_SSL
-static int ns_ssl_err(struct ns_connection *conn, int res) {
- int ssl_err = SSL_get_error(conn->ssl, res);
- if (ssl_err == SSL_ERROR_WANT_READ) conn->flags |= NSF_WANT_READ;
- if (ssl_err == SSL_ERROR_WANT_WRITE) conn->flags |= NSF_WANT_WRITE;
- return ssl_err;
-}
-#endif
-
-static void ns_read_from_socket(struct ns_connection *conn) {
- char buf[NS_READ_BUFFER_SIZE];
- int n = 0;
-
- if (conn->flags & NSF_CONNECTING) {
- int ok = 1, ret;
- socklen_t len = sizeof(ok);
-
- ret = getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &ok, &len);
- (void) ret;
-#ifdef NS_ENABLE_SSL
- if (ret == 0 && ok == 0 && conn->ssl != NULL) {
- int res = SSL_connect(conn->ssl);
- int ssl_err = ns_ssl_err(conn, res);
- if (res == 1) {
- conn->flags |= NSF_SSL_HANDSHAKE_DONE;
- } else if (ssl_err == SSL_ERROR_WANT_READ ||
- ssl_err == SSL_ERROR_WANT_WRITE) {
- return; // Call us again
- } else {
- ok = 1;
- }
- conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE);
- }
-#endif
- conn->flags &= ~NSF_CONNECTING;
- DBG(("%p ok=%d", conn, ok));
- if (ok != 0) {
- conn->flags |= NSF_CLOSE_IMMEDIATELY;
- }
- ns_call(conn, NS_CONNECT, &ok);
- return;
- }
-
-#ifdef NS_ENABLE_SSL
- if (conn->ssl != NULL) {
- if (conn->flags & NSF_SSL_HANDSHAKE_DONE) {
- // SSL library may have more bytes ready to read then we ask to read.
- // Therefore, read in a loop until we read everything. Without the loop,
- // we skip to the next select() cycle which can just timeout.
- while ((n = SSL_read(conn->ssl, buf, sizeof(buf))) > 0) {
- DBG(("%p %d <- %d bytes (SSL)", conn, conn->flags, n));
- iobuf_append(&conn->recv_iobuf, buf, n);
- ns_call(conn, NS_RECV, &n);
- }
- ns_ssl_err(conn, n);
- } else {
- int res = SSL_accept(conn->ssl);
- int ssl_err = ns_ssl_err(conn, res);
- if (res == 1) {
- conn->flags |= NSF_SSL_HANDSHAKE_DONE;
- conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE);
- } else if (ssl_err == SSL_ERROR_WANT_READ ||
- ssl_err == SSL_ERROR_WANT_WRITE) {
- return; // Call us again
- } else {
- conn->flags |= NSF_CLOSE_IMMEDIATELY;
- }
- return;
- }
- } else
-#endif
- {
- while ((n = (int) recv(conn->sock, buf, sizeof(buf), 0)) > 0) {
- DBG(("%p %d <- %d bytes (PLAIN)", conn, conn->flags, n));
- iobuf_append(&conn->recv_iobuf, buf, n);
- ns_call(conn, NS_RECV, &n);
- }
- }
-
- if (ns_is_error(n)) {
- conn->flags |= NSF_CLOSE_IMMEDIATELY;
- }
-}
-
-static void ns_write_to_socket(struct ns_connection *conn) {
- struct iobuf *io = &conn->send_iobuf;
- int n = 0;
-
-#ifdef NS_ENABLE_SSL
- if (conn->ssl != NULL) {
- n = SSL_write(conn->ssl, io->buf, io->len);
- if (n <= 0) {
- int ssl_err = ns_ssl_err(conn, n);
- if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
- return; // Call us again
- } else {
- conn->flags |= NSF_CLOSE_IMMEDIATELY;
- }
- } else {
- conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE);
- }
- } else
-#endif
- { n = (int) send(conn->sock, io->buf, io->len, 0); }
-
- DBG(("%p %d -> %d bytes", conn, conn->flags, n));
-
- ns_call(conn, NS_SEND, &n);
- if (ns_is_error(n)) {
- conn->flags |= NSF_CLOSE_IMMEDIATELY;
- } else if (n > 0) {
- iobuf_remove(io, n);
- }
-}
-
-int ns_send(struct ns_connection *conn, const void *buf, size_t len) {
- return (int) ns_out(conn, buf, len);
-}
-
-static void ns_handle_udp(struct ns_connection *ls) {
- struct ns_connection nc;
- char buf[NS_UDP_RECEIVE_BUFFER_SIZE];
- ssize_t n;
- socklen_t s_len = sizeof(nc.sa);
-
- memset(&nc, 0, sizeof(nc));
- n = recvfrom(ls->sock, buf, sizeof(buf), 0, &nc.sa.sa, &s_len);
- if (n <= 0) {
- DBG(("%p recvfrom: %s", ls, strerror(errno)));
- } else {
- nc.mgr = ls->mgr;
- nc.recv_iobuf.buf = buf;
- nc.recv_iobuf.len = nc.recv_iobuf.size = n;
- nc.sock = ls->sock;
- nc.callback = ls->callback;
- nc.user_data = ls->user_data;
- nc.proto_data = ls->proto_data;
- nc.mgr = ls->mgr;
- nc.listener = ls;
- nc.flags = NSF_UDP;
- DBG(("%p %d bytes received", ls, n));
- ns_call(&nc, NS_RECV, &n);
- }
-}
-
-static void ns_add_to_set(sock_t sock, fd_set *set, sock_t *max_fd) {
- if ( (sock != INVALID_SOCKET) && (sock < FD_SETSIZE) ) {
- FD_SET(sock, set);
- if (*max_fd == INVALID_SOCKET || sock > *max_fd) {
- *max_fd = sock;
- }
- }
-}
-
-time_t ns_mgr_poll(struct ns_mgr *mgr, int milli) {
- struct ns_connection *conn, *tmp_conn;
- struct timeval tv;
- fd_set read_set, write_set;
- sock_t max_fd = INVALID_SOCKET;
- time_t current_time = time(NULL);
-
- FD_ZERO(&read_set);
- FD_ZERO(&write_set);
- ns_add_to_set(mgr->ctl[1], &read_set, &max_fd);
-
- for (conn = mgr->active_connections; conn != NULL; conn = tmp_conn) {
- tmp_conn = conn->next;
- if (!(conn->flags & (NSF_LISTENING | NSF_CONNECTING))) {
- ns_call(conn, NS_POLL, &current_time);
- }
- if (conn->flags & NSF_CLOSE_IMMEDIATELY) {
- ns_close_conn(conn);
- } else {
- if (!(conn->flags & NSF_WANT_WRITE)) {
- //DBG(("%p read_set", conn));
- ns_add_to_set(conn->sock, &read_set, &max_fd);
- }
- if (((conn->flags & NSF_CONNECTING) && !(conn->flags & NSF_WANT_READ)) ||
- (conn->send_iobuf.len > 0 && !(conn->flags & NSF_CONNECTING) &&
- !(conn->flags & NSF_BUFFER_BUT_DONT_SEND))) {
- //DBG(("%p write_set", conn));
- ns_add_to_set(conn->sock, &write_set, &max_fd);
- }
- }
- }
-
- tv.tv_sec = milli / 1000;
- tv.tv_usec = (milli % 1000) * 1000;
-
- if (select((int) max_fd + 1, &read_set, &write_set, NULL, &tv) < 0) {
- return 0;
- } else {
- // select() might have been waiting for a long time, reset current_time
- // now to prevent last_io_time being set to the past.
- current_time = time(NULL);
-
- // Read wakeup messages
- if (mgr->ctl[1] != INVALID_SOCKET &&
- FD_ISSET(mgr->ctl[1], &read_set)) {
- struct ctl_msg ctl_msg;
- int len = (int) recv(mgr->ctl[1], (char *) &ctl_msg, sizeof(ctl_msg), 0);
- send(mgr->ctl[1], ctl_msg.message, 1, 0);
- if (len >= (int) sizeof(ctl_msg.callback) && ctl_msg.callback != NULL) {
- struct ns_connection *c;
- for (c = ns_next(mgr, NULL); c != NULL; c = ns_next(mgr, c)) {
- ctl_msg.callback(c, NS_POLL, ctl_msg.message);
- }
- }
- }
-
- for (conn = mgr->active_connections; conn != NULL; conn = tmp_conn) {
- tmp_conn = conn->next;
- if (FD_ISSET(conn->sock, &read_set)) {
- if (conn->flags & NSF_LISTENING) {
- if (conn->flags & NSF_UDP) {
- ns_handle_udp(conn);
- } else {
- // We're not looping here, and accepting just one connection at
- // a time. The reason is that eCos does not respect non-blocking
- // flag on a listening socket and hangs in a loop.
- accept_conn(conn);
- }
- } else {
- conn->last_io_time = current_time;
- ns_read_from_socket(conn);
- }
- }
-
- if (FD_ISSET(conn->sock, &write_set)) {
- if (conn->flags & NSF_CONNECTING) {
- ns_read_from_socket(conn);
- } else if (!(conn->flags & NSF_BUFFER_BUT_DONT_SEND)) {
- conn->last_io_time = current_time;
- ns_write_to_socket(conn);
- }
- }
- }
- }
-
- for (conn = mgr->active_connections; conn != NULL; conn = tmp_conn) {
- tmp_conn = conn->next;
- if ((conn->flags & NSF_CLOSE_IMMEDIATELY) ||
- (conn->send_iobuf.len == 0 &&
- (conn->flags & NSF_FINISHED_SENDING_DATA))) {
- ns_close_conn(conn);
- }
- }
-
- return current_time;
-}
-
-struct ns_connection *ns_connect(struct ns_mgr *mgr, const char *address,
- ns_callback_t callback, void *user_data) {
- sock_t sock = INVALID_SOCKET;
- struct ns_connection *nc = NULL;
- union socket_address sa;
- char cert[100], ca_cert[100];
- int rc, use_ssl, proto;
-
- ns_parse_address(address, &sa, &proto, &use_ssl, cert, ca_cert);
- if ((sock = socket(AF_INET, proto, 0)) == INVALID_SOCKET) {
- return NULL;
- }
- ns_set_non_blocking_mode(sock);
- rc = (proto == SOCK_DGRAM) ? 0 : connect(sock, &sa.sa, sizeof(sa.sin));
-
- if (rc != 0 && ns_is_error(rc)) {
- closesocket(sock);
- return NULL;
- } else if ((nc = ns_add_sock(mgr, sock, callback, user_data)) == NULL) {
- closesocket(sock);
- return NULL;
- }
-
- nc->sa = sa; // Important, cause UDP conns will use sendto()
- nc->flags = (proto == SOCK_DGRAM) ? NSF_UDP : NSF_CONNECTING;
-
-#ifdef NS_ENABLE_SSL
- if (use_ssl) {
- if ((nc->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL ||
- ns_use_cert(nc->ssl_ctx, cert) != 0 ||
- ns_use_ca_cert(nc->ssl_ctx, ca_cert) != 0 ||
- (nc->ssl = SSL_new(nc->ssl_ctx)) == NULL) {
- ns_close_conn(nc);
- return NULL;
- } else {
- SSL_set_fd(nc->ssl, sock);
- }
- }
-#endif
-
- return nc;
-}
-
-struct ns_connection *ns_add_sock(struct ns_mgr *s, sock_t sock,
- ns_callback_t callback, void *user_data) {
- struct ns_connection *conn;
- if ((conn = (struct ns_connection *) NS_MALLOC(sizeof(*conn))) != NULL) {
- memset(conn, 0, sizeof(*conn));
- ns_set_non_blocking_mode(sock);
- ns_set_close_on_exec(sock);
- conn->sock = sock;
- conn->user_data = user_data;
- conn->callback = callback;
- conn->mgr = s;
- conn->last_io_time = time(NULL);
- ns_add_conn(s, conn);
- DBG(("%p %d", conn, sock));
- }
- return conn;
-}
-
-struct ns_connection *ns_next(struct ns_mgr *s, struct ns_connection *conn) {
- return conn == NULL ? s->active_connections : conn->next;
-}
-
-void ns_broadcast(struct ns_mgr *mgr, ns_callback_t cb,void *data, size_t len) {
- struct ctl_msg ctl_msg;
- if (mgr->ctl[0] != INVALID_SOCKET && data != NULL &&
- len < sizeof(ctl_msg.message)) {
- ctl_msg.callback = cb;
- memcpy(ctl_msg.message, data, len);
- send(mgr->ctl[0], (char *) &ctl_msg,
- offsetof(struct ctl_msg, message) + len, 0);
- recv(mgr->ctl[0], (char *) &len, 1, 0);
- }
-}
-
-void ns_mgr_init(struct ns_mgr *s, void *user_data) {
- memset(s, 0, sizeof(*s));
- s->ctl[0] = s->ctl[1] = INVALID_SOCKET;
- s->user_data = user_data;
-
-#ifdef _WIN32
- { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
-#else
- // Ignore SIGPIPE signal, so if client cancels the request, it
- // won't kill the whole process.
- signal(SIGPIPE, SIG_IGN);
-#endif
-
-#ifndef NS_DISABLE_SOCKETPAIR
- {
- int attempts = 0, max_attempts = NS_MAX_SOCKETPAIR_ATTEMPTS;
- do {
- ns_socketpair2(s->ctl, SOCK_DGRAM);
- } while (s->ctl[0] == INVALID_SOCKET && ++attempts < max_attempts);
- }
-#endif
-
-#ifdef NS_ENABLE_SSL
- {static int init_done; if (!init_done) { SSL_library_init(); init_done++; }}
-#endif
-}
-
-void ns_mgr_free(struct ns_mgr *s) {
- struct ns_connection *conn, *tmp_conn;
-
- DBG(("%p", s));
- if (s == NULL) return;
- // Do one last poll, see https://github.com/cesanta/mongoose/issues/286
- ns_mgr_poll(s, 0);
-
- if (s->ctl[0] != INVALID_SOCKET) closesocket(s->ctl[0]);
- if (s->ctl[1] != INVALID_SOCKET) closesocket(s->ctl[1]);
- s->ctl[0] = s->ctl[1] = INVALID_SOCKET;
-
- for (conn = s->active_connections; conn != NULL; conn = tmp_conn) {
- tmp_conn = conn->next;
- ns_close_conn(conn);
- }
-}
-// net_skeleton end
-#endif // NOEMBED_NET_SKELETON
-
-#include <ctype.h>
-
-#ifdef _WIN32 //////////////// Windows specific defines and includes
-#include <io.h> // For _lseeki64
-#include <direct.h> // For _mkdir
-#ifndef S_ISDIR
-#define S_ISDIR(x) ((x) & _S_IFDIR)
-#endif
-#ifdef stat
-#undef stat
-#endif
-#ifdef lseek
-#undef lseek
-#endif
-#ifdef popen
-#undef popen
-#endif
-#ifdef pclose
-#undef pclose
-#endif
-#define stat(x, y) mg_stat((x), (y))
-#define fopen(x, y) mg_fopen((x), (y))
-#define open(x, y, z) mg_open((x), (y), (z))
-#define close(x) _close(x)
-#define fileno(x) _fileno(x)
-#define lseek(x, y, z) _lseeki64((x), (y), (z))
-#define read(x, y, z) _read((x), (y), (z))
-#define write(x, y, z) _write((x), (y), (z))
-#define popen(x, y) _popen((x), (y))
-#define pclose(x) _pclose(x)
-#define mkdir(x, y) _mkdir(x)
-#define rmdir(x) _rmdir(x)
-#define strdup(x) _strdup(x)
-#ifndef __func__
-#define STRX(x) #x
-#define STR(x) STRX(x)
-#define __func__ __FILE__ ":" STR(__LINE__)
-#endif
-// find proper defines for this for VS and other compilers
-#if defined(__USE_MINGW_ANSI_STDIO)
-#define INT64_FMT "lld"
-#else
-#define INT64_FMT "I64d"
-#endif
-#define flockfile(x) ((void) (x))
-#define funlockfile(x) ((void) (x))
-typedef struct _stati64 file_stat_t;
-typedef HANDLE process_id_t;
-
-#else ////////////// UNIX specific defines and includes
-
-#if !defined(MONGOOSE_NO_FILESYSTEM) &&\
- (!defined(MONGOOSE_NO_DAV) || !defined(MONGOOSE_NO_DIRECTORY_LISTING))
-#include <dirent.h>
-#endif
-#if !defined(MONGOOSE_NO_FILESYSTEM) && !defined(MONGOOSE_NO_DL)
-#include <dlfcn.h>
-#endif
-#include <inttypes.h>
-#include <pwd.h>
-#if !defined(O_BINARY)
-#define O_BINARY 0
-#endif
-#define INT64_FMT PRId64
-typedef struct stat file_stat_t;
-typedef pid_t process_id_t;
-#endif //////// End of platform-specific defines and includes
-
-#include "mongoose.h"
-
-#define MAX_REQUEST_SIZE 16384
-#define IOBUF_SIZE 8192
-#define MAX_PATH_SIZE 8192
-#define DEFAULT_CGI_PATTERN "**.cgi$|**.pl$|**.php$"
-#define CGI_ENVIRONMENT_SIZE 8192
-#define MAX_CGI_ENVIR_VARS 64
-#define ENV_EXPORT_TO_CGI "MONGOOSE_CGI"
-#define PASSWORDS_FILE_NAME ".htpasswd"
-
-#ifndef MONGOOSE_USE_WEBSOCKET_PING_INTERVAL
-#define MONGOOSE_USE_WEBSOCKET_PING_INTERVAL 5
-#endif
-
-// Extra HTTP headers to send in every static file reply
-#if !defined(MONGOOSE_USE_EXTRA_HTTP_HEADERS)
-#define MONGOOSE_USE_EXTRA_HTTP_HEADERS ""
-#endif
-
-#ifndef MONGOOSE_POST_SIZE_LIMIT
-#define MONGOOSE_POST_SIZE_LIMIT 0
-#endif
-
-#ifndef MONGOOSE_IDLE_TIMEOUT_SECONDS
-#define MONGOOSE_IDLE_TIMEOUT_SECONDS 300
-#endif
-
-#if defined(NS_DISABLE_SOCKETPAIR) && !defined(MONGOOSE_NO_CGI)
-#define MONGOOSE_NO_CGI
-#endif
-
-#ifdef MONGOOSE_NO_FILESYSTEM
-#define MONGOOSE_NO_AUTH
-#if !defined(MONGOOSE_NO_CGI)
-#define MONGOOSE_NO_CGI
-#endif
-#define MONGOOSE_NO_DAV
-#define MONGOOSE_NO_DIRECTORY_LISTING
-#define MONGOOSE_NO_LOGGING
-#define MONGOOSE_NO_SSI
-#define MONGOOSE_NO_DL
-#endif
-
-struct vec {
- const char *ptr;
- size_t len;
-};
-
-// For directory listing and WevDAV support
-struct dir_entry {
- struct connection *conn;
- char *file_name;
- file_stat_t st;
-};
-
-// NOTE(lsm): this enum should be in sync with the config_options.
-enum {
- ACCESS_CONTROL_LIST,
-#ifndef MONGOOSE_NO_FILESYSTEM
- ACCESS_LOG_FILE,
-#ifndef MONGOOSE_NO_AUTH
- AUTH_DOMAIN,
-#endif
-#ifndef MONGOOSE_NO_CGI
- CGI_INTERPRETER,
- CGI_PATTERN,
-#endif
- DAV_AUTH_FILE,
- DAV_ROOT,
- DOCUMENT_ROOT,
-#ifndef MONGOOSE_NO_DIRECTORY_LISTING
- ENABLE_DIRECTORY_LISTING,
-#endif
-#endif
- ENABLE_PROXY,
- EXTRA_MIME_TYPES,
-#if !defined(MONGOOSE_NO_FILESYSTEM) && !defined(MONGOOSE_NO_AUTH)
- GLOBAL_AUTH_FILE,
-#endif
-#ifndef MONGOOSE_NO_FILESYSTEM
- HIDE_FILES_PATTERN,
- HEXDUMP_FILE,
- INDEX_FILES,
-#endif
- LISTENING_PORT,
-#ifndef _WIN32
- RUN_AS_USER,
-#endif
-#ifndef MONGOOSE_NO_SSI
- SSI_PATTERN,
-#endif
- URL_REWRITES,
- NUM_OPTIONS
-};
-
-static const char *static_config_options[] = {
- "access_control_list", NULL,
-#ifndef MONGOOSE_NO_FILESYSTEM
- "access_log_file", NULL,
-#ifndef MONGOOSE_NO_AUTH
- "auth_domain", "mydomain.com",
-#endif
-#ifndef MONGOOSE_NO_CGI
- "cgi_interpreter", NULL,
- "cgi_pattern", DEFAULT_CGI_PATTERN,
-#endif
- "dav_auth_file", NULL,
- "dav_root", NULL,
- "document_root", NULL,
-#ifndef MONGOOSE_NO_DIRECTORY_LISTING
- "enable_directory_listing", "yes",
-#endif
-#endif
- "enable_proxy", NULL,
- "extra_mime_types", NULL,
-#if !defined(MONGOOSE_NO_FILESYSTEM) && !defined(MONGOOSE_NO_AUTH)
- "global_auth_file", NULL,
-#endif
-#ifndef MONGOOSE_NO_FILESYSTEM
- "hide_files_patterns", NULL,
- "hexdump_file", NULL,
- "index_files","index.html,index.htm,index.shtml,index.cgi,index.php",
-#endif
- "listening_port", NULL,
-#ifndef _WIN32
- "run_as_user", NULL,
-#endif
-#ifndef MONGOOSE_NO_SSI
- "ssi_pattern", "**.shtml$|**.shtm$",
-#endif
- "url_rewrites", NULL,
- NULL
-};
-
-struct mg_server {
- struct ns_mgr ns_mgr;
- union socket_address lsa; // Listening socket address
- mg_handler_t event_handler;
- char *config_options[NUM_OPTIONS];
-};
-
-// Local endpoint representation
-union endpoint {
- int fd; // Opened regular local file
- struct ns_connection *nc; // CGI or proxy->target connection
-};
-
-enum endpoint_type {
- EP_NONE, EP_FILE, EP_CGI, EP_USER, EP_PUT, EP_CLIENT, EP_PROXY
-};
-
-#define MG_HEADERS_SENT NSF_USER_1
-#define MG_USING_CHUNKED_API NSF_USER_2
-#define MG_CGI_CONN NSF_USER_3
-#define MG_PROXY_CONN NSF_USER_4
-#define MG_PROXY_DONT_PARSE NSF_USER_5
-
-struct connection {
- struct ns_connection *ns_conn; // NOTE(lsm): main.c depends on this order
- struct mg_connection mg_conn;
- struct mg_server *server;
- union endpoint endpoint;
- enum endpoint_type endpoint_type;
- char *path_info;
- char *request;
- int64_t num_bytes_recv; // Total number of bytes received
- int64_t cl; // Reply content length, for Range support
- ssize_t request_len; // Request length, including last \r\n after last header
-};
-
-#define MG_CONN_2_CONN(c) ((struct connection *) ((char *) (c) - \
- offsetof(struct connection, mg_conn)))
-
-static void open_local_endpoint(struct connection *conn, int skip_user);
-static void close_local_endpoint(struct connection *conn);
-static void mg_ev_handler(struct ns_connection *nc, int ev, void *p);
-
-static const struct {
- const char *extension;
- size_t ext_len;
- const char *mime_type;
-} static_builtin_mime_types[] = {
- {".html", 5, "text/html"},
- {".htm", 4, "text/html"},
- {".shtm", 5, "text/html"},
- {".shtml", 6, "text/html"},
- {".css", 4, "text/css"},
- {".js", 3, "application/javascript"},
- {".ico", 4, "image/x-icon"},
- {".gif", 4, "image/gif"},
- {".jpg", 4, "image/jpeg"},
- {".jpeg", 5, "image/jpeg"},
- {".png", 4, "image/png"},
- {".svg", 4, "image/svg+xml"},
- {".txt", 4, "text/plain"},
- {".torrent", 8, "application/x-bittorrent"},
- {".wav", 4, "audio/x-wav"},
- {".mp3", 4, "audio/x-mp3"},
- {".mid", 4, "audio/mid"},
- {".m3u", 4, "audio/x-mpegurl"},
- {".ogg", 4, "application/ogg"},
- {".ram", 4, "audio/x-pn-realaudio"},
- {".xml", 4, "text/xml"},
- {".json", 5, "application/json"},
- {".xslt", 5, "application/xml"},
- {".xsl", 4, "application/xml"},
- {".ra", 3, "audio/x-pn-realaudio"},
- {".doc", 4, "application/msword"},
- {".exe", 4, "application/octet-stream"},
- {".zip", 4, "application/x-zip-compressed"},
- {".xls", 4, "application/excel"},
- {".tgz", 4, "application/x-tar-gz"},
- {".tar", 4, "application/x-tar"},
- {".gz", 3, "application/x-gunzip"},
- {".arj", 4, "application/x-arj-compressed"},
- {".rar", 4, "application/x-rar-compressed"},
- {".rtf", 4, "application/rtf"},
- {".pdf", 4, "application/pdf"},
- {".swf", 4, "application/x-shockwave-flash"},
- {".mpg", 4, "video/mpeg"},
- {".webm", 5, "video/webm"},
- {".mpeg", 5, "video/mpeg"},
- {".mov", 4, "video/quicktime"},
- {".mp4", 4, "video/mp4"},
- {".m4v", 4, "video/x-m4v"},
- {".asf", 4, "video/x-ms-asf"},
- {".avi", 4, "video/x-msvideo"},
- {".bmp", 4, "image/bmp"},
- {".ttf", 4, "application/x-font-ttf"},
- {NULL, 0, NULL}
-};
-
-#ifdef MONGOOSE_ENABLE_THREADS
-void *mg_start_thread(void *(*f)(void *), void *p) {
- return ns_start_thread(f, p);
-}
-#endif // MONGOOSE_ENABLE_THREADS
-
-#ifndef MONGOOSE_NO_MMAP
-#ifdef _WIN32
-static void *mmap(void *addr, int64_t len, int prot, int flags, int fd,
- int offset) {
- HANDLE fh = (HANDLE) _get_osfhandle(fd);
- HANDLE mh = CreateFileMapping(fh, 0, PAGE_READONLY, 0, 0, 0);
- void *p = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, (size_t) len);
- CloseHandle(mh);
- return p;
-}
-#define munmap(x, y) UnmapViewOfFile(x)
-#define MAP_FAILED NULL
-#define MAP_PRIVATE 0
-#define PROT_READ 0
-#elif defined(__OS2__)
-static void *mmap(void *addr, int64_t len, int prot, int flags, int fd,
- int offset) {
- void *p;
-
- int pos = lseek( fd, 0, SEEK_CUR ); /* Get a current position */
-
- if (pos == -1)
- return NULL;
-
- /* Seek to offset offset */
- if (lseek( fd, offset, SEEK_SET) == -1)
- return NULL;
-
- p = malloc(len);
-
- /* Read in a file */
- if (!p || read(fd, p, len) == -1) {
- free(p);
- p = NULL;
- }
-
- /* Restore the position */
- lseek(fd, pos, SEEK_SET);
-
- return p;
-}
-#define munmap(x, y) free(x)
-#define MAP_FAILED NULL
-#define MAP_PRIVATE 0
-#define PROT_READ 0
-#else
-#include <sys/mman.h>
-#endif
-
-void *mg_mmap(FILE *fp, size_t size) {
- void *p = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fileno(fp), 0);
- return p == MAP_FAILED ? NULL : p;
-}
-
-void mg_munmap(void *p, size_t size) {
- munmap(p, size);
-}
-#endif // MONGOOSE_NO_MMAP
-
-#if defined(_WIN32) && !defined(MONGOOSE_NO_FILESYSTEM)
-// Encode 'path' which is assumed UTF-8 string, into UNICODE string.
-// wbuf and wbuf_len is a target buffer and its length.
-static void to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
- char buf[MAX_PATH_SIZE * 2], buf2[MAX_PATH_SIZE * 2], *p;
-
- strncpy(buf, path, sizeof(buf));
- buf[sizeof(buf) - 1] = '\0';
-
- // Trim trailing slashes. Leave backslash for paths like "X:\"
- p = buf + strlen(buf) - 1;
- while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
-
- // Convert to Unicode and back. If doubly-converted string does not
- // match the original, something is fishy, reject.
- memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
- WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
- NULL, NULL);
- if (strcmp(buf, buf2) != 0) {
- wbuf[0] = L'\0';
- }
-}
-
-static int mg_stat(const char *path, file_stat_t *st) {
- wchar_t wpath[MAX_PATH_SIZE];
- to_wchar(path, wpath, ARRAY_SIZE(wpath));
- DBG(("[%ls] -> %d", wpath, _wstati64(wpath, st)));
- return _wstati64(wpath, st);
-}
-
-static FILE *mg_fopen(const char *path, const char *mode) {
- wchar_t wpath[MAX_PATH_SIZE], wmode[10];
- to_wchar(path, wpath, ARRAY_SIZE(wpath));
- to_wchar(mode, wmode, ARRAY_SIZE(wmode));
- return _wfopen(wpath, wmode);
-}
-
-static int mg_open(const char *path, int flag, int mode) {
- wchar_t wpath[MAX_PATH_SIZE];
- to_wchar(path, wpath, ARRAY_SIZE(wpath));
- return _wopen(wpath, flag, mode);
-}
-#endif // _WIN32 && !MONGOOSE_NO_FILESYSTEM
-
-// A helper function for traversing a comma separated list of values.
-// It returns a list pointer shifted to the next value, or NULL if the end
-// of the list found.
-// Value is stored in val vector. If value has form "x=y", then eq_val
-// vector is initialized to point to the "y" part, and val vector length
-// is adjusted to point only to "x".
-static const char *next_option(const char *list, struct vec *val,
- struct vec *eq_val) {
- if (list == NULL || *list == '\0') {
- // End of the list
- list = NULL;
- } else {
- val->ptr = list;
- if ((list = strchr(val->ptr, ',')) != NULL) {
- // Comma found. Store length and shift the list ptr
- val->len = list - val->ptr;
- list++;
- } else {
- // This value is the last one
- list = val->ptr + strlen(val->ptr);
- val->len = list - val->ptr;
- }
-
- if (eq_val != NULL) {
- // Value has form "x=y", adjust pointers and lengths
- // so that val points to "x", and eq_val points to "y".
- eq_val->len = 0;
- eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
- if (eq_val->ptr != NULL) {
- eq_val->ptr++; // Skip over '=' character
- eq_val->len = val->ptr + val->len - eq_val->ptr;
- val->len = (eq_val->ptr - val->ptr) - 1;
- }
- }
- }
-
- return list;
-}
-
-// Like snprintf(), but never returns negative value, or a value
-// that is larger than a supplied buffer.
-static int mg_vsnprintf(char *buf, size_t buflen, const char *fmt, va_list ap) {
- int n;
- if (buflen < 1) return 0;
- n = vsnprintf(buf, buflen, fmt, ap);
- if (n < 0) {
- n = 0;
- } else if (n >= (int) buflen) {
- n = (int) buflen - 1;
- }
- buf[n] = '\0';
- return n;
-}
-
-static int mg_snprintf(char *buf, size_t buflen, const char *fmt, ...) {
- va_list ap;
- int n;
- va_start(ap, fmt);
- n = mg_vsnprintf(buf, buflen, fmt, ap);
- va_end(ap);
- return n;
-}
-
-// Check whether full request is buffered. Return:
-// -1 if request is malformed
-// 0 if request is not yet fully buffered
-// >0 actual request length, including last \r\n\r\n
-static int get_request_len(const char *s, size_t buf_len) {
- const unsigned char *buf = (unsigned char *) s;
- size_t i;
-
- for (i = 0; i < buf_len; i++) {
- // Control characters are not allowed but >=128 are.
- // Abort scan as soon as one malformed character is found.
- if (!isprint(buf[i]) && buf[i] != '\r' && buf[i] != '\n' && buf[i] < 128) {
- return -1;
- } else if (buf[i] == '\n' && i + 1 < buf_len && buf[i + 1] == '\n') {
- return i + 2;
- } else if (buf[i] == '\n' && i + 2 < buf_len && buf[i + 1] == '\r' &&
- buf[i + 2] == '\n') {
- return i + 3;
- }
- }
-
- return 0;
-}
-
-// Skip the characters until one of the delimiters characters found.
-// 0-terminate resulting word. Skip the rest of the delimiters if any.
-// Advance pointer to buffer to the next word. Return found 0-terminated word.
-static char *skip(char **buf, const char *delimiters) {
- char *p, *begin_word, *end_word, *end_delimiters;
-
- begin_word = *buf;
- end_word = begin_word + strcspn(begin_word, delimiters);
- end_delimiters = end_word + strspn(end_word, delimiters);
-
- for (p = end_word; p < end_delimiters; p++) {
- *p = '\0';
- }
-
- *buf = end_delimiters;
-
- return begin_word;
-}
-
-// Parse HTTP headers from the given buffer, advance buffer to the point
-// where parsing stopped.
-static void parse_http_headers(char **buf, struct mg_connection *ri) {
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(ri->http_headers); i++) {
- ri->http_headers[i].name = skip(buf, ": ");
- ri->http_headers[i].value = skip(buf, "\r\n");
- if (ri->http_headers[i].name[0] == '\0')
- break;
- ri->num_headers = i + 1;
- }
-}
-
-static const char *status_code_to_str(int status_code) {
- switch (status_code) {
-
- case 100: return "Continue";
- case 101: return "Switching Protocols";
- case 102: return "Processing";
-
- case 200: return "OK";
- case 201: return "Created";
- case 202: return "Accepted";
- case 203: return "Non-Authoritative Information";
- case 204: return "No Content";
- case 205: return "Reset Content";
- case 206: return "Partial Content";
- case 207: return "Multi-Status";
- case 208: return "Already Reported";
- case 226: return "IM Used";
-
- case 300: return "Multiple Choices";
- case 301: return "Moved Permanently";
- case 302: return "Found";
- case 303: return "See Other";
- case 304: return "Not Modified";
- case 305: return "Use Proxy";
- case 306: return "Switch Proxy";
- case 307: return "Temporary Redirect";
- case 308: return "Permanent Redirect";
-
- case 400: return "Bad Request";
- case 401: return "Unauthorized";
- case 402: return "Payment Required";
- case 403: return "Forbidden";
- case 404: return "Not Found";
- case 405: return "Method Not Allowed";
- case 406: return "Not Acceptable";
- case 407: return "Proxy Authentication Required";
- case 408: return "Request Timeout";
- case 409: return "Conflict";
- case 410: return "Gone";
- case 411: return "Length Required";
- case 412: return "Precondition Failed";
- case 413: return "Payload Too Large";
- case 414: return "URI Too Long";
- case 415: return "Unsupported Media Type";
- case 416: return "Requested Range Not Satisfiable";
- case 417: return "Expectation Failed";
- case 418: return "I\'m a teapot";
- case 422: return "Unprocessable Entity";
- case 423: return "Locked";
- case 424: return "Failed Dependency";
- case 426: return "Upgrade Required";
- case 428: return "Precondition Required";
- case 429: return "Too Many Requests";
- case 431: return "Request Header Fields Too Large";
- case 451: return "Unavailable For Legal Reasons";
-
- case 500: return "Internal Server Error";
- case 501: return "Not Implemented";
- case 502: return "Bad Gateway";
- case 503: return "Service Unavailable";
- case 504: return "Gateway Timeout";
- case 505: return "HTTP Version Not Supported";
- case 506: return "Variant Also Negotiates";
- case 507: return "Insufficient Storage";
- case 508: return "Loop Detected";
- case 510: return "Not Extended";
- case 511: return "Network Authentication Required";
-
- default: return "Server Error";
- }
-}
-
-static int call_user(struct connection *conn, enum mg_event ev) {
- return conn != NULL && conn->server != NULL &&
- conn->server->event_handler != NULL ?
- conn->server->event_handler(&conn->mg_conn, ev) : MG_FALSE;
-}
-
-static void send_http_error(struct connection *conn, int code,
- const char *fmt, ...) {
- const char *message = status_code_to_str(code);
- const char *rewrites = conn->server->config_options[URL_REWRITES];
- char headers[200], body[200];
- struct vec a, b;
- va_list ap;
- int body_len, headers_len, match_code;
-
- conn->mg_conn.status_code = code;
-
- // Invoke error handler if it is set
- if (call_user(conn, MG_HTTP_ERROR) == MG_TRUE) {
- close_local_endpoint(conn);
- return;
- }
-
- // Handle error code rewrites
- while ((rewrites = next_option(rewrites, &a, &b)) != NULL) {
- if ((match_code = atoi(a.ptr)) > 0 && match_code == code) {
- struct mg_connection *c = &conn->mg_conn;
- c->status_code = 302;
- mg_printf(c, "HTTP/1.1 %d Moved\r\n"
- "Location: %.*s?code=%d&orig_uri=%s&query_string=%s\r\n\r\n",
- c->status_code, b.len, b.ptr, code, c->uri,
- c->query_string == NULL ? "" : c->query_string);
- close_local_endpoint(conn);
- return;
- }
- }
-
- body_len = mg_snprintf(body, sizeof(body), "%d %s\n", code, message);
- if (fmt != NULL) {
- va_start(ap, fmt);
- body_len += mg_vsnprintf(body + body_len, sizeof(body) - body_len, fmt, ap);
- va_end(ap);
- }
- if ((code >= 300 && code <= 399) || code == 204) {
- // 3xx errors do not have body
- body_len = 0;
- }
- headers_len = mg_snprintf(headers, sizeof(headers),
- "HTTP/1.1 %d %s\r\nContent-Length: %d\r\n"
- "Content-Type: text/plain\r\n\r\n",
- code, message, body_len);
- ns_send(conn->ns_conn, headers, headers_len);
- ns_send(conn->ns_conn, body, body_len);
- close_local_endpoint(conn); // This will write to the log file
-}
-
-static void write_chunk(struct connection *conn, const char *buf, int len) {
- char chunk_size[50];
- int n = mg_snprintf(chunk_size, sizeof(chunk_size), "%X\r\n", len);
- ns_send(conn->ns_conn, chunk_size, n);
- ns_send(conn->ns_conn, buf, len);
- ns_send(conn->ns_conn, "\r\n", 2);
-}
-
-size_t mg_printf(struct mg_connection *conn, const char *fmt, ...) {
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = mg_vprintf(conn, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-size_t mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap) {
- struct connection *c = MG_CONN_2_CONN(conn);
-
- ns_vprintf(c->ns_conn, fmt, ap);
-
- return c->ns_conn->send_iobuf.len;
-}
-
-static void ns_forward(struct ns_connection *from, struct ns_connection *to) {
- DBG(("%p -> %p %lu bytes", from, to, (unsigned long)from->recv_iobuf.len));
- ns_send(to, from->recv_iobuf.buf, from->recv_iobuf.len);
- iobuf_remove(&from->recv_iobuf, from->recv_iobuf.len);
-}
-
-#ifndef MONGOOSE_NO_CGI
-#ifdef _WIN32
-struct threadparam {
- sock_t s;
- HANDLE hPipe;
-};
-
-static int wait_until_ready(sock_t sock, int for_read) {
- fd_set set;
- if ( (sock == INVALID_SOCKET) || (sock >= FD_SETSIZE) )
- return 0;
- FD_ZERO(&set);
- FD_SET(sock, &set);
- select(sock + 1, for_read ? &set : 0, for_read ? 0 : &set, 0, 0);
- return 1;
-}
-
-static void *push_to_stdin(void *arg) {
- struct threadparam *tp = (struct threadparam *)arg;
- int n, sent, stop = 0;
- DWORD k;
- char buf[IOBUF_SIZE];
-
- while (!stop && wait_until_ready(tp->s, 1) &&
- (n = recv(tp->s, buf, sizeof(buf), 0)) > 0) {
- if (n == -1 && GetLastError() == WSAEWOULDBLOCK) continue;
- for (sent = 0; !stop && sent < n; sent += k) {
- if (!WriteFile(tp->hPipe, buf + sent, n - sent, &k, 0)) stop = 1;
- }
- }
- DBG(("%s", "FORWARDED EVERYTHING TO CGI"));
- CloseHandle(tp->hPipe);
- NS_FREE(tp);
- _endthread();
- return NULL;
-}
-
-static void *pull_from_stdout(void *arg) {
- struct threadparam *tp = (struct threadparam *)arg;
- int k = 0, stop = 0;
- DWORD n, sent;
- char buf[IOBUF_SIZE];
-
- while (!stop && ReadFile(tp->hPipe, buf, sizeof(buf), &n, NULL)) {
- for (sent = 0; !stop && sent < n; sent += k) {
- if (wait_until_ready(tp->s, 0) &&
- (k = send(tp->s, buf + sent, n - sent, 0)) <= 0) stop = 1;
- }
- }
- DBG(("%s", "EOF FROM CGI"));
- CloseHandle(tp->hPipe);
- shutdown(tp->s, 2); // Without this, IO thread may get truncated data
- closesocket(tp->s);
- NS_FREE(tp);
- _endthread();
- return NULL;
-}
-
-static void spawn_stdio_thread(sock_t sock, HANDLE hPipe,
- void *(*func)(void *)) {
- struct threadparam *tp = (struct threadparam *)NS_MALLOC(sizeof(*tp));
- if (tp != NULL) {
- tp->s = sock;
- tp->hPipe = hPipe;
- mg_start_thread(func, tp);
- }
-}
-
-static void abs_path(const char *utf8_path, char *abs_path, size_t len) {
- wchar_t buf[MAX_PATH_SIZE], buf2[MAX_PATH_SIZE];
- to_wchar(utf8_path, buf, ARRAY_SIZE(buf));
- GetFullPathNameW(buf, ARRAY_SIZE(buf2), buf2, NULL);
- WideCharToMultiByte(CP_UTF8, 0, buf2, wcslen(buf2) + 1, abs_path, len, 0, 0);
-}
-
-static process_id_t start_process(char *interp, const char *cmd,
- const char *env, const char *envp[],
- const char *dir, sock_t sock) {
- STARTUPINFOW si;
- PROCESS_INFORMATION pi;
- HANDLE a[2], b[2], me = GetCurrentProcess();
- wchar_t wcmd[MAX_PATH_SIZE], full_dir[MAX_PATH_SIZE];
- char buf[MAX_PATH_SIZE], buf4[MAX_PATH_SIZE], buf5[MAX_PATH_SIZE],
- cmdline[MAX_PATH_SIZE], *p;
- DWORD flags = DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS;
- FILE *fp;
-
- memset(&si, 0, sizeof(si));
- memset(&pi, 0, sizeof(pi));
-
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE;
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-
- CreatePipe(&a[0], &a[1], NULL, 0);
- CreatePipe(&b[0], &b[1], NULL, 0);
- DuplicateHandle(me, a[0], me, &si.hStdInput, 0, TRUE, flags);
- DuplicateHandle(me, b[1], me, &si.hStdOutput, 0, TRUE, flags);
-
- if (interp == NULL && (fp = fopen(cmd, "r")) != NULL) {
- buf[0] = buf[1] = '\0';
- fgets(buf, sizeof(buf), fp);
- buf[sizeof(buf) - 1] = '\0';
- if (buf[0] == '#' && buf[1] == '!') {
- interp = buf + 2;
- for (p = interp + strlen(interp) - 1;
- isspace(* (uint8_t *) p) && p > interp; p--) *p = '\0';
- }
- fclose(fp);
- }
-
- if (interp != NULL) {
- abs_path(interp, buf4, ARRAY_SIZE(buf4));
- interp = buf4;
- }
- abs_path(dir, buf5, ARRAY_SIZE(buf5));
- to_wchar(dir, full_dir, ARRAY_SIZE(full_dir));
- mg_snprintf(cmdline, sizeof(cmdline), "%s%s\"%s\"",
- interp ? interp : "", interp ? " " : "", cmd);
- to_wchar(cmdline, wcmd, ARRAY_SIZE(wcmd));
-
- if (CreateProcessW(NULL, wcmd, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP,
- (void *) env, full_dir, &si, &pi) != 0) {
- spawn_stdio_thread(sock, a[1], push_to_stdin);
- spawn_stdio_thread(sock, b[0], pull_from_stdout);
- } else {
- CloseHandle(a[1]);
- CloseHandle(b[0]);
- closesocket(sock);
- }
- DBG(("CGI command: [%ls] -> %p", wcmd, pi.hProcess));
-
- // Not closing a[0] and b[1] because we've used DUPLICATE_CLOSE_SOURCE
- CloseHandle(si.hStdOutput);
- CloseHandle(si.hStdInput);
- //CloseHandle(pi.hThread);
- //CloseHandle(pi.hProcess);
-
- return pi.hProcess;
-}
-#else
-static process_id_t start_process(const char *interp, const char *cmd,
- const char *env, const char *envp[],
- const char *dir, sock_t sock) {
- char buf[500];
- process_id_t pid = fork();
- (void) env;
-
- if (pid == 0) {
- (void) chdir(dir);
- (void) dup2(sock, 0);
- (void) dup2(sock, 1);
- closesocket(sock);
-
- // After exec, all signal handlers are restored to their default values,
- // with one exception of SIGCHLD. According to POSIX.1-2001 and Linux's
- // implementation, SIGCHLD's handler will leave unchanged after exec
- // if it was set to be ignored. Restore it to default action.
- signal(SIGCHLD, SIG_DFL);
-
- if (interp == NULL) {
- execle(cmd, cmd, (char *) 0, envp); // Using (char *) 0 to avoid warning
- } else {
- execle(interp, interp, cmd, (char *) 0, envp);
- }
- snprintf(buf, sizeof(buf), "Status: 500\r\n\r\n"
- "500 Server Error: %s%s%s: %s", interp == NULL ? "" : interp,
- interp == NULL ? "" : " ", cmd, strerror(errno));
- send(1, buf, strlen(buf), 0);
- exit(EXIT_FAILURE); // exec call failed
- }
-
- return pid;
-}
-#endif // _WIN32
-
-// This structure helps to create an environment for the spawned CGI program.
-// Environment is an array of "VARIABLE=VALUE\0" ASCIIZ strings,
-// last element must be NULL.
-// However, on Windows there is a requirement that all these VARIABLE=VALUE\0
-// strings must reside in a contiguous buffer. The end of the buffer is
-// marked by two '\0' characters.
-// We satisfy both worlds: we create an envp array (which is vars), all
-// entries are actually pointers inside buf.
-struct cgi_env_block {
- struct mg_connection *conn;
- char buf[CGI_ENVIRONMENT_SIZE]; // Environment buffer
- const char *vars[MAX_CGI_ENVIR_VARS]; // char *envp[]
- int len; // Space taken
- int nvars; // Number of variables in envp[]
-};
-
-// Append VARIABLE=VALUE\0 string to the buffer, and add a respective
-// pointer into the vars array.
-static char *addenv(struct cgi_env_block *block, const char *fmt, ...) {
- int n, space;
- char *added;
- va_list ap;
-
- // Calculate how much space is left in the buffer
- space = sizeof(block->buf) - block->len - 2;
- assert(space >= 0);
-
- // Make a pointer to the free space int the buffer
- added = block->buf + block->len;
-
- // Copy VARIABLE=VALUE\0 string into the free space
- va_start(ap, fmt);
- n = mg_vsnprintf(added, (size_t) space, fmt, ap);
- va_end(ap);
-
- // Make sure we do not overflow buffer and the envp array
- if (n > 0 && n + 1 < space &&
- block->nvars < (int) ARRAY_SIZE(block->vars) - 2) {
- // Append a pointer to the added string into the envp array
- block->vars[block->nvars++] = added;
- // Bump up used length counter. Include \0 terminator
- block->len += n + 1;
- }
-
- return added;
-}
-
-static void addenv2(struct cgi_env_block *blk, const char *name) {
- const char *s;
- if ((s = getenv(name)) != NULL) addenv(blk, "%s=%s", name, s);
-}
-
-static void prepare_cgi_environment(struct connection *conn,
- const char *prog,
- struct cgi_env_block *blk) {
- struct mg_connection *ri = &conn->mg_conn;
- const char *s, *slash;
- char *p, **opts = conn->server->config_options;
- int i;
-
- blk->len = blk->nvars = 0;
- blk->conn = ri;
-
- if ((s = getenv("SERVER_NAME")) != NULL) {
- addenv(blk, "SERVER_NAME=%s", s);
- } else {
- addenv(blk, "SERVER_NAME=%s", ri->local_ip);
- }
- addenv(blk, "SERVER_ROOT=%s", opts[DOCUMENT_ROOT]);
- addenv(blk, "DOCUMENT_ROOT=%s", opts[DOCUMENT_ROOT]);
- addenv(blk, "SERVER_SOFTWARE=%s/%s", "Mongoose", MONGOOSE_VERSION);
-
- // Prepare the environment block
- addenv(blk, "%s", "GATEWAY_INTERFACE=CGI/1.1");
- addenv(blk, "%s", "SERVER_PROTOCOL=HTTP/1.1");
- addenv(blk, "%s", "REDIRECT_STATUS=200"); // For PHP
-
- // TODO(lsm): fix this for IPv6 case
- //addenv(blk, "SERVER_PORT=%d", ri->remote_port);
-
- addenv(blk, "REQUEST_METHOD=%s", ri->request_method);
- addenv(blk, "REMOTE_ADDR=%s", ri->remote_ip);
- addenv(blk, "REMOTE_PORT=%d", ri->remote_port);
- addenv(blk, "REQUEST_URI=%s%s%s", ri->uri,
- ri->query_string == NULL ? "" : "?",
- ri->query_string == NULL ? "" : ri->query_string);
-
- // SCRIPT_NAME
- if (conn->path_info != NULL) {
- addenv(blk, "SCRIPT_NAME=%.*s",
- (int) (strlen(ri->uri) - strlen(conn->path_info)), ri->uri);
- addenv(blk, "PATH_INFO=%s", conn->path_info);
- } else {
- s = strrchr(prog, '/');
- slash = strrchr(ri->uri, '/');
- addenv(blk, "SCRIPT_NAME=%.*s%s",
- slash == NULL ? 0 : (int) (slash - ri->uri), ri->uri,
- s == NULL ? prog : s);
- }
-
- addenv(blk, "SCRIPT_FILENAME=%s", prog);
- addenv(blk, "PATH_TRANSLATED=%s", prog);
- addenv(blk, "HTTPS=%s", conn->ns_conn->ssl != NULL ? "on" : "off");
-
- if ((s = mg_get_header(ri, "Content-Type")) != NULL)
- addenv(blk, "CONTENT_TYPE=%s", s);
-
- if (ri->query_string != NULL)
- addenv(blk, "QUERY_STRING=%s", ri->query_string);
-
- if ((s = mg_get_header(ri, "Content-Length")) != NULL)
- addenv(blk, "CONTENT_LENGTH=%s", s);
-
- addenv2(blk, "PATH");
- addenv2(blk, "TMP");
- addenv2(blk, "TEMP");
- addenv2(blk, "TMPDIR");
- addenv2(blk, "PERLLIB");
- addenv2(blk, ENV_EXPORT_TO_CGI);
-
-#if defined(_WIN32)
- addenv2(blk, "COMSPEC");
- addenv2(blk, "SYSTEMROOT");
- addenv2(blk, "SystemDrive");
- addenv2(blk, "ProgramFiles");
- addenv2(blk, "ProgramFiles(x86)");
- addenv2(blk, "CommonProgramFiles(x86)");
-#else
- addenv2(blk, "LD_LIBRARY_PATH");
-#endif // _WIN32
-
- // Add all headers as HTTP_* variables
- for (i = 0; i < ri->num_headers; i++) {
- p = addenv(blk, "HTTP_%s=%s",
- ri->http_headers[i].name, ri->http_headers[i].value);
-
- // Convert variable name into uppercase, and change - to _
- for (; *p != '=' && *p != '\0'; p++) {
- if (*p == '-')
- *p = '_';
- *p = (char) toupper(* (unsigned char *) p);
- }
- }
-
- blk->vars[blk->nvars++] = NULL;
- blk->buf[blk->len++] = '\0';
-
- assert(blk->nvars < (int) ARRAY_SIZE(blk->vars));
- assert(blk->len > 0);
- assert(blk->len < (int) sizeof(blk->buf));
-}
-
-static const char cgi_status[] = "HTTP/1.1 200 OK\r\n";
-
-static void open_cgi_endpoint(struct connection *conn, const char *prog) {
- struct cgi_env_block blk;
- char dir[MAX_PATH_SIZE];
- const char *p;
- sock_t fds[2];
-
- prepare_cgi_environment(conn, prog, &blk);
- // CGI must be executed in its own directory. 'dir' must point to the
- // directory containing executable program, 'p' must point to the
- // executable program name relative to 'dir'.
- if ((p = strrchr(prog, '/')) == NULL) {
- mg_snprintf(dir, sizeof(dir), "%s", ".");
- } else {
- mg_snprintf(dir, sizeof(dir), "%.*s", (int) (p - prog), prog);
- }
-
- // Try to create socketpair in a loop until success. ns_socketpair()
- // can be interrupted by a signal and fail.
- // TODO(lsm): use sigaction to restart interrupted syscall
- {
- int attempts = 0, max_attempts = NS_MAX_SOCKETPAIR_ATTEMPTS;
- do {
- ns_socketpair(fds);
- } while (fds[0] == INVALID_SOCKET && ++attempts < max_attempts);
-
- if (fds[0] == INVALID_SOCKET) {
- closesocket(fds[0]);
- send_http_error(conn, 500, "ns_socketpair() failed");
- }
- }
-
- if (start_process(conn->server->config_options[CGI_INTERPRETER],
- prog, blk.buf, blk.vars, dir, fds[1]) != 0) {
- conn->endpoint_type = EP_CGI;
- conn->endpoint.nc = ns_add_sock(&conn->server->ns_mgr, fds[0],
- mg_ev_handler, conn);
- conn->endpoint.nc->flags |= MG_CGI_CONN;
- ns_send(conn->ns_conn, cgi_status, sizeof(cgi_status) - 1);
- conn->mg_conn.status_code = 200;
- conn->ns_conn->flags |= NSF_BUFFER_BUT_DONT_SEND;
- // Pass POST data to the CGI process
- conn->endpoint.nc->send_iobuf = conn->ns_conn->recv_iobuf;
- iobuf_init(&conn->ns_conn->recv_iobuf, 0);
- } else {
- closesocket(fds[0]);
- send_http_error(conn, 500, "start_process(%s) failed", prog);
- }
-
-#ifndef _WIN32
- closesocket(fds[1]); // On Windows, CGI stdio thread closes that socket
-#endif
-}
-
-static void on_cgi_data(struct ns_connection *nc) {
- struct connection *conn = (struct connection *) nc->user_data;
- const char *status = "500";
- struct mg_connection c;
-
- if (!conn) return;
-
- // Copy CGI data from CGI socket to the client send buffer
- ns_forward(nc, conn->ns_conn);
-
- // If reply has not been parsed yet, parse it
- if (conn->ns_conn->flags & NSF_BUFFER_BUT_DONT_SEND) {
- struct iobuf *io = &conn->ns_conn->send_iobuf;
- size_t s_len = sizeof(cgi_status) - 1;
- int len = get_request_len(io->buf + s_len, io->len - s_len);
- char buf[MAX_REQUEST_SIZE], *s = buf;
-
- if (len == 0) return;
-
- if (len < 0 || len > (int) sizeof(buf)) {
- len = io->len;
- iobuf_remove(io, io->len);
- send_http_error(conn, 500, "CGI program sent malformed headers: [%.*s]",
- len, io->buf);
- } else {
- memset(&c, 0, sizeof(c));
- memcpy(buf, io->buf + s_len, len);
- buf[len - 1] = '\0';
- parse_http_headers(&s, &c);
- if (mg_get_header(&c, "Location") != NULL) {
- status = "302";
- } else if ((status = (char *) mg_get_header(&c, "Status")) == NULL) {
- status = "200";
- }
- memcpy(io->buf + 9, status, 3);
- conn->mg_conn.status_code = atoi(status);
- }
- conn->ns_conn->flags &= ~NSF_BUFFER_BUT_DONT_SEND;
- }
-}
-#endif // !MONGOOSE_NO_CGI
-
-static char *mg_strdup(const char *str) {
- char *copy = (char *) NS_MALLOC(strlen(str) + 1);
- if (copy != NULL) {
- strcpy(copy, str);
- }
- return copy;
-}
-
-static int isbyte(int n) {
- return n >= 0 && n <= 255;
-}
-
-static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
- int n, a, b, c, d, slash = 32, len = 0;
-
- if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5 ||
- sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) &&
- isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) &&
- slash >= 0 && slash < 33) {
- len = n;
- *net = ((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | d;
- *mask = slash ? 0xffffffffU << (32 - slash) : 0;
- }
-
- return len;
-}
-
-// Verify given socket address against the ACL.
-// Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
-static int check_acl(const char *acl, uint32_t remote_ip) {
- int allowed, flag;
- uint32_t net, mask;
- struct vec vec;
-
- // If any ACL is set, deny by default
- allowed = acl == NULL ? '+' : '-';
-
- while ((acl = next_option(acl, &vec, NULL)) != NULL) {
- flag = vec.ptr[0];
- if ((flag != '+' && flag != '-') ||
- parse_net(&vec.ptr[1], &net, &mask) == 0) {
- return -1;
- }
-
- if (net == (remote_ip & mask)) {
- allowed = flag;
- }
- }
-
- return allowed == '+';
-}
-
-// Protect against directory disclosure attack by removing '..',
-// excessive '/' and '\' characters
-static void remove_double_dots_and_double_slashes(char *s) {
- char *p = s;
-
- while (*s != '\0') {
- *p++ = *s++;
- if (s[-1] == '/' || s[-1] == '\\') {
- // Skip all following slashes, backslashes and double-dots
- while (s[0] != '\0') {
- if (s[0] == '/' || s[0] == '\\') { s++; }
- else if (s[0] == '.' && (s[1] == '/' || s[1] == '\\')) { s += 2; }
- else if (s[0] == '.' && s[1] == '.' && s[2] == '\0') { s += 2; }
- else if (s[0] == '.' && s[1] == '.' && (s[2] == '/' || s[2] == '\\')) { s += 3; }
- else { break; }
- }
- }
- }
- *p = '\0';
-}
-
-int mg_url_decode(const char *src, size_t src_len, char *dst,
- size_t dst_len, int is_form_url_encoded) {
- size_t i, j = 0;
- int a, b;
-#define HEXTOI(x) (isdigit(x) ? (x) - '0' : (x) - 'W')
-
- for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
- if (src[i] == '%' && i + 2 < src_len &&
- isxdigit(* (const unsigned char *) (src + i + 1)) &&
- isxdigit(* (const unsigned char *) (src + i + 2))) {
- a = tolower(* (const unsigned char *) (src + i + 1));
- b = tolower(* (const unsigned char *) (src + i + 2));
- dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
- i += 2;
- } else if (is_form_url_encoded && src[i] == '+') {
- dst[j] = ' ';
- } else {
- dst[j] = src[i];
- }
- }
-
- dst[j] = '\0'; // Null-terminate the destination
-
- return i >= src_len ? j : -1;
-}
-
-static int is_valid_http_method(const char *s) {
- return !strcmp(s, "GET") || !strcmp(s, "POST") || !strcmp(s, "HEAD") ||
- !strcmp(s, "CONNECT") || !strcmp(s, "PUT") || !strcmp(s, "DELETE") ||
- !strcmp(s, "OPTIONS") || !strcmp(s, "PROPFIND") || !strcmp(s, "MKCOL") ||
- !strcmp(s, "PATCH");
-}
-
-// Parse HTTP request, fill in mg_request structure.
-// This function modifies the buffer by NUL-terminating
-// HTTP request components, header names and header values.
-// Note that len must point to the last \n of HTTP headers.
-static size_t parse_http_message(char *buf, size_t len,
- struct mg_connection *ri) {
- int is_request, n;
-
- // Reset the connection. Make sure that we don't touch fields that are
- // set elsewhere: remote_ip, remote_port, server_param
- ri->request_method = ri->uri = ri->http_version = ri->query_string = NULL;
- ri->num_headers = ri->status_code = ri->is_websocket = ri->content_len = 0;
-
- if (len < 1) return ~0;
-
- buf[len - 1] = '\0';
-
- // RFC says that all initial whitespaces should be ignored
- while (*buf != '\0' && isspace(* (unsigned char *) buf)) {
- buf++;
- }
- ri->request_method = skip(&buf, " ");
- ri->uri = skip(&buf, " ");
- ri->http_version = skip(&buf, "\r\n");
-
- // HTTP message could be either HTTP request or HTTP response, e.g.
- // "GET / HTTP/1.0 ...." or "HTTP/1.0 200 OK ..."
- is_request = is_valid_http_method(ri->request_method);
- if ((is_request && memcmp(ri->http_version, "HTTP/", 5) != 0) ||
- (!is_request && memcmp(ri->request_method, "HTTP/", 5) != 0)) {
- len = ~0;
- } else {
- if (is_request) {
- ri->http_version += 5;
- } else {
- ri->status_code = atoi(ri->uri);
- }
- parse_http_headers(&buf, ri);
-
- if ((ri->query_string = strchr(ri->uri, '?')) != NULL) {
- *(char *) ri->query_string++ = '\0';
- }
- n = (int) strlen(ri->uri);
- mg_url_decode(ri->uri, n, (char *) ri->uri, n + 1, 0);
- if (*ri->uri == '/' || *ri->uri == '.') {
- remove_double_dots_and_double_slashes((char *) ri->uri);
- }
- }
-
- return len;
-}
-
-static int lowercase(const char *s) {
- return tolower(* (const unsigned char *) s);
-}
-
-static int mg_strcasecmp(const char *s1, const char *s2) {
- int diff;
-
- do {
- diff = lowercase(s1++) - lowercase(s2++);
- } while (diff == 0 && s1[-1] != '\0');
-
- return diff;
-}
-
-static int mg_strncasecmp(const char *s1, const char *s2, size_t len) {
- int diff = 0;
-
- if (len > 0)
- do {
- diff = lowercase(s1++) - lowercase(s2++);
- } while (diff == 0 && s1[-1] != '\0' && --len > 0);
-
- return diff;
-}
-
-// Return HTTP header value, or NULL if not found.
-const char *mg_get_header(const struct mg_connection *ri, const char *s) {
- int i;
-
- for (i = 0; i < ri->num_headers; i++)
- if (!mg_strcasecmp(s, ri->http_headers[i].name))
- return ri->http_headers[i].value;
-
- return NULL;
-}
-
-// Perform case-insensitive match of string against pattern
-int mg_match_prefix(const char *pattern, ssize_t pattern_len, const char *str) {
- const char *or_str;
- int len, res, i = 0, j = 0;
-
- if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
- res = mg_match_prefix(pattern, or_str - pattern, str);
- return res > 0 ? res : mg_match_prefix(or_str + 1,
- (pattern + pattern_len) - (or_str + 1), str);
- }
-
- for (; i < pattern_len; i++, j++) {
- if (pattern[i] == '?' && str[j] != '\0') {
- continue;
- } else if (pattern[i] == '$') {
- return str[j] == '\0' ? j : -1;
- } else if (pattern[i] == '*') {
- i++;
- if (pattern[i] == '*') {
- i++;
- len = (int) strlen(str + j);
- } else {
- len = (int) strcspn(str + j, "/");
- }
- if (i == pattern_len) {
- return j + len;
- }
- do {
- res = mg_match_prefix(pattern + i, pattern_len - i, str + j + len);
- } while (res == -1 && len-- > 0);
- return res == -1 ? -1 : j + res + len;
- } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
- return -1;
- }
- }
- return j;
-}
-
-// This function prints HTML pages, and expands "{{something}}" blocks
-// inside HTML by calling appropriate callback functions.
-// Note that {{@path/to/file}} construct outputs embedded file's contents,
-// which provides SSI-like functionality.
-void mg_template(struct mg_connection *conn, const char *s,
- struct mg_expansion *expansions) {
- int i, j, pos = 0, inside_marker = 0;
-
- for (i = 0; s[i] != '\0'; i++) {
- if (inside_marker == 0 && !memcmp(&s[i], "{{", 2)) {
- if (i > pos) {
- mg_send_data(conn, &s[pos], i - pos);
- }
- pos = i;
- inside_marker = 1;
- }
- if (inside_marker == 1 && !memcmp(&s[i], "}}", 2)) {
- for (j = 0; expansions[j].keyword != NULL; j++) {
- const char *kw = expansions[j].keyword;
- if ((int) strlen(kw) == i - (pos + 2) &&
- memcmp(kw, &s[pos + 2], i - (pos + 2)) == 0) {
- expansions[j].handler(conn);
- pos = i + 2;
- break;
- }
- }
- inside_marker = 0;
- }
- }
- if (i > pos) {
- mg_send_data(conn, &s[pos], i - pos);
- }
-}
-
-#ifndef MONGOOSE_NO_FILESYSTEM
-static int is_dav_request(const struct connection *conn) {
- const char *s = conn->mg_conn.request_method;
- return !strcmp(s, "PUT") || !strcmp(s, "DELETE") ||
- !strcmp(s, "MKCOL") || !strcmp(s, "PROPFIND");
-}
-
-static int must_hide_file(struct connection *conn, const char *path) {
- const char *pw_pattern = "**" PASSWORDS_FILE_NAME "$";
- const char *pattern = conn->server->config_options[HIDE_FILES_PATTERN];
- return mg_match_prefix(pw_pattern, strlen(pw_pattern), path) > 0 ||
- (pattern != NULL && mg_match_prefix(pattern, strlen(pattern), path) > 0);
-}
-
-// Return 1 if real file has been found, 0 otherwise
-static int convert_uri_to_file_name(struct connection *conn, char *buf,
- size_t buf_len, file_stat_t *st) {
- struct vec a, b;
- const char *rewrites = conn->server->config_options[URL_REWRITES];
- const char *root =
-#ifndef MONGOOSE_NO_DAV
- is_dav_request(conn) && conn->server->config_options[DAV_ROOT] != NULL ?
- conn->server->config_options[DAV_ROOT] :
-#endif
- conn->server->config_options[DOCUMENT_ROOT];
-#ifndef MONGOOSE_NO_CGI
- const char *cgi_pat = conn->server->config_options[CGI_PATTERN];
- char *p;
-#endif
- const char *uri = conn->mg_conn.uri;
- const char *domain = mg_get_header(&conn->mg_conn, "Host");
- // Important: match_len has to be declared as int, unless rewrites break.
- int match_len, root_len = root == NULL ? 0 : strlen(root);
-
- // Perform virtual hosting rewrites
- if (rewrites != NULL && domain != NULL) {
- const char *colon = strchr(domain, ':');
- size_t domain_len = colon == NULL ? strlen(domain) : colon - domain;
-
- while ((rewrites = next_option(rewrites, &a, &b)) != NULL) {
- if (a.len > 1 && a.ptr[0] == '@' && a.len == domain_len + 1 &&
- mg_strncasecmp(a.ptr + 1, domain, domain_len) == 0) {
- root = b.ptr;
- root_len = b.len;
- break;
- }
- }
- }
-
- // No filesystem access
- if (root == NULL || root_len == 0) return 0;
-
- // Handle URL rewrites
- mg_snprintf(buf, buf_len, "%.*s%s", root_len, root, uri);
- rewrites = conn->server->config_options[URL_REWRITES]; // Re-initialize!
- while ((rewrites = next_option(rewrites, &a, &b)) != NULL) {
- if ((match_len = mg_match_prefix(a.ptr, a.len, uri)) > 0) {
- mg_snprintf(buf, buf_len, "%.*s%s", (int) b.len, b.ptr, uri + match_len);
- break;
- }
- }
-
- if (stat(buf, st) == 0) return 1;
-
-#ifndef MONGOOSE_NO_CGI
- // Support PATH_INFO for CGI scripts.
- for (p = buf + strlen(root) + 2; *p != '\0'; p++) {
- if (*p == '/') {
- *p = '\0';
- if (mg_match_prefix(cgi_pat, strlen(cgi_pat), buf) > 0 &&
- !stat(buf, st)) {
- DBG(("!!!! [%s]", buf));
- *p = '/';
- conn->path_info = mg_strdup(p);
- *p = '\0';
- return 1;
- }
- *p = '/';
- }
- }
-#endif
-
- return 0;
-}
-#endif // MONGOOSE_NO_FILESYSTEM
-
-static int should_keep_alive(const struct mg_connection *conn) {
- struct connection *c = MG_CONN_2_CONN(conn);
- const char *method = conn->request_method;
- const char *http_version = conn->http_version;
- const char *header = mg_get_header(conn, "Connection");
- return method != NULL &&
- (!strcmp(method, "GET") || c->endpoint_type == EP_USER) &&
- ((header != NULL && !mg_strcasecmp(header, "keep-alive")) ||
- (header == NULL && http_version && !strcmp(http_version, "1.1")));
-}
-
-size_t mg_write(struct mg_connection *c, const void *buf, size_t len) {
- struct connection *conn = MG_CONN_2_CONN(c);
- ns_send(conn->ns_conn, buf, len);
- return conn->ns_conn->send_iobuf.len;
-}
-
-void mg_send_status(struct mg_connection *c, int status) {
- struct connection *conn = MG_CONN_2_CONN(c);
- if (c->status_code == 0) {
- c->status_code = status;
- mg_printf(c, "HTTP/1.1 %d %s\r\n", status, status_code_to_str(status));
- }
- conn->ns_conn->flags |= MG_USING_CHUNKED_API;
-}
-
-void mg_send_header(struct mg_connection *c, const char *name, const char *v) {
- struct connection *conn = MG_CONN_2_CONN(c);
- if (c->status_code == 0) {
- c->status_code = 200;
- mg_printf(c, "HTTP/1.1 %d %s\r\n", 200, status_code_to_str(200));
- }
- mg_printf(c, "%s: %s\r\n", name, v);
- conn->ns_conn->flags |= MG_USING_CHUNKED_API;
-}
-
-static void terminate_headers(struct mg_connection *c) {
- struct connection *conn = MG_CONN_2_CONN(c);
- if (!(conn->ns_conn->flags & MG_HEADERS_SENT)) {
- mg_send_header(c, "Transfer-Encoding", "chunked");
- mg_write(c, "\r\n", 2);
- conn->ns_conn->flags |= MG_HEADERS_SENT;
- }
-}
-
-size_t mg_send_data(struct mg_connection *c, const void *data, int data_len) {
- struct connection *conn = MG_CONN_2_CONN(c);
- terminate_headers(c);
- write_chunk(MG_CONN_2_CONN(c), (const char *) data, data_len);
- return conn->ns_conn->send_iobuf.len;
-}
-
-size_t mg_printf_data(struct mg_connection *c, const char *fmt, ...) {
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = mg_vprintf_data(c, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-size_t mg_vprintf_data(struct mg_connection *c, const char *fmt, va_list ap) {
- struct connection *conn = MG_CONN_2_CONN(c);
- int len;
- char mem[IOBUF_SIZE], *buf = mem;
-
- terminate_headers(c);
-
- len = ns_avprintf(&buf, sizeof(mem), fmt, ap);
-
- if (len >= 0) {
- write_chunk((struct connection *) conn, buf, len);
- }
- if (buf != mem && buf != NULL) {
- NS_FREE(buf);
- }
- return conn->ns_conn->send_iobuf.len;
-}
-
-#if !defined(MONGOOSE_NO_WEBSOCKET) || !defined(MONGOOSE_NO_AUTH)
-static int is_big_endian(void) {
- static const int n = 1;
- return ((char *) &n)[0] == 0;
-}
-#endif
-
-#ifndef MONGOOSE_NO_WEBSOCKET
-// START OF SHA-1 code
-// Copyright(c) By Steve Reid <steve@edmweb.com>
-#define SHA1HANDSOFF
-#if defined(__sun)
-#include "solarisfixes.h"
-#endif
-
-union char64long16 { unsigned char c[64]; uint32_t l[16]; };
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-static uint32_t blk0(union char64long16 *block, int i) {
- // Forrest: SHA expect BIG_ENDIAN, swap if LITTLE_ENDIAN
- if (!is_big_endian()) {
- block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) |
- (rol(block->l[i], 8) & 0x00FF00FF);
- }
- return block->l[i];
-}
-
-/* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */
-#undef blk
-#undef R0
-#undef R1
-#undef R2
-#undef R3
-#undef R4
-
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
- ^block->l[(i+2)&15]^block->l[i&15],1))
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(block, i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-typedef struct {
- uint32_t state[5];
- uint32_t count[2];
- unsigned char buffer[64];
-} SHA1_CTX;
-
-static void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) {
- uint32_t a, b, c, d, e;
- union char64long16 block[1];
-
- memcpy(block, buffer, 64);
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- // Erase working structures. The order of operations is important,
- // used to ensure that compiler doesn't optimize those out.
- memset(block, 0, sizeof(block));
- a = b = c = d = e = 0;
- (void) a; (void) b; (void) c; (void) d; (void) e;
-}
-
-static void SHA1Init(SHA1_CTX *context) {
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
-}
-
-static void SHA1Update(SHA1_CTX *context, const unsigned char *data,
- size_t len) {
- size_t i, j;
-
- j = context->count[0];
- if ((context->count[0] += len << 3) < j)
- context->count[1]++;
- context->count[1] += (len>>29);
- j = (j >> 3) & 63;
- if ((j + len) > 63) {
- memcpy(&context->buffer[j], data, (i = 64-j));
- SHA1Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64) {
- SHA1Transform(context->state, &data[i]);
- }
- j = 0;
- }
- else i = 0;
- memcpy(&context->buffer[j], &data[i], len - i);
-}
-
-static void SHA1Final(unsigned char digest[20], SHA1_CTX *context) {
- unsigned i;
- unsigned char finalcount[8], c;
-
- for (i = 0; i < 8; i++) {
- finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255);
- }
- c = 0200;
- SHA1Update(context, &c, 1);
- while ((context->count[0] & 504) != 448) {
- c = 0000;
- SHA1Update(context, &c, 1);
- }
- SHA1Update(context, finalcount, 8);
- for (i = 0; i < 20; i++) {
- digest[i] = (unsigned char)
- ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
- memset(context, '\0', sizeof(*context));
- memset(&finalcount, '\0', sizeof(finalcount));
-}
-// END OF SHA1 CODE
-
-static void base64_encode(const unsigned char *src, int src_len, char *dst) {
- static const char *b64 =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- int i, j, a, b, c;
-
- for (i = j = 0; i < src_len; i += 3) {
- a = src[i];
- b = i + 1 >= src_len ? 0 : src[i + 1];
- c = i + 2 >= src_len ? 0 : src[i + 2];
-
- dst[j++] = b64[a >> 2];
- dst[j++] = b64[((a & 3) << 4) | (b >> 4)];
- if (i + 1 < src_len) {
- dst[j++] = b64[(b & 15) << 2 | (c >> 6)];
- }
- if (i + 2 < src_len) {
- dst[j++] = b64[c & 63];
- }
- }
- while (j % 4 != 0) {
- dst[j++] = '=';
- }
- dst[j++] = '\0';
-}
-
-static void send_websocket_handshake(struct mg_connection *conn,
- const char *key) {
- static const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- char buf[500], sha[20], b64_sha[sizeof(sha) * 2];
- SHA1_CTX sha_ctx;
-
- mg_snprintf(buf, sizeof(buf), "%s%s", key, magic);
- SHA1Init(&sha_ctx);
- SHA1Update(&sha_ctx, (unsigned char *) buf, strlen(buf));
- SHA1Final((unsigned char *) sha, &sha_ctx);
- base64_encode((unsigned char *) sha, sizeof(sha), b64_sha);
- mg_snprintf(buf, sizeof(buf), "%s%s%s",
- "HTTP/1.1 101 Switching Protocols\r\n"
- "Upgrade: websocket\r\n"
- "Connection: Upgrade\r\n"
- "Sec-WebSocket-Accept: ", b64_sha, "\r\n\r\n");
-
- mg_write(conn, buf, strlen(buf));
-}
-
-static size_t deliver_websocket_frame(struct connection *conn) {
- // Having buf unsigned char * is important, as it is used below in arithmetic
- unsigned char *buf = (unsigned char *) conn->ns_conn->recv_iobuf.buf;
- size_t i, len, buf_len = conn->ns_conn->recv_iobuf.len, frame_len = 0,
- mask_len = 0, header_len = 0, data_len = 0, buffered = 0;
-
- if (buf_len >= 2) {
- len = buf[1] & 127;
- mask_len = buf[1] & 128 ? 4 : 0;
- if (len < 126 && buf_len >= mask_len) {
- data_len = len;
- header_len = 2 + mask_len;
- } else if (len == 126 && buf_len >= 4 + mask_len) {
- header_len = 4 + mask_len;
- data_len = ((((size_t) buf[2]) << 8) + buf[3]);
- } else if (buf_len >= 10 + mask_len) {
- header_len = 10 + mask_len;
- data_len = (size_t) (((uint64_t) htonl(* (uint32_t *) &buf[2])) << 32) +
- htonl(* (uint32_t *) &buf[6]);
- }
- }
-
- frame_len = header_len + data_len;
- buffered = frame_len > 0 && frame_len <= buf_len;
-
- if (buffered) {
- conn->mg_conn.content_len = data_len;
- conn->mg_conn.content = (char *) buf + header_len;
- conn->mg_conn.wsbits = buf[0];
-
- // Apply mask if necessary
- if (mask_len > 0) {
- for (i = 0; i < data_len; i++) {
- buf[i + header_len] ^= (buf + header_len - mask_len)[i % 4];
- }
- }
-
- // Call the handler and remove frame from the iobuf
- if (call_user(conn, MG_REQUEST) == MG_FALSE ||
- (buf[0] & 0x0f) == WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
- conn->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
- }
- iobuf_remove(&conn->ns_conn->recv_iobuf, frame_len);
- }
-
- return buffered;
-}
-
-size_t mg_websocket_write(struct mg_connection *conn, int opcode,
- const char *data, size_t data_len) {
- unsigned char mem[4192], *copy = mem;
- size_t copy_len = 0;
-
- /* Check overflow */
- if (data_len > ~(size_t)0 - (size_t)10) {
- return 0;
- }
-
- if (data_len + 10 > sizeof(mem) &&
- (copy = (unsigned char *) NS_MALLOC(data_len + 10)) == NULL) {
- return 0;
- }
-
- copy[0] = 0x80 + (opcode & 0x0f);
-
- // Frame format: http://tools.ietf.org/html/rfc6455#section-5.2
- if (data_len < 126) {
- // Inline 7-bit length field
- copy[1] = data_len;
- memcpy(copy + 2, data, data_len);
- copy_len = 2 + data_len;
- } else if (data_len <= 0xFFFF) {
- // 16-bit length field
- copy[1] = 126;
- * (uint16_t *) (copy + 2) = (uint16_t) htons((uint16_t) data_len);
- memcpy(copy + 4, data, data_len);
- copy_len = 4 + data_len;
- } else {
- // 64-bit length field
- const uint32_t hi = htonl((uint32_t) ((uint64_t) data_len >> 32));
- const uint32_t lo = htonl(data_len & 0xffffffff);
- copy[1] = 127;
- memcpy(copy+2,&hi,sizeof(hi));
- memcpy(copy+6,&lo,sizeof(lo));
- memcpy(copy + 10, data, data_len);
- copy_len = 10 + data_len;
- }
-
- if (copy_len > 0) {
- mg_write(conn, copy, copy_len);
- }
- if (copy != mem) {
- NS_FREE(copy);
- }
-
- // If we send closing frame, schedule a connection to be closed after
- // data is drained to the client.
- if (opcode == WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
- MG_CONN_2_CONN(conn)->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
- }
-
- return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len;
-}
-
-size_t mg_websocket_printf(struct mg_connection *conn, int opcode,
- const char *fmt, ...) {
- char mem[4192], *buf = mem;
- va_list ap;
- int len;
-
- va_start(ap, fmt);
- if ((len = ns_avprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
- mg_websocket_write(conn, opcode, buf, len);
- }
- va_end(ap);
-
- if (buf != mem && buf != NULL) {
- NS_FREE(buf);
- }
-
- return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len;
-}
-
-static void send_websocket_handshake_if_requested(struct mg_connection *conn) {
- const char *ver = mg_get_header(conn, "Sec-WebSocket-Version"),
- *key = mg_get_header(conn, "Sec-WebSocket-Key");
- if (ver != NULL && key != NULL) {
- conn->is_websocket = 1;
- if (call_user(MG_CONN_2_CONN(conn), MG_WS_HANDSHAKE) == MG_FALSE) {
- send_websocket_handshake(conn, key);
- }
- call_user(MG_CONN_2_CONN(conn), MG_WS_CONNECT);
- }
-}
-
-static void ping_idle_websocket_connection(struct connection *conn, time_t t) {
- if (t - conn->ns_conn->last_io_time > MONGOOSE_USE_WEBSOCKET_PING_INTERVAL) {
- mg_websocket_write(&conn->mg_conn, WEBSOCKET_OPCODE_PING, "", 0);
- }
-}
-#else
-#define ping_idle_websocket_connection(conn, t)
-#endif // !MONGOOSE_NO_WEBSOCKET
-
-static void write_terminating_chunk(struct connection *conn) {
- mg_write(&conn->mg_conn, "0\r\n\r\n", 5);
-}
-
-static int call_request_handler(struct connection *conn) {
- int result;
- conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf;
- if ((result = call_user(conn, MG_REQUEST)) == MG_TRUE) {
- if (conn->ns_conn->flags & MG_USING_CHUNKED_API) {
- terminate_headers(&conn->mg_conn);
- write_terminating_chunk(conn);
- }
- close_local_endpoint(conn);
- }
- return result;
-}
-
-const char *mg_get_mime_type(const char *path, const char *default_mime_type) {
- const char *ext;
- size_t i, path_len;
-
- path_len = strlen(path);
-
- for (i = 0; static_builtin_mime_types[i].extension != NULL; i++) {
- ext = path + (path_len - static_builtin_mime_types[i].ext_len);
- if (path_len > static_builtin_mime_types[i].ext_len &&
- mg_strcasecmp(ext, static_builtin_mime_types[i].extension) == 0) {
- return static_builtin_mime_types[i].mime_type;
- }
- }
-
- return default_mime_type;
-}
-
-#ifndef MONGOOSE_NO_FILESYSTEM
-// Convert month to the month number. Return -1 on error, or month number
-static int get_month_index(const char *s) {
- static const char *month_names[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- int i;
-
- for (i = 0; i < (int) ARRAY_SIZE(month_names); i++)
- if (!strcmp(s, month_names[i]))
- return i;
-
- return -1;
-}
-
-static int num_leap_years(int year) {
- return year / 4 - year / 100 + year / 400;
-}
-
-// Parse UTC date-time string, and return the corresponding time_t value.
-static time_t parse_date_string(const char *datetime) {
- static const unsigned short days_before_month[] = {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
- };
- char month_str[32];
- int second, minute, hour, day, month, year, leap_days, days;
- time_t result = (time_t) 0;
-
- if (((sscanf(datetime, "%d/%3s/%d %d:%d:%d",
- &day, month_str, &year, &hour, &minute, &second) == 6) ||
- (sscanf(datetime, "%d %3s %d %d:%d:%d",
- &day, month_str, &year, &hour, &minute, &second) == 6) ||
- (sscanf(datetime, "%*3s, %d %3s %d %d:%d:%d",
- &day, month_str, &year, &hour, &minute, &second) == 6) ||
- (sscanf(datetime, "%d-%3s-%d %d:%d:%d",
- &day, month_str, &year, &hour, &minute, &second) == 6)) &&
- year > 1970 &&
- (month = get_month_index(month_str)) != -1) {
- leap_days = num_leap_years(year) - num_leap_years(1970);
- year -= 1970;
- days = year * 365 + days_before_month[month] + (day - 1) + leap_days;
- result = days * 24 * 3600 + hour * 3600 + minute * 60 + second;
- }
-
- return result;
-}
-
-// Look at the "path" extension and figure what mime type it has.
-// Store mime type in the vector.
-static void get_mime_type(const struct mg_server *server, const char *path,
- struct vec *vec) {
- struct vec ext_vec, mime_vec;
- const char *list, *ext;
- size_t path_len;
-
- path_len = strlen(path);
-
- // Scan user-defined mime types first, in case user wants to
- // override default mime types.
- list = server->config_options[EXTRA_MIME_TYPES];
- while ((list = next_option(list, &ext_vec, &mime_vec)) != NULL) {
- // ext now points to the path suffix
- ext = path + path_len - ext_vec.len;
- if (mg_strncasecmp(ext, ext_vec.ptr, ext_vec.len) == 0) {
- *vec = mime_vec;
- return;
- }
- }
-
- vec->ptr = mg_get_mime_type(path, "text/plain");
- vec->len = strlen(vec->ptr);
-}
-
-static const char *suggest_connection_header(const struct mg_connection *conn) {
- return should_keep_alive(conn) ? "keep-alive" : "close";
-}
-
-static void construct_etag(char *buf, size_t buf_len, const file_stat_t *st) {
- mg_snprintf(buf, buf_len, "\"%lx.%" INT64_FMT "\"",
- (unsigned long) st->st_mtime, (int64_t) st->st_size);
-}
-
-// Return True if we should reply 304 Not Modified.
-static int is_not_modified(const struct connection *conn,
- const file_stat_t *stp) {
- char etag[64];
- const char *ims = mg_get_header(&conn->mg_conn, "If-Modified-Since");
- const char *inm = mg_get_header(&conn->mg_conn, "If-None-Match");
- construct_etag(etag, sizeof(etag), stp);
- return (inm != NULL && !mg_strcasecmp(etag, inm)) ||
- (ims != NULL && stp->st_mtime <= parse_date_string(ims));
-}
-
-// For given directory path, substitute it to valid index file.
-// Return 0 if index file has been found, -1 if not found.
-// If the file is found, it's stats is returned in stp.
-static int find_index_file(struct connection *conn, char *path,
- size_t path_len, file_stat_t *stp) {
- const char *list = conn->server->config_options[INDEX_FILES];
- file_stat_t st;
- struct vec filename_vec;
- size_t n = strlen(path);
- int found = 0;
-
- // The 'path' given to us points to the directory. Remove all trailing
- // directory separator characters from the end of the path, and
- // then append single directory separator character.
- while (n > 0 && path[n - 1] == '/') {
- n--;
- }
- path[n] = '/';
-
- // Traverse index files list. For each entry, append it to the given
- // path and see if the file exists. If it exists, break the loop
- while ((list = next_option(list, &filename_vec, NULL)) != NULL) {
-
- if (path_len <= n + 2) {
- continue;
- }
-
- // Ignore too long entries that may overflow path buffer
- if (filename_vec.len > (path_len - (n + 2)))
- continue;
-
- // Prepare full path to the index file
- strncpy(path + n + 1, filename_vec.ptr, filename_vec.len);
- path[n + 1 + filename_vec.len] = '\0';
-
- //DBG(("[%s]", path));
-
- // Does it exist?
- if (!stat(path, &st)) {
- // Yes it does, break the loop
- *stp = st;
- found = 1;
- break;
- }
- }
-
- // If no index file exists, restore directory path
- if (!found) {
- path[n] = '/';
- path[n + 1] = '\0';
- }
-
- return found;
-}
-
-static int parse_range_header(const char *header, int64_t *a, int64_t *b) {
-// return sscanf(header, "bytes=%" INT64_FMT "-%" INT64_FMT, a, b);
-// return sscanf(header, "bytes=%ld-%ld" INT64_FMT, a, b);
- return 0;
-}
-
-static void gmt_time_string(char *buf, size_t buf_len, time_t *t) {
- strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(t));
-}
-
-static void open_file_endpoint(struct connection *conn, const char *path,
- file_stat_t *st, const char *extra_headers) {
- char date[64], lm[64], etag[64], range[64], headers[1000];
- const char *msg = "OK", *hdr;
- time_t t, curtime = time(NULL);
- int64_t r1, r2;
- struct vec mime_vec;
- int n;
-
- conn->endpoint_type = EP_FILE;
- ns_set_close_on_exec(conn->endpoint.fd);
- conn->mg_conn.status_code = 200;
-
- get_mime_type(conn->server, path, &mime_vec);
- conn->cl = st->st_size;
- range[0] = '\0';
-
- // If Range: header specified, act accordingly
- r1 = r2 = 0;
- hdr = mg_get_header(&conn->mg_conn, "Range");
- if (hdr != NULL && (n = parse_range_header(hdr, &r1, &r2)) > 0 &&
- r1 >= 0 && r2 >= 0) {
- conn->mg_conn.status_code = 206;
- conn->cl = n == 2 ? (r2 > conn->cl ? conn->cl : r2) - r1 + 1: conn->cl - r1;
- mg_snprintf(range, sizeof(range), "Content-Range: bytes "
- "%" INT64_FMT "-%" INT64_FMT "/%" INT64_FMT "\r\n",
- r1, r1 + conn->cl - 1, (int64_t) st->st_size);
- msg = "Partial Content";
- lseek(conn->endpoint.fd, r1, SEEK_SET);
- }
-
- // Prepare Etag, Date, Last-Modified headers. Must be in UTC, according to
- // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
- gmt_time_string(date, sizeof(date), &curtime);
- t = st->st_mtime; // store in local variable for NDK compile
- gmt_time_string(lm, sizeof(lm), &t);
- construct_etag(etag, sizeof(etag), st);
-
- n = mg_snprintf(headers, sizeof(headers),
- "HTTP/1.1 %d %s\r\n"
- "Date: %s\r\n"
- "Last-Modified: %s\r\n"
- "Etag: %s\r\n"
- "Content-Type: %.*s\r\n"
- "Content-Length: %" INT64_FMT "\r\n"
- "Connection: %s\r\n"
- "Accept-Ranges: bytes\r\n"
- "%s%s%s\r\n",
- conn->mg_conn.status_code, msg, date, lm, etag,
- (int) mime_vec.len, mime_vec.ptr, conn->cl,
- suggest_connection_header(&conn->mg_conn),
- range, extra_headers == NULL ? "" : extra_headers,
- MONGOOSE_USE_EXTRA_HTTP_HEADERS);
- ns_send(conn->ns_conn, headers, n);
-
- if (!strcmp(conn->mg_conn.request_method, "HEAD")) {
- conn->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
- close(conn->endpoint.fd);
- conn->endpoint_type = EP_NONE;
- }
-}
-
-void mg_send_file_data(struct mg_connection *c, int fd) {
- struct connection *conn = MG_CONN_2_CONN(c);
- conn->endpoint_type = EP_FILE;
- conn->endpoint.fd = fd;
- ns_set_close_on_exec(conn->endpoint.fd);
-}
-#endif // MONGOOSE_NO_FILESYSTEM
-
-static void call_request_handler_if_data_is_buffered(struct connection *conn) {
-#ifndef MONGOOSE_NO_WEBSOCKET
- if (conn->mg_conn.is_websocket) {
- do { } while (deliver_websocket_frame(conn));
- } else
-#endif
- if (conn->num_bytes_recv >= (conn->cl + conn->request_len) &&
- call_request_handler(conn) == MG_FALSE) {
- open_local_endpoint(conn, 1);
- }
-}
-
-#if !defined(MONGOOSE_NO_DIRECTORY_LISTING) || !defined(MONGOOSE_NO_DAV)
-
-#ifdef _WIN32
-struct dirent {
- char d_name[MAX_PATH_SIZE];
-};
-
-typedef struct DIR {
- HANDLE handle;
- WIN32_FIND_DATAW info;
- struct dirent result;
-} DIR;
-
-// Implementation of POSIX opendir/closedir/readdir for Windows.
-static DIR *opendir(const char *name) {
- DIR *dir = NULL;
- wchar_t wpath[MAX_PATH_SIZE];
- DWORD attrs;
-
- if (name == NULL) {
- SetLastError(ERROR_BAD_ARGUMENTS);
- } else if ((dir = (DIR *) NS_MALLOC(sizeof(*dir))) == NULL) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- } else {
- to_wchar(name, wpath, ARRAY_SIZE(wpath));
- attrs = GetFileAttributesW(wpath);
- if (attrs != 0xFFFFFFFF &&
- ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
- (void) wcscat(wpath, L"\\*");
- dir->handle = FindFirstFileW(wpath, &dir->info);
- dir->result.d_name[0] = '\0';
- } else {
- NS_FREE(dir);
- dir = NULL;
- }
- }
-
- return dir;
-}
-
-static int closedir(DIR *dir) {
- int result = 0;
-
- if (dir != NULL) {
- if (dir->handle != INVALID_HANDLE_VALUE)
- result = FindClose(dir->handle) ? 0 : -1;
-
- NS_FREE(dir);
- } else {
- result = -1;
- SetLastError(ERROR_BAD_ARGUMENTS);
- }
-
- return result;
-}
-
-static struct dirent *readdir(DIR *dir) {
- struct dirent *result = 0;
-
- if (dir) {
- if (dir->handle != INVALID_HANDLE_VALUE) {
- result = &dir->result;
- (void) WideCharToMultiByte(CP_UTF8, 0,
- dir->info.cFileName, -1, result->d_name,
- sizeof(result->d_name), NULL, NULL);
-
- if (!FindNextFileW(dir->handle, &dir->info)) {
- (void) FindClose(dir->handle);
- dir->handle = INVALID_HANDLE_VALUE;
- }
-
- } else {
- SetLastError(ERROR_FILE_NOT_FOUND);
- }
- } else {
- SetLastError(ERROR_BAD_ARGUMENTS);
- }
-
- return result;
-}
-#endif // _WIN32 POSIX opendir/closedir/readdir implementation
-
-static int scan_directory(struct connection *conn, const char *dir,
- struct dir_entry **arr) {
- char path[MAX_PATH_SIZE];
- struct dir_entry *p;
- struct dirent *dp;
- int arr_size = 0, arr_ind = 0, inc = 100;
- DIR *dirp;
-
- *arr = NULL;
- if ((dirp = (opendir(dir))) == NULL) return 0;
-
- while ((dp = readdir(dirp)) != NULL) {
- // Do not show current dir and hidden files
- if (!strcmp(dp->d_name, ".") ||
- !strcmp(dp->d_name, "..") ||
- must_hide_file(conn, dp->d_name)) {
- continue;
- }
- mg_snprintf(path, sizeof(path), "%s%c%s", dir, '/', dp->d_name);
-
- // Resize the array if necessary
- if (arr_ind >= arr_size) {
- if ((p = (struct dir_entry *)
- NS_REALLOC(*arr, (inc + arr_size) * sizeof(**arr))) != NULL) {
- // Memset new chunk to zero, otherwise st_mtime will have garbage which
- // can make strftime() segfault, see
- // http://code.google.com/p/mongoose/issues/detail?id=79
- memset(p + arr_size, 0, sizeof(**arr) * inc);
-
- *arr = p;
- arr_size += inc;
- }
- }
-
- if (arr_ind < arr_size) {
- (*arr)[arr_ind].conn = conn;
- (*arr)[arr_ind].file_name = strdup(dp->d_name);
- stat(path, &(*arr)[arr_ind].st);
- arr_ind++;
- }
- }
- closedir(dirp);
-
- return arr_ind;
-}
-
-size_t mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len) {
- static const char *dont_escape = "._-$,;~()";
- static const char *hex = "0123456789abcdef";
- size_t i = 0, j = 0;
-
- for (i = j = 0; dst_len > 0 && i < s_len && j + 2 < dst_len - 1; i++, j++) {
- if (isalnum(* (const unsigned char *) (src + i)) ||
- strchr(dont_escape, * (const unsigned char *) (src + i)) != NULL) {
- dst[j] = src[i];
- } else if (j + 3 < dst_len) {
- dst[j] = '%';
- dst[j + 1] = hex[(* (const unsigned char *) (src + i)) >> 4];
- dst[j + 2] = hex[(* (const unsigned char *) (src + i)) & 0xf];
- j += 2;
- }
- }
-
- dst[j] = '\0';
- return j;
-}
-#endif // !NO_DIRECTORY_LISTING || !MONGOOSE_NO_DAV
-
-#ifndef MONGOOSE_NO_DIRECTORY_LISTING
-
-static void print_dir_entry(const struct dir_entry *de) {
- char size[64], mod[64], href[MAX_PATH_SIZE * 3];
- int64_t fsize = de->st.st_size;
- int is_dir = S_ISDIR(de->st.st_mode);
- const char *slash = is_dir ? "/" : "";
- time_t t;
-
- if (is_dir) {
- mg_snprintf(size, sizeof(size), "%s", "[DIRECTORY]");
- } else {
- // We use (signed) cast below because MSVC 6 compiler cannot
- // convert unsigned __int64 to double.
- if (fsize < 1024) {
- mg_snprintf(size, sizeof(size), "%d", (int) fsize);
- } else if (fsize < 0x100000) {
- mg_snprintf(size, sizeof(size), "%.1fk", (double) fsize / 1024.0);
- } else if (fsize < 0x40000000) {
- mg_snprintf(size, sizeof(size), "%.1fM", (double) fsize / 1048576);
- } else {
- mg_snprintf(size, sizeof(size), "%.1fG", (double) fsize / 1073741824);
- }
- }
- t = de->st.st_mtime; // store in local variable for NDK compile
- strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", localtime(&t));
- mg_url_encode(de->file_name, strlen(de->file_name), href, sizeof(href));
- mg_printf_data(&de->conn->mg_conn,
- "<tr><td><a href=\"%s%s\">%s%s</a></td>"
- "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
- href, slash, de->file_name, slash, mod, size);
-}
-
-// Sort directory entries by size, or name, or modification time.
-// On windows, __cdecl specification is needed in case if project is built
-// with __stdcall convention. qsort always requires __cdels callback.
-static int __cdecl compare_dir_entries(const void *p1, const void *p2) {
- const struct dir_entry *a = (const struct dir_entry *) p1,
- *b = (const struct dir_entry *) p2;
- const char *qs = a->conn->mg_conn.query_string ?
- a->conn->mg_conn.query_string : "na";
- int cmp_result = 0;
-
- if (S_ISDIR(a->st.st_mode) && !S_ISDIR(b->st.st_mode)) {
- return -1; // Always put directories on top
- } else if (!S_ISDIR(a->st.st_mode) && S_ISDIR(b->st.st_mode)) {
- return 1; // Always put directories on top
- } else if (*qs == 'n') {
- cmp_result = strcmp(a->file_name, b->file_name);
- } else if (*qs == 's') {
- cmp_result = a->st.st_size == b->st.st_size ? 0 :
- a->st.st_size > b->st.st_size ? 1 : -1;
- } else if (*qs == 'd') {
- cmp_result = a->st.st_mtime == b->st.st_mtime ? 0 :
- a->st.st_mtime > b->st.st_mtime ? 1 : -1;
- }
-
- return qs[1] == 'd' ? -cmp_result : cmp_result;
-}
-
-static void send_directory_listing(struct connection *conn, const char *dir) {
- struct dir_entry *arr = NULL;
- int i, num_entries, sort_direction = conn->mg_conn.query_string != NULL &&
- conn->mg_conn.query_string[1] == 'd' ? 'a' : 'd';
-
- mg_send_header(&conn->mg_conn, "Transfer-Encoding", "chunked");
- mg_send_header(&conn->mg_conn, "Content-Type", "text/html; charset=utf-8");
-
- mg_printf_data(&conn->mg_conn,
- "<html><head><title>Index of %s</title>"
- "<style>th {text-align: left;}</style></head>"
- "<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">"
- "<tr><th><a href=\"?n%c\">Name</a></th>"
- "<th><a href=\"?d%c\">Modified</a></th>"
- "<th><a href=\"?s%c\">Size</a></th></tr>"
- "<tr><td colspan=\"3\"><hr></td></tr>",
- conn->mg_conn.uri, conn->mg_conn.uri,
- sort_direction, sort_direction, sort_direction);
-
- num_entries = scan_directory(conn, dir, &arr);
- if (arr) {
- qsort(arr, num_entries, sizeof(arr[0]), compare_dir_entries);
- for (i = 0; i < num_entries; i++) {
- print_dir_entry(&arr[i]);
- NS_FREE(arr[i].file_name);
- }
- NS_FREE(arr);
- }
-
- write_terminating_chunk(conn);
- close_local_endpoint(conn);
-}
-#endif // MONGOOSE_NO_DIRECTORY_LISTING
-
-#ifndef MONGOOSE_NO_DAV
-static void print_props(struct connection *conn, const char *uri,
- file_stat_t *stp) {
- char mtime[64];
- time_t t = stp->st_mtime; // store in local variable for NDK compile
- gmt_time_string(mtime, sizeof(mtime), &t);
- mg_printf(&conn->mg_conn,
- "<d:response>"
- "<d:href>%s</d:href>"
- "<d:propstat>"
- "<d:prop>"
- "<d:resourcetype>%s</d:resourcetype>"
- "<d:getcontentlength>%" INT64_FMT "</d:getcontentlength>"
- "<d:getlastmodified>%s</d:getlastmodified>"
- "</d:prop>"
- "<d:status>HTTP/1.1 200 OK</d:status>"
- "</d:propstat>"
- "</d:response>\n",
- uri, S_ISDIR(stp->st_mode) ? "<d:collection/>" : "",
- (int64_t) stp->st_size, mtime);
-}
-
-static void handle_propfind(struct connection *conn, const char *path,
- file_stat_t *stp, int exists) {
- static const char header[] = "HTTP/1.1 207 Multi-Status\r\n"
- "Connection: close\r\n"
- "Content-Type: text/xml; charset=utf-8\r\n\r\n"
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
- "<d:multistatus xmlns:d='DAV:'>\n";
- static const char footer[] = "</d:multistatus>";
- const char *depth = mg_get_header(&conn->mg_conn, "Depth");
-#ifdef MONGOOSE_NO_DIRECTORY_LISTING
- const char *list_dir = "no";
-#else
- const char *list_dir = conn->server->config_options[ENABLE_DIRECTORY_LISTING];
-#endif
-
- conn->mg_conn.status_code = 207;
-
- // Print properties for the requested resource itself
- if (!exists) {
- conn->mg_conn.status_code = 404;
- mg_printf(&conn->mg_conn, "%s", "HTTP/1.1 404 Not Found\r\n\r\n");
- } else if (S_ISDIR(stp->st_mode) && mg_strcasecmp(list_dir, "yes") != 0) {
- conn->mg_conn.status_code = 403;
- mg_printf(&conn->mg_conn, "%s",
- "HTTP/1.1 403 Directory Listing Denied\r\n\r\n");
- } else {
- ns_send(conn->ns_conn, header, sizeof(header) - 1);
- print_props(conn, conn->mg_conn.uri, stp);
-
- if (S_ISDIR(stp->st_mode) &&
- (depth == NULL || strcmp(depth, "0") != 0)) {
- struct dir_entry *arr = NULL;
- int i, num_entries = scan_directory(conn, path, &arr);
-
- for (i = 0; i < num_entries; i++) {
- char buf[MAX_PATH_SIZE * 3];
- struct dir_entry *de = &arr[i];
- mg_url_encode(de->file_name, strlen(de->file_name), buf, sizeof(buf));
- print_props(conn, buf, &de->st);
- NS_FREE(de->file_name);
- }
- NS_FREE(arr);
- }
- ns_send(conn->ns_conn, footer, sizeof(footer) - 1);
- }
-
- close_local_endpoint(conn);
-}
-
-static void handle_mkcol(struct connection *conn, const char *path) {
- int status_code = 500;
-
- if (conn->mg_conn.content_len > 0) {
- status_code = 415;
- } else if (!mkdir(path, 0755)) {
- status_code = 201;
- } else if (errno == EEXIST) {
- status_code = 405;
- } else if (errno == EACCES) {
- status_code = 403;
- } else if (errno == ENOENT) {
- status_code = 409;
- }
- send_http_error(conn, status_code, NULL);
-}
-
-static int remove_directory(const char *dir) {
- char path[MAX_PATH_SIZE];
- struct dirent *dp;
- file_stat_t st;
- DIR *dirp;
-
- if ((dirp = opendir(dir)) == NULL) return 0;
-
- while ((dp = readdir(dirp)) != NULL) {
- if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
- mg_snprintf(path, sizeof(path), "%s%c%s", dir, '/', dp->d_name);
- stat(path, &st);
- if (S_ISDIR(st.st_mode)) {
- remove_directory(path);
- } else {
- remove(path);
- }
- }
- closedir(dirp);
- rmdir(dir);
-
- return 1;
-}
-
-static void handle_delete(struct connection *conn, const char *path) {
- file_stat_t st;
-
- if (stat(path, &st) != 0) {
- send_http_error(conn, 404, NULL);
- } else if (S_ISDIR(st.st_mode)) {
- remove_directory(path);
- send_http_error(conn, 204, NULL);
- } else if (remove(path) == 0) {
- send_http_error(conn, 204, NULL);
- } else {
- send_http_error(conn, 423, NULL);
- }
-}
-
-// For a given PUT path, create all intermediate subdirectories
-// for given path. Return 0 if the path itself is a directory,
-// or -1 on error, 1 if OK.
-static int put_dir(const char *path) {
- char buf[MAX_PATH_SIZE];
- const char *s, *p;
- file_stat_t st;
-
- // Create intermediate directories if they do not exist
- for (s = p = path + 1; (p = strchr(s, '/')) != NULL; s = ++p) {
- if (p - path >= (int) sizeof(buf)) return -1; // Buffer overflow
- memcpy(buf, path, p - path);
- buf[p - path] = '\0';
- if (stat(buf, &st) != 0 && mkdir(buf, 0755) != 0) return -1;
- if (p[1] == '\0') return 0; // Path is a directory itself
- }
-
- return 1;
-}
-
-static void handle_put(struct connection *conn, const char *path) {
- file_stat_t st;
- const char *range, *cl_hdr = mg_get_header(&conn->mg_conn, "Content-Length");
- int64_t r1, r2;
- int rc;
-
- conn->mg_conn.status_code = !stat(path, &st) ? 200 : 201;
- if ((rc = put_dir(path)) == 0) {
- mg_printf(&conn->mg_conn, "HTTP/1.1 %d OK\r\n\r\n",
- conn->mg_conn.status_code);
- close_local_endpoint(conn);
- } else if (rc == -1) {
- send_http_error(conn, 500, "put_dir: %s", strerror(errno));
- } else if (cl_hdr == NULL) {
- send_http_error(conn, 411, NULL);
- } else if ((conn->endpoint.fd =
- open(path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0644)) < 0) {
- send_http_error(conn, 500, "open(%s): %s", path, strerror(errno));
- } else {
- DBG(("PUT [%s] %lu", path, (unsigned long) conn->ns_conn->recv_iobuf.len));
- conn->endpoint_type = EP_PUT;
- ns_set_close_on_exec(conn->endpoint.fd);
- range = mg_get_header(&conn->mg_conn, "Content-Range");
- conn->cl = to64(cl_hdr);
- r1 = r2 = 0;
- if (range != NULL && parse_range_header(range, &r1, &r2) > 0) {
- conn->mg_conn.status_code = 206;
- lseek(conn->endpoint.fd, r1, SEEK_SET);
- conn->cl = r2 > r1 ? r2 - r1 + 1: conn->cl - r1;
- }
- mg_printf(&conn->mg_conn, "HTTP/1.1 %d OK\r\nContent-Length: 0\r\n\r\n",
- conn->mg_conn.status_code);
- }
-}
-
-static void forward_put_data(struct connection *conn) {
- struct iobuf *io = &conn->ns_conn->recv_iobuf;
- size_t k = conn->cl < (int64_t) io->len ? conn->cl : (int64_t) io->len; // To write
- size_t n = write(conn->endpoint.fd, io->buf, k); // Write them!
- if (n > 0) {
- iobuf_remove(io, n);
- conn->cl -= n;
- }
- if (conn->cl <= 0) {
- close_local_endpoint(conn);
- }
-}
-#endif // MONGOOSE_NO_DAV
-
-static void send_options(struct connection *conn) {
- conn->mg_conn.status_code = 200;
- mg_printf(&conn->mg_conn, "%s",
- "HTTP/1.1 200 OK\r\nAllow: GET, POST, HEAD, CONNECT, PUT, "
- "DELETE, OPTIONS, PROPFIND, MKCOL\r\nDAV: 1\r\n\r\n");
- close_local_endpoint(conn);
-}
-
-#ifndef MONGOOSE_NO_AUTH
-void mg_send_digest_auth_request(struct mg_connection *c) {
- struct connection *conn = MG_CONN_2_CONN(c);
- c->status_code = 401;
- mg_printf(c,
- "HTTP/1.1 401 Unauthorized\r\n"
- "Content-Length: 0\r\n"
- "WWW-Authenticate: Digest qop=\"auth\", "
- "realm=\"%s\", nonce=\"%lu\"\r\n\r\n",
- conn->server->config_options[AUTH_DOMAIN],
- (unsigned long) time(NULL));
- if (conn->cl > 0) {
- conn->ns_conn->flags |= NSF_DISCARD;
- } else {
- close_local_endpoint(conn);
- }
-}
-
-// Use the global passwords file, if specified by auth_gpass option,
-// or search for .htpasswd in the requested directory.
-static FILE *open_auth_file(struct connection *conn, const char *path,
- int is_directory) {
- char name[MAX_PATH_SIZE];
- const char *p, *gpass = conn->server->config_options[GLOBAL_AUTH_FILE];
- FILE *fp = NULL;
-
- if (gpass != NULL) {
- // Use global passwords file
- fp = fopen(gpass, "r");
- } else if (is_directory) {
- mg_snprintf(name, sizeof(name), "%s%c%s", path, '/', PASSWORDS_FILE_NAME);
- fp = fopen(name, "r");
- } else {
- // Try to find .htpasswd in requested directory.
- if ((p = strrchr(path, '/')) == NULL) p = path;
- mg_snprintf(name, sizeof(name), "%.*s%c%s",
- (int) (p - path), path, '/', PASSWORDS_FILE_NAME);
- fp = fopen(name, "r");
- }
-
- return fp;
-}
-
-#if !defined(HAVE_MD5) && !defined(MONGOOSE_NO_AUTH)
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-typedef struct MD5Context {
- uint32_t buf[4];
- uint32_t bits[2];
- unsigned char in[64];
-} MD5_CTX;
-
-static void byteReverse(unsigned char *buf, unsigned longs) {
- uint32_t t;
-
- // Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN
- if (is_big_endian()) {
- do {
- t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- * (uint32_t *) buf = t;
- buf += 4;
- } while (--longs);
- }
-}
-
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-// Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
-// initialization constants.
-static void MD5Init(MD5_CTX *ctx) {
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) {
- register uint32_t a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-static void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len) {
- uint32_t t;
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
- ctx->bits[1]++;
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f;
-
- if (t) {
- unsigned char *p = (unsigned char *) ctx->in + t;
-
- t = 64 - t;
- if (len < t) {
- memcpy(p, buf, len);
- return;
- }
- memcpy(p, buf, t);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += t;
- len -= t;
- }
-
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += 64;
- len -= 64;
- }
-
- memcpy(ctx->in, buf, len);
-}
-
-static void MD5Final(unsigned char digest[16], MD5_CTX *ctx) {
- unsigned count;
- unsigned char *p;
- uint32_t *a;
-
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- p = ctx->in + count;
- *p++ = 0x80;
- count = 64 - 1 - count;
- if (count < 8) {
- memset(p, 0, count);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- memset(ctx->in, 0, 56);
- } else {
- memset(p, 0, count - 8);
- }
- byteReverse(ctx->in, 14);
-
- a = (uint32_t *)ctx->in;
- a[14] = ctx->bits[0];
- a[15] = ctx->bits[1];
-
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- byteReverse((unsigned char *) ctx->buf, 4);
- memcpy(digest, ctx->buf, 16);
- memset((char *) ctx, 0, sizeof(*ctx));
-}
-#endif // !HAVE_MD5
-
-
-
-// Stringify binary data. Output buffer must be twice as big as input,
-// because each byte takes 2 bytes in string representation
-static void bin2str(char *to, const unsigned char *p, size_t len) {
- static const char *hex = "0123456789abcdef";
-
- for (; len--; p++) {
- *to++ = hex[p[0] >> 4];
- *to++ = hex[p[0] & 0x0f];
- }
- *to = '\0';
-}
-
-// Return stringified MD5 hash for list of strings. Buffer must be 33 bytes.
-char *mg_md5(char buf[33], ...) {
- unsigned char hash[16];
- const char *p;
- va_list ap;
- MD5_CTX ctx;
-
- MD5Init(&ctx);
-
- va_start(ap, buf);
- while ((p = va_arg(ap, const char *)) != NULL) {
- MD5Update(&ctx, (const unsigned char *) p, (unsigned) strlen(p));
- }
- va_end(ap);
-
- MD5Final(hash, &ctx);
- bin2str(buf, hash, sizeof(hash));
- return buf;
-}
-
-// Check the user's password, return 1 if OK
-static int check_password(const char *method, const char *ha1, const char *uri,
- const char *nonce, const char *nc, const char *cnonce,
- const char *qop, const char *response) {
- char ha2[32 + 1], expected_response[32 + 1];
-
-#if 0
- // Check for authentication timeout
- if ((unsigned long) time(NULL) - (unsigned long) to64(nonce) > 3600 * 2) {
- return 0;
- }
-#endif
-
- mg_md5(ha2, method, ":", uri, NULL);
- mg_md5(expected_response, ha1, ":", nonce, ":", nc,
- ":", cnonce, ":", qop, ":", ha2, NULL);
-
- return mg_strcasecmp(response, expected_response) == 0 ? MG_TRUE : MG_FALSE;
-}
-
-
-// Authorize against the opened passwords file. Return 1 if authorized.
-int mg_authorize_digest(struct mg_connection *c, FILE *fp) {
- struct connection *conn = MG_CONN_2_CONN(c);
- const char *hdr;
- char line[256], f_user[256], ha1[256], f_domain[256], user[100], nonce[100],
- uri[MAX_REQUEST_SIZE], cnonce[100], resp[100], qop[100], nc[100];
-
- if (c == NULL || fp == NULL) return 0;
- if ((hdr = mg_get_header(c, "Authorization")) == NULL ||
- mg_strncasecmp(hdr, "Digest ", 7) != 0) return 0;
- if (!mg_parse_header(hdr, "username", user, sizeof(user))) return 0;
- if (!mg_parse_header(hdr, "cnonce", cnonce, sizeof(cnonce))) return 0;
- if (!mg_parse_header(hdr, "response", resp, sizeof(resp))) return 0;
- if (!mg_parse_header(hdr, "uri", uri, sizeof(uri))) return 0;
- if (!mg_parse_header(hdr, "qop", qop, sizeof(qop))) return 0;
- if (!mg_parse_header(hdr, "nc", nc, sizeof(nc))) return 0;
- if (!mg_parse_header(hdr, "nonce", nonce, sizeof(nonce))) return 0;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
- if (sscanf(line, "%[^:]:%[^:]:%s", f_user, f_domain, ha1) == 3 &&
- !strcmp(user, f_user) &&
- // NOTE(lsm): due to a bug in MSIE, we do not compare URIs
- !strcmp(conn->server->config_options[AUTH_DOMAIN], f_domain))
- return check_password(c->request_method, ha1, uri,
- nonce, nc, cnonce, qop, resp);
- }
- return MG_FALSE;
-}
-
-
-// Return 1 if request is authorised, 0 otherwise.
-static int is_authorized(struct connection *conn, const char *path,
- int is_directory) {
- FILE *fp;
- int authorized = MG_TRUE;
-
- if ((fp = open_auth_file(conn, path, is_directory)) != NULL) {
- authorized = mg_authorize_digest(&conn->mg_conn, fp);
- fclose(fp);
- }
-
- return authorized;
-}
-
-static int is_authorized_for_dav(struct connection *conn) {
- const char *auth_file = conn->server->config_options[DAV_AUTH_FILE];
- const char *method = conn->mg_conn.request_method;
- FILE *fp;
- int authorized = MG_FALSE;
-
- // If dav_auth_file is not set, allow non-authorized PROPFIND
- if (method != NULL && !strcmp(method, "PROPFIND") && auth_file == NULL) {
- authorized = MG_TRUE;
- } else if (auth_file != NULL && (fp = fopen(auth_file, "r")) != NULL) {
- authorized = mg_authorize_digest(&conn->mg_conn, fp);
- fclose(fp);
- }
-
- return authorized;
-}
-#endif // MONGOOSE_NO_AUTH
-
-static int parse_header(const char *str, size_t str_len, const char *var_name,
- char *buf, size_t buf_size) {
- int ch = ' ', ch1 = ',', len = 0;
- size_t n = strlen(var_name);
- const char *p, *end = str + str_len, *s = NULL;
-
- if (buf != NULL && buf_size > 0) buf[0] = '\0';
-
- // Find where variable starts
- for (s = str; s != NULL && s + n < end; s++) {
- if ((s == str || s[-1] == ch || s[-1] == ch1) && s[n] == '=' &&
- !memcmp(s, var_name, n)) break;
- }
-
- if (s != NULL && &s[n + 1] < end) {
- s += n + 1;
- if (*s == '"' || *s == '\'') ch = ch1 = *s++;
- p = s;
- while (p < end && p[0] != ch && p[0] != ch1 && len < (int) buf_size) {
- if (ch == ch1 && p[0] == '\\' && p[1] == ch) p++;
- buf[len++] = *p++;
- }
- if (len >= (int) buf_size || (ch != ' ' && *p != ch)) {
- len = 0;
- } else {
- if (len > 0 && s[len - 1] == ',') len--;
- if (len > 0 && s[len - 1] == ';') len--;
- buf[len] = '\0';
- }
- }
-
- return len;
-}
-
-int mg_parse_header(const char *s, const char *var_name, char *buf,
- size_t buf_size) {
- return parse_header(s, s == NULL ? 0 : strlen(s), var_name, buf, buf_size);
-}
-
-#ifndef MONGOOSE_NO_SSI
-static void send_ssi_file(struct mg_connection *, const char *, FILE *, int);
-
-static void send_file_data(struct mg_connection *conn, FILE *fp) {
- char buf[IOBUF_SIZE];
- size_t n;
- while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
- mg_write(conn, buf, n);
- }
-}
-
-static void do_ssi_include(struct mg_connection *conn, const char *ssi,
- char *tag, int include_level) {
- char file_name[IOBUF_SIZE], path[MAX_PATH_SIZE], *p;
- char **opts = (MG_CONN_2_CONN(conn))->server->config_options;
- FILE *fp;
-
- // sscanf() is safe here, since send_ssi_file() also uses buffer
- // of size MG_BUF_LEN to get the tag. So strlen(tag) is always < MG_BUF_LEN.
- if (sscanf(tag, " virtual=\"%[^\"]\"", file_name) == 1) {
- // File name is relative to the webserver root
- mg_snprintf(path, sizeof(path), "%s%c%s",
- opts[DOCUMENT_ROOT], '/', file_name);
- } else if (sscanf(tag, " abspath=\"%[^\"]\"", file_name) == 1) {
- // File name is relative to the webserver working directory
- // or it is absolute system path
- mg_snprintf(path, sizeof(path), "%s", file_name);
- } else if (sscanf(tag, " file=\"%[^\"]\"", file_name) == 1 ||
- sscanf(tag, " \"%[^\"]\"", file_name) == 1) {
- // File name is relative to the current document
- mg_snprintf(path, sizeof(path), "%s", ssi);
- if ((p = strrchr(path, '/')) != NULL) {
- p[1] = '\0';
- }
- mg_snprintf(path + strlen(path), sizeof(path) - strlen(path), "%s",
- file_name);
- } else {
- mg_printf(conn, "Bad SSI #include: [%s]", tag);
- return;
- }
-
- if ((fp = fopen(path, "rb")) == NULL) {
- mg_printf(conn, "Cannot open SSI #include: [%s]: fopen(%s): %s",
- tag, path, strerror(errno));
- } else {
- ns_set_close_on_exec(fileno(fp));
- if (mg_match_prefix(opts[SSI_PATTERN], strlen(opts[SSI_PATTERN]),
- path) > 0) {
- send_ssi_file(conn, path, fp, include_level + 1);
- } else {
- send_file_data(conn, fp);
- }
- fclose(fp);
- }
-}
-
-#ifndef MONGOOSE_NO_POPEN
-static void do_ssi_exec(struct mg_connection *conn, char *tag) {
- char cmd[IOBUF_SIZE];
- FILE *fp;
-
- if (sscanf(tag, " \"%[^\"]\"", cmd) != 1) {
- mg_printf(conn, "Bad SSI #exec: [%s]", tag);
- } else if ((fp = popen(cmd, "r")) == NULL) {
- mg_printf(conn, "Cannot SSI #exec: [%s]: %s", cmd, strerror(errno));
- } else {
- send_file_data(conn, fp);
- pclose(fp);
- }
-}
-#endif // !MONGOOSE_NO_POPEN
-
-static void send_ssi_file(struct mg_connection *conn, const char *path,
- FILE *fp, int include_level) {
- char buf[IOBUF_SIZE];
- int ch, offset, len, in_ssi_tag;
-
- if (include_level > 10) {
- mg_printf(conn, "SSI #include level is too deep (%s)", path);
- return;
- }
-
- in_ssi_tag = len = offset = 0;
- while ((ch = fgetc(fp)) != EOF) {
- if (in_ssi_tag && ch == '>') {
- in_ssi_tag = 0;
- buf[len++] = (char) ch;
- buf[len] = '\0';
- assert(len <= (int) sizeof(buf));
- if (len < 6 || memcmp(buf, "<!--#", 5) != 0) {
- // Not an SSI tag, pass it
- (void) mg_write(conn, buf, (size_t) len);
- } else {
- if (!memcmp(buf + 5, "include", 7)) {
- do_ssi_include(conn, path, buf + 12, include_level);
-#if !defined(MONGOOSE_NO_POPEN)
- } else if (!memcmp(buf + 5, "exec", 4)) {
- do_ssi_exec(conn, buf + 9);
-#endif // !NO_POPEN
- } else {
- mg_printf(conn, "%s: unknown SSI " "command: \"%s\"", path, buf);
- }
- }
- len = 0;
- } else if (in_ssi_tag) {
- if (len == 5 && memcmp(buf, "<!--#", 5) != 0) {
- // Not an SSI tag
- in_ssi_tag = 0;
- } else if (len == (int) sizeof(buf) - 2) {
- mg_printf(conn, "%s: SSI tag is too large", path);
- len = 0;
- }
- buf[len++] = ch & 0xff;
- } else if (ch == '<') {
- in_ssi_tag = 1;
- if (len > 0) {
- mg_write(conn, buf, (size_t) len);
- }
- len = 0;
- buf[len++] = ch & 0xff;
- } else {
- buf[len++] = ch & 0xff;
- if (len == (int) sizeof(buf)) {
- mg_write(conn, buf, (size_t) len);
- len = 0;
- }
- }
- }
-
- // Send the rest of buffered data
- if (len > 0) {
- mg_write(conn, buf, (size_t) len);
- }
-}
-
-static void handle_ssi_request(struct connection *conn, const char *path) {
- FILE *fp;
- struct vec mime_vec;
-
- if ((fp = fopen(path, "rb")) == NULL) {
- send_http_error(conn, 500, "fopen(%s): %s", path, strerror(errno));
- } else {
- ns_set_close_on_exec(fileno(fp));
- get_mime_type(conn->server, path, &mime_vec);
- conn->mg_conn.status_code = 200;
- mg_printf(&conn->mg_conn,
- "HTTP/1.1 %d OK\r\n"
- "Content-Type: %.*s\r\n"
- "Connection: close\r\n\r\n",
- conn->mg_conn.status_code, (int) mime_vec.len, mime_vec.ptr);
- send_ssi_file(&conn->mg_conn, path, fp, 0);
- fclose(fp);
- close_local_endpoint(conn);
- }
-}
-#endif
-
-static void proxy_request(struct ns_connection *pc, struct mg_connection *c) {
- int i, sent_close_header = 0;
-
- ns_printf(pc, "%s %s%s%s HTTP/%s\r\n", c->request_method, c->uri,
- c->query_string ? "?" : "",
- c->query_string ? c->query_string : "",
- c->http_version);
- for (i = 0; i < c->num_headers; i++) {
- if (mg_strcasecmp(c->http_headers[i].name, "Connection") == 0) {
- // Force connection close, cause we don't parse proxy replies
- // therefore we don't know message boundaries
- ns_printf(pc, "%s: %s\r\n", "Connection", "close");
- sent_close_header = 1;
- } else {
- ns_printf(pc, "%s: %s\r\n", c->http_headers[i].name,
- c->http_headers[i].value);
- }
- }
- if (!sent_close_header) {
- ns_printf(pc, "%s: %s\r\n", "Connection", "close");
- }
- ns_printf(pc, "%s", "\r\n");
- ns_send(pc, c->content, c->content_len);
-
-}
-
-#ifdef NS_ENABLE_SSL
-int mg_terminate_ssl(struct mg_connection *c, const char *cert) {
- static const char ok[] = "HTTP/1.0 200 OK\r\n\r\n";
- struct connection *conn = MG_CONN_2_CONN(c);
- SSL_CTX *ctx;
-
- DBG(("%p MITM", conn));
- if ((ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) return 0;
-
- SSL_CTX_use_certificate_file(ctx, cert, 1);
- SSL_CTX_use_PrivateKey_file(ctx, cert, 1);
- SSL_CTX_use_certificate_chain_file(ctx, cert);
-
- // When clear-text reply is pushed to client, switch to SSL mode.
- // TODO(lsm): check for send() failure
- send(conn->ns_conn->sock, ok, sizeof(ok) - 1, 0);
- //DBG(("%p %lu %d SEND", c, (unsigned long) sizeof(ok) - 1, n));
- conn->ns_conn->send_iobuf.len = 0;
- conn->endpoint_type = EP_USER; // To keep-alive in close_local_endpoint()
- close_local_endpoint(conn); // Clean up current CONNECT request
- if ((conn->ns_conn->ssl = SSL_new(ctx)) != NULL) {
- SSL_set_fd(conn->ns_conn->ssl, conn->ns_conn->sock);
- }
- SSL_CTX_free(ctx);
- return 1;
-}
-#endif
-
-int mg_forward(struct mg_connection *c, const char *addr) {
- static const char ok[] = "HTTP/1.1 200 OK\r\n\r\n";
- struct connection *conn = MG_CONN_2_CONN(c);
- struct ns_connection *pc;
-
- if ((pc = ns_connect(&conn->server->ns_mgr, addr,
- mg_ev_handler, conn)) == NULL) {
- conn->ns_conn->flags |= NSF_CLOSE_IMMEDIATELY;
- return 0;
- }
-
- // Interlink two connections
- pc->flags |= MG_PROXY_CONN;
- conn->endpoint_type = EP_PROXY;
- conn->endpoint.nc = pc;
- DBG(("%p [%s] [%s] -> %p %p", conn, c->uri, addr, pc, conn->ns_conn->ssl));
-
- if (strcmp(c->request_method, "CONNECT") == 0) {
- // For CONNECT request, reply with 200 OK. Tunnel is established.
- // TODO(lsm): check for send() failure
- (void) send(conn->ns_conn->sock, ok, sizeof(ok) - 1, 0);
- } else {
- // Strip "http://host:port" part from the URI
- if (memcmp(c->uri, "http://", 7) == 0) c->uri += 7;
- while (*c->uri != '\0' && *c->uri != '/') c->uri++;
- proxy_request(pc, c);
- }
- return 1;
-}
-
-static void proxify_connection(struct connection *conn) {
- char proto[10], host[500], cert[500], addr[1000];
- unsigned short port = 80;
- struct mg_connection *c = &conn->mg_conn;
- int n = 0;
- const char *url = c->uri;
-
- proto[0] = host[0] = cert[0] = '\0';
- if (sscanf(url, "%499[^: ]:%hu%n", host, &port, &n) != 2 &&
- sscanf(url, "%9[a-z]://%499[^: ]:%hu%n", proto, host, &port, &n) != 3 &&
- sscanf(url, "%9[a-z]://%499[^/ ]%n", proto, host, &n) != 2) {
- n = 0;
- }
-
- snprintf(addr, sizeof(addr), "%s://%s:%hu",
- conn->ns_conn->ssl != NULL ? "ssl" : "tcp", host, port);
- if (n <= 0 || !mg_forward(c, addr)) {
- conn->ns_conn->flags |= NSF_CLOSE_IMMEDIATELY;
- }
-}
-
-#ifndef MONGOOSE_NO_FILESYSTEM
-void mg_send_file_internal(struct mg_connection *c, const char *file_name,
- file_stat_t *st, int exists,
- const char *extra_headers) {
- struct connection *conn = MG_CONN_2_CONN(c);
- char path[MAX_PATH_SIZE];
- const int is_directory = S_ISDIR(st->st_mode);
-#ifndef MONGOOSE_NO_CGI
- const char *cgi_pat = conn->server->config_options[CGI_PATTERN];
-#else
- const char *cgi_pat = DEFAULT_CGI_PATTERN;
-#endif
-#ifndef MONGOOSE_NO_DIRECTORY_LISTING
- const char *dir_lst = conn->server->config_options[ENABLE_DIRECTORY_LISTING];
-#else
- const char *dir_lst = "yes";
-#endif
-
- mg_snprintf(path, sizeof(path), "%s", file_name);
-
- if (!exists || must_hide_file(conn, path)) {
- send_http_error(conn, 404, NULL);
- } else if (is_directory &&
- conn->mg_conn.uri[strlen(conn->mg_conn.uri) - 1] != '/') {
- conn->mg_conn.status_code = 301;
- mg_printf(&conn->mg_conn, "HTTP/1.1 301 Moved Permanently\r\n"
- "Location: %s/\r\n\r\n", conn->mg_conn.uri);
- close_local_endpoint(conn);
- } else if (is_directory && !find_index_file(conn, path, sizeof(path), st)) {
- if (!mg_strcasecmp(dir_lst, "yes")) {
-#ifndef MONGOOSE_NO_DIRECTORY_LISTING
- send_directory_listing(conn, path);
-#else
- send_http_error(conn, 501, NULL);
-#endif
- } else {
- send_http_error(conn, 403, NULL);
- }
- } else if (mg_match_prefix(cgi_pat, strlen(cgi_pat), path) > 0) {
-#if !defined(MONGOOSE_NO_CGI)
- open_cgi_endpoint(conn, path);
-#else
- send_http_error(conn, 501, NULL);
-#endif // !MONGOOSE_NO_CGI
-#ifndef MONGOOSE_NO_SSI
- } else if (mg_match_prefix(conn->server->config_options[SSI_PATTERN],
- strlen(conn->server->config_options[SSI_PATTERN]),
- path) > 0) {
- handle_ssi_request(conn, path);
-#endif
- } else if (is_not_modified(conn, st)) {
- send_http_error(conn, 304, NULL);
- } else if ((conn->endpoint.fd = open(path, O_RDONLY | O_BINARY, 0)) != -1) {
- // O_BINARY is required for Windows, otherwise in default text mode
- // two bytes \r\n will be read as one.
- open_file_endpoint(conn, path, st, extra_headers);
- } else {
- send_http_error(conn, 404, NULL);
- }
-}
-void mg_send_file(struct mg_connection *c, const char *file_name,
- const char *extra_headers) {
- file_stat_t st;
- const int exists = stat(file_name, &st) == 0;
- mg_send_file_internal(c, file_name, &st, exists, extra_headers);
-}
-#endif // !MONGOOSE_NO_FILESYSTEM
-
-static void open_local_endpoint(struct connection *conn, int skip_user) {
-#ifndef MONGOOSE_NO_FILESYSTEM
- char path[MAX_PATH_SIZE];
- file_stat_t st;
- int exists = 0;
-#endif
-
- // If EP_USER was set in a prev call, reset it
- conn->endpoint_type = EP_NONE;
-
-#ifndef MONGOOSE_NO_AUTH
- if (conn->server->event_handler && call_user(conn, MG_AUTH) == MG_FALSE) {
- mg_send_digest_auth_request(&conn->mg_conn);
- return;
- }
-#endif
-
- // Call URI handler if one is registered for this URI
- if (skip_user == 0 && conn->server->event_handler != NULL) {
- conn->endpoint_type = EP_USER;
-#if MONGOOSE_POST_SIZE_LIMIT > 1
- {
- const char *cl = mg_get_header(&conn->mg_conn, "Content-Length");
- if ((strcmp(conn->mg_conn.request_method, "POST") == 0 ||
- strcmp(conn->mg_conn.request_method, "PUT") == 0) &&
- (cl == NULL || to64(cl) > MONGOOSE_POST_SIZE_LIMIT)) {
- send_http_error(conn, 500, "POST size > %lu",
- (unsigned long) MONGOOSE_POST_SIZE_LIMIT);
- }
- }
-#endif
- return;
- }
-
- if (strcmp(conn->mg_conn.request_method, "CONNECT") == 0 ||
- mg_strncasecmp(conn->mg_conn.uri, "http", 4) == 0) {
- const char *enp = conn->server->config_options[ENABLE_PROXY];
- if (enp == NULL || strcmp(enp, "yes") != 0) {
- send_http_error(conn, 405, NULL);
- } else {
- proxify_connection(conn);
- }
- return;
- }
-
- if (!strcmp(conn->mg_conn.request_method, "OPTIONS")) {
- send_options(conn);
- return;
- }
-
-#ifdef MONGOOSE_NO_FILESYSTEM
- send_http_error(conn, 404, NULL);
-#else
- exists = convert_uri_to_file_name(conn, path, sizeof(path), &st);
-
- if (!strcmp(conn->mg_conn.request_method, "OPTIONS")) {
- send_options(conn);
- } else if (conn->server->config_options[DOCUMENT_ROOT] == NULL) {
- send_http_error(conn, 404, NULL);
-#ifndef MONGOOSE_NO_AUTH
- } else if ((!is_dav_request(conn) && !is_authorized(conn, path,
- exists && S_ISDIR(st.st_mode))) ||
- (is_dav_request(conn) && !is_authorized_for_dav(conn))) {
- mg_send_digest_auth_request(&conn->mg_conn);
- close_local_endpoint(conn);
-#endif
-#ifndef MONGOOSE_NO_DAV
- } else if (must_hide_file(conn, path)) {
- send_http_error(conn, 404, NULL);
- } else if (!strcmp(conn->mg_conn.request_method, "PROPFIND")) {
- handle_propfind(conn, path, &st, exists);
- } else if (!strcmp(conn->mg_conn.request_method, "MKCOL")) {
- handle_mkcol(conn, path);
- } else if (!strcmp(conn->mg_conn.request_method, "DELETE")) {
- handle_delete(conn, path);
- } else if (!strcmp(conn->mg_conn.request_method, "PUT")) {
- handle_put(conn, path);
-#endif
- } else {
- mg_send_file_internal(&conn->mg_conn, path, &st, exists, NULL);
- }
-#endif // MONGOOSE_NO_FILESYSTEM
-}
-
-static void send_continue_if_expected(struct connection *conn) {
- static const char expect_response[] = "HTTP/1.1 100 Continue\r\n\r\n";
- const char *expect_hdr = mg_get_header(&conn->mg_conn, "Expect");
-
- if (expect_hdr != NULL && !mg_strcasecmp(expect_hdr, "100-continue")) {
- ns_send(conn->ns_conn, expect_response, sizeof(expect_response) - 1);
- }
-}
-
-// Conform to http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
-static int is_valid_uri(const char *uri) {
- unsigned short n;
- return uri[0] == '/' ||
- strcmp(uri, "*") == 0 || // OPTIONS method can use asterisk URI
- mg_strncasecmp(uri, "http", 4) == 0 || // Naive check for the absolute URI
- sscanf(uri, "%*[^ :]:%hu", &n) > 0; // CONNECT method can use host:port
-}
-
-static void try_parse(struct connection *conn) {
- struct iobuf *io = &conn->ns_conn->recv_iobuf;
-
- if (conn->request_len == 0 &&
- (conn->request_len = get_request_len(io->buf, io->len)) > 0) {
- // If request is buffered in, remove it from the iobuf. This is because
- // iobuf could be reallocated, and pointers in parsed request could
- // become invalid.
- conn->request = (char *) NS_MALLOC(conn->request_len);
- if (conn->request == NULL) {
- conn->ns_conn->flags |= NSF_CLOSE_IMMEDIATELY;
- return;
- }
- memcpy(conn->request, io->buf, conn->request_len);
- //DBG(("%p [%.*s]", conn, conn->request_len, conn->request));
- iobuf_remove(io, conn->request_len);
- conn->request_len = parse_http_message(conn->request, conn->request_len,
- &conn->mg_conn);
- if (conn->request_len > 0) {
- const char *cl_hdr = mg_get_header(&conn->mg_conn, "Content-Length");
- conn->cl = cl_hdr == NULL ? 0 : to64(cl_hdr);
- conn->mg_conn.content_len = (size_t) conn->cl;
- }
- }
-}
-
-static void do_proxy(struct connection *conn) {
- if (0 && conn->request_len == 0) {
- try_parse(conn);
- DBG(("%p parsing -> %d", conn, conn->request_len));
- if (conn->request_len > 0 && call_user(conn, MG_REQUEST) == MG_FALSE) {
- proxy_request(conn->endpoint.nc, &conn->mg_conn);
- } else if (conn->request_len < 0) {
- ns_forward(conn->ns_conn, conn->endpoint.nc);
- }
- } else {
- DBG(("%p forwarding", conn));
- ns_forward(conn->ns_conn, conn->endpoint.nc);
- }
-}
-
-static void on_recv_data(struct connection *conn) {
- struct iobuf *io = &conn->ns_conn->recv_iobuf;
- int n;
-
- if (conn->endpoint_type == EP_PROXY) {
- if (conn->endpoint.nc != NULL) do_proxy(conn);
- return;
- }
-
- if (conn->ns_conn->flags & NSF_DISCARD) {
- size_t n = conn->cl;
- if (n > io->len) {
- n = io->len;
- }
- iobuf_remove(io, n);
- conn->cl -= n;
- if (conn->cl == 0) {
- close_local_endpoint(conn);
- }
- return;
- }
-
- try_parse(conn);
- DBG(("%p %d %lu %d", conn, conn->request_len, (unsigned long)io->len,
- conn->ns_conn->flags));
- if (conn->request_len < 0 ||
- (conn->request_len > 0 && !is_valid_uri(conn->mg_conn.uri))) {
- send_http_error(conn, 400, NULL);
- } else if (conn->request_len == 0 && io->len > MAX_REQUEST_SIZE) {
- send_http_error(conn, 413, NULL);
- } else if (conn->request_len > 0 &&
- strcmp(conn->mg_conn.http_version, "1.0") != 0 &&
- strcmp(conn->mg_conn.http_version, "1.1") != 0) {
- send_http_error(conn, 505, NULL);
- } else if (conn->request_len > 0 && conn->endpoint_type == EP_NONE) {
-#ifndef MONGOOSE_NO_WEBSOCKET
- send_websocket_handshake_if_requested(&conn->mg_conn);
-#endif
- send_continue_if_expected(conn);
- open_local_endpoint(conn, 0);
- }
-
-#ifndef MONGOOSE_NO_CGI
- if (conn->endpoint_type == EP_CGI && conn->endpoint.nc != NULL) {
- ns_forward(conn->ns_conn, conn->endpoint.nc);
- }
-#endif
- if (conn->endpoint_type == EP_USER) {
- conn->mg_conn.content = io->buf;
- conn->mg_conn.content_len = io->len;
- n = call_user(conn, MG_RECV);
- if (n < 0) {
- conn->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
- } else if ((size_t) n <= io->len) {
- iobuf_remove(io, n);
- }
- call_request_handler_if_data_is_buffered(conn);
- }
-#ifndef MONGOOSE_NO_DAV
- if (conn->endpoint_type == EP_PUT && io->len > 0) {
- forward_put_data(conn);
- }
-#endif
-}
-
-static void call_http_client_handler(struct connection *conn) {
- //conn->mg_conn.status_code = code;
- // For responses without Content-Lengh, use the whole buffer
- if (conn->cl == 0) {
- conn->mg_conn.content_len = conn->ns_conn->recv_iobuf.len;
- }
- conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf;
- if (call_user(conn, MG_REPLY) == MG_FALSE) {
- conn->ns_conn->flags |= NSF_CLOSE_IMMEDIATELY;
- }
- iobuf_remove(&conn->ns_conn->recv_iobuf, conn->mg_conn.content_len);
- conn->mg_conn.status_code = 0;
- conn->cl = conn->num_bytes_recv = conn->request_len = 0;
- NS_FREE(conn->request);
- conn->request = NULL;
-}
-
-static void process_response(struct connection *conn) {
- struct iobuf *io = &conn->ns_conn->recv_iobuf;
-
- try_parse(conn);
- DBG(("%p %d %lu", conn, conn->request_len, (unsigned long)io->len));
- if (conn->request_len < 0 ||
- (conn->request_len == 0 && io->len > MAX_REQUEST_SIZE)) {
- call_http_client_handler(conn);
- } else if ((int64_t) io->len >= conn->cl) {
- call_http_client_handler(conn);
- }
-}
-
-struct mg_connection *mg_connect(struct mg_server *server, const char *addr) {
- struct ns_connection *nsconn;
- struct connection *conn;
-
- nsconn = ns_connect(&server->ns_mgr, addr, mg_ev_handler, NULL);
- if (nsconn == NULL) return 0;
-
- if ((conn = (struct connection *) NS_CALLOC(1, sizeof(*conn))) == NULL) {
- nsconn->flags |= NSF_CLOSE_IMMEDIATELY;
- return 0;
- }
-
- // Interlink two structs
- conn->ns_conn = nsconn;
- nsconn->user_data = conn;
-
- conn->server = server;
- conn->endpoint_type = EP_CLIENT;
- //conn->handler = handler;
- conn->mg_conn.server_param = server->ns_mgr.user_data;
- conn->ns_conn->flags = NSF_CONNECTING;
-
- return &conn->mg_conn;
-}
-
-#ifndef MONGOOSE_NO_LOGGING
-static void log_header(const struct mg_connection *conn, const char *header,
- FILE *fp) {
- const char *header_value;
-
- if ((header_value = mg_get_header(conn, header)) == NULL) {
- (void) fprintf(fp, "%s", " -");
- } else {
- (void) fprintf(fp, " \"%s\"", header_value);
- }
-}
-
-static void log_access(const struct connection *conn, const char *path) {
- const struct mg_connection *c = &conn->mg_conn;
- FILE *fp = (path == NULL) ? NULL : fopen(path, "a+");
- char date[64], user[100];
- time_t now;
-
- if (fp == NULL) return;
- now = time(NULL);
- strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", localtime(&now));
-
- flockfile(fp);
- mg_parse_header(mg_get_header(&conn->mg_conn, "Authorization"), "username",
- user, sizeof(user));
- fprintf(fp, "%s - %s [%s] \"%s %s%s%s HTTP/%s\" %d 0",
- c->remote_ip, user[0] == '\0' ? "-" : user, date,
- c->request_method ? c->request_method : "-",
- c->uri ? c->uri : "-", c->query_string ? "?" : "",
- c->query_string ? c->query_string : "",
- c->http_version, c->status_code);
- log_header(c, "Referer", fp);
- log_header(c, "User-Agent", fp);
- fputc('\n', fp);
- fflush(fp);
-
- funlockfile(fp);
- fclose(fp);
-}
-#endif
-
-static void close_local_endpoint(struct connection *conn) {
- struct mg_connection *c = &conn->mg_conn;
- // Must be done before free()
- int keep_alive = should_keep_alive(&conn->mg_conn) &&
- (conn->endpoint_type == EP_FILE || conn->endpoint_type == EP_USER);
- DBG(("%p %d %d %d", conn, conn->endpoint_type, keep_alive,
- conn->ns_conn->flags));
-
- switch (conn->endpoint_type) {
- case EP_PUT:
- case EP_FILE:
- close(conn->endpoint.fd);
- break;
- case EP_CGI:
- case EP_PROXY:
- if (conn->endpoint.nc != NULL) {
- DBG(("%p %p %p :-)", conn, conn->ns_conn, conn->endpoint.nc));
- conn->endpoint.nc->flags |= NSF_CLOSE_IMMEDIATELY;
- conn->endpoint.nc->user_data = NULL;
- }
- break;
- default: break;
- }
-
-#ifndef MONGOOSE_NO_LOGGING
- if (c->status_code > 0 && conn->endpoint_type != EP_CLIENT &&
- c->status_code != 400) {
- log_access(conn, conn->server->config_options[ACCESS_LOG_FILE]);
- }
-#endif
-
- // Gobble possible POST data sent to the URI handler
- iobuf_free(&conn->ns_conn->recv_iobuf);
- NS_FREE(conn->request);
- NS_FREE(conn->path_info);
- conn->endpoint.nc = NULL;
- conn->request = conn->path_info = NULL;
-
- conn->endpoint_type = EP_NONE;
- conn->cl = conn->num_bytes_recv = conn->request_len = 0;
- conn->ns_conn->flags &= ~(NSF_FINISHED_SENDING_DATA | NSF_DISCARD |
- NSF_BUFFER_BUT_DONT_SEND | NSF_CLOSE_IMMEDIATELY |
- MG_HEADERS_SENT | MG_USING_CHUNKED_API);
-
- // Do not memset() the whole structure, as some of the fields
- // (IP addresses & ports, server_param) must survive. Nullify the rest.
- c->request_method = c->uri = c->http_version = c->query_string = NULL;
- c->num_headers = c->status_code = c->is_websocket = c->content_len = 0;
- c->callback_param = NULL;
-
- if (keep_alive) {
- on_recv_data(conn); // Can call us recursively if pipelining is used
- } else {
- conn->ns_conn->flags |= conn->ns_conn->send_iobuf.len == 0 ?
- NSF_CLOSE_IMMEDIATELY : NSF_FINISHED_SENDING_DATA;
- }
-}
-
-static void transfer_file_data(struct connection *conn) {
- char buf[IOBUF_SIZE];
- size_t n;
-
- // If output buffer is too big, don't send anything. Wait until
- // mongoose drains already buffered data to the client.
- if (conn->ns_conn->send_iobuf.len > sizeof(buf) * 2) return;
-
- // Do not send anyt
- n = read(conn->endpoint.fd, buf, conn->cl < (int64_t) sizeof(buf) ?
- (int) conn->cl : (int) sizeof(buf));
-
- if (n <= 0) {
- close_local_endpoint(conn);
- } else if (n > 0) {
- conn->cl -= n;
- ns_send(conn->ns_conn, buf, n);
- if (conn->cl <= 0) {
- close_local_endpoint(conn);
- }
- }
-}
-
-time_t mg_poll_server(struct mg_server *server, int milliseconds) {
- return ns_mgr_poll(&server->ns_mgr, milliseconds);
-}
-
-void mg_destroy_server(struct mg_server **server) {
- if (server != NULL && *server != NULL) {
- struct mg_server *s = *server;
- int i;
-
- ns_mgr_free(&s->ns_mgr);
- for (i = 0; i < (int) ARRAY_SIZE(s->config_options); i++) {
- NS_FREE(s->config_options[i]); // It is OK to free(NULL)
- }
- NS_FREE(s);
- *server = NULL;
- }
-}
-
-struct mg_connection *mg_next(struct mg_server *s, struct mg_connection *c) {
- struct ns_connection *nc = ns_next(&s->ns_mgr, c == NULL ? NULL :
- MG_CONN_2_CONN(c)->ns_conn);
- if (nc != NULL && nc->user_data != NULL) {
- return & ((struct connection *) nc->user_data)->mg_conn;
- } else {
- return NULL;
- }
-}
-
-static int get_var(const char *data, size_t data_len, const char *name,
- char *dst, size_t dst_len, int n) {
- const char *p, *e = data + data_len, *s;
- size_t name_len;
- int i = 0, len = -1;
-
- if (dst == NULL || dst_len == 0) {
- len = -2;
- } else if (data == NULL || name == NULL || data_len == 0) {
- dst[0] = '\0';
- } else {
- name_len = strlen(name);
- dst[0] = '\0';
-
- // data is "var1=val1&var2=val2...". Find variable first
- for (p = data; p + name_len < e; p++) {
- if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
- !mg_strncasecmp(name, p, name_len)) {
-
- if (n != i++) continue;
-
- // Point p to variable value
- p += name_len + 1;
-
- // Point s to the end of the value
- s = (const char *) memchr(p, '&', (size_t)(e - p));
- if (s == NULL) {
- s = e;
- }
- assert(s >= p);
-
- // Decode variable into destination buffer
- len = mg_url_decode(p, (size_t)(s - p), dst, dst_len, 1);
-
- // Redirect error code from -1 to -2 (destination buffer too small).
- if (len == -1) {
- len = -2;
- }
- break;
- }
- }
- }
-
- return len;
-}
-
-int mg_get_var_n(const struct mg_connection *conn, const char *name,
- char *dst, size_t dst_len, int n) {
- int len = get_var(conn->query_string, conn->query_string == NULL ? 0 :
- strlen(conn->query_string), name, dst, dst_len, n);
- if (len == -1) {
- len = get_var(conn->content, conn->content_len, name, dst, dst_len, n);
- }
- return len;
-}
-
-int mg_get_var(const struct mg_connection *conn, const char *name,
- char *dst, size_t dst_len) {
- return mg_get_var_n(conn, name, dst, dst_len, 0);
-}
-
-static int get_line_len(const char *buf, int buf_len) {
- int len = 0;
- while (len < buf_len && buf[len] != '\n') len++;
- return buf[len] == '\n' ? len + 1: -1;
-}
-
-int mg_parse_multipart(const char *buf, int buf_len,
- char *var_name, int var_name_len,
- char *file_name, int file_name_len,
- const char **data, int *data_len) {
- static const char cd[] = "Content-Disposition: ";
- //struct mg_connection c;
- int hl, bl, n, ll, pos, cdl = sizeof(cd) - 1;
- //char *p;
-
- if (buf == NULL || buf_len <= 0) return 0;
- if ((hl = get_request_len(buf, buf_len)) <= 0) return 0;
- if (buf[0] != '-' || buf[1] != '-' || buf[2] == '\n') return 0;
-
- // Get boundary length
- bl = get_line_len(buf, buf_len);
-
- // Loop through headers, fetch variable name and file name
- var_name[0] = file_name[0] = '\0';
- for (n = bl; (ll = get_line_len(buf + n, hl - n)) > 0; n += ll) {
- if (mg_strncasecmp(cd, buf + n, cdl) == 0) {
- parse_header(buf + n + cdl, ll - (cdl + 2), "name",
- var_name, var_name_len);
- parse_header(buf + n + cdl, ll - (cdl + 2), "filename",
- file_name, file_name_len);
- }
- }
-
- // Scan body, search for terminating boundary
- for (pos = hl; pos + (bl - 2) < buf_len; pos++) {
- if (buf[pos] == '-' && !memcmp(buf, &buf[pos], bl - 2)) {
- if (data_len != NULL) *data_len = (pos - 2) - hl;
- if (data != NULL) *data = buf + hl;
- return pos;
- }
- }
-
- return 0;
-}
-
-const char **mg_get_valid_option_names(void) {
- return static_config_options;
-}
-
-void mg_copy_listeners(struct mg_server *s, struct mg_server *to) {
- struct ns_connection *c;
- for (c = ns_next(&s->ns_mgr, NULL); c != NULL; c = ns_next(&s->ns_mgr, c)) {
- struct ns_connection *tmp;
- if ((c->flags & NSF_LISTENING) &&
- (tmp = (struct ns_connection *) NS_MALLOC(sizeof(*tmp))) != NULL) {
- memcpy(tmp, c, sizeof(*tmp));
-
-#if defined(NS_ENABLE_SSL) && defined(HEADER_SSL_H)
- /* OpenSSL only. See https://github.com/cesanta/mongoose/issues/441 */
- if (tmp->ssl_ctx != NULL) {
- tmp->ssl_ctx->references++;
- }
-#endif
-
- tmp->mgr = &to->ns_mgr;
- ns_add_conn(tmp->mgr, tmp);
- }
- }
-}
-
-static int get_option_index(const char *name) {
- int i;
-
- for (i = 0; static_config_options[i * 2] != NULL; i++) {
- if (strcmp(static_config_options[i * 2], name) == 0) {
- return i;
- }
- }
- return -1;
-}
-
-static void set_default_option_values(char **opts) {
- const char *value, **all_opts = mg_get_valid_option_names();
- int i;
-
- for (i = 0; all_opts[i * 2] != NULL; i++) {
- value = all_opts[i * 2 + 1];
- if (opts[i] == NULL && value != NULL) {
- opts[i] = mg_strdup(value);
- }
- }
-}
-
-const char *mg_set_option(struct mg_server *server, const char *name,
- const char *value) {
- int ind = get_option_index(name);
- const char *error_msg = NULL;
- char **v = NULL;
-
- if (ind < 0) return "No such option";
- v = &server->config_options[ind];
-
- // Return success immediately if setting to the same value
- if ((*v == NULL && value == NULL) ||
- (value != NULL && *v != NULL && !strcmp(value, *v))) {
- return NULL;
- }
-
- if (*v != NULL) {
- NS_FREE(*v);
- *v = NULL;
- }
-
- if (value == NULL || value[0] == '\0') return NULL;
-
- *v = mg_strdup(value);
- DBG(("%s [%s]", name, *v));
-
- if (ind == LISTENING_PORT) {
- char buf[500] = "";
- size_t n = 0;
- struct vec vec;
-
- /*
- * Ports can be specified as 0, meaning that OS has to choose any
- * free port that is available. In order to pass chosen port number to
- * the user, we rewrite all 0 port to chosen values.
- */
- while ((value = next_option(value, &vec, NULL)) != NULL) {
- struct ns_connection *c = ns_bind(&server->ns_mgr, vec.ptr,
- mg_ev_handler, NULL);
- if (c == NULL) {
- error_msg = "Cannot bind to port";
- break;
- } else {
- char buf2[50], cert[100], ca[100];
- union socket_address sa;
- int proto, use_ssl;
-
- ns_parse_address(vec.ptr, &sa, &proto, &use_ssl, cert, ca);
- ns_sock_to_str(c->sock, buf2, sizeof(buf2),
- memchr(vec.ptr, ':', vec.len) == NULL ? 2 : 3);
-
- n += snprintf(buf + n, sizeof(buf) - n, "%s%s%s%s%s%s%s",
- n > 0 ? "," : "",
- use_ssl ? "ssl://" : "",
- buf2, cert[0] ? ":" : "", cert, ca[0] ? ":" : "", ca);
- }
- }
- buf[sizeof(buf) - 1] = '\0';
- NS_FREE(*v);
- *v = mg_strdup(buf);
-#ifndef MONGOOSE_NO_FILESYSTEM
- } else if (ind == HEXDUMP_FILE) {
- server->ns_mgr.hexdump_file = *v;
-#endif
-#if !defined(_WIN32) && !defined(MONGOOSE_NO_USER)
- } else if (ind == RUN_AS_USER) {
- struct passwd *pw;
- if ((pw = getpwnam(value)) == NULL) {
- error_msg = "Unknown user";
- } else if (setgid(pw->pw_gid) != 0) {
- error_msg = "setgid() failed";
- } else if (setuid(pw->pw_uid) != 0) {
- error_msg = "setuid() failed";
- }
-#endif
- }
-
- return error_msg;
-}
-
-static void set_ips(struct ns_connection *nc, int is_rem) {
- struct connection *conn = (struct connection *) nc->user_data;
- struct mg_connection *c = &conn->mg_conn;
- char buf[100];
-
- ns_sock_to_str(nc->sock, buf, sizeof(buf), is_rem ? 7 : 3);
- sscanf(buf, "%47[^:]:%hu",
- is_rem ? c->remote_ip : c->local_ip,
- is_rem ? &c->remote_port : &c->local_port);
- //DBG(("%p %s %s", conn, is_rem ? "rem" : "loc", buf));
-}
-
-static void on_accept(struct ns_connection *nc, union socket_address *sa) {
- struct mg_server *server = (struct mg_server *) nc->mgr;
- struct connection *conn;
-
- if (!check_acl(server->config_options[ACCESS_CONTROL_LIST],
- ntohl(* (uint32_t *) &sa->sin.sin_addr)) ||
- (conn = (struct connection *) NS_CALLOC(1, sizeof(*conn))) == NULL) {
- nc->flags |= NSF_CLOSE_IMMEDIATELY;
- } else {
- // Circularly link two connection structures
- nc->user_data = conn;
- conn->ns_conn = nc;
-
- // Initialize the rest of connection attributes
- conn->server = server;
- conn->mg_conn.server_param = nc->mgr->user_data;
- set_ips(nc, 1);
- set_ips(nc, 0);
- }
-}
-
-static void process_udp(struct ns_connection *nc) {
- struct iobuf *io = &nc->recv_iobuf;
- struct connection conn;
-
- memset(&conn, 0, sizeof(conn));
- conn.ns_conn = nc;
- conn.server = (struct mg_server *) nc->mgr;
- conn.request_len = parse_http_message(io->buf, io->len, &conn.mg_conn);
- on_recv_data(&conn);
- //ns_printf(nc, "%s", "HTTP/1.0 200 OK\r\n\r\n");
-}
-
-#ifdef MONGOOSE_SEND_NS_EVENTS
-static void send_ns_event(struct ns_connection *nc, int ev, void *p) {
- struct connection *conn = (struct connection *) nc->user_data;
- if (conn != NULL) {
- void *param[2] = { nc, p };
- conn->mg_conn.callback_param = param;
- call_user(conn, (enum mg_event) ev);
- }
-}
-#else
-static void send_ns_event(struct ns_connection *nc, int ev, void *p) {
- (void) nc; (void) p; (void) ev;
-}
-#endif
-
-static void mg_ev_handler(struct ns_connection *nc, int ev, void *p) {
- struct connection *conn = (struct connection *) nc->user_data;
-
- // Send NS event to the handler. Note that call_user won't send an event
- // if conn == NULL. Therefore, repeat this for NS_ACCEPT event as well.
- send_ns_event(nc, ev, p);
-
- switch (ev) {
- case NS_ACCEPT:
- on_accept(nc, (union socket_address *) p);
- send_ns_event(nc, ev, p);
- break;
-
- case NS_CONNECT:
- if (nc->user_data != NULL) {
- set_ips(nc, 1);
- set_ips(nc, 0);
- }
- conn->mg_conn.status_code = * (int *) p;
- if (conn->mg_conn.status_code != 0 ||
- (!(nc->flags & MG_PROXY_CONN) &&
- call_user(conn, MG_CONNECT) == MG_FALSE)) {
- nc->flags |= NSF_CLOSE_IMMEDIATELY;
- }
- break;
-
- case NS_RECV:
- if (conn != NULL) {
- conn->num_bytes_recv += * (int *) p;
- }
-
- if (nc->flags & NSF_UDP) {
- process_udp(nc);
- } else if (nc->listener != NULL) {
- on_recv_data(conn);
-#ifndef MONGOOSE_NO_CGI
- } else if (nc->flags & MG_CGI_CONN) {
- on_cgi_data(nc);
-#endif
- } else if (nc->flags & MG_PROXY_CONN) {
- if (conn != NULL) {
- ns_forward(nc, conn->ns_conn);
- }
- } else {
- process_response(conn);
- }
- break;
-
- case NS_SEND:
- break;
-
- case NS_CLOSE:
- nc->user_data = NULL;
- if (nc->flags & (MG_CGI_CONN | MG_PROXY_CONN)) {
- DBG(("%p %p closing cgi/proxy conn", conn, nc));
- if (conn && conn->ns_conn) {
- conn->ns_conn->flags &= ~NSF_BUFFER_BUT_DONT_SEND;
- conn->ns_conn->flags |= conn->ns_conn->send_iobuf.len > 0 ?
- NSF_FINISHED_SENDING_DATA : NSF_CLOSE_IMMEDIATELY;
- conn->endpoint.nc = NULL;
- }
- } else if (conn != NULL) {
- DBG(("%p %p %d closing", conn, nc, conn->endpoint_type));
-
- if (conn->endpoint_type == EP_CLIENT && nc->recv_iobuf.len > 0) {
- call_http_client_handler(conn);
- }
-
- call_user(conn, MG_CLOSE);
- close_local_endpoint(conn);
- conn->ns_conn = NULL;
- NS_FREE(conn);
- }
- break;
-
- case NS_POLL:
- if (conn != NULL) {
- if (call_user(conn, MG_POLL) == MG_TRUE) {
- if (conn->ns_conn->flags & MG_HEADERS_SENT) {
- write_terminating_chunk(conn);
- }
- close_local_endpoint(conn);
- /*
- * MG_POLL callback returned MG_TRUE,
- * i.e. data is sent, set corresponding flag
- */
- conn->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
- }
-
- if (conn->endpoint_type == EP_FILE) {
- transfer_file_data(conn);
- }
- }
-
- // Expire idle connections
- {
- time_t current_time = * (time_t *) p;
-
- if (conn != NULL && conn->mg_conn.is_websocket) {
- ping_idle_websocket_connection(conn, current_time);
- }
-
- if (nc->listener != NULL &&
- nc->last_io_time + MONGOOSE_IDLE_TIMEOUT_SECONDS < current_time) {
- mg_ev_handler(nc, NS_CLOSE, NULL);
- nc->flags |= NSF_CLOSE_IMMEDIATELY;
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-static void iter2(struct ns_connection *nc, int ev, void *param) {
- mg_handler_t func = NULL;
- struct connection *conn = (struct connection *) nc->user_data;
- const char *msg = (const char *) param;
- int n;
- (void) ev;
-
- //DBG(("%p [%s]", conn, msg));
- if (sscanf(msg, "%p %n", (void **) &func, &n) && func != NULL && conn != NULL) {
- conn->mg_conn.callback_param = (void *) (msg + n);
- func(&conn->mg_conn, MG_POLL);
- }
-}
-
-void mg_wakeup_server_ex(struct mg_server *server, mg_handler_t cb,
- const char *fmt, ...) {
- va_list ap;
- char buf[8 * 1024];
- int len;
-
- // Encode callback (cb) into a buffer
- len = snprintf(buf, sizeof(buf), "%p ", cb);
- va_start(ap, fmt);
- len += vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
- va_end(ap);
-
- // "len + 1" is to include terminating \0 in the message
- ns_broadcast(&server->ns_mgr, iter2, buf, len + 1);
-}
-
-void mg_wakeup_server(struct mg_server *server) {
- ns_broadcast(&server->ns_mgr, NULL, (void *) "", 0);
-}
-
-const char *mg_get_option(const struct mg_server *server, const char *name) {
- const char **opts = (const char **) server->config_options;
- int i = get_option_index(name);
- return i == -1 ? NULL : opts[i] == NULL ? "" : opts[i];
-}
-
-struct mg_server *mg_create_server(void *server_data, mg_handler_t handler) {
- struct mg_server *server = (struct mg_server *) NS_CALLOC(1, sizeof(*server));
- ns_mgr_init(&server->ns_mgr, server_data);
- set_default_option_values(server->config_options);
- server->event_handler = handler;
- return server;
-}
diff --git a/3rdparty/mongoose/mongoose.h b/3rdparty/mongoose/mongoose.h
deleted file mode 100644
index 7d9dc2f4926..00000000000
--- a/3rdparty/mongoose/mongoose.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
-// Copyright (c) 2013-2014 Cesanta Software Limited
-// All rights reserved
-//
-// This software is dual-licensed: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation. For the terms of this
-// license, see <http://www.gnu.org/licenses/>.
-//
-// You are free to use this software under the terms of the GNU General
-// Public License, but WITHOUT ANY WARRANTY; without even the implied
-// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU General Public License for more details.
-//
-// Alternatively, you can license this software under a commercial
-// license, as set out in <http://cesanta.com/>.
-
-#ifndef MONGOOSE_HEADER_INCLUDED
-#define MONGOOSE_HEADER_INCLUDED
-
-#define MONGOOSE_VERSION "5.6"
-
-#include <stdarg.h> // required for va_list
-#include <stdio.h> // required for FILE
-#include <stddef.h> // required for size_t
-#include <sys/types.h> // required for time_t
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-// This structure contains information about HTTP request.
-struct mg_connection {
- const char *request_method; // "GET", "POST", etc
- const char *uri; // URL-decoded URI
- const char *http_version; // E.g. "1.0", "1.1"
- const char *query_string; // URL part after '?', not including '?', or NULL
-
- char remote_ip[48]; // Max IPv6 string length is 45 characters
- char local_ip[48]; // Local IP address
- unsigned short remote_port; // Client's port
- unsigned short local_port; // Local port number
-
- int num_headers; // Number of HTTP headers
- struct mg_header {
- const char *name; // HTTP header name
- const char *value; // HTTP header value
- } http_headers[30];
-
- char *content; // POST (or websocket message) data, or NULL
- size_t content_len; // Data length
-
- int is_websocket; // Connection is a websocket connection
- int status_code; // HTTP status code for HTTP error handler
- int wsbits; // First byte of the websocket frame
- void *server_param; // Parameter passed to mg_create_server()
- void *connection_param; // Placeholder for connection-specific data
- void *callback_param;
-};
-
-struct mg_server; // Opaque structure describing server instance
-enum mg_result { MG_FALSE, MG_TRUE, MG_MORE };
-enum mg_event {
- MG_POLL = 100, // If callback returns MG_TRUE connection closes
- // after all of data is sent
- MG_CONNECT, // If callback returns MG_FALSE, connect fails
- MG_AUTH, // If callback returns MG_FALSE, authentication fails
- MG_REQUEST, // If callback returns MG_FALSE, Mongoose continues with req
- MG_REPLY, // If callback returns MG_FALSE, Mongoose closes connection
- MG_RECV, // Mongoose has received POST data chunk.
- // Callback should return a number of bytes to discard from
- // the receive buffer, or -1 to close the connection.
- MG_CLOSE, // Connection is closed, callback return value is ignored
- MG_WS_HANDSHAKE, // New websocket connection, handshake request
- MG_WS_CONNECT, // New websocket connection established
- MG_HTTP_ERROR // If callback returns MG_FALSE, Mongoose continues with err
-};
-typedef int (*mg_handler_t)(struct mg_connection *, enum mg_event);
-
-// Websocket opcodes, from http://tools.ietf.org/html/rfc6455
-enum {
- WEBSOCKET_OPCODE_CONTINUATION = 0x0,
- WEBSOCKET_OPCODE_TEXT = 0x1,
- WEBSOCKET_OPCODE_BINARY = 0x2,
- WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
- WEBSOCKET_OPCODE_PING = 0x9,
- WEBSOCKET_OPCODE_PONG = 0xa
-};
-
-// Server management functions
-struct mg_server *mg_create_server(void *server_param, mg_handler_t handler);
-void mg_destroy_server(struct mg_server **);
-const char *mg_set_option(struct mg_server *, const char *opt, const char *val);
-time_t mg_poll_server(struct mg_server *, int milliseconds);
-const char **mg_get_valid_option_names(void);
-const char *mg_get_option(const struct mg_server *server, const char *name);
-void mg_copy_listeners(struct mg_server *from, struct mg_server *to);
-struct mg_connection *mg_next(struct mg_server *, struct mg_connection *);
-void mg_wakeup_server(struct mg_server *);
-void mg_wakeup_server_ex(struct mg_server *, mg_handler_t, const char *, ...);
-struct mg_connection *mg_connect(struct mg_server *, const char *);
-
-// Connection management functions
-void mg_send_status(struct mg_connection *, int status_code);
-void mg_send_header(struct mg_connection *, const char *name, const char *val);
-size_t mg_send_data(struct mg_connection *, const void *data, int data_len);
-size_t mg_printf_data(struct mg_connection *, const char *format, ...);
-size_t mg_vprintf_data(struct mg_connection *, const char *format, va_list ap);
-size_t mg_write(struct mg_connection *, const void *buf, size_t len);
-size_t mg_printf(struct mg_connection *conn, const char *fmt, ...);
-size_t mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap);
-
-size_t mg_websocket_write(struct mg_connection *, int opcode,
- const char *data, size_t data_len);
-size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
- const char *fmt, ...);
-
-void mg_send_file(struct mg_connection *, const char *path, const char *);
-void mg_send_file_data(struct mg_connection *, int fd);
-
-const char *mg_get_header(const struct mg_connection *, const char *name);
-const char *mg_get_mime_type(const char *name, const char *default_mime_type);
-int mg_get_var(const struct mg_connection *conn, const char *var_name,
- char *buf, size_t buf_len);
-int mg_get_var_n(const struct mg_connection *conn, const char *var_name,
- char *buf, size_t buf_len, int n);
-int mg_parse_header(const char *hdr, const char *var_name, char *buf, size_t);
-int mg_parse_multipart(const char *buf, int buf_len,
- char *var_name, int var_name_len,
- char *file_name, int file_name_len,
- const char **data, int *data_len);
-
-
-// Utility functions
-void *mg_start_thread(void *(*func)(void *), void *param);
-char *mg_md5(char buf[33], ...);
-int mg_authorize_digest(struct mg_connection *c, FILE *fp);
-size_t mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len);
-int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len, int);
-int mg_terminate_ssl(struct mg_connection *c, const char *cert);
-int mg_forward(struct mg_connection *c, const char *addr);
-void *mg_mmap(FILE *fp, size_t size);
-void mg_munmap(void *p, size_t size);
-
-
-// Templates support
-struct mg_expansion {
- const char *keyword;
- void (*handler)(struct mg_connection *);
-};
-void mg_template(struct mg_connection *, const char *text,
- struct mg_expansion *expansions);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // MONGOOSE_HEADER_INCLUDED
diff --git a/3rdparty/mongoose/scripts/embed_binary_files.pl b/3rdparty/mongoose/scripts/embed_binary_files.pl
deleted file mode 100644
index cf75a0d254c..00000000000
--- a/3rdparty/mongoose/scripts/embed_binary_files.pl
+++ /dev/null
@@ -1,53 +0,0 @@
-# This program is used to embed arbitrary data into a C binary. It takes
-# a list of files as an input, and produces a .c data file that contains
-# contents of all these files as collection of char arrays.
-#
-# Usage: perl <this_file> <file1> [file2, ...] > embedded_data.c
-
-foreach my $i (0 .. $#ARGV) {
- open FD, '<:raw', $ARGV[$i] or die "Cannot open $ARGV[$i]: $!\n";
- printf("static const unsigned char v%d[] = {", $i);
- my $byte;
- my $j = 0;
- while (read(FD, $byte, 1)) {
- if (($j % 12) == 0) {
- print "\n";
- }
- printf ' %#04x,', ord($byte);
- $j++;
- }
- print " 0x00\n};\n";
- close FD;
-}
-
-print <<EOS;
-
-#include <stddef.h>
-#include <string.h>
-
-static const struct embedded_file {
- const char *name;
- const unsigned char *data;
- size_t size;
-} embedded_files[] = {
-EOS
-
-foreach my $i (0 .. $#ARGV) {
- print " {\"$ARGV[$i]\", v$i, sizeof(v$i) - 1},\n";
-}
-
-print <<EOS;
- {NULL, NULL, 0}
-};
-
-const char *find_embedded_file(const char *name, size_t *size) {
- const struct embedded_file *p;
- for (p = embedded_files; p->name != NULL; p++) {
- if (!strcmp(p->name, name)) {
- if (size != NULL) { *size = p->size; }
- return (const char *) p->data;
- }
- }
- return NULL;
-}
-EOS
diff --git a/3rdparty/mongoose/test/Makefile b/3rdparty/mongoose/test/Makefile
deleted file mode 100644
index e749285a509..00000000000
--- a/3rdparty/mongoose/test/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2014 Cesanta Software
-# All rights reserved
-
-PROG = unit_test
-PROF_FLAGS = -fprofile-arcs -ftest-coverage -g -O0 -DGUI
-CFLAGS = -W -Wall -pthread -I.. $(PROF_FLAGS) $(CFLAGS_EXTRA)
-SOURCES = $(PROG).c
-
-all: $(PROG)
- ./$(PROG)
- gcov -b $(PROG).c | egrep '^(File|Lines)'
-
-$(PROG): $(SOURCES) Makefile ../mongoose.c clean
- $(CC) -o $(PROG) $(SOURCES) $(CFLAGS) -ldl -lssl
-
-win:
- wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /Fe$(PROG).exe
- wine $(PROG).exe
-
-clean:
- rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
diff --git a/3rdparty/mongoose/test/unit_test.c b/3rdparty/mongoose/test/unit_test.c
deleted file mode 100644
index 615cb6ad08c..00000000000
--- a/3rdparty/mongoose/test/unit_test.c
+++ /dev/null
@@ -1,533 +0,0 @@
-// Unit test for the mongoose web server.
-// g++ -W -Wall -pedantic -g unit_test.c -lssl && ./a.out
-// cl unit_test.c /MD
-
-#ifndef _WIN32
-#define NS_ENABLE_IPV6
-#define NS_ENABLE_SSL
-#endif
-#define MONGOOSE_POST_SIZE_LIMIT 999
-
-// USE_* definitions must be made before #include "mongoose.c" !
-#include "../mongoose.c"
-
-#define FAIL(str, line) do { \
- printf("Fail on line %d: [%s]\n", line, str); \
- return str; \
-} while (0)
-
-#define ASSERT(expr) do { \
- static_num_tests++; \
- if (!(expr)) FAIL(#expr, __LINE__); \
-} while (0)
-
-#define RUN_TEST(test) do { const char *msg = test(); \
- if (msg) return msg; } while (0)
-
-#define HTTP_PORT "45772"
-#define LISTENING_ADDR "127.0.0.1:" HTTP_PORT
-
-static int static_num_tests = 0;
-
-#if 0
-// Connects to host:port, and sends formatted request to it. Returns
-// malloc-ed reply and reply length, or NULL on error. Reply contains
-// everything including headers, not just the message body.
-static char *wget(const char *host, int port, int *len, const char *fmt, ...) {
- char buf[2000], *reply = NULL;
- int request_len, reply_size = 0, n, sock = -1;
- struct sockaddr_in sin;
- struct hostent *he = NULL;
- va_list ap;
-
- if (host != NULL &&
- (he = gethostbyname(host)) != NULL &&
- (sock = socket(PF_INET, SOCK_STREAM, 0)) != -1) {
- sin.sin_family = AF_INET;
- sin.sin_port = htons((uint16_t) port);
- sin.sin_addr = * (struct in_addr *) he->h_addr_list[0];
- if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) == 0) {
-
- // Format and send the request.
- va_start(ap, fmt);
- request_len = vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- while (request_len > 0 && (n = send(sock, buf, request_len, 0)) > 0) {
- request_len -= n;
- }
- if (request_len == 0) {
- *len = 0;
- while ((n = recv(sock, buf, sizeof(buf), 0)) > 0) {
- if (*len + n > reply_size) {
- // Leak possible
- reply = (char *) realloc(reply, reply_size + sizeof(buf));
- reply_size += sizeof(buf);
- }
- if (reply != NULL) {
- memcpy(reply + *len, buf, n);
- *len += n;
- }
- }
- }
- closesocket(sock);
- }
- }
-
- return reply;
-}
-#endif
-
-static char *read_file(const char *path, int *size) {
- FILE *fp;
- struct stat st;
- char *data = NULL;
- if ((fp = fopen(path, "rb")) != NULL && !fstat(fileno(fp), &st)) {
- *size = (int) st.st_size;
- data = (char *) malloc(*size);
- fread(data, 1, *size, fp);
- fclose(fp);
- }
- return data;
-}
-
-static const char *test_parse_http_message() {
- struct mg_connection ri;
- char req1[] = "GET / HTTP/1.1\r\n\r\n";
- char req2[] = "BLAH / HTTP/1.1\r\n\r\n";
- char req3[] = "GET / HTTP/1.1\r\nBah\r\n";
- char req4[] = "GET / HTTP/1.1\r\nA: foo bar\r\nB: bar\r\nbaz\r\n\r\n";
- char req5[] = "GET / HTTP/1.1\r\n\r\n";
- char req6[] = "G";
- char req7[] = " blah ";
- char req8[] = " HTTP/1.1 200 OK \n\n";
- char req9[] = "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n";
-
- ASSERT(get_request_len("\r\n", 3) == -1);
- ASSERT(get_request_len("\r\n", 2) == 0);
- ASSERT(get_request_len("GET", 3) == 0);
- ASSERT(get_request_len("\n\n", 2) == 2);
- ASSERT(get_request_len("\n\r\n", 3) == 3);
- ASSERT(get_request_len("\xdd\xdd", 2) == 0);
- ASSERT(get_request_len("\xdd\x03", 2) == -1);
- ASSERT(get_request_len(req3, sizeof(req3) - 1) == 0);
- ASSERT(get_request_len(req6, sizeof(req6) - 1) == 0);
- ASSERT(get_request_len(req7, sizeof(req7) - 1) == 0);
-
- ASSERT(parse_http_message(req9, sizeof(req9) - 1, &ri) == sizeof(req9) - 1);
- ASSERT(ri.num_headers == 1);
-
- ASSERT(parse_http_message(req1, sizeof(req1) - 1, &ri) == sizeof(req1) - 1);
- ASSERT(strcmp(ri.http_version, "1.1") == 0);
- ASSERT(ri.num_headers == 0);
-
- ASSERT(parse_http_message(req2, sizeof(req2) - 1, &ri) == (size_t) ~0);
- ASSERT(parse_http_message(req6, 0, &ri) == (size_t) ~0);
- ASSERT(parse_http_message(req8, sizeof(req8) - 1, &ri) == sizeof(req8) - 1);
-
- // TODO(lsm): Fix this. Header value may span multiple lines.
- ASSERT(parse_http_message(req4, sizeof(req4) - 1, &ri) == sizeof(req4) - 1);
- ASSERT(strcmp(ri.http_version, "1.1") == 0);
- ASSERT(ri.num_headers == 3);
- ASSERT(strcmp(ri.http_headers[0].name, "A") == 0);
- ASSERT(strcmp(ri.http_headers[0].value, "foo bar") == 0);
- ASSERT(strcmp(ri.http_headers[1].name, "B") == 0);
- ASSERT(strcmp(ri.http_headers[1].value, "bar") == 0);
- ASSERT(strcmp(ri.http_headers[2].name, "baz\r\n\r") == 0);
- ASSERT(strcmp(ri.http_headers[2].value, "") == 0);
-
- ASSERT(parse_http_message(req5, sizeof(req5) - 1, &ri) == sizeof(req5) - 1);
- ASSERT(strcmp(ri.request_method, "GET") == 0);
- ASSERT(strcmp(ri.http_version, "1.1") == 0);
-
- return NULL;
-}
-
-static const char *test_should_keep_alive(void) {
- struct mg_connection conn;
- char req1[] = "GET / HTTP/1.1\r\n\r\n";
- char req2[] = "GET / HTTP/1.0\r\n\r\n";
- char req3[] = "GET / HTTP/1.1\r\nConnection: close\r\n\r\n";
- char req4[] = "GET / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n";
-
- memset(&conn, 0, sizeof(conn));
- ASSERT(parse_http_message(req1, sizeof(req1) - 1, &conn) == sizeof(req1) - 1);
- ASSERT(should_keep_alive(&conn) != 0);
-
- parse_http_message(req2, sizeof(req2) - 1, &conn);
- ASSERT(should_keep_alive(&conn) == 0);
-
- parse_http_message(req3, sizeof(req3) - 1, &conn);
- ASSERT(should_keep_alive(&conn) == 0);
-
- parse_http_message(req4, sizeof(req4) - 1, &conn);
- ASSERT(should_keep_alive(&conn) != 0);
-
- return NULL;
-}
-
-static const char *test_match_prefix(void) {
- ASSERT(mg_match_prefix("/api", 4, "/api") == 4);
- ASSERT(mg_match_prefix("/a/", 3, "/a/b/c") == 3);
- ASSERT(mg_match_prefix("/a/", 3, "/ab/c") == -1);
- ASSERT(mg_match_prefix("/blog/", 6, "/") == -1);
- ASSERT(mg_match_prefix("/*/", 3, "/ab/c") == 4);
- ASSERT(mg_match_prefix("**", 2, "/a/b/c") == 6);
- ASSERT(mg_match_prefix("/*", 2, "/a/b/c") == 2);
- ASSERT(mg_match_prefix("*/*", 3, "/a/b/c") == 2);
- ASSERT(mg_match_prefix("**/", 3, "/a/b/c") == 5);
- ASSERT(mg_match_prefix("**.foo|**.bar", 13, "a.bar") == 5);
- ASSERT(mg_match_prefix("a|b|cd", 6, "cdef") == 2);
- ASSERT(mg_match_prefix("a|b|c?", 6, "cdef") == 2);
- ASSERT(mg_match_prefix("a|?|cd", 6, "cdef") == 1);
- ASSERT(mg_match_prefix("/a/**.cgi", 9, "/foo/bar/x.cgi") == -1);
- ASSERT(mg_match_prefix("/a/**.cgi", 9, "/a/bar/x.cgi") == 12);
- ASSERT(mg_match_prefix("**/", 3, "/a/b/c") == 5);
- ASSERT(mg_match_prefix("**/$", 4, "/a/b/c") == -1);
- ASSERT(mg_match_prefix("**/$", 4, "/a/b/") == 5);
- ASSERT(mg_match_prefix("$", 1, "") == 0);
- ASSERT(mg_match_prefix("$", 1, "x") == -1);
- ASSERT(mg_match_prefix("*$", 2, "x") == 1);
- ASSERT(mg_match_prefix("/$", 2, "/") == 1);
- ASSERT(mg_match_prefix("**/$", 4, "/a/b/c") == -1);
- ASSERT(mg_match_prefix("**/$", 4, "/a/b/") == 5);
- ASSERT(mg_match_prefix("*", 1, "/hello/") == 0);
- ASSERT(mg_match_prefix("**.a$|**.b$", 11, "/a/b.b/") == -1);
- ASSERT(mg_match_prefix("**.a$|**.b$", 11, "/a/b.b") == 6);
- ASSERT(mg_match_prefix("**.a$|**.b$", 11, "/a/B.A") == 6);
- ASSERT(mg_match_prefix("**o$", 4, "HELLO") == 5);
- return NULL;
-}
-
-static const char *test_remove_double_dots() {
- struct { char before[30], after[30]; } data[] = {
- {"////a", "/a"},
- {"/.....", "/....."},
- {"/......", "/......"},
- {"...", "..."},
- {"/...///", "/.../"},
- {"/a...///", "/a.../"},
- {"/.x", "/.x"},
- {"/\\", "/"},
- {"/a\\", "/a\\"},
- {"/a\\\\...", "/a\\..."},
- {"foo/x..y/././y/../../..", "foo/x..y/y/"},
- {"foo/..x", "foo/..x"},
- };
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(data); i++) {
- remove_double_dots_and_double_slashes(data[i].before);
- ASSERT(strcmp(data[i].before, data[i].after) == 0);
- }
-
- return NULL;
-}
-
-static const char *test_get_var(void) {
- static const char *data = "a=1&&b=2&d&=&c=3%20&e=&k=aa&a=23";
- static const char *data2 = "q=&st=2012%2F11%2F13+17%3A05&et=&team_id=";
- char buf[20];
-
- ASSERT(get_var(data, strlen(data), "a", buf, sizeof(buf), 0) == 1);
- ASSERT(buf[0] == '1' && buf[1] == '\0');
- ASSERT(get_var(data, strlen(data), "a", buf, sizeof(buf), 1) == 2);
- ASSERT(strcmp(buf, "23") == 0);
- ASSERT(get_var(data, strlen(data), "b", buf, sizeof(buf), 0) == 1);
- ASSERT(buf[0] == '2' && buf[1] == '\0');
- ASSERT(get_var(data, strlen(data), "c", buf, sizeof(buf), 0) == 2);
- ASSERT(buf[0] == '3' && buf[1] == ' ' && buf[2] == '\0');
- ASSERT(get_var(data, strlen(data), "e", buf, sizeof(buf), 0) == 0);
- ASSERT(buf[0] == '\0');
-
- ASSERT(get_var(data, strlen(data), "d", buf, sizeof(buf), 0) == -1);
- ASSERT(get_var(data, strlen(data), "c", buf, 2, 0) == -2);
-
- ASSERT(get_var(data, strlen(data), "x", NULL, 10, 0) == -2);
- ASSERT(get_var(data, strlen(data), "x", buf, 0, 0) == -2);
- ASSERT(get_var(data2, strlen(data2), "st", buf, 16, 0) == -2);
- ASSERT(get_var(data2, strlen(data2), "st", buf, 17, 0) == 16);
- return NULL;
-}
-
-static const char *test_url_decode(void) {
- char buf[100];
-
- ASSERT(mg_url_decode("foo", 3, buf, 3, 0) == -1); // No space for \0
- ASSERT(mg_url_decode("foo", 3, buf, 4, 0) == 3);
- ASSERT(strcmp(buf, "foo") == 0);
-
- ASSERT(mg_url_decode("a+", 2, buf, sizeof(buf), 0) == 2);
- ASSERT(strcmp(buf, "a+") == 0);
-
- ASSERT(mg_url_decode("a+", 2, buf, sizeof(buf), 1) == 2);
- ASSERT(strcmp(buf, "a ") == 0);
-
- ASSERT(mg_url_decode("%61", 1, buf, sizeof(buf), 1) == 1);
- printf("[%s]\n", buf);
- ASSERT(strcmp(buf, "%") == 0);
-
- ASSERT(mg_url_decode("%61", 2, buf, sizeof(buf), 1) == 2);
- ASSERT(strcmp(buf, "%6") == 0);
-
- ASSERT(mg_url_decode("%61", 3, buf, sizeof(buf), 1) == 1);
- ASSERT(strcmp(buf, "a") == 0);
- return NULL;
-}
-
-static const char *test_url_encode(void) {
- char buf[100];
- ASSERT(mg_url_encode("", 0, buf, sizeof(buf)) == 0);
- ASSERT(buf[0] == '\0');
- ASSERT(mg_url_encode("foo", 3, buf, sizeof(buf)) == 3);
- ASSERT(strcmp(buf, "foo") == 0);
- ASSERT(mg_url_encode("f o", 3, buf, sizeof(buf)) == 5);
- ASSERT(strcmp(buf, "f%20o") == 0);
- return NULL;
-}
-
-static const char *test_to64(void) {
- ASSERT(to64("0") == 0);
- ASSERT(to64("") == 0);
- ASSERT(to64("123") == 123);
- ASSERT(to64("-34") == -34);
- ASSERT(to64("3566626116") == 3566626116);
- return NULL;
-}
-
-static const char *test_base64_encode(void) {
- const char *in[] = {"a", "ab", "abc", "abcd", NULL};
- const char *out[] = {"YQ==", "YWI=", "YWJj", "YWJjZA=="};
- char buf[100];
- int i;
-
- for (i = 0; in[i] != NULL; i++) {
- base64_encode((unsigned char *) in[i], strlen(in[i]), buf);
- ASSERT(!strcmp(buf, out[i]));
- }
-
- return NULL;
-}
-
-static const char *test_mg_parse_header(void) {
- const char *str = "xx=1 kl yy, ert=234 kl=123, uri=\"/?name=x,y\", "
- "ii=\"12\\\"34\" zz='aa bb',tt=2,gf=\"xx d=1234";
- char buf[20];
- ASSERT(mg_parse_header(str, "yy", buf, sizeof(buf)) == 0);
- ASSERT(mg_parse_header(str, "ert", buf, sizeof(buf)) == 3);
- ASSERT(strcmp(buf, "234") == 0);
- ASSERT(mg_parse_header(str, "ert", buf, 2) == 0);
- ASSERT(mg_parse_header(str, "ert", buf, 3) == 0);
- ASSERT(mg_parse_header(str, "ert", buf, 4) == 3);
- ASSERT(mg_parse_header(str, "gf", buf, sizeof(buf)) == 0);
- ASSERT(mg_parse_header(str, "zz", buf, sizeof(buf)) == 5);
- ASSERT(strcmp(buf, "aa bb") == 0);
- ASSERT(mg_parse_header(str, "d", buf, sizeof(buf)) == 4);
- ASSERT(strcmp(buf, "1234") == 0);
- buf[0] = 'x';
- ASSERT(mg_parse_header(str, "MMM", buf, sizeof(buf)) == 0);
- ASSERT(buf[0] == '\0');
- ASSERT(mg_parse_header(str, "kl", buf, sizeof(buf)) == 3);
- ASSERT(strcmp(buf, "123") == 0);
- ASSERT(mg_parse_header(str, "xx", buf, sizeof(buf)) == 1);
- ASSERT(strcmp(buf, "1") == 0);
- ASSERT(mg_parse_header(str, "ii", buf, sizeof(buf)) == 5);
- ASSERT(strcmp(buf, "12\"34") == 0);
- ASSERT(mg_parse_header(str, "tt", buf, sizeof(buf)) == 1);
- ASSERT(strcmp(buf, "2") == 0);
- ASSERT(mg_parse_header(str, "uri", buf, sizeof(buf)) == 10);
- return NULL;
-}
-
-static const char *test_next_option(void) {
- const char *p, *list = "x/8,/y**=1;2k,z";
- struct vec a, b;
- int i;
-
- ASSERT(next_option(NULL, &a, &b) == NULL);
- for (i = 0, p = list; (p = next_option(p, &a, &b)) != NULL; i++) {
- ASSERT(i != 0 || (a.ptr == list && a.len == 3 && b.len == 0));
- ASSERT(i != 1 || (a.ptr == list + 4 && a.len == 4 && b.ptr == list + 9 &&
- b.len == 4));
-
- ASSERT(i != 2 || (a.ptr == list + 14 && a.len == 1 && b.len == 0));
- }
- return NULL;
-}
-
-static int evh1(struct mg_connection *conn, enum mg_event ev) {
- char *buf = (char *) conn->connection_param;
- int result = MG_FALSE;
-
- switch (ev) {
- case MG_CONNECT:
- mg_printf(conn, "GET %s HTTP/1.0\r\n\r\n",
- buf[0] == '1' ? "/cb1" : "/non_exist");
- result = MG_TRUE;
- break;
- case MG_HTTP_ERROR:
- mg_printf(conn, "HTTP/1.0 404 NF\r\n\r\nERR: %d", conn->status_code);
- result = MG_TRUE;
- break;
- case MG_REQUEST:
- if (!strcmp(conn->uri, "/cb1")) {
- mg_printf(conn, "HTTP/1.0 200 OK\r\n\r\n%s %s %s",
- (char *) conn->server_param,
- buf == NULL ? "?" : "!", conn->remote_ip);
- result = MG_TRUE;
- }
- break;
- case MG_REPLY:
- if (buf != NULL) {
- sprintf(buf + 1, "%.*s", (int) conn->content_len, conn->content);
- }
- break;
- case MG_AUTH:
- result = MG_TRUE;
- break;
- default:
- break;
- }
-
- return result;
-}
-
-static const char *test_server(void) {
- char buf1[100] = "1", buf2[100] = "2";
- struct mg_server *server = mg_create_server((void *) "foo", evh1);
- struct mg_connection *conn;
-
- ASSERT(server != NULL);
- ASSERT(mg_set_option(server, "listening_port", LISTENING_ADDR) == NULL);
- ASSERT(mg_set_option(server, "document_root", ".") == NULL);
-
- ASSERT((conn = mg_connect(server, "127.0.0.1:" HTTP_PORT)) != NULL);
- conn->connection_param = buf1;
- ASSERT((conn = mg_connect(server, "127.0.0.1:" HTTP_PORT)) != NULL);
- conn->connection_param = buf2;
-
- { int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
- ASSERT(strcmp(buf1, "1foo ? 127.0.0.1") == 0);
- ASSERT(strcmp(buf2, "2ERR: 404") == 0);
-
- ASSERT(strcmp(static_config_options[URL_REWRITES * 2], "url_rewrites") == 0);
- mg_destroy_server(&server);
- ASSERT(server == NULL);
- return NULL;
-}
-
-#define DISP "Content-Disposition: form/data; "
-#define CRLF "\r\n"
-#define BOUNDARY "--xyz"
-static const char *test_parse_multipart(void) {
- char a[100], b[100];
- const char *p;
- static const char f1[] = BOUNDARY CRLF DISP "name=f1" CRLF CRLF
- "some_content" CRLF BOUNDARY CRLF
- BOUNDARY CRLF DISP "name=f2; filename=\"foo bar.txt\"" CRLF CRLF
- "another_content" CRLF BOUNDARY CRLF
- "--" CRLF;
- int n, n2, len, f1_len = sizeof(f1) - 1;
-
- ASSERT(mg_parse_multipart("", 0, a, sizeof(a), b, sizeof(b), &p, &len) == 0);
- ASSERT(mg_parse_multipart("a", 1, a, sizeof(a), b, sizeof(b), &p, &len) == 0);
- ASSERT((n = mg_parse_multipart(f1, f1_len, a, sizeof(a),
- b, sizeof(b), &p, &len)) > 0);
- ASSERT(len == 12);
- ASSERT(memcmp(p, "some_content", len) == 0);
- ASSERT(strcmp(a, "f1") == 0);
- ASSERT(b[0] == '\0');
-
- ASSERT((n2 = mg_parse_multipart(f1 + n, f1_len - n, a, sizeof(a),
- b, sizeof(b), &p, &len)) > 0);
- ASSERT(len == 15);
- ASSERT(memcmp(p, "another_content", len) == 0);
- ASSERT(strcmp(a, "f2") == 0);
- ASSERT(strcmp(b, "foo bar.txt") == 0);
-
- ASSERT((n2 = mg_parse_multipart(f1 + n + n2, f1_len - (n + n2), a, sizeof(a),
- b, sizeof(b), &p, &len)) == 0);
-
- return NULL;
-}
-
-static int evh2(struct mg_connection *conn, enum mg_event ev) {
- char *file_data, *cp = (char *) conn->connection_param;
- int file_size, result = MG_FALSE;
-
- switch (ev) {
- case MG_AUTH:
- result = MG_TRUE;
- break;
- case MG_CONNECT:
- mg_printf(conn, "GET /%s HTTP/1.0\r\n\r\n", cp);
- result = MG_TRUE;
- break;
- case MG_REQUEST:
- break;
- case MG_REPLY:
- file_data = read_file("unit_test.c", &file_size);
- sprintf(cp, "%d %s", (size_t) file_size == conn->content_len &&
- memcmp(file_data, conn->content, file_size) == 0 ? 1 : 0,
- conn->query_string == NULL ? "?" : conn->query_string);
- free(file_data);
- break;
- default:
- break;
- }
-
- return result;
-}
-
-static const char *test_mg_set_option(void) {
- struct mg_server *server = mg_create_server(NULL, NULL);
- ASSERT(mg_set_option(server, "listening_port", "0") == NULL);
- ASSERT(mg_get_option(server, "listening_port")[0] != '\0');
- mg_destroy_server(&server);
- return NULL;
-}
-
-static const char *test_rewrites(void) {
- char buf1[100] = "xx", addr[50];
- struct mg_server *server = mg_create_server(NULL, evh2);
- struct mg_connection *conn;
- const char *port;
-
- ASSERT(mg_set_option(server, "listening_port", "0") == NULL);
- ASSERT(mg_set_option(server, "document_root", ".") == NULL);
- ASSERT(mg_set_option(server, "url_rewrites", "/xx=unit_test.c") == NULL);
- ASSERT((port = mg_get_option(server, "listening_port")) != NULL);
- snprintf(addr, sizeof(addr), "127.0.0.1:%s", port);
- ASSERT((conn = mg_connect(server, addr)) != NULL);
- conn->connection_param = buf1;
-
- { int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
-
- ASSERT(strcmp(buf1, "1 ?") == 0);
- mg_destroy_server(&server);
- return NULL;
-}
-
-static const char *run_all_tests(void) {
- RUN_TEST(test_should_keep_alive);
- RUN_TEST(test_match_prefix);
- RUN_TEST(test_remove_double_dots);
- RUN_TEST(test_parse_http_message);
- RUN_TEST(test_to64);
- RUN_TEST(test_url_decode);
- RUN_TEST(test_url_encode);
- RUN_TEST(test_base64_encode);
- RUN_TEST(test_mg_parse_header);
- RUN_TEST(test_get_var);
- RUN_TEST(test_next_option);
- RUN_TEST(test_parse_multipart);
- RUN_TEST(test_mg_set_option);
- RUN_TEST(test_server);
- RUN_TEST(test_rewrites);
- return NULL;
-}
-
-int __cdecl main(void) {
- const char *fail_msg = run_all_tests();
- printf("%s, tests run: %d\n", fail_msg ? "FAIL" : "PASS", static_num_tests);
- return fail_msg == NULL ? EXIT_SUCCESS : EXIT_FAILURE;
-}
diff --git a/scripts/src/3rdparty.lua b/scripts/src/3rdparty.lua
index 1b94702544b..06fbc35e71c 100644
--- a/scripts/src/3rdparty.lua
+++ b/scripts/src/3rdparty.lua
@@ -461,46 +461,6 @@ project "lsqlite3"
}
--------------------------------------------------
--- mongoose library objects
---------------------------------------------------
-
-project "mongoose"
- uuid "ff05b529-2b6f-4166-9dff-5fe2aef89c40"
- kind "StaticLib"
-
- configuration { "vs*" }
- buildoptions {
- "/wd4996", -- warning C4996: 'function': was declared deprecated
- "/wd4100", -- warning C4100: 'xxx' : unreferenced formal parameter
- "/wd4245", -- warning C4245: 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
- "/wd4267", -- warning C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data
- "/wd4244", -- warning C4244: 'argument' : conversion from 'xxx' to 'xxx', possible loss of data
- }
-
- configuration { "vs2015" }
- buildoptions {
- "/wd4456", -- warning C4456: declaration of 'xxx' hides previous local declaration
- }
-
- configuration { }
-
- options {
- "ForceCPP",
- }
- defines {
- "MONGOOSE_ENABLE_THREADS",
- "NS_STACK_SIZE=0"
- }
-
- includedirs {
- MAME_DIR .. "3rdparty/mongoose",
- }
-
- files {
- MAME_DIR .. "3rdparty/mongoose/mongoose.c",
- }
-
---------------------------------------------------
-- jsoncpp library objects
--------------------------------------------------
diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua
index eded02ed368..de4197c84d7 100644
--- a/scripts/src/emu.lua
+++ b/scripts/src/emu.lua
@@ -245,8 +245,6 @@ files {
MAME_DIR .. "src/emu/debug/textbuf.h",
MAME_DIR .. "src/emu/profiler.c",
MAME_DIR .. "src/emu/profiler.h",
- MAME_DIR .. "src/emu/webengine.c",
- MAME_DIR .. "src/emu/webengine.h",
MAME_DIR .. "src/emu/sound/filter.c",
MAME_DIR .. "src/emu/sound/filter.h",
MAME_DIR .. "src/devices/sound/flt_vol.c",
diff --git a/scripts/src/main.lua b/scripts/src/main.lua
index d4d991dcdfa..20a3e5b6038 100644
--- a/scripts/src/main.lua
+++ b/scripts/src/main.lua
@@ -116,7 +116,6 @@ end
"lua",
"lsqlite3",
"jsoncpp",
- "mongoose",
}
if _OPTIONS["with-bundled-zlib"] then
diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c
index 22344cb2deb..37d451ca0fb 100644
--- a/src/emu/debug/debugcpu.c
+++ b/src/emu/debug/debugcpu.c
@@ -1931,8 +1931,6 @@ void device_debug::instruction_hook(offs_t curpc)
// flush any pending updates before waiting again
machine.debug_view().flush_osd_updates();
- machine.manager().web()->serve();
-
// clear the memory modified flag and wait
global->memory_modified = false;
if (machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)
diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c
index a163a7ae65d..1e578068b77 100644
--- a/src/emu/emuopts.c
+++ b/src/emu/emuopts.c
@@ -185,10 +185,6 @@ const options_entry emu_options::s_option_entries[] =
{ OPTION_AUTOBOOT_COMMAND ";ab", NULL, OPTION_STRING, "command to execute after machine boot" },
{ OPTION_AUTOBOOT_DELAY, "2", OPTION_INTEGER, "timer delay in sec to trigger command execution on autoboot" },
{ OPTION_AUTOBOOT_SCRIPT ";script", NULL, OPTION_STRING, "lua script to execute after machine boot" },
- { OPTION_HTTP, "0", OPTION_BOOLEAN, "enable local http server" },
- { OPTION_HTTP_PORT, "8080", OPTION_STRING, "http server listener port" },
- { OPTION_HTTP_PATH, "web", OPTION_STRING, "path to web files" },
- { OPTION_CONSOLE, "0", OPTION_BOOLEAN, "enable emulator LUA console" },
{ NULL }
};
diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h
index d59ecd10a0a..9e8485bde29 100644
--- a/src/emu/emuopts.h
+++ b/src/emu/emuopts.h
@@ -189,11 +189,6 @@ enum
#define OPTION_AUTOBOOT_DELAY "autoboot_delay"
#define OPTION_AUTOBOOT_SCRIPT "autoboot_script"
-#define OPTION_HTTP "http"
-#define OPTION_HTTP_PORT "http_port"
-#define OPTION_HTTP_PATH "http_path"
-#define OPTION_CONSOLE "console"
-
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -366,11 +361,6 @@ public:
int autoboot_delay() const { return int_value(OPTION_AUTOBOOT_DELAY); }
const char *autoboot_script() const { return value(OPTION_AUTOBOOT_SCRIPT); }
- bool http() const { return bool_value(OPTION_HTTP); }
- const char *http_port() const { return value(OPTION_HTTP_PORT); }
- const char *http_path() const { return value(OPTION_HTTP_PATH); }
- bool console() const { return bool_value(OPTION_CONSOLE); }
-
// FIXME: Couriersud: This should be in image_device_exit
void remove_device_options();
diff --git a/src/emu/luaengine.c b/src/emu/luaengine.c
index b5c9764fb77..6013ac6dc62 100644
--- a/src/emu/luaengine.c
+++ b/src/emu/luaengine.c
@@ -17,7 +17,6 @@
#include "osdepend.h"
#include "drivenum.h"
#include "ui/ui.h"
-#include "mongoose/mongoose.h"
//**************************************************************************
// LUA ENGINE
@@ -862,13 +861,14 @@ void lua_engine::serve_lua()
} while (1);
}
+/*
static void *serve_lua(void *param)
{
lua_engine *engine = (lua_engine *)param;
engine->serve_lua();
return NULL;
}
-
+*/
//-------------------------------------------------
// lua_engine - constructor
@@ -1025,7 +1025,6 @@ void lua_engine::initialize()
void lua_engine::start_console()
{
- mg_start_thread(::serve_lua, this);
}
//-------------------------------------------------
diff --git a/src/emu/machine.c b/src/emu/machine.c
index 39529e546f0..7c24cb21455 100644
--- a/src/emu/machine.c
+++ b/src/emu/machine.c
@@ -393,8 +393,6 @@ int running_machine::run(bool firstrun)
js_set_main_loop(this);
#endif
- manager().web()->serve();
-
// execute CPUs if not paused
if (!m_paused)
m_scheduler.timeslice();
diff --git a/src/emu/mame.c b/src/emu/mame.c
index 526cf304015..84d726c3e2e 100644
--- a/src/emu/mame.c
+++ b/src/emu/mame.c
@@ -117,7 +117,6 @@ machine_manager* machine_manager::instance()
machine_manager::machine_manager(emu_options &options,osd_interface &osd)
: m_osd(osd),
m_options(options),
- m_web(options),
m_new_driver_pending(NULL),
m_machine(NULL)
{
@@ -155,8 +154,6 @@ void machine_manager::schedule_new_driver(const game_driver &driver)
void machine_manager::update_machine()
{
m_lua.set_machine(m_machine);
- m_web.set_machine(m_machine);
- if (m_machine!=NULL) m_web.push_message("update_machine");
}
/*-------------------------------------------------
@@ -175,9 +172,6 @@ int machine_manager::execute()
int error = MAMERR_NONE;
m_lua.initialize();
- if (m_options.console()) {
- m_lua.start_console();
- }
while (error == MAMERR_NONE && !exit_pending)
{
m_new_driver_pending = NULL;
diff --git a/src/emu/mame.h b/src/emu/mame.h
index 03d3dae3892..7f0c2b1ed37 100644
--- a/src/emu/mame.h
+++ b/src/emu/mame.h
@@ -18,8 +18,6 @@
#include <time.h>
-#include "webengine.h"
-
class osd_interface;
//**************************************************************************
@@ -89,7 +87,6 @@ public:
osd_interface &osd() const;
emu_options &options() const { return m_options; }
- web_engine *web() { return &m_web; }
lua_engine *lua() { return &m_lua; }
running_machine *machine() { return m_machine; }
@@ -105,7 +102,6 @@ private:
osd_interface & m_osd; // reference to OSD system
emu_options & m_options; // reference to options
- web_engine m_web;
lua_engine m_lua;
const game_driver * m_new_driver_pending; // pointer to the next pending driver
diff --git a/src/emu/ui/ui.c b/src/emu/ui/ui.c
index d6dca99c255..b2c30a6acfd 100644
--- a/src/emu/ui/ui.c
+++ b/src/emu/ui/ui.c
@@ -374,7 +374,6 @@ void ui_manager::display_startup_screens(bool first_time, bool show_disclaimer)
// loop while we have a handler
while (m_handler_callback != handler_ingame && !machine().scheduled_event_pending() && !ui_menu::stack_has_special_main_menu())
{
- machine().manager().web()->serve();
machine().video().frame_update();
}
diff --git a/src/emu/webengine.c b/src/emu/webengine.c
deleted file mode 100644
index ad6d1928a7e..00000000000
--- a/src/emu/webengine.c
+++ /dev/null
@@ -1,545 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Miodrag Milanovic
-/***************************************************************************
-
- webengine.c
-
- Handle MAME internal web server.
-
-***************************************************************************/
-
-#include "mongoose/mongoose.h"
-#include "jsoncpp/include/json/json.h"
-#include "emu.h"
-#include "emuopts.h"
-#include "ui/ui.h"
-#include "webengine.h"
-#include "lua.hpp"
-
-#include "osdepend.h"
-
-//**************************************************************************
-// WEB ENGINE
-//**************************************************************************
-
-char* websanitize_statefilename ( char* unsanitized )
-{
- // It's important that we remove any dangerous characters from any filename
- // we receive from a web client. This can be a serious security hole.
- // As MAME/MESS policy is lowercase filenames, also lowercase it.
-
- char* sanitized = new char[64];
- int insertpoint =0;
- char charcompare;
-
- while (*unsanitized != 0)
- {
- charcompare = *unsanitized;
- // ASCII 48-57 are 0-9
- // ASCII 97-122 are lowercase A-Z
-
- if ((charcompare >= 48 && charcompare <= 57) || (charcompare >= 97 && charcompare <= 122))
- {
- sanitized[insertpoint] = charcompare;
- insertpoint++;
- sanitized[insertpoint] = '\0'; // Make sure we're null-terminated.
- }
- // ASCII 65-90 are uppercase A-Z. These need to be lowercased.
- if (charcompare >= 65 && charcompare <= 90)
- {
- sanitized[insertpoint] = tolower(charcompare); // Lowercase it
- insertpoint++;
- sanitized[insertpoint] = '\0'; // Make sure we're null-terminated.
- }
- unsanitized++;
- }
- return (sanitized);
-}
-
-int web_engine::json_game_handler(struct mg_connection *conn)
-{
- Json::Value data;
- data["name"] = m_machine->system().name;
- data["description"] = m_machine->system().description;
- data["year"] = m_machine->system().year;
- data["manufacturer"] = m_machine->system().manufacturer;
- data["parent"] = m_machine->system().parent;
- data["source_file"] = m_machine->system().source_file;
- data["flags"] = m_machine->system().flags;
- data["ispaused"] = m_machine->paused();
-
- Json::FastWriter writer;
- std::string json = writer.write(data);
- // Send HTTP reply to the client
- mg_printf(conn,
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: application/json\r\n"
- "Content-Length: %d\r\n" // Always set Content-Length
- "\r\n"
- "%s",
- (int)json.length(), json.c_str());
-
- // Returning non-zero tells mongoose that our function has replied to
- // the client, and mongoose should not send client any more data.
-
- return MG_TRUE;
-}
-
-int web_engine::json_slider_handler(struct mg_connection *conn)
-{
- const slider_state *curslider;
- std::string tempstring;
- Json::Value array(Json::arrayValue);
-
- // add all sliders
- for (curslider = machine().ui().get_slider_list(); curslider != NULL; curslider = curslider->next)
- {
- INT32 curval = (*curslider->update)(machine(), curslider->arg, &tempstring, SLIDER_NOCHANGE);
- Json::Value data;
- data["description"] = curslider->description;
- data["minval"] = curslider->minval;
- data["maxval"] = curslider->maxval;
- data["defval"] = curslider->defval;
- data["incval"] = curslider->incval;
- data["curval"] = curval;
- array.append(data);
- }
-
- // add all sliders
- for (curslider = (slider_state*)machine().osd().get_slider_list(); curslider != NULL; curslider = curslider->next)
- {
- INT32 curval = (*curslider->update)(machine(), curslider->arg, &tempstring, SLIDER_NOCHANGE);
- Json::Value data;
- data["description"] = curslider->description;
- data["minval"] = curslider->minval;
- data["maxval"] = curslider->maxval;
- data["defval"] = curslider->defval;
- data["incval"] = curslider->incval;
- data["curval"] = curval;
- array.append(data);
- }
- Json::FastWriter writer;
- std::string json = writer.write(array);
- // Send HTTP reply to the client
- mg_printf(conn,
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: application/json\r\n"
- "Content-Length: %d\r\n" // Always set Content-Length
- "\r\n"
- "%s",
- (int)json.length(), json.c_str());
-
- return MG_TRUE;
-}
-
-void reg_string(struct lua_State *L, const char *name, const char *val) {
- lua_pushstring(L, name);
- lua_pushstring(L, val);
- lua_rawset(L, -3);
-}
-
-void reg_int(struct lua_State *L, const char *name, int val) {
- lua_pushstring(L, name);
- lua_pushinteger(L, val);
- lua_rawset(L, -3);
-}
-
-void reg_function(struct lua_State *L, const char *name,
- lua_CFunction func, struct mg_connection *conn) {
- lua_pushstring(L, name);
- lua_pushlightuserdata(L, conn);
- lua_pushcclosure(L, func, 1);
- lua_rawset(L, -3);
-}
-
-static int lua_write(lua_State *L) {
- int i, num_args;
- const char *str;
- size_t size;
- struct mg_connection *conn = (struct mg_connection *)
- lua_touserdata(L, lua_upvalueindex(1));
-
- num_args = lua_gettop(L);
- for (i = 1; i <= num_args; i++) {
- if (lua_isstring(L, i)) {
- str = lua_tolstring(L, i, &size);
- mg_send_data(conn, str, size);
- }
- }
-
- return 0;
-}
-
-static int lua_header(lua_State *L) {
- struct mg_connection *conn = (struct mg_connection *)
- lua_touserdata(L, lua_upvalueindex(1));
-
- const char *header = luaL_checkstring(L,1);
- const char *value = luaL_checkstring(L,2);
-
- mg_send_header(conn, header, value);
-
- return 0;
-}
-
-
-static void prepare_lua_environment(struct mg_connection *ri, lua_State *L) {
- extern void luaL_openlibs(lua_State *);
- int i;
-
- luaL_openlibs(L);
-
- if (ri == NULL) return;
-
- // Register mg module
- lua_newtable(L);
- reg_function(L, "write", lua_write, ri);
- reg_function(L, "header", lua_header, ri);
-
- // Export request_info
- lua_pushstring(L, "request_info");
- lua_newtable(L);
- reg_string(L, "request_method", ri->request_method);
- reg_string(L, "uri", ri->uri);
- reg_string(L, "http_version", ri->http_version);
- reg_string(L, "query_string", ri->query_string);
- reg_string(L, "remote_ip", ri->remote_ip);
- reg_int(L, "remote_port", ri->remote_port);
- reg_string(L, "local_ip", ri->local_ip);
- reg_int(L, "local_port", ri->local_port);
- lua_pushstring(L, "content");
- lua_pushlstring(L, ri->content == NULL ? "" : ri->content, ri->content_len);
- lua_rawset(L, -3);
- reg_int(L, "num_headers", ri->num_headers);
- lua_pushstring(L, "http_headers");
- lua_newtable(L);
- for (i = 0; i < ri->num_headers; i++) {
- reg_string(L, ri->http_headers[i].name, ri->http_headers[i].value);
- }
- lua_rawset(L, -3);
- lua_rawset(L, -3);
-
- lua_setglobal(L, "mg");
-
-}
-
-
-static void lsp(struct mg_connection *conn, const char *p, int len, lua_State *L) {
- int i, j, pos = 0;
- for (i = 0; i < len; i++) {
- if (p[i] == '<' && p[i + 1] == '?') {
- for (j = i + 1; j < len ; j++) {
- if (p[j] == '?' && p[j + 1] == '>') {
- if (i-pos!=0) mg_send_data(conn, p + pos, i - pos);
- if (luaL_loadbuffer(L, p + (i + 2), j - (i + 2), "") == 0) {
- lua_pcall(L, 0, LUA_MULTRET, 0);
- }
- pos = j + 2;
- i = pos - 1;
- break;
- }
- }
- }
- }
- if (i > pos) {
- mg_send_data(conn, p + pos, i - pos);
- }
-}
-
-static int filename_endswith(const char *str, const char *suffix)
-{
- if (!str || !suffix)
- return 0;
- size_t lenstr = strlen(str);
- size_t lensuffix = strlen(suffix);
- if (lensuffix > lenstr)
- return 0;
- return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
-}
-
-// This function will be called by mongoose on every new request.
-int web_engine::begin_request_handler(struct mg_connection *conn)
-{
- std::string file_path = std::string(mg_get_option(m_server, "document_root")).append(PATH_SEPARATOR).append(conn->uri);
- if (filename_endswith(file_path.c_str(), ".lp"))
- {
- FILE *fp = NULL;
- if ((fp = fopen(file_path.c_str(), "rb")) != NULL) {
- fseek (fp, 0, SEEK_END);
- size_t size = ftell(fp);
- fseek (fp, 0, SEEK_SET);
- char *data = (char*)mg_mmap(fp,size);
-
- lua_State *L = luaL_newstate();
- prepare_lua_environment(conn, L);
- lsp(conn, data, (int) size, L);
- if (L != NULL) lua_close(L);
- mg_munmap(data,size);
- fclose(fp);
- return MG_TRUE;
- } else {
- return MG_FALSE;
- }
- }
- else if (!strncmp(conn->uri, "/json/",6))
- {
- if (!strcmp(conn->uri, "/json/game"))
- {
- return json_game_handler(conn);
- }
- if (!strcmp(conn->uri, "/json/slider"))
- {
- return json_slider_handler(conn);
- }
- }
- else if (!strncmp(conn->uri, "/keypost",8))
- {
- // Is there any sane way to determine the length of the buffer before getting it?
- // A request for a way was previously filed with the mongoose devs,
- // but it looks like it was never implemented.
-
- // For now, we'll allow a paste buffer of 32k.
- // To-do: Send an error if the paste is too big?
- char cmd_val[32768];
-
- int pastelength = mg_get_var(conn, "val", cmd_val, sizeof(cmd_val));
- if (pastelength > 0) {
- machine().ioport().natkeyboard().post_utf8(cmd_val);
- }
- // Send HTTP reply to the client
- mg_printf(conn,
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain\r\n"
- "Content-Length: 2\r\n" // Always set Content-Length
- "\r\n"
- "OK");
-
- // Returning non-zero tells mongoose that our function has replied to
- // the client, and mongoose should not send client any more data.
- return MG_TRUE;
- }
- else if (!strncmp(conn->uri, "/keyupload",8))
- {
- char *upload_data;
- int data_length, ofs = 0;
- char var_name[100], file_name[255];
- while ((ofs = mg_parse_multipart(conn->content + ofs, conn->content_len - ofs, var_name, sizeof(var_name), file_name, sizeof(file_name), (const char **)&upload_data, &data_length)) > 0) {
- mg_printf_data(conn, "File: %s, size: %d bytes", file_name, data_length);
- }
-
- // That upload_data contains more than we need. It also has the headers.
- // We'll need to strip it down to just what we want.
-
- if ((&data_length > 0) && (sizeof(file_name) > 0))
- {
- // MSVC doesn't yet support variable-length arrays, so chop the string the old-fashioned way
- upload_data[data_length] = '\0';
-
- // Now paste the stripped down paste_data..
- machine().ioport().natkeyboard().post_utf8(upload_data);
- }
- return MG_TRUE;
- }
- else if (!strncmp(conn->uri, "/cmd",4))
- {
- char cmd_name[64];
- mg_get_var(conn, "name", cmd_name, sizeof(cmd_name));
-
- if(!strcmp(cmd_name,"softreset"))
- {
- m_machine->schedule_soft_reset();
- }
- else if(!strcmp(cmd_name,"hardreset"))
- {
- m_machine->schedule_hard_reset();
- }
- else if(!strcmp(cmd_name,"exit"))
- {
- m_machine->schedule_exit();
- }
- else if(!strcmp(cmd_name,"togglepause"))
- {
- if (m_machine->paused())
- m_machine->resume();
- else
- m_machine->pause();
- }
- else if(!strcmp(cmd_name,"savestate"))
- {
- char cmd_val[64];
- mg_get_var(conn, "val", cmd_val, sizeof(cmd_val));
- char *filename = websanitize_statefilename(cmd_val);
- m_machine->schedule_save(filename);
- }
- else if(!strcmp(cmd_name,"loadstate"))
- {
- char cmd_val[64];
- mg_get_var(conn, "val", cmd_val, sizeof(cmd_val));
- char *filename = cmd_val;
- m_machine->schedule_load(filename);
- }
- else if(!strcmp(cmd_name,"loadauto"))
- {
- // This is here to just load the autosave and only the autosave.
- m_machine->schedule_load("auto");
- }
-
- // Send HTTP reply to the client
- mg_printf(conn,
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain\r\n"
- "Content-Length: 2\r\n" // Always set Content-Length
- "\r\n"
- "OK");
-
- // Returning non-zero tells mongoose that our function has replied to
- // the client, and mongoose should not send client any more data.
- return MG_TRUE;
- }
- else if (!strncmp(conn->uri, "/slider",7))
- {
- char cmd_id[64];
- char cmd_val[64];
- mg_get_var(conn, "id", cmd_id, sizeof(cmd_id));
- mg_get_var(conn, "val", cmd_val, sizeof(cmd_val));
- int cnt = 0;
- int id = atoi(cmd_id);
- const slider_state *curslider;
- for (curslider = machine().ui().get_slider_list(); curslider != NULL; curslider = curslider->next)
- {
- if (cnt==id)
- (*curslider->update)(machine(), curslider->arg, NULL, atoi(cmd_val));
- cnt++;
- }
- for (curslider = (slider_state*)machine().osd().get_slider_list(); curslider != NULL; curslider = curslider->next)
- {
- if (cnt==id)
- (*curslider->update)(machine(), curslider->arg, NULL, atoi(cmd_val));
- cnt++;
- }
-
- // Send HTTP reply to the client
- mg_printf(conn,
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain\r\n"
- "Content-Length: 2\r\n" // Always set Content-Length
- "\r\n"
- "OK");
-
- // Returning non-zero tells mongoose that our function has replied to
- // the client, and mongoose should not send client any more data.
- return MG_TRUE;
- }
- else if (!strncmp(conn->uri, "/screenshot.png",15))
- {
- screen_device_iterator iter(m_machine->root_device());
- screen_device *screen = iter.first();
-
- if (screen == NULL)
- {
- return 0;
- }
-
- std::string fname("screenshot.png");
- emu_file file(m_machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open(fname.c_str());
-
- if (filerr != FILERR_NONE)
- {
- return 0;
- }
-
- m_machine->video().save_snapshot(screen, file);
- std::string fullpath(file.fullpath());
- file.close();
- mg_send_header(conn, "Cache-Control", "no-cache, no-store, must-revalidate");
- mg_send_header(conn, "Pragma", "no-cache");
- mg_send_header(conn, "Expires", "0");
- mg_send_file(conn, fullpath.c_str(), NULL);
- return MG_MORE; // It is important to return MG_MORE after mg_send_file!
- }
- return 0;
-}
-
-static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
- if (ev == MG_REQUEST) {
- if (conn->is_websocket) {
- // This handler is called for each incoming websocket frame, one or more
- // times for connection lifetime.
- // Echo websocket data back to the client.
- return conn->content_len == 4 && !memcmp(conn->content, "exit", 4) ? MG_FALSE : MG_TRUE;
- } else {
- web_engine *engine = static_cast<web_engine *>(conn->server_param);
- return engine->begin_request_handler(conn);
- }
- } else if (ev== MG_WS_CONNECT) {
- // New websocket connection. Send connection ID back to the client.
- mg_websocket_printf(conn, WEBSOCKET_OPCODE_TEXT, "update_machine");
- return MG_FALSE;
- } else if (ev == MG_AUTH) {
- return MG_TRUE;
- } else {
- return MG_FALSE;
- }
-}
-
-//-------------------------------------------------
-// web_engine - constructor
-//-------------------------------------------------
-
-web_engine::web_engine(emu_options &options)
- : m_options(options),
- m_machine(NULL),
- m_server(NULL),
- //m_lastupdatetime(0),
- m_exiting_core(false),
- m_http(m_options.http())
-
-{
- if (m_http) {
- m_server = mg_create_server(this, ev_handler);
-
- mg_set_option(m_server, "listening_port", options.http_port());
- mg_set_option(m_server, "document_root", options.http_path());
- }
-
-}
-
-//-------------------------------------------------
-// ~web_engine - destructor
-//-------------------------------------------------
-
-web_engine::~web_engine()
-{
- if (m_http)
- close();
-}
-
-//-------------------------------------------------
-// close - close and cleanup of lua engine
-//-------------------------------------------------
-
-void web_engine::close()
-{
- m_exiting_core = 1;
- // Cleanup, and free server instance
- mg_destroy_server(&m_server);
-}
-
-void web_engine::serve()
-{
- if (m_http) mg_poll_server(m_server, 0);
-}
-
-void web_engine::push_message(const char *message)
-{
- struct mg_connection *c;
- if (m_server!=NULL) {
- // Iterate over all connections, and push current time message to websocket ones.
- for (c = mg_next(m_server, NULL); c != NULL; c = mg_next(m_server, c)) {
- if (c->is_websocket) {
- mg_websocket_write(c, 1, message, strlen(message));
- }
- }
- }
-}
diff --git a/src/emu/webengine.h b/src/emu/webengine.h
deleted file mode 100644
index 7d0a3189fc3..00000000000
--- a/src/emu/webengine.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Miodrag Milanovic
-/***************************************************************************
-
- webengine.h
-
- Handle MAME internal web server.
-
-***************************************************************************/
-
-#pragma once
-
-#ifndef __WEB_ENGINE_H__
-#define __WEB_ENGINE_H__
-
-struct mg_server; // Handle for the HTTP server itself
-struct mg_connection; // Handle for the individual connection
-
-class web_engine
-{
-public:
- // construction/destruction
- web_engine(emu_options &options);
- ~web_engine();
-
- void serve();
- void push_message(const char *message);
- void close();
-
- void set_machine(running_machine *machine) { m_machine = machine; }
- int begin_request_handler(struct mg_connection *conn);
-protected:
- // getters
- running_machine &machine() const { return *m_machine; }
-
- int json_game_handler(struct mg_connection *conn);
- int json_slider_handler(struct mg_connection *conn);
-private:
- // internal state
- emu_options & m_options;
- running_machine * m_machine;
- struct mg_server * m_server;
- //osd_ticks_t m_lastupdatetime;
- bool m_exiting_core;
- bool m_http;
-};
-
-#endif /* __web_engine_H__ */
diff --git a/web/css/images/ajax-loader.gif b/web/css/images/ajax-loader.gif
deleted file mode 100644
index fd1a189c21f..00000000000
--- a/web/css/images/ajax-loader.gif
+++ /dev/null
Binary files differ
diff --git a/web/css/images/icons-18-black.png b/web/css/images/icons-18-black.png
deleted file mode 100644
index 791646384bf..00000000000
--- a/web/css/images/icons-18-black.png
+++ /dev/null
Binary files differ
diff --git a/web/css/images/icons-18-white.png b/web/css/images/icons-18-white.png
deleted file mode 100644
index 3419b81f6a8..00000000000
--- a/web/css/images/icons-18-white.png
+++ /dev/null
Binary files differ
diff --git a/web/css/images/icons-36-black.png b/web/css/images/icons-36-black.png
deleted file mode 100644
index 043bfcd5211..00000000000
--- a/web/css/images/icons-36-black.png
+++ /dev/null
Binary files differ
diff --git a/web/css/images/icons-36-white.png b/web/css/images/icons-36-white.png
deleted file mode 100644
index 12455c907a4..00000000000
--- a/web/css/images/icons-36-white.png
+++ /dev/null
Binary files differ
diff --git a/web/css/jquery.mobile.css b/web/css/jquery.mobile.css
deleted file mode 100644
index 0975cbc5b14..00000000000
--- a/web/css/jquery.mobile.css
+++ /dev/null
@@ -1,12 +0,0 @@
-/*! jQuery Mobile 1.3.2 | Git HEAD hash: 528cf0e <> 2013-07-19T22:17:57Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */
-
-/*!
-* jQuery Mobile 1.3.2
-* Git HEAD hash: 528cf0e96940644ea644096bfeb913ed920ffaef <> Date: Fri Jul 19 2013 22:17:57 UTC
-* http://jquerymobile.com
-*
-* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors
-* Released under the MIT license.
-* http://jquery.org/license
-*
-*/.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:700;text-shadow:0 -1px 0 #000;background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111));background-image:-webkit-linear-gradient(#3c3c3c,#111);background-image:-moz-linear-gradient(#3c3c3c,#111);background-image:-ms-linear-gradient(#3c3c3c,#111);background-image:-o-linear-gradient(#3c3c3c,#111);background-image:linear-gradient(#3c3c3c,#111)}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 0 #111;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#222));background-image:-webkit-linear-gradient(#444,#222);background-image:-moz-linear-gradient(#444,#222);background-image:-ms-linear-gradient(#444,#222);background-image:-o-linear-gradient(#444,#222);background-image:linear-gradient(#444,#222)}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:700}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#2d2d2d));background-image:-webkit-linear-gradient(#444,#2d2d2d);background-image:-moz-linear-gradient(#444,#2d2d2d);background-image:-ms-linear-gradient(#444,#2d2d2d);background-image:-o-linear-gradient(#444,#2d2d2d);background-image:linear-gradient(#444,#2d2d2d)}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#555),to(#383838));background-image:-webkit-linear-gradient(#555,#383838);background-image:-moz-linear-gradient(#555,#383838);background-image:-ms-linear-gradient(#555,#383838);background-image:-o-linear-gradient(#555,#383838);background-image:linear-gradient(#555,#383838)}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#202020),to(#2c2c2c));background-image:-webkit-linear-gradient(#202020,#2c2c2c);background-image:-moz-linear-gradient(#202020,#2c2c2c);background-image:-ms-linear-gradient(#202020,#2c2c2c);background-image:-o-linear-gradient(#202020,#2c2c2c);background-image:linear-gradient(#202020,#2c2c2c)}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:700;text-shadow:0 1px 0 #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#497bae));background-image:-webkit-linear-gradient(#6facd5,#497bae);background-image:-moz-linear-gradient(#6facd5,#497bae);background-image:-ms-linear-gradient(#6facd5,#497bae);background-image:-o-linear-gradient(#6facd5,#497bae);background-image:linear-gradient(#6facd5,#497bae)}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:700}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#ccc));background-image:-webkit-linear-gradient(#ddd,#ccc);background-image:-moz-linear-gradient(#ddd,#ccc);background-image:-ms-linear-gradient(#ddd,#ccc);background-image:-o-linear-gradient(#ddd,#ccc);background-image:linear-gradient(#ddd,#ccc)}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:700}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#5f9cc5),to(#396b9e));background-image:-webkit-linear-gradient(#5f9cc5,#396b9e);background-image:-moz-linear-gradient(#5f9cc5,#396b9e);background-image:-ms-linear-gradient(#5f9cc5,#396b9e);background-image:-o-linear-gradient(#5f9cc5,#396b9e);background-image:linear-gradient(#5f9cc5,#396b9e)}.ui-btn-up-b:visited,.ui-btn-up-b a.ui-link-inherit{color:#fff}.ui-btn-hover-b{border:1px solid #00415e;background:#4b88b6;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#4272a4));background-image:-webkit-linear-gradient(#6facd5,#4272a4);background-image:-moz-linear-gradient(#6facd5,#4272a4);background-image:-ms-linear-gradient(#6facd5,#4272a4);background-image:-o-linear-gradient(#6facd5,#4272a4);background-image:linear-gradient(#6facd5,#4272a4)}.ui-btn-hover-b:visited,.ui-btn-hover-b:hover,.ui-btn-hover-b a.ui-link-inherit{color:#fff}.ui-btn-down-b{border:1px solid #225377;background:#4e89c5;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#295b8e),to(#3e79b5));background-image:-webkit-linear-gradient(#295b8e,#3e79b5);background-image:-moz-linear-gradient(#295b8e,#3e79b5);background-image:-ms-linear-gradient(#295b8e,#3e79b5);background-image:-o-linear-gradient(#295b8e,#3e79b5);background-image:linear-gradient(#295b8e,#3e79b5)}.ui-btn-down-b:visited,.ui-btn-down-b:hover,.ui-btn-down-b a.ui-link-inherit{color:#fff}.ui-btn-up-b,.ui-btn-hover-b,.ui-btn-down-b{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-c{border:1px solid #b3b3b3;background:#eee;color:#3e3e3e;font-weight:700;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#ddd));background-image:-webkit-linear-gradient(#f0f0f0,#ddd);background-image:-moz-linear-gradient(#f0f0f0,#ddd);background-image:-ms-linear-gradient(#f0f0f0,#ddd);background-image:-o-linear-gradient(#f0f0f0,#ddd);background-image:linear-gradient(#f0f0f0,#ddd)}.ui-bar-c .ui-link-inherit{color:#3e3e3e}.ui-bar-c a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-c a.ui-link:visited{color:#2489ce}.ui-bar-c a.ui-link:hover{color:#2489ce}.ui-bar-c a.ui-link:active{color:#2489ce}.ui-bar-c,.ui-bar-c input,.ui-bar-c select,.ui-bar-c textarea,.ui-bar-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c,.ui-overlay-c{border:1px solid #aaa;color:#333;text-shadow:0 1px 0 #fff;background:#f9f9f9;background-image:-webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#eee));background-image:-webkit-linear-gradient(#f9f9f9,#eee);background-image:-moz-linear-gradient(#f9f9f9,#eee);background-image:-ms-linear-gradient(#f9f9f9,#eee);background-image:-o-linear-gradient(#f9f9f9,#eee);background-image:linear-gradient(#f9f9f9,#eee)}.ui-overlay-c{background-image:none;border-width:0}.ui-body-c,.ui-body-c input,.ui-body-c select,.ui-body-c textarea,.ui-body-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c .ui-link-inherit{color:#333}.ui-body-c .ui-link{color:#2489ce;font-weight:700}.ui-body-c .ui-link:visited{color:#2489ce}.ui-body-c .ui-link:hover{color:#2489ce}.ui-body-c .ui-link:active{color:#2489ce}.ui-btn-up-c{border:1px solid #ccc;background:#eee;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f1f1f1));background-image:-webkit-linear-gradient(#fff,#f1f1f1);background-image:-moz-linear-gradient(#fff,#f1f1f1);background-image:-ms-linear-gradient(#fff,#f1f1f1);background-image:-o-linear-gradient(#fff,#f1f1f1);background-image:linear-gradient(#fff,#f1f1f1)}.ui-btn-up-c:visited,.ui-btn-up-c a.ui-link-inherit{color:#2f3e46}.ui-btn-hover-c{border:1px solid #bbb;background:#dfdfdf;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f6f6f6),to(#e0e0e0));background-image:-webkit-linear-gradient(#f6f6f6,#e0e0e0);background-image:-moz-linear-gradient(#f6f6f6,#e0e0e0);background-image:-ms-linear-gradient(#f6f6f6,#e0e0e0);background-image:-o-linear-gradient(#f6f6f6,#e0e0e0);background-image:linear-gradient(#f6f6f6,#e0e0e0)}.ui-btn-hover-c:visited,.ui-btn-hover-c:hover,.ui-btn-hover-c a.ui-link-inherit{color:#2f3e46}.ui-btn-down-c{border:1px solid #bbb;background:#d6d6d6;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#d0d0d0),to(#dfdfdf));background-image:-webkit-linear-gradient(#d0d0d0,#dfdfdf);background-image:-moz-linear-gradient(#d0d0d0,#dfdfdf);background-image:-ms-linear-gradient(#d0d0d0,#dfdfdf);background-image:-o-linear-gradient(#d0d0d0,#dfdfdf);background-image:linear-gradient(#d0d0d0,#dfdfdf)}.ui-btn-down-c:visited,.ui-btn-down-c:hover,.ui-btn-down-c a.ui-link-inherit{color:#2f3e46}.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-d{border:1px solid #bbb;background:#bbb;color:#333;font-weight:700;text-shadow:0 1px 0 #eee;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#bbb));background-image:-webkit-linear-gradient(#ddd,#bbb);background-image:-moz-linear-gradient(#ddd,#bbb);background-image:-ms-linear-gradient(#ddd,#bbb);background-image:-o-linear-gradient(#ddd,#bbb);background-image:linear-gradient(#ddd,#bbb)}.ui-bar-d,.ui-bar-d input,.ui-bar-d select,.ui-bar-d textarea,.ui-bar-d button{font-family:Helvetica,Arial,sans-serif}.ui-bar-d .ui-link-inherit{color:#333}.ui-bar-d a.ui-link{color:#2489ce;font-weight:700}.ui-bar-d a.ui-link:visited{color:#2489ce}.ui-bar-d a.ui-link:hover{color:#2489ce}.ui-bar-d a.ui-link:active{color:#2489ce}.ui-body-d,.ui-overlay-d{border:1px solid #bbb;color:#333;text-shadow:0 1px 0 #fff;background:#fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#fff));background-image:-webkit-linear-gradient(#fff,#fff);background-image:-moz-linear-gradient(#fff,#fff);background-image:-ms-linear-gradient(#fff,#fff);background-image:-o-linear-gradient(#fff,#fff);background-image:linear-gradient(#fff,#fff)}.ui-overlay-d{background-image:none;border-width:0}.ui-body-d,.ui-body-d input,.ui-body-d select,.ui-body-d textarea,.ui-body-d button{font-family:Helvetica,Arial,sans-serif}.ui-body-d .ui-link-inherit{color:#333}.ui-body-d .ui-link{color:#2489ce;font-weight:700}.ui-body-d .ui-link:visited{color:#2489ce}.ui-body-d .ui-link:hover{color:#2489ce}.ui-body-d .ui-link:active{color:#2489ce}.ui-btn-up-d{border:1px solid #bbb;background:#fff;font-weight:700;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#f6f6f6));background-image:-webkit-linear-gradient(#fafafa,#f6f6f6);background-image:-moz-linear-gradient(#fafafa,#f6f6f6);background-image:-ms-linear-gradient(#fafafa,#f6f6f6);background-image:-o-linear-gradient(#fafafa,#f6f6f6);background-image:linear-gradient(#fafafa,#f6f6f6)}.ui-btn-up-d:visited,.ui-btn-up-d a.ui-link-inherit{color:#333}.ui-btn-hover-d{border:1px solid #aaa;background:#eee;font-weight:700;color:#333;cursor:pointer;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#eee),to(#fff));background-image:-webkit-linear-gradient(#eee,#fff);background-image:-moz-linear-gradient(#eee,#fff);background-image:-ms-linear-gradient(#eee,#fff);background-image:-o-linear-gradient(#eee,#fff);background-image:linear-gradient(#eee,#fff)}.ui-btn-hover-d:visited,.ui-btn-hover-d:hover,.ui-btn-hover-d a.ui-link-inherit{color:#333}.ui-btn-down-d{border:1px solid #aaa;background:#eee;font-weight:700;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#e5e5e5),to(#f2f2f2));background-image:-webkit-linear-gradient(#e5e5e5,#f2f2f2);background-image:-moz-linear-gradient(#e5e5e5,#f2f2f2);background-image:-ms-linear-gradient(#e5e5e5,#f2f2f2);background-image:-o-linear-gradient(#e5e5e5,#f2f2f2);background-image:linear-gradient(#e5e5e5,#f2f2f2)}.ui-btn-down-d:visited,.ui-btn-down-d:hover,.ui-btn-down-d a.ui-link-inherit{color:#333}.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-e{border:1px solid #f7c942;background:#fadb4e;color:#333;font-weight:700;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fceda7),to(#fbef7e));background-image:-webkit-linear-gradient(#fceda7,#fbef7e);background-image:-moz-linear-gradient(#fceda7,#fbef7e);background-image:-ms-linear-gradient(#fceda7,#fbef7e);background-image:-o-linear-gradient(#fceda7,#fbef7e);background-image:linear-gradient(#fceda7,#fbef7e)}.ui-bar-e,.ui-bar-e input,.ui-bar-e select,.ui-bar-e textarea,.ui-bar-e button{font-family:Helvetica,Arial,sans-serif}.ui-bar-e .ui-link-inherit{color:#333}.ui-bar-e a.ui-link{color:#2489ce;font-weight:700}.ui-bar-e a.ui-link:visited{color:#2489ce}.ui-bar-e a.ui-link:hover{color:#2489ce}.ui-bar-e a.ui-link:active{color:#2489ce}.ui-body-e,.ui-overlay-e{border:1px solid #f7c942;color:#222;text-shadow:0 1px 0 #fff;background:#fff9df;background-image:-webkit-gradient(linear,left top,left bottom,from(#fffadf),to(#fff3a5));background-image:-webkit-linear-gradient(#fffadf,#fff3a5);background-image:-moz-linear-gradient(#fffadf,#fff3a5);background-image:-ms-linear-gradient(#fffadf,#fff3a5);background-image:-o-linear-gradient(#fffadf,#fff3a5);background-image:linear-gradient(#fffadf,#fff3a5)}.ui-overlay-e{background-image:none;border-width:0}.ui-body-e,.ui-body-e input,.ui-body-e select,.ui-body-e textarea,.ui-body-e button{font-family:Helvetica,Arial,sans-serif}.ui-body-e .ui-link-inherit{color:#222}.ui-body-e .ui-link{color:#2489ce;font-weight:700}.ui-body-e .ui-link:visited{color:#2489ce}.ui-body-e .ui-link:hover{color:#2489ce}.ui-body-e .ui-link:active{color:#2489ce}.ui-btn-up-e{border:1px solid #f4c63f;background:#fadb4e;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#ffefaa),to(#ffe155));background-image:-webkit-linear-gradient(#ffefaa,#ffe155);background-image:-moz-linear-gradient(#ffefaa,#ffe155);background-image:-ms-linear-gradient(#ffefaa,#ffe155);background-image:-o-linear-gradient(#ffefaa,#ffe155);background-image:linear-gradient(#ffefaa,#ffe155)}.ui-btn-up-e:visited,.ui-btn-up-e a.ui-link-inherit{color:#222}.ui-btn-hover-e{border:1px solid #f2c43d;background:#fbe26f;font-weight:700;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff5ba),to(#fbdd52));background-image:-webkit-linear-gradient(#fff5ba,#fbdd52);background-image:-moz-linear-gradient(#fff5ba,#fbdd52);background-image:-ms-linear-gradient(#fff5ba,#fbdd52);background-image:-o-linear-gradient(#fff5ba,#fbdd52);background-image:linear-gradient(#fff5ba,#fbdd52)}.ui-btn-hover-e:visited,.ui-btn-hover-e:hover,.ui-btn-hover-e a.ui-link-inherit{color:#333}.ui-btn-down-e{border:1px solid #f2c43d;background:#fceda7;font-weight:700;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f8d94c),to(#fadb4e));background-image:-webkit-linear-gradient(#f8d94c,#fadb4e);background-image:-moz-linear-gradient(#f8d94c,#fadb4e);background-image:-ms-linear-gradient(#f8d94c,#fadb4e);background-image:-o-linear-gradient(#f8d94c,#fadb4e);background-image:linear-gradient(#f8d94c,#fadb4e)}.ui-btn-down-e:visited,.ui-btn-down-e:hover,.ui-btn-down-e a.ui-link-inherit{color:#333}.ui-btn-up-e,.ui-btn-hover-e,.ui-btn-down-e{font-family:Helvetica,Arial,sans-serif;text-decoration:none}a.ui-link-inherit{text-decoration:none!important}.ui-btn-active{border:1px solid #2373a5;background:#5393c5;font-weight:700;color:#fff;cursor:pointer;text-shadow:0 1px 0 #3373a5;text-decoration:none;background-image:-webkit-gradient(linear,left top,left bottom,from(#5393c5),to(#6facd5));background-image:-webkit-linear-gradient(#5393c5,#6facd5);background-image:-moz-linear-gradient(#5393c5,#6facd5);background-image:-ms-linear-gradient(#5393c5,#6facd5);background-image:-o-linear-gradient(#5393c5,#6facd5);background-image:linear-gradient(#5393c5,#6facd5);font-family:Helvetica,Arial,sans-serif}.ui-btn-active:visited,.ui-btn-active:hover,.ui-btn-active a.ui-link-inherit{color:#fff}.ui-btn-inner{border-top:1px solid #fff;border-color:rgba(255,255,255,.3)}.ui-corner-all{-webkit-border-radius:.6em;border-radius:.6em}.ui-br{border-color:#828282;border-color:rgba(130,130,130,.3);border-style:solid}.ui-disabled{filter:Alpha(Opacity=30);opacity:.3;zoom:1}.ui-disabled,.ui-disabled a{cursor:default!important;pointer-events:none}.ui-icon,.ui-icon-searchfield:after{background:#666;background:rgba(0,0,0,.4);background-image:url(images/icons-18-white.png);background-repeat:no-repeat;-webkit-border-radius:9px;border-radius:9px}.ui-icon-alt .ui-icon,.ui-icon-alt .ui-icon-searchfield:after{background-color:#fff;background-color:rgba(255,255,255,.3);background-image:url(images/icons-18-black.png);background-repeat:no-repeat}.ui-icon-nodisc .ui-icon,.ui-icon-nodisc .ui-icon-searchfield:after,.ui-icon-nodisc .ui-icon-alt .ui-icon,.ui-icon-nodisc .ui-icon-alt .ui-icon-searchfield:after{background-color:transparent}.ui-icon-plus{background-position:-1px -1px}.ui-icon-minus{background-position:-37px -1px}.ui-icon-delete{background-position:-73px -1px}.ui-icon-arrow-r{background-position:-108px -1px}.ui-icon-arrow-l{background-position:-144px -1px}.ui-icon-arrow-u{background-position:-180px -1px}.ui-icon-arrow-d{background-position:-216px -1px}.ui-icon-check{background-position:-252px -1px}.ui-icon-gear{background-position:-288px -1px}.ui-icon-refresh{background-position:-323px -1px}.ui-icon-forward{background-position:-360px -1px}.ui-icon-back{background-position:-396px -1px}.ui-icon-grid{background-position:-432px -1px}.ui-icon-star{background-position:-467px -1px}.ui-icon-alert{background-position:-503px -1px}.ui-icon-info{background-position:-539px -1px}.ui-icon-home{background-position:-575px -1px}.ui-icon-search,.ui-icon-searchfield:after{background-position:-611px -1px}.ui-icon-checkbox-on{background-position:-647px -1px}.ui-icon-checkbox-off{background-position:-683px -1px}.ui-icon-radio-on{background-position:-718px -1px}.ui-icon-radio-off{background-position:-754px -1px}.ui-icon-bars{background-position:-788px -1px}.ui-icon-edit{background-position:-824px -1px}@media only screen and (-webkit-min-device-pixel-ratio:1.3),only screen and (min--moz-device-pixel-ratio:1.3),only screen and (min-resolution:200dpi){.ui-icon-plus,.ui-icon-minus,.ui-icon-delete,.ui-icon-arrow-r,.ui-icon-arrow-l,.ui-icon-arrow-u,.ui-icon-arrow-d,.ui-icon-check,.ui-icon-gear,.ui-icon-refresh,.ui-icon-forward,.ui-icon-back,.ui-icon-grid,.ui-icon-star,.ui-icon-alert,.ui-icon-info,.ui-icon-home,.ui-icon-bars,.ui-icon-edit,.ui-icon-search,.ui-icon-searchfield:after,.ui-icon-checkbox-off,.ui-icon-checkbox-on,.ui-icon-radio-off,.ui-icon-radio-on{background-image:url(images/icons-36-white.png);-moz-background-size:864px 18px;-o-background-size:864px 18px;-webkit-background-size:864px 18px;background-size:864px 18px}.ui-icon-alt .ui-icon{background-image:url(images/icons-36-black.png)}.ui-icon-plus{background-position:0 50%}.ui-icon-minus{background-position:-36px 50%}.ui-icon-delete{background-position:-72px 50%}.ui-icon-arrow-r{background-position:-108px 50%}.ui-icon-arrow-l{background-position:-144px 50%}.ui-icon-arrow-u{background-position:-179px 50%}.ui-icon-arrow-d{background-position:-215px 50%}.ui-icon-check{background-position:-252px 50%}.ui-icon-gear{background-position:-287px 50%}.ui-icon-refresh{background-position:-323px 50%}.ui-icon-forward{background-position:-360px 50%}.ui-icon-back{background-position:-395px 50%}.ui-icon-grid{background-position:-431px 50%}.ui-icon-star{background-position:-467px 50%}.ui-icon-alert{background-position:-503px 50%}.ui-icon-info{background-position:-538px 50%}.ui-icon-home{background-position:-575px 50%}.ui-icon-search,.ui-icon-searchfield:after{background-position:-611px 50%}.ui-icon-checkbox-on{background-position:-647px 50%}.ui-icon-checkbox-off{background-position:-683px 50%}.ui-icon-radio-on{background-position:-718px 50%}.ui-icon-radio-off{background-position:-754px 50%}.ui-icon-bars{background-position:-788px 50%}.ui-icon-edit{background-position:-824px 50%}}.ui-checkbox .ui-icon,.ui-selectmenu-list .ui-icon{-webkit-border-radius:3px;border-radius:3px}.ui-icon-checkbox-off,.ui-icon-radio-off{background-color:transparent}.ui-checkbox-on .ui-icon,.ui-radio-on .ui-icon{background-color:#4596ce}.ui-icon-loading{background:url(images/ajax-loader.gif);background-size:46px 46px}.ui-btn-corner-all{-webkit-border-radius:1em;border-radius:1em}.ui-corner-all,.ui-btn-corner-all{-webkit-background-clip:padding;background-clip:padding-box}.ui-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5;position:absolute;width:100%;height:100%}.ui-overlay-shadow{-moz-box-shadow:0 0 12px rgba(0,0,0,.6);-webkit-box-shadow:0 0 12px rgba(0,0,0,.6);box-shadow:0 0 12px rgba(0,0,0,.6)}.ui-shadow{-moz-box-shadow:0 1px 3px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,.2);box-shadow:0 1px 3px rgba(0,0,0,.2)}.ui-bar-a .ui-shadow,.ui-bar-b .ui-shadow,.ui-bar-c .ui-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.ui-shadow-inset{-moz-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);box-shadow:inset 0 1px 4px rgba(0,0,0,.2)}.ui-icon-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.4);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.4);box-shadow:0 1px 0 rgba(255,255,255,.4)}.ui-btn:focus,.ui-link-inherit:focus{outline:0}.ui-btn.ui-focus{z-index:1}.ui-focus,.ui-btn:focus{-moz-box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe;-webkit-box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe;box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe}.ui-input-text.ui-focus,.ui-input-search.ui-focus{-moz-box-shadow:0 0 12px #387bbe;-webkit-box-shadow:0 0 12px #387bbe;box-shadow:0 0 12px #387bbe}.ui-mobile-nosupport-boxshadow *{-moz-box-shadow:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui-mobile-nosupport-boxshadow .ui-focus,.ui-mobile-nosupport-boxshadow .ui-btn:focus,.ui-mobile-nosupport-boxshadow .ui-link-inherit:focus{outline-width:1px;outline-style:auto}.ui-mobile,.ui-mobile body{height:99.9%}.ui-mobile fieldset,.ui-page{padding:0;margin:0}.ui-mobile a img,.ui-mobile fieldset{border-width:0}.ui-mobile fieldset{min-width:0}.ui-mobile-viewport{margin:0;overflow-x:visible;-webkit-text-size-adjust:100%;-ms-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}body.ui-mobile-viewport,div.ui-mobile-viewport{overflow-x:hidden}.ui-mobile [data-role=page],.ui-mobile [data-role=dialog],.ui-page{top:0;left:0;width:100%;min-height:100%;position:absolute;display:none;border:0}.ui-mobile .ui-page-active{display:block;overflow:visible}.ui-page{outline:0}@media screen and (orientation:portrait){.ui-mobile .ui-page{min-height:420px}}@media screen and (orientation:landscape){.ui-mobile .ui-page{min-height:300px}}.ui-loading .ui-loader{display:block}.ui-loader{display:none;z-index:9999999;position:fixed;top:50%;left:50%;border:0}.ui-loader-default{background:0;filter:Alpha(Opacity=18);opacity:.18;width:46px;height:46px;margin-left:-23px;margin-top:-23px}.ui-loader-verbose{width:200px;filter:Alpha(Opacity=88);opacity:.88;box-shadow:0 1px 1px -1px #fff;height:auto;margin-left:-110px;margin-top:-43px;padding:10px}.ui-loader-default h1{font-size:0;width:0;height:0;overflow:hidden}.ui-loader-verbose h1{font-size:16px;margin:0;text-align:center}.ui-loader .ui-icon{background-color:#000;display:block;margin:0;width:44px;height:44px;padding:1px;-webkit-border-radius:36px;border-radius:36px}.ui-loader-verbose .ui-icon{margin:0 auto 10px;filter:Alpha(Opacity=75);opacity:.75}.ui-loader-textonly{padding:15px;margin-left:-115px}.ui-loader-textonly .ui-icon{display:none}.ui-loader-fakefix{position:absolute}.ui-mobile-rendering>*{visibility:hidden}.ui-bar,.ui-body{position:relative;padding:.4em 15px;overflow:hidden;display:block;clear:both}.ui-bar{font-size:16px;margin:0}.ui-bar h1,.ui-bar h2,.ui-bar h3,.ui-bar h4,.ui-bar h5,.ui-bar h6{margin:0;padding:0;font-size:16px;display:inline-block}.ui-header,.ui-footer{position:relative;zoom:1}.ui-mobile .ui-header,.ui-mobile .ui-footer{border-left-width:0;border-right-width:0}.ui-header .ui-btn-left,.ui-header .ui-btn-right,.ui-footer .ui-btn-left,.ui-footer .ui-btn-right,.ui-header-fixed.ui-fixed-hidden .ui-btn-left,.ui-header-fixed.ui-fixed-hidden .ui-btn-right{position:absolute;top:3px}.ui-header-fixed .ui-btn-left,.ui-header-fixed .ui-btn-right{top:4px}.ui-header .ui-btn-left,.ui-footer .ui-btn-left{left:5px}.ui-header .ui-btn-right,.ui-footer .ui-btn-right{right:5px}.ui-footer>.ui-btn-icon-notext,.ui-header>.ui-btn-icon-notext,.ui-header-fixed.ui-fixed-hidden>.ui-btn-icon-notext{top:6px}.ui-header-fixed>.ui-btn-icon-notext{top:7px}.ui-header .ui-title,.ui-footer .ui-title{min-height:1.1em;text-align:center;font-size:16px;display:block;margin:.6em 30% .8em;padding:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;outline:0!important}.ui-footer .ui-title{margin:.6em 15px .8em}.ui-content{border-width:0;overflow:visible;overflow-x:hidden;padding:15px}.ui-corner-all>.ui-header:first-child,.ui-corner-all>.ui-content:first-child,.ui-corner-all>.ui-footer:first-child{-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit;-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit}.ui-corner-all>.ui-header:last-child,.ui-corner-all>.ui-content:last-child,.ui-corner-all>.ui-footer:last-child{-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-icon{width:18px;height:18px}.ui-nojs{position:absolute;left:-9999px}.ui-hide-label label.ui-input-text,.ui-hide-label label.ui-select,.ui-hide-label label.ui-slider,.ui-hide-label label.ui-submit,.ui-hide-label .ui-controlgroup-label,.ui-hidden-accessible{position:absolute!important;left:-9999px;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.ui-page-pre-in{opacity:0}.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms;animation-timing-function:ease-out;animation-duration:350ms}.out{-webkit-animation-timing-function:ease-in;-webkit-animation-duration:225ms;-moz-animation-timing-function:ease-in;-moz-animation-duration:225ms;animation-timing-function:ease-in;animation-duration:225ms}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@-moz-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeout{from{opacity:1}to{opacity:0}}@-moz-keyframes fadeout{from{opacity:1}to{opacity:0}}@keyframes fadeout{from{opacity:1}to{opacity:0}}.fade.out{opacity:0;-webkit-animation-duration:125ms;-webkit-animation-name:fadeout;-moz-animation-duration:125ms;-moz-animation-name:fadeout;animation-duration:125ms;animation-name:fadeout}.fade.in{opacity:1;-webkit-animation-duration:225ms;-webkit-animation-name:fadein;-moz-animation-duration:225ms;-moz-animation-name:fadein;animation-duration:225ms;animation-name:fadein}.pop{-webkit-transform-origin:50% 50%;-moz-transform-origin:50% 50%;transform-origin:50% 50%}.pop.in{-webkit-transform:scale(1);-webkit-animation-name:popin;-webkit-animation-duration:350ms;-moz-transform:scale(1);-moz-animation-name:popin;-moz-animation-duration:350ms;transform:scale(1);animation-name:popin;animation-duration:350ms;opacity:1}.pop.out{-webkit-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-name:fadeout;-moz-animation-duration:100ms;animation-name:fadeout;animation-duration:100ms;opacity:0}.pop.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein;animation-name:fadein}.pop.out.reverse{-webkit-transform:scale(.8);-webkit-animation-name:popout;-moz-transform:scale(.8);-moz-animation-name:popout;transform:scale(.8);animation-name:popout}@-webkit-keyframes popin{from{-webkit-transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);opacity:1}}@-moz-keyframes popin{from{-moz-transform:scale(.8);opacity:0}to{-moz-transform:scale(1);opacity:1}}@keyframes popin{from{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}@-webkit-keyframes popout{from{-webkit-transform:scale(1);opacity:1}to{-webkit-transform:scale(.8);opacity:0}}@-moz-keyframes popout{from{-moz-transform:scale(1);opacity:1}to{-moz-transform:scale(.8);opacity:0}}@keyframes popout{from{transform:scale(1);opacity:1}to{transform:scale(.8);opacity:0}}@-webkit-keyframes slideinfromright{from{-webkit-transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0)}}@-moz-keyframes slideinfromright{from{-moz-transform:translateX(100%)}to{-moz-transform:translateX(0)}}@keyframes slideinfromright{from{transform:translateX(100%)}to{transform:translateX(0)}}@-webkit-keyframes slideinfromleft{from{-webkit-transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0)}}@-moz-keyframes slideinfromleft{from{-moz-transform:translateX(-100%)}to{-moz-transform:translateX(0)}}@keyframes slideinfromleft{from{transform:translateX(-100%)}to{transform:translateX(0)}}@-webkit-keyframes slideouttoleft{from{-webkit-transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0)}}@-moz-keyframes slideouttoleft{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(-100%)}}@keyframes slideouttoleft{from{transform:translateX(0)}to{transform:translateX(-100%)}}@-webkit-keyframes slideouttoright{from{-webkit-transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0)}}@-moz-keyframes slideouttoright{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(100%)}}@keyframes slideouttoright{from{transform:translateX(0)}to{transform:translateX(100%)}}.slide.out,.slide.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms;animation-timing-function:ease-out;animation-duration:350ms}.slide.out{-webkit-transform:translate3d(-100%,0,0);-webkit-animation-name:slideouttoleft;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft;transform:translateX(-100%);animation-name:slideouttoleft}.slide.in{-webkit-transform:translate3d(0,0,0);-webkit-animation-name:slideinfromright;-moz-transform:translateX(0);-moz-animation-name:slideinfromright;transform:translateX(0);animation-name:slideinfromright}.slide.out.reverse{-webkit-transform:translate3d(100%,0,0);-webkit-animation-name:slideouttoright;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright;transform:translateX(100%);animation-name:slideouttoright}.slide.in.reverse{-webkit-transform:translate3d(0,0,0);-webkit-animation-name:slideinfromleft;-moz-transform:translateX(0);-moz-animation-name:slideinfromleft;transform:translateX(0);animation-name:slideinfromleft}.slidefade.out{-webkit-transform:translateX(-100%);-webkit-animation-name:slideouttoleft;-webkit-animation-duration:225ms;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft;-moz-animation-duration:225ms;transform:translateX(-100%);animation-name:slideouttoleft;animation-duration:225ms}.slidefade.in{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-webkit-animation-duration:200ms;-moz-transform:translateX(0);-moz-animation-name:fadein;-moz-animation-duration:200ms;transform:translateX(0);animation-name:fadein;animation-duration:200ms}.slidefade.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:slideouttoright;-webkit-animation-duration:200ms;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright;-moz-animation-duration:200ms;transform:translateX(100%);animation-name:slideouttoright;animation-duration:200ms}.slidefade.in.reverse{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-webkit-animation-duration:200ms;-moz-transform:translateX(0);-moz-animation-name:fadein;-moz-animation-duration:200ms;transform:translateX(0);animation-name:fadein;animation-duration:200ms}.slidedown.out{-webkit-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-name:fadeout;-moz-animation-duration:100ms;animation-name:fadeout;animation-duration:100ms}.slidedown.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfromtop;-webkit-animation-duration:250ms;-moz-transform:translateY(0);-moz-animation-name:slideinfromtop;-moz-animation-duration:250ms;transform:translateY(0);animation-name:slideinfromtop;animation-duration:250ms}.slidedown.in.reverse{-webkit-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-name:fadein;-moz-animation-duration:150ms;animation-name:fadein;animation-duration:150ms}.slidedown.out.reverse{-webkit-transform:translateY(-100%);-webkit-animation-name:slideouttotop;-webkit-animation-duration:200ms;-moz-transform:translateY(-100%);-moz-animation-name:slideouttotop;-moz-animation-duration:200ms;transform:translateY(-100%);animation-name:slideouttotop;animation-duration:200ms}@-webkit-keyframes slideinfromtop{from{-webkit-transform:translateY(-100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfromtop{from{-moz-transform:translateY(-100%)}to{-moz-transform:translateY(0)}}@keyframes slideinfromtop{from{transform:translateY(-100%)}to{transform:translateY(0)}}@-webkit-keyframes slideouttotop{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(-100%)}}@-moz-keyframes slideouttotop{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(-100%)}}@keyframes slideouttotop{from{transform:translateY(0)}to{transform:translateY(-100%)}}.slideup.out{-webkit-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-name:fadeout;-moz-animation-duration:100ms;animation-name:fadeout;animation-duration:100ms}.slideup.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfrombottom;-webkit-animation-duration:250ms;-moz-transform:translateY(0);-moz-animation-name:slideinfrombottom;-moz-animation-duration:250ms;transform:translateY(0);animation-name:slideinfrombottom;animation-duration:250ms}.slideup.in.reverse{-webkit-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-name:fadein;-moz-animation-duration:150ms;animation-name:fadein;animation-duration:150ms}.slideup.out.reverse{-webkit-transform:translateY(100%);-webkit-animation-name:slideouttobottom;-webkit-animation-duration:200ms;-moz-transform:translateY(100%);-moz-animation-name:slideouttobottom;-moz-animation-duration:200ms;transform:translateY(100%);animation-name:slideouttobottom;animation-duration:200ms}@-webkit-keyframes slideinfrombottom{from{-webkit-transform:translateY(100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfrombottom{from{-moz-transform:translateY(100%)}to{-moz-transform:translateY(0)}}@keyframes slideinfrombottom{from{transform:translateY(100%)}to{transform:translateY(0)}}@-webkit-keyframes slideouttobottom{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(100%)}}@-moz-keyframes slideouttobottom{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(100%)}}@keyframes slideouttobottom{from{transform:translateY(0)}to{transform:translateY(100%)}}.viewport-flip{-webkit-perspective:1000;-moz-perspective:1000;perspective:1000;position:absolute}.flip{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-moz-backface-visibility:hidden;-moz-transform:translateX(0);backface-visibility:hidden;transform:translateX(0)}.flip.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-webkit-animation-duration:175ms;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-moz-animation-duration:175ms;transform:rotateY(-90deg) scale(.9);animation-name:flipouttoleft;animation-duration:175ms}.flip.in{-webkit-animation-name:flipintoright;-webkit-animation-duration:225ms;-moz-animation-name:flipintoright;-moz-animation-duration:225ms;animation-name:flipintoright;animation-duration:225ms}.flip.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright;transform:rotateY(90deg) scale(.9);animation-name:flipouttoright}.flip.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@keyframes flipouttoleft{from{transform:rotateY(0)}to{transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@keyframes flipouttoright{from{transform:rotateY(0)}to{transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoleft{from{transform:rotateY(-90deg) scale(.9)}to{transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoright{from{transform:rotateY(90deg) scale(.9)}to{transform:rotateY(0)}}.viewport-turn{-webkit-perspective:200px;-moz-perspective:200px;-ms-perspective:200px;perspective:200px;position:absolute}.turn{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-webkit-transform-origin:0;-moz-backface-visibility:hidden;-moz-transform:translateX(0);-moz-transform-origin:0;backface-visibility :hidden;transform:translateX(0);transform-origin:0}.turn.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-webkit-animation-duration:125ms;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-moz-animation-duration:125ms;transform:rotateY(-90deg) scale(.9);animation-name:flipouttoleft;animation-duration:125ms}.turn.in{-webkit-animation-name:flipintoright;-webkit-animation-duration:250ms;-moz-animation-name:flipintoright;-moz-animation-duration:250ms;animation-name:flipintoright;animation-duration:250ms}.turn.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright;transform:rotateY(90deg) scale(.9);animation-name:flipouttoright}.turn.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@keyframes flipouttoleft{from{transform:rotateY(0)}to{transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@keyframes flipouttoright{from{transform:rotateY(0)}to{transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoleft{from{transform:rotateY(-90deg) scale(.9)}to{transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoright{from{transform:rotateY(90deg) scale(.9)}to{transform:rotateY(0)}}.flow{-webkit-transform-origin:50% 30%;-webkit-box-shadow:0 0 20px rgba(0,0,0,.4);-moz-transform-origin:50% 30%;-moz-box-shadow:0 0 20px rgba(0,0,0,.4);transform-origin:50% 30%;box-shadow:0 0 20px rgba(0,0,0,.4)}.ui-dialog.flow{-webkit-transform-origin:none;-webkit-box-shadow:none;-moz-transform-origin:none;-moz-box-shadow:none;transform-origin:none;box-shadow:none}.flow.out{-webkit-transform:translateX(-100%) scale(.7);-webkit-animation-name:flowouttoleft;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(-100%) scale(.7);-moz-animation-name:flowouttoleft;-moz-animation-timing-function:ease;-moz-animation-duration:350ms;transform:translateX(-100%) scale(.7);animation-name:flowouttoleft;animation-timing-function:ease;animation-duration:350ms}.flow.in{-webkit-transform:translateX(0) scale(1);-webkit-animation-name:flowinfromright;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(0) scale(1);-moz-animation-name:flowinfromright;-moz-animation-timing-function:ease;-moz-animation-duration:350ms;transform:translateX(0) scale(1);animation-name:flowinfromright;animation-timing-function:ease;animation-duration:350ms}.flow.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:flowouttoright;-moz-transform:translateX(100%);-moz-animation-name:flowouttoright;transform:translateX(100%);animation-name:flowouttoright}.flow.in.reverse{-webkit-animation-name:flowinfromleft;-moz-animation-name:flowinfromleft;animation-name:flowinfromleft}@-webkit-keyframes flowouttoleft{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(-100%) scale(.7)}}@-moz-keyframes flowouttoleft{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(-100%) scale(.7)}}@keyframes flowouttoleft{0%{transform:translateX(0) scale(1)}60%,70%{transform:translateX(0) scale(.7)}100%{transform:translateX(-100%) scale(.7)}}@-webkit-keyframes flowouttoright{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(100%) scale(.7)}}@-moz-keyframes flowouttoright{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(100%) scale(.7)}}@keyframes flowouttoright{0%{transform:translateX(0) scale(1)}60%,70%{transform:translateX(0) scale(.7)}100%{transform:translateX(100%) scale(.7)}}@-webkit-keyframes flowinfromleft{0%{-webkit-transform:translateX(-100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromleft{0%{-moz-transform:translateX(-100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}@keyframes flowinfromleft{0%{transform:translateX(-100%) scale(.7)}30%,40%{transform:translateX(0) scale(.7)}100%{transform:translateX(0) scale(1)}}@-webkit-keyframes flowinfromright{0%{-webkit-transform:translateX(100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromright{0%{-moz-transform:translateX(100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}@keyframes flowinfromright{0%{transform:translateX(100%) scale(.7)}30%,40%{transform:translateX(0) scale(.7)}100%{transform:translateX(0) scale(1)}}.ui-grid-a,.ui-grid-b,.ui-grid-c,.ui-grid-d{overflow:hidden}.ui-block-a,.ui-block-b,.ui-block-c,.ui-block-d,.ui-block-e{margin:0;padding:0;border:0;float:left;min-height:1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-grid-solo .ui-block-a{display:block;float:none}.ui-grid-a .ui-block-a,.ui-grid-a .ui-block-b{width:49.95%}.ui-grid-a>:nth-child(n){width:50%;margin-right:-.5px}.ui-grid-a .ui-block-a{clear:left}.ui-grid-b .ui-block-a,.ui-grid-b .ui-block-b,.ui-grid-b .ui-block-c{width:33.25%}.ui-grid-b>:nth-child(n){width:33.333%;margin-right:-.5px}.ui-grid-b .ui-block-a{clear:left}.ui-grid-c .ui-block-a,.ui-grid-c .ui-block-b,.ui-grid-c .ui-block-c,.ui-grid-c .ui-block-d{width:24.925%}.ui-grid-c>:nth-child(n){width:25%;margin-right:-.5px}.ui-grid-c .ui-block-a{clear:left}.ui-grid-d .ui-block-a,.ui-grid-d .ui-block-b,.ui-grid-d .ui-block-c,.ui-grid-d .ui-block-d,.ui-grid-d .ui-block-e{width:19.925%}.ui-grid-d>:nth-child(n){width:20%}.ui-grid-d .ui-block-a{clear:left}@media all and (max-width:35em){.ui-responsive .ui-block-a,.ui-responsive .ui-block-b,.ui-responsive .ui-block-c,.ui-responsive .ui-block-d,.ui-responsive .ui-block-e{width:100%;float:none}}.ui-header-fixed,.ui-footer-fixed{left:0;right:0;width:100%;position:fixed;z-index:1000}.ui-header-fixed{top:-1px;padding-top:1px}.ui-header-fixed.ui-fixed-hidden{top:0;padding-top:0}.ui-footer-fixed{bottom:-1px;padding-bottom:1px}.ui-footer-fixed.ui-fixed-hidden{bottom:0;padding-bottom:0}.ui-header-fullscreen,.ui-footer-fullscreen{filter:Alpha(Opacity=90);opacity:.9}.ui-page-header-fixed{padding-top:2.6875em}.ui-page-footer-fixed{padding-bottom:2.6875em}.ui-page-header-fullscreen>.ui-content,.ui-page-footer-fullscreen>.ui-content{padding:0}.ui-fixed-hidden{position:absolute}.ui-page-header-fullscreen .ui-fixed-hidden,.ui-page-footer-fullscreen .ui-fixed-hidden{left:-9999px}.ui-header-fixed .ui-btn,.ui-footer-fixed .ui-btn{z-index:10}.ui-android-2x-fixed .ui-li-has-thumb{-webkit-transform:translate3d(0,0,0)}.ui-navbar{max-width:100%}.ui-navbar.ui-mini{margin:0}.ui-navbar ul:before,.ui-navbar ul:after{content:" ";display:table}.ui-navbar ul:after{clear:both}.ui-navbar ul{list-style:none;margin:0;padding:0;position:relative;display:block;border:0;max-width:100%;overflow:visible;zoom:1}.ui-navbar li .ui-btn{display:block;text-align:center;margin:0 -1px 0 0;border-right-width:0}.ui-navbar li .ui-btn-icon-right .ui-icon{right:6px}.ui-navbar li:last-child .ui-btn,.ui-navbar .ui-grid-duo .ui-block-b .ui-btn{margin-right:0;border-right-width:1px}.ui-header .ui-navbar li:last-child .ui-btn,.ui-footer .ui-navbar li:last-child .ui-btn,.ui-header .ui-navbar .ui-grid-duo .ui-block-b .ui-btn,.ui-footer .ui-navbar .ui-grid-duo .ui-block-b .ui-btn{margin-right:-1px;border-right-width:0}.ui-navbar .ui-grid-duo li.ui-block-a:last-child .ui-btn{margin-right:-1px;border-right-width:1px}.ui-header .ui-navbar li .ui-btn,.ui-footer .ui-navbar li .ui-btn{border-top-width:0;border-bottom-width:0}.ui-header .ui-navbar .ui-grid-b li.ui-block-c .ui-btn,.ui-footer .ui-navbar .ui-grid-b li.ui-block-c .ui-btn{margin-right:-5px}.ui-header .ui-navbar .ui-grid-c li.ui-block-d .ui-btn,.ui-footer .ui-navbar .ui-grid-c li.ui-block-d .ui-btn,.ui-header .ui-navbar .ui-grid-d li.ui-block-e .ui-btn,.ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn{margin-right:-4px}.ui-header .ui-navbar .ui-grid-b li.ui-block-c .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-b li.ui-block-c .ui-btn-icon-right .ui-icon,.ui-header .ui-navbar .ui-grid-c li.ui-block-d .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-c li.ui-block-d .ui-btn-icon-right .ui-icon,.ui-header .ui-navbar .ui-grid-d li.ui-block-e .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn-icon-right .ui-icon{right:8px}.ui-navbar li .ui-btn .ui-btn-inner{padding-top:.7em;padding-bottom:.8em}.ui-navbar li .ui-btn-icon-top .ui-btn-inner{padding-top:30px}.ui-navbar li .ui-btn-icon-bottom .ui-btn-inner{padding-bottom:30px}.ui-btn{display:block;text-align:center;cursor:pointer;position:relative;margin:.5em 0;padding:0}.ui-mini{margin-top:.25em;margin-bottom:.25em}.ui-btn-left,.ui-btn-right,.ui-input-clear,.ui-btn-inline,.ui-grid-a .ui-btn,.ui-grid-b .ui-btn,.ui-grid-c .ui-btn,.ui-grid-d .ui-btn,.ui-grid-e .ui-btn,.ui-grid-solo .ui-btn{margin-right:5px;margin-left:5px}.ui-btn-inner{font-size:16px;padding:.6em 20px;min-width:.75em;display:block;position:relative;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;zoom:1}.ui-btn input,.ui-btn button{z-index:2}.ui-btn-left,.ui-btn-right,.ui-btn-inline{display:inline-block;vertical-align:middle}.ui-mobile .ui-btn-left,.ui-mobile .ui-btn-right,.ui-btn-left>.ui-btn,.ui-btn-right>.ui-btn{margin:0}.ui-btn-block{display:block}.ui-header>.ui-btn,.ui-footer>.ui-btn{display:inline-block;margin:0}.ui-header .ui-btn-block,.ui-footer .ui-btn-block{display:block}.ui-header .ui-btn-inner,.ui-footer .ui-btn-inner,.ui-mini .ui-btn-inner{font-size:12.5px;padding:.55em 11px .5em}.ui-fullsize .ui-btn-inner,.ui-fullsize .ui-btn-inner{font-size:16px;padding:.6em 20px}.ui-btn-icon-notext{width:24px;height:24px}.ui-btn-icon-notext .ui-btn-inner{padding:0;height:100%}.ui-btn-icon-notext .ui-btn-inner .ui-icon{margin:2px 1px 2px 3px;float:left}.ui-btn-text{position:relative;z-index:1;width:100%;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}div.ui-btn-text{width:auto}.ui-btn-icon-notext .ui-btn-text{position:absolute;left:-9999px}.ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-btn-icon-right .ui-btn-inner{padding-right:40px}.ui-btn-icon-top .ui-btn-inner{padding-top:40px}.ui-btn-icon-bottom .ui-btn-inner{padding-bottom:40px}.ui-header .ui-btn-icon-left .ui-btn-inner,.ui-footer .ui-btn-icon-left .ui-btn-inner,.ui-mini.ui-btn-icon-left .ui-btn-inner,.ui-mini .ui-btn-icon-left .ui-btn-inner{padding-left:30px}.ui-header .ui-btn-icon-right .ui-btn-inner,.ui-footer .ui-btn-icon-right .ui-btn-inner,.ui-mini.ui-btn-icon-right .ui-btn-inner,.ui-mini .ui-btn-icon-right .ui-btn-inner{padding-right:30px}.ui-header .ui-btn-icon-top .ui-btn-inner,.ui-footer .ui-btn-icon-top .ui-btn-inner{padding:30px 3px .5em}.ui-mini.ui-btn-icon-top .ui-btn-inner,.ui-mini .ui-btn-icon-top .ui-btn-inner{padding-top:30px}.ui-header .ui-btn-icon-bottom .ui-btn-inner,.ui-footer .ui-btn-icon-bottom .ui-btn-inner{padding:.55em 3px 30px}.ui-mini.ui-btn-icon-bottom .ui-btn-inner,.ui-mini .ui-btn-icon-bottom .ui-btn-inner{padding-bottom:30px}.ui-btn-inner{-webkit-border-radius:inherit;border-radius:inherit}.ui-btn-icon-notext .ui-icon{display:block;z-index:0}.ui-btn-icon-left>.ui-btn-inner>.ui-icon,.ui-btn-icon-right>.ui-btn-inner>.ui-icon{position:absolute;top:50%;margin-top:-9px}.ui-btn-icon-top .ui-btn-inner .ui-icon,.ui-btn-icon-bottom .ui-btn-inner .ui-icon{position:absolute;left:50%;margin-left:-9px}.ui-btn-icon-left .ui-icon{left:10px}.ui-btn-icon-right .ui-icon{right:10px}.ui-btn-icon-top .ui-icon{top:10px}.ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-header .ui-btn-icon-left .ui-icon,.ui-footer .ui-btn-icon-left .ui-icon,.ui-mini.ui-btn-icon-left .ui-icon,.ui-mini .ui-btn-icon-left .ui-icon{left:5px}.ui-header .ui-btn-icon-right .ui-icon,.ui-footer .ui-btn-icon-right .ui-icon,.ui-mini.ui-btn-icon-right .ui-icon,.ui-mini .ui-btn-icon-right .ui-icon{right:5px}.ui-header .ui-btn-icon-top .ui-icon,.ui-footer .ui-btn-icon-top .ui-icon,.ui-mini.ui-btn-icon-top .ui-icon,.ui-mini .ui-btn-icon-top .ui-icon{top:5px}.ui-header .ui-btn-icon-bottom .ui-icon,.ui-footer .ui-btn-icon-bottom .ui-icon,.ui-mini.ui-btn-icon-bottom .ui-icon,.ui-mini .ui-btn-icon-bottom .ui-icon{bottom:5px}.ui-btn-hidden{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-appearance:none;cursor:pointer;background:#fff;background:rgba(255,255,255,0);filter:Alpha(Opacity=0);opacity:.1;font-size:1px;border:0;text-indent:-9999px}.ui-disabled .ui-btn-hidden{display:none}.ui-disabled{z-index:1}.ui-field-contain .ui-btn.ui-submit{margin:0}label.ui-submit{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .3em;display:block}@media all and (min-width:28em){.ui-field-contain label.ui-submit{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-btn.ui-submit{width:78%;display:inline-block;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-hide-label .ui-btn.ui-submit{width:auto;display:block}}.ui-collapsible-inset{margin:.5em 0}.ui-collapsible-heading{font-size:16px;display:block;margin:0 -15px;padding:0;position:relative}.ui-collapsible-inset .ui-collapsible-heading{margin:0}.ui-collapsible-heading .ui-btn{text-align:left;margin:0;border-left-width:0;border-right-width:0}.ui-collapsible-inset .ui-collapsible-heading .ui-btn{border-right-width:1px;border-left-width:1px}.ui-collapsible-collapsed+.ui-collapsible:not(.ui-collapsible-inset) .ui-collapsible-heading .ui-btn{border-top-width:0}.ui-collapsible-set .ui-collapsible:not(.ui-collapsible-inset) .ui-collapsible-heading .ui-btn{border-top-width:1px}.ui-collapsible-heading .ui-btn-inner{padding-left:12px;padding-right:12px}.ui-collapsible-heading .ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-collapsible-heading .ui-btn-icon-right .ui-btn-inner{padding-right:40px}.ui-collapsible-heading .ui-btn-icon-top .ui-btn-inner,.ui-collapsible-heading .ui-btn-icon-bottom .ui-btn-inner{text-align:center}.ui-collapsible-heading .ui-btn-icon-left.ui-mini .ui-btn-inner{padding-left:30px}.ui-collapsible-heading .ui-btn-icon-right.ui-mini .ui-btn-inner{padding-right:30px}.ui-collapsible-heading .ui-btn span.ui-btn{position:absolute;left:6px;top:50%;margin:-12px 0 0 0;width:20px;height:20px;padding:1px 0 1px 2px;text-indent:-9999px}.ui-collapsible-heading .ui-btn span.ui-btn .ui-btn-inner{padding:10px 0}.ui-collapsible-heading .ui-btn span.ui-btn .ui-icon{left:0;margin-top:-10px}.ui-collapsible-heading-status{position:absolute;top:-9999px;left:0}.ui-collapsible-content{display:block;margin:0 -15px;padding:10px 15px;border-left-width:0;border-right-width:0;border-top:0;background-image:none}.ui-collapsible-inset .ui-collapsible-content{margin:0;border-right-width:1px;border-left-width:1px}.ui-collapsible-content-collapsed{display:none}.ui-collapsible-set>.ui-collapsible.ui-corner-all{-webkit-border-radius:0;border-radius:0}.ui-collapsible-heading,.ui-collapsible-heading>.ui-btn{-webkit-border-radius:inherit;border-radius:inherit}.ui-collapsible-set .ui-collapsible.ui-first-child{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit;-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit}.ui-collapsible-content,.ui-collapsible-set .ui-collapsible.ui-last-child{-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit;-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-collapsible-themed-content:not(.ui-collapsible-collapsed)>.ui-collapsible-heading{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0}.ui-collapsible-set{margin:.5em 0}.ui-collapsible-set .ui-collapsible{margin:-1px 0 0}.ui-collapsible-set .ui-collapsible.ui-first-child{margin-top:0}.ui-controlgroup,fieldset.ui-controlgroup{padding:0;margin:.5em 0;zoom:1}.ui-controlgroup.ui-mini,fieldset.ui-controlgroup.ui-mini{margin:.25em 0}.ui-field-contain .ui-controlgroup,.ui-field-contain fieldset.ui-controlgroup{margin:0}.ui-bar .ui-controlgroup{margin:0 5px}.ui-controlgroup-label{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .4em}.ui-controlgroup-label legend{max-width:100%}.ui-controlgroup-controls label.ui-select,.ui-controlgroup-controls label.ui-submit{position:absolute;left:-9999px}.ui-controlgroup li{list-style:none}.ui-controlgroup .ui-btn{margin:0}.ui-controlgroup .ui-btn-icon-notext{width:auto;height:auto;top:auto}.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner{height:20px;padding:.6em 20px}.ui-controlgroup-horizontal .ui-btn-icon-notext .ui-btn-inner{width:18px}.ui-controlgroup.ui-mini .ui-btn-icon-notext .ui-btn-inner,.ui-header .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner,.ui-footer .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner{height:16px;padding:.55em 11px .5em}.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner .ui-icon{position:absolute;top:50%;right:50%;margin:-9px -9px 0 0}.ui-controlgroup-horizontal .ui-btn-inner{text-align:center}.ui-controlgroup-horizontal.ui-mini .ui-btn-inner{height:16px;line-height:16px}.ui-controlgroup .ui-checkbox label,.ui-controlgroup .ui-radio label{font-size:16px}.ui-controlgroup-horizontal .ui-controlgroup-controls:before,.ui-controlgroup-horizontal .ui-controlgroup-controls:after{content:"";display:table}.ui-controlgroup-horizontal .ui-controlgroup-controls:after{clear:both}.ui-controlgroup-horizontal .ui-controlgroup-controls{display:inline-block;vertical-align:middle;zoom:1}.ui-controlgroup-horizontal .ui-controlgroup-controls>.ui-btn,.ui-controlgroup-horizontal .ui-controlgroup-controls li>.ui-btn,.ui-controlgroup-horizontal .ui-checkbox,.ui-controlgroup-horizontal .ui-radio,.ui-controlgroup-horizontal .ui-select{float:left;clear:none;margin:0}.ui-controlgroup-horizontal .ui-select .ui-btn-text{width:auto}.ui-controlgroup-vertical .ui-btn{border-bottom-width:0}.ui-controlgroup-vertical .ui-btn.ui-last-child{border-bottom-width:1px}.ui-controlgroup-horizontal .ui-btn{border-right-width:0}.ui-controlgroup-horizontal .ui-btn.ui-last-child{border-right-width:1px}.ui-controlgroup .ui-btn-corner-all{-webkit-border-radius:0;border-radius:0}.ui-controlgroup .ui-controlgroup-controls,.ui-controlgroup .ui-radio,.ui-controlgroup .ui-checkbox,.ui-controlgroup .ui-select,.ui-controlgroup li{-webkit-border-radius:inherit;border-radius:inherit}.ui-controlgroup-vertical .ui-btn.ui-first-child{-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit;-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit}.ui-controlgroup-vertical .ui-btn.ui-last-child{-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-controlgroup-horizontal .ui-btn.ui-first-child{-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit;-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-controlgroup-horizontal .ui-btn.ui-last-child{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-controlgroup .ui-shadow:not(.ui-focus){-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}@media all and (min-width:28em){.ui-field-contain .ui-controlgroup-label{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-controlgroup-controls{width:78%;display:inline-block}.ui-field-contain .ui-controlgroup .ui-select{width:100%;display:block}.ui-field-contain .ui-controlgroup-horizontal .ui-select{width:auto}.ui-hide-label .ui-controlgroup-controls{width:100%}}.ui-dialog{background:none!important}.ui-dialog-contain{width:92.5%;max-width:500px;margin:10% auto 15px;padding:0;position:relative;top:-15px}.ui-dialog-contain>.ui-header,.ui-dialog-contain>.ui-content,.ui-dialog-contain>.ui-footer{display:block;position:relative;width:auto;margin:0}.ui-dialog-contain>.ui-header{border:0;overflow:hidden;z-index:10;padding:0}.ui-dialog-contain>.ui-content{padding:15px}.ui-dialog-contain>.ui-footer{z-index:10;padding:0 15px}.ui-popup-open .ui-header-fixed,.ui-popup-open .ui-footer-fixed{position:absolute!important}.ui-popup-screen{background-image:url(data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==);top:0;left:0;right:0;bottom:1px;position:absolute;filter:Alpha(Opacity=0);opacity:0;z-index:1099}.ui-popup-screen.in{opacity:.5;filter:Alpha(Opacity=50)}.ui-popup-screen.out{opacity:0;filter:Alpha(Opacity=0)}.ui-popup-container{z-index:1100;display:inline-block;position:absolute;padding:0;outline:0}.ui-popup{position:relative}.ui-popup.ui-content,.ui-popup .ui-content{overflow:visible}.ui-popup>p,.ui-popup>h1,.ui-popup>h2,.ui-popup>h3,.ui-popup>h4,.ui-popup>h5,.ui-popup>h6{margin:.5em 7px}.ui-popup>span{display:block;margin:.5em 7px}.ui-popup .ui-title{font-size:16px;font-weight:700;margin-top:.5em;margin-bottom:.5em}.ui-popup-container .ui-content>p,.ui-popup-container .ui-content>h1,.ui-popup-container .ui-content>h2,.ui-popup-container .ui-content>h3,.ui-popup-container .ui-content>h4,.ui-popup-container .ui-content>h5,.ui-popup-container .ui-content>h6{margin:.5em 0}.ui-popup-container .ui-content>span{margin:0}.ui-popup-container .ui-content>p:first-child,.ui-popup-container .ui-content>h1:first-child,.ui-popup-container .ui-content>h2:first-child,.ui-popup-container .ui-content>h3:first-child,.ui-popup-container .ui-content>h4:first-child,.ui-popup-container .ui-content>h5:first-child,.ui-popup-container .ui-content>h6:first-child{margin-top:0}.ui-popup-container .ui-content>p:last-child,.ui-popup-container .ui-content>h1:last-child,.ui-popup-container .ui-content>h2:last-child,.ui-popup-container .ui-content>h3:last-child,.ui-popup-container .ui-content>h4:last-child,.ui-popup-container .ui-content>h5:last-child,.ui-popup-container .ui-content>h6:last-child{margin-bottom:0}.ui-popup>img{width:auto;height:auto;max-width:100%;max-height:100%;vertical-align:middle}.ui-popup:not(.ui-content)>img:only-child,.ui-popup:not(.ui-content)>.ui-btn-left:first-child+img:last-child,.ui-popup:not(.ui-content)>.ui-btn-right:first-child+img:last-child{-webkit-border-radius:inherit;border-radius:inherit}.ui-popup iframe{vertical-align:middle}@media all and (min-width:28em){.ui-popup .ui-field-contain label.ui-submit,.ui-popup .ui-field-contain .ui-controlgroup-label,.ui-popup .ui-field-contain label.ui-select,.ui-popup .ui-field-contain label.ui-input-text{font-size:16px;line-height:1.4;display:block;font-weight:400;margin:0 0 .3em}.ui-popup .ui-field-contain .ui-btn.ui-submit,.ui-popup .ui-field-contain .ui-controlgroup-controls,.ui-popup .ui-field-contain .ui-select,.ui-popup .ui-field-contain input.ui-input-text,.ui-popup .ui-field-contain textarea.ui-input-text,.ui-popup .ui-field-contain .ui-input-search{width:100%;display:block}}.ui-popup>.ui-btn-left,.ui-popup>.ui-btn-right{position:absolute;top:-9px;margin:0;z-index:1101}.ui-popup>.ui-btn-left{left:-9px}.ui-popup>.ui-btn-right{right:-9px}.ui-popup-hidden{top:-99999px;left:-9999px;visibility:hidden}.ui-checkbox,.ui-radio{position:relative;clear:both;margin:0;z-index:1}.ui-checkbox .ui-btn,.ui-radio .ui-btn{text-align:left;z-index:2}.ui-controlgroup .ui-checkbox .ui-btn,.ui-controlgroup .ui-radio .ui-btn{margin:0}.ui-checkbox .ui-btn-inner,.ui-radio .ui-btn-inner{white-space:normal}.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner{padding-left:45px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-left .ui-btn-inner{padding-left:36px}.ui-checkbox .ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-btn-icon-right .ui-btn-inner{padding-right:45px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-right .ui-btn-inner{padding-right:36px}.ui-checkbox .ui-btn-icon-top .ui-btn-inner,.ui-radio .ui-btn-icon-top .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-btn-icon-bottom .ui-btn-inner,.ui-radio .ui-btn-icon-bottom .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-icon,.ui-radio .ui-icon{top:1.1em}.ui-checkbox .ui-btn-icon-left .ui-icon,.ui-radio .ui-btn-icon-left .ui-icon{left:15px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-icon,.ui-radio .ui-mini.ui-btn-icon-left .ui-icon{left:9px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-checkbox .ui-btn-icon-top .ui-icon,.ui-radio .ui-btn-icon-top .ui-icon{top:10px}.ui-checkbox .ui-btn-icon-bottom .ui-icon,.ui-radio .ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-controlgroup-horizontal .ui-checkbox .ui-icon,.ui-controlgroup-horizontal .ui-radio .ui-icon{display:none}.ui-controlgroup-horizontal .ui-checkbox .ui-btn-inner,.ui-controlgroup-horizontal .ui-radio .ui-btn-inner{padding:.6em 20px}.ui-controlgroup-horizontal .ui-checkbox .ui-mini .ui-btn-inner,.ui-controlgroup-horizontal .ui-radio .ui-mini .ui-btn-inner{padding:.55em 11px .5em}.ui-checkbox input,.ui-radio input{position:absolute;left:20px;top:50%;width:10px;height:10px;margin:-5px 0 0 0;outline:0!important;z-index:1}.ui-field-contain,fieldset.ui-field-contain{padding:.8em 0;margin:0;border-width:0 0 1px;overflow:visible}.ui-field-contain:last-child{border-bottom-width:0}.ui-field-contain{max-width:100%}@media all and (min-width:28em){.ui-field-contain,.ui-mobile fieldset.ui-field-contain{border-width:0;padding:0;margin:1em 0}}.ui-select{display:block;position:relative}.ui-select select{position:absolute;left:-9999px;top:-9999px}.ui-select .ui-btn{opacity:1}.ui-field-contain .ui-select .ui-btn{margin:0}.ui-select .ui-btn select{cursor:pointer;-webkit-appearance:none;left:0;top:0;width:100%;min-height:1.5em;min-height:100%;height:3em;max-height:100%;filter:Alpha(Opacity=0);opacity:0;z-index:2}.ui-select .ui-disabled{opacity:.3}.ui-select .ui-disabled select{display:none}@-moz-document url-prefix(){.ui-select .ui-btn select{opacity:.0001}}.ui-select .ui-btn.ui-select-nativeonly{border-radius:0;border:0}.ui-select .ui-btn.ui-select-nativeonly select{opacity:1;text-indent:0;display:block}.ui-select .ui-disabled.ui-select-nativeonly .ui-btn-inner{opacity:0}.ui-select .ui-btn-icon-right .ui-btn-inner,.ui-select .ui-li-has-count .ui-btn-inner{padding-right:45px}.ui-select .ui-mini.ui-btn-icon-right .ui-btn-inner{padding-right:32px}.ui-select .ui-btn-icon-right.ui-li-has-count .ui-btn-inner{padding-right:80px}.ui-select .ui-mini.ui-btn-icon-right.ui-li-has-count .ui-btn-inner{padding-right:67px}.ui-select .ui-btn-icon-right .ui-icon{right:15px}.ui-select .ui-mini.ui-btn-icon-right .ui-icon{right:7px}.ui-select .ui-btn-icon-right.ui-li-has-count .ui-li-count{right:45px}.ui-select .ui-mini.ui-btn-icon-right.ui-li-has-count .ui-li-count{right:32px}label.ui-select{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .3em;display:block}.ui-select .ui-btn-text,.ui-selectmenu .ui-btn-text{display:block;min-height:1em;overflow:hidden!important}.ui-select .ui-btn-text{text-overflow:ellipsis}.ui-selectmenu{padding:6px;min-width:160px}.ui-selectmenu .ui-listview{margin:0}.ui-selectmenu .ui-btn.ui-li-divider{cursor:default}.ui-screen-hidden,.ui-selectmenu-list .ui-li .ui-icon{display:none}.ui-selectmenu-list .ui-li .ui-icon{display:block}.ui-li.ui-selectmenu-placeholder{display:none}.ui-selectmenu .ui-header{margin:0;padding:0}.ui-selectmenu.ui-popup .ui-header{-webkit-border-top-left-radius:0;border-top-left-radius:0;-webkit-border-top-right-radius:0;border-top-right-radius:0}.ui-selectmenu .ui-header .ui-title{margin:.6em 46px .8em}@media all and (min-width:28em){.ui-field-contain label.ui-select{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-select{width:78%;display:inline-block}.ui-hide-label .ui-select{width:100%}}.ui-selectmenu .ui-header h1:after{content:'.';visibility:hidden}label.ui-input-text{font-size:16px;line-height:1.4;display:block;font-weight:400;margin:0 0 .3em}input.ui-input-text,textarea.ui-input-text{background-image:none;padding:.4em;margin:.5em 0;min-height:1.4em;line-height:1.4em;font-size:16px;display:block;width:100%;outline:0}input.ui-mini,.ui-mini input,textarea.ui-mini{font-size:14px}div.ui-input-text input.ui-input-text,div.ui-input-text textarea.ui-input-text,.ui-input-search input.ui-input-text{border:0;width:100%;padding:.4em 0;margin:0;display:block;background:transparent none;outline:0!important}.ui-input-search,div.ui-input-text{margin:.5em 0;background-image:none;position:relative}.ui-input-search{padding:0 30px}div.ui-input-text{padding:0 .4em}div.ui-input-has-clear{padding:0 30px 0 .4em}input.ui-input-text.ui-mini,textarea.ui-input-text.ui-mini,.ui-input-search.ui-mini,div.ui-input-text.ui-mini{margin:.25em 0}.ui-field-contain input.ui-input-text,.ui-field-contain textarea.ui-input-text,.ui-field-contain .ui-input-search,.ui-field-contain div.ui-input-text{margin:0}textarea.ui-input-text{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}input.ui-input-text{-webkit-appearance:none}textarea.ui-input-text{height:50px;-webkit-transition:height 200ms linear;-moz-transition:height 200ms linear;-o-transition:height 200ms linear;transition:height 200ms linear}textarea.ui-mini{height:45px}.ui-icon-searchfield:after{position:absolute;left:7px;top:50%;margin-top:-9px;content:"";width:18px;height:18px;opacity:.5}.ui-input-search .ui-input-clear,.ui-input-text .ui-input-clear{position:absolute;right:0;top:50%;margin-top:-13px}.ui-mini .ui-input-clear{right:-3px}.ui-input-search .ui-input-clear-hidden,.ui-input-text .ui-input-clear-hidden{display:none}input::-moz-placeholder,textarea::-moz-placeholder{color:#aaa}:-ms-input-placeholder{color:#aaa}input[type=number]::-webkit-outer-spin-button{margin:0}@media all and (min-width:28em){.ui-field-contain label.ui-input-text{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain input.ui-input-text,.ui-field-contain textarea.ui-input-text,.ui-field-contain .ui-input-search,.ui-field-contain div.ui-input-text{width:78%;display:inline-block}.ui-field-contain .ui-input-search,.ui-field-contain div.ui-input-text{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-hide-label input.ui-input-text,.ui-hide-label textarea.ui-input-text,.ui-hide-label .ui-input-search,.ui-hide-label div.ui-input-text,.ui-input-search input.ui-input-text,div.ui-input-text input.ui-input-text{width:100%}}.ui-rangeslider{zoom:1;margin:0}.ui-rangeslider:before,.ui-rangeslider:after{content:"";display:table}.ui-rangeslider:after{clear:both}.ui-rangeslider input.ui-input-text.ui-slider-input{margin:.57143em 0}.ui-rangeslider.ui-mini input.ui-slider-input{margin:.28571em 0}.ui-rangeslider input.ui-slider-input.ui-rangeslider-last{float:right}.ui-rangeslider .ui-rangeslider-sliders{position:relative;overflow:visible;height:30px;margin:.5em 68px}.ui-rangeslider.ui-mini .ui-rangeslider-sliders{margin:.25em 68px}.ui-field-contain .ui-rangeslider input.ui-slider-input,.ui-field-contain .ui-rangeslider.ui-mini input.ui-slider-input,.ui-field-contain .ui-rangeslider .ui-rangeslider-sliders,.ui-field-contain .ui-rangeslider.ui-mini .ui-rangeslider-sliders{margin-top:0;margin-bottom:0}.ui-rangeslider .ui-rangeslider-sliders .ui-slider-track{position:absolute;top:6px;right:0;left:0;margin:0}.ui-rangeslider.ui-mini .ui-rangeslider-sliders .ui-slider-track{top:8px}.ui-rangeslider .ui-slider-track:first-child .ui-slider-bg{display:none}.ui-rangeslider .ui-rangeslider-sliders .ui-slider-track:first-child{background-color:transparent;background:0;border-width:0;height:0}html >body .ui-rangeslider .ui-rangeslider-sliders .ui-slider-track:first-child{height:15px;border-width:1px}html >body .ui-rangeslider.ui-mini .ui-rangeslider-sliders .ui-slider-track:first-child{height:12px}@media all and (min-width:28em){.ui-field-contain .ui-rangeslider label.ui-slider{float:left}.ui-field-contain .ui-rangeslider input.ui-slider-input{position:relative;z-index:1}.ui-field-contain .ui-rangeslider input.ui-slider-input.ui-rangeslider-first,.ui-field-contain .ui-rangeslider.ui-mini input.ui-slider-input.ui-rangeslider-first{margin-right:17px}.ui-field-contain .ui-rangeslider .ui-rangeslider-sliders,.ui-field-contain .ui-rangeslider.ui-mini .ui-rangeslider-sliders{float:left;width:78%;margin:0 -68px}.ui-field-contain .ui-rangeslider .ui-slider-track,.ui-field-contain .ui-rangeslider.ui-mini .ui-slider-track{right:68px;left:68px}.ui-field-contain.ui-hide-label .ui-rangeslider input.ui-slider-input.ui-rangeslider-first{margin:0}.ui-field-contain.ui-hide-label .ui-rangeslider .ui-rangeslider-sliders,.ui-field-contain.ui-hide-label .ui-rangeslider.ui-mini .ui-rangeslider-sliders{width:auto;float:none;margin:0 68px}.ui-field-contain.ui-hide-label .ui-rangeslider .ui-slider-track,.ui-field-contain.ui-hide-label .ui-rangeslider.ui-mini .ui-slider-track{right:0;left:0}}.ui-listview{margin:0}ol.ui-listview,ol.ui-listview .ui-li-divider{counter-reset:listnumbering}.ui-content .ui-listview,.ui-panel-inner>.ui-listview{margin:-15px}.ui-collapsible-content>.ui-listview{margin:-10px -15px}.ui-content .ui-listview-inset,.ui-panel-inner .ui-listview-inset{margin:1em 0}.ui-collapsible-content .ui-listview-inset{margin:.5em 0}.ui-listview,.ui-li{list-style:none;padding:0}.ui-li,.ui-li.ui-field-contain{display:block;margin:0;position:relative;overflow:visible;text-align:left;border-width:0;border-top-width:1px}.ui-li.ui-btn,.ui-li.ui-field-contain,.ui-li-divider,.ui-li-static{margin:0}.ui-listview-inset .ui-li{border-right-width:1px;border-left-width:1px}.ui-li.ui-last-child,.ui-li.ui-field-contain.ui-last-child{border-bottom-width:1px}.ui-collapsible-content>.ui-listview:not(.ui-listview-inset)>.ui-li.ui-first-child{border-top-width:0}.ui-collapsible-themed-content .ui-listview:not(.ui-listview-inset)>.ui-li.ui-last-child{border-bottom-width:0}.ui-li .ui-btn-text a.ui-link-inherit{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-static{background-image:none}.ui-li-divider{padding:.5em 15px;font-size:14px;font-weight:700}ol.ui-listview .ui-link-inherit:before,ol.ui-listview .ui-li-static:before,.ui-li-dec{font-size:.8em;display:inline-block;padding-right:.3em;font-weight:400;counter-increment:listnumbering;content:counter(listnumbering) ". "}ol.ui-listview .ui-li-jsnumbering:before{content:""!important}.ui-listview .ui-li>.ui-btn-text{-webkit-border-radius:inherit;border-radius:inherit}.ui-listview>.ui-li.ui-first-child,.ui-listview .ui-btn.ui-first-child>.ui-li>.ui-btn-text>.ui-link-inherit{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit;-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit}.ui-listview>.ui-li.ui-last-child,.ui-listview .ui-btn.ui-last-child>.ui-li>.ui-btn-text>.ui-link-inherit,.ui-collapsible-content>.ui-listview:not(.ui-listview-inset),.ui-collapsible-content>.ui-listview:not(.ui-listview-inset) .ui-li.ui-last-child{-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit;-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-listview>.ui-li.ui-first-child .ui-li-link-alt{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit}.ui-listview>.ui-li.ui-last-child .ui-li-link-alt{-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-listview>.ui-li.ui-first-child .ui-li-thumb:not(.ui-li-icon){-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit}.ui-listview>.ui-li.ui-last-child .ui-li-thumb:not(.ui-li-icon){-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-li>.ui-btn-inner{display:block;position:relative;padding:0}.ui-li .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li{padding:.7em 15px;display:block}.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-thumb{min-height:59px;padding-left:100px}.ui-li-has-icon .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-icon{min-height:20px;padding-left:40px}.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-count,.ui-li-divider.ui-li-has-count{padding-right:45px}.ui-li-has-arrow .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow{padding-right:40px}.ui-li-has-arrow.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow.ui-li-has-count{padding-right:75px}.ui-li-heading{font-size:16px;font-weight:700;display:block;margin:.6em 0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-desc{font-size:12px;font-weight:400;display:block;margin:-.5em 0 .6em;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}ol.ui-listview>.ui-li .ui-li-heading{display:inline-block;width:100%;margin-left:-1.3em;text-indent:1.3em;vertical-align:middle}ol.ui-listview>.ui-li .ui-li-desc:not(.ui-li-aside){text-indent:1.55em}.ui-li-thumb,.ui-listview .ui-li-icon{position:absolute;left:1px;top:0;max-height:80px;max-width:80px}.ui-listview .ui-li-icon{max-height:16px;max-width:16px;left:10px;top:.9em}.ui-li-thumb,.ui-listview .ui-li-icon,.ui-li-content{float:left;margin-right:10px}.ui-li-aside{float:right;width:50%;text-align:right;margin:.3em 0}@media all and (min-width:480px){.ui-li-aside{width:45%}}.ui-li-divider{cursor:default}.ui-li-has-alt .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-alt{padding-right:53px}.ui-li-has-alt.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-alt.ui-li-has-count{padding-right:88px}.ui-li-has-count .ui-li-count{position:absolute;font-size:11px;font-weight:700;padding:.2em .5em;top:50%;margin-top:-.9em;right:10px}.ui-li-has-count.ui-li-divider .ui-li-count,.ui-li-has-count .ui-link-inherit .ui-li-count{margin-top:-.95em}.ui-li-has-arrow.ui-li-has-count .ui-li-count{right:40px}.ui-li-has-alt.ui-li-has-count .ui-li-count{right:53px}.ui-li-link-alt{position:absolute;width:40px;height:100%;border-width:0;border-left-width:1px;top:0;right:0;margin:0;padding:0;z-index:2}.ui-li-link-alt .ui-btn{overflow:hidden;position:absolute;right:8px;top:50%;margin:-13px 0 0 0;border-bottom-width:1px;z-index:-1}.ui-li-link-alt .ui-btn-inner{padding:0;height:100%;position:absolute;width:100%;top:0;left:0}.ui-li-link-alt .ui-btn .ui-icon{right:50%;margin-right:-9px}.ui-li-link-alt .ui-btn-icon-notext .ui-btn-inner .ui-icon{position:absolute;top:50%;margin-top:-9px}.ui-listview * .ui-btn-inner>.ui-btn>.ui-btn-inner{border-top:0}.ui-listview-filter{border-width:0;overflow:hidden;margin:-15px -15px 15px -15px}.ui-collapsible-content .ui-listview-filter{margin:-10px -15px 10px -15px;border-bottom:inherit}.ui-listview-filter-inset{margin:-15px -5px;background:transparent}.ui-collapsible-content .ui-listview-filter-inset{margin:-5px;border-bottom-width:0}.ui-listview-filter .ui-input-search{margin:5px;width:auto;display:block}.ui-li.ui-screen-hidden{display:none}@media only screen and (min-device-width:768px) and (max-device-width:1024px){.ui-li .ui-btn-text{overflow:visible}}label.ui-slider{font-size:16px;line-height:1.4;font-weight:400;margin:0;display:block}.ui-field-contain label.ui-slider{margin-bottom:.4em}div.ui-slider{height:30px;margin:.5em 0;zoom:1}div.ui-slider.ui-mini{margin:.25em 0}.ui-field-contain div.ui-slider,.ui-field-contain div.ui-slider.ui-mini{margin:0}div.ui-slider:before,div.ui-slider:after{content:"";display:table}div.ui-slider:after{clear:both}input.ui-input-text.ui-slider-input{display:block;float:left;margin:0;padding:4px;width:40px;height:22px;line-height:22px;font-size:14px;border-width:0;background-image:none;font-weight:700;text-align:center;vertical-align:text-bottom;outline:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;-ms-box-sizing:content-box;box-sizing:content-box}.ui-slider-input::-webkit-outer-spin-button,.ui-slider-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.ui-slider-track,.ui-slider-switch{position:relative;overflow:visible;height:15px;margin:0 15px 0 68px;top:6px}.ui-slider-track.ui-mini{height:12px;top:8px}.ui-slider-bg{border:0;height:100%}.ui-slider-track .ui-btn.ui-slider-handle,.ui-slider-switch .ui-btn.ui-slider-handle{position:absolute;z-index:1;top:50%;width:28px;height:28px;margin:-15px 0 0 -15px;outline:0}.ui-slider-track.ui-mini .ui-slider-handle{height:14px;width:14px;margin:-8px 0 0 -7px}.ui-slider-handle .ui-btn-inner{padding:0;height:100%}.ui-slider-track.ui-mini .ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:-9px 0 0 -9px;border-top:0}select.ui-slider-switch{display:none}div.ui-slider-switch{display:inline-block;height:32px;width:5.8em;margin:.5em 0;top:0}div.ui-slider-switch:before,div.ui-slider-switch:after{display:none;clear:none}div.ui-slider-switch.ui-mini{width:5em;height:29px;margin:.25em 0;top:0}.ui-field-contain .ui-slider-switch,.ui-field-contain .ui-slider-switch.ui-mini{margin:0}.ui-slider-inneroffset{margin:0 16px;position:relative;z-index:1}.ui-slider-switch.ui-mini .ui-slider-inneroffset{margin:0 15px 0 14px}.ui-slider-switch .ui-btn.ui-slider-handle{margin:1px 0 0 -15px}.ui-slider-switch.ui-mini .ui-slider-handle{width:25px;height:25px;margin:1px 0 0 -13px;padding:0}.ui-slider-handle-snapping{-webkit-transition:left 70ms linear;-moz-transition:left 70ms linear}.ui-slider-switch.ui-mini .ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:0;border-top:0}.ui-slider-switch .ui-slider-label{position:absolute;text-align:center;width:100%;overflow:hidden;font-size:16px;top:0;line-height:2;min-height:100%;border-width:0;white-space:nowrap;cursor:pointer}.ui-slider-switch.ui-mini .ui-slider-label{font-size:14px}.ui-slider-switch .ui-slider-label-a{z-index:1;left:0;text-indent:-1.5em}.ui-slider-switch .ui-slider-label-b{z-index:0;right:0;text-indent:1.5em}@media all and (min-width:28em){.ui-field-contain label.ui-slider{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain div.ui-slider{display:inline-block;width:78%}.ui-field-contain.ui-hide-label div.ui-slider{display:block;width:auto}.ui-field-contain div.ui-slider-switch,.ui-field-contain.ui-hide-label div.ui-slider-switch{display:inline-block;width:5.8em}.ui-field-contain div.ui-slider-switch.ui-mini{width:5em}}.ui-table{border:0;border-collapse:collapse;padding:0;width:100%}.ui-table th,.ui-table td{line-height:1.5em;text-align:left;padding:.4em .5em;vertical-align:top}.ui-table th .ui-btn,.ui-table td .ui-btn{line-height:normal}.ui-table th{font-weight:700}.ui-table caption{text-align:left;margin-bottom:1.4em;opacity:.5}.table-stroke thead th{border-bottom:1px solid #d6d6d6;border-bottom:1px solid rgba(0,0,0,.1)}.table-stroke tbody th,.table-stroke tbody td{border-bottom:1px solid #e6e6e6;border-bottom:1px solid rgba(0,0,0,.05)}.table-stripe tbody tr:nth-child(odd) td,.table-stripe tbody tr:nth-child(odd) th{background-color:#eee;background-color:rgba(0,0,0,.04)}.table-stripe thead th,.table-stripe tbody tr:last-child{border-bottom:1px solid #d6d6d6;border-bottom:1px solid rgba(0,0,0,.1)}.ui-table-columntoggle-btn{float:right;margin-bottom:.8em}.ui-table-columntoggle-popup fieldset{margin:0}@media only all{th.ui-table-priority-6,td.ui-table-priority-6,th.ui-table-priority-5,td.ui-table-priority-5,th.ui-table-priority-4,td.ui-table-priority-4,th.ui-table-priority-3,td.ui-table-priority-3,th.ui-table-priority-2,td.ui-table-priority-2,th.ui-table-priority-1,td.ui-table-priority-1{display:none}}@media screen and (min-width:20em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-1,.ui-table-columntoggle.ui-responsive td.ui-table-priority-1{display:table-cell}}@media screen and (min-width:30em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-2,.ui-table-columntoggle.ui-responsive td.ui-table-priority-2{display:table-cell}}@media screen and (min-width:40em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-3,.ui-table-columntoggle.ui-responsive td.ui-table-priority-3{display:table-cell}}@media screen and (min-width:50em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-4,.ui-table-columntoggle.ui-responsive td.ui-table-priority-4{display:table-cell}}@media screen and (min-width:60em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-5,.ui-table-columntoggle.ui-responsive td.ui-table-priority-5{display:table-cell}}@media screen and (min-width:70em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-6,.ui-table-columntoggle.ui-responsive td.ui-table-priority-6{display:table-cell}}.ui-table-columntoggle th.ui-table-cell-hidden,.ui-table-columntoggle td.ui-table-cell-hidden,.ui-table-columntoggle.ui-responsive th.ui-table-cell-hidden,.ui-table-columntoggle.ui-responsive td.ui-table-cell-hidden{display:none}.ui-table-columntoggle th.ui-table-cell-visible,.ui-table-columntoggle td.ui-table-cell-visible,.ui-table-columntoggle.ui-responsive th.ui-table-cell-visible,.ui-table-columntoggle.ui-responsive td.ui-table-cell-visible{display:table-cell}.ui-table-reflow td .ui-table-cell-label,.ui-table-reflow th .ui-table-cell-label{display:none}@media only all{.ui-table-reflow thead td,.ui-table-reflow thead th{display:none}.ui-table-reflow td,.ui-table-reflow th{text-align:left;display:block}.ui-table-reflow tbody th{margin-top:3em}.ui-table-reflow td .ui-table-cell-label,.ui-table-reflow th .ui-table-cell-label{padding:.4em;min-width:30%;display:inline-block;margin:-.4em 1em -.4em -.4em}.ui-table-reflow th .ui-table-cell-label-top,.ui-table-reflow td .ui-table-cell-label-top{display:block;padding:.4em 0;margin:.4em 0;text-transform:uppercase;font-size:.9em;font-weight:400}}@media (min-width:35em){.ui-table-reflow.ui-responsive{display:table-row-group}.ui-table-reflow.ui-responsive td,.ui-table-reflow.ui-responsive th,.ui-table-reflow.ui-responsive tbody th,.ui-table-reflow.ui-responsive tbody td,.ui-table-reflow.ui-responsive thead td,.ui-table-reflow.ui-responsive thead th{display:table-cell;margin:0}.ui-table-reflow.ui-responsive td .ui-table-cell-label,.ui-table-reflow.ui-responsive th .ui-table-cell-label{display:none}}@media (max-width:35em){.ui-table-reflow.ui-responsive td,.ui-table-reflow.ui-responsive th{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;clear:left}}.ui-panel{width:17em;min-height:100%;max-height:none;border-width:0;position:absolute;top:0;display:block}.ui-panel-closed{width:0;max-height:100%;overflow:hidden;visibility:hidden}.ui-panel-fixed{position:fixed;bottom:-1px;padding-bottom:1px}.ui-panel-display-overlay{z-index:1001}.ui-panel-display-reveal{z-index:0}.ui-panel-display-push{z-index:999}.ui-panel-inner{padding:15px}.ui-panel-content-wrap{position:relative;left:0;min-height:inherit;border:0;z-index:999}.ui-panel-content-wrap-display-overlay,.ui-panel-animate.ui-panel-content-wrap>.ui-header,.ui-panel-content-wrap-closed{position:static}.ui-panel-dismiss{position:absolute;top:0;left:0;height:100%;width:100%;z-index:1002;display:none}.ui-panel-dismiss-open{display:block}.ui-panel-animate{-webkit-transition:-webkit-transform 350ms ease;-moz-transition:-moz-transform 350ms ease;transition:transform 350ms ease}.ui-panel-animate.ui-panel:not(.ui-panel-display-reveal),.ui-panel-animate.ui-panel:not(.ui-panel-display-reveal)>div,.ui-panel-animate.ui-panel-closed.ui-panel-display-reveal>div,.ui-panel-animate.ui-panel-content-wrap,.ui-panel-animate.ui-panel-content-fixed-toolbar{-webkit-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0)}.ui-panel-position-left{left:-17em}.ui-panel-animate.ui-panel-position-left.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-left.ui-panel-display-push{left:0;-webkit-transform:translate3d(-17em,0,0);-moz-transform:translate3d(-17em,0,0);transform:translate3d(-17em,0,0)}.ui-panel-position-left.ui-panel-display-reveal,.ui-panel-position-left.ui-panel-open{left:0}.ui-panel-animate.ui-panel-position-left.ui-panel-open.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-left.ui-panel-open.ui-panel-display-push{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-moz-transform:none}.ui-panel-position-right{right:-17em}.ui-panel-animate.ui-panel-position-right.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-right.ui-panel-display-push{right:0;-webkit-transform:translate3d(17em,0,0);-moz-transform:translate3d(17em,0,0);transform:translate3d(17em,0,0)}.ui-panel-position-right.ui-panel-display-reveal,.ui-panel-position-right.ui-panel-open{right:0}.ui-panel-animate.ui-panel-position-right.ui-panel-open.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-right.ui-panel-open.ui-panel-display-push{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-moz-transform:none}.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open,.ui-panel-content-wrap-position-left.ui-panel-content-wrap-open,.ui-panel-dismiss-position-left.ui-panel-dismiss-open{left:17em;right:-17em}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-reveal,.ui-panel-animate.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push,.ui-panel-animate.ui-panel-content-wrap-position-left.ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal,.ui-panel-animate.ui-panel-content-wrap-position-left.ui-panel-content-wrap-open.ui-panel-content-wrap-display-push{left:0;right:0;-webkit-transform:translate3d(17em,0,0);-moz-transform:translate3d(17em,0,0);transform:translate3d(17em,0,0)}.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open,.ui-panel-content-wrap-position-right.ui-panel-content-wrap-open,.ui-panel-dismiss-position-right.ui-panel-dismiss-open{left:-17em;right:17em}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-reveal,.ui-panel-animate.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push,.ui-panel-animate.ui-panel-content-wrap-position-right.ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal,.ui-panel-animate.ui-panel-content-wrap-position-right.ui-panel-content-wrap-open.ui-panel-content-wrap-display-push{left:0;right:0;-webkit-transform:translate3d(-17em,0,0);-moz-transform:translate3d(-17em,0,0);transform:translate3d(-17em,0,0)}.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-overlay,.ui-panel-content-wrap-open.ui-panel-content-wrap-display-overlay{left:0}.ui-page-active.ui-page-panel{overflow-x:hidden}.ui-panel-display-reveal{-webkit-box-shadow:inset -5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:inset -5px 0 5px rgba(0,0,0,.15);box-shadow:inset -5px 0 5px rgba(0,0,0,.15)}.ui-panel-position-right.ui-panel-display-reveal{-webkit-box-shadow:inset 5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:inset 5px 0 5px rgba(0,0,0,.15);box-shadow:inset 5px 0 5px rgba(0,0,0,.15)}.ui-panel-display-overlay{-webkit-box-shadow:5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:5px 0 5px rgba(0,0,0,.15);box-shadow:5px 0 5px rgba(0,0,0,.15)}.ui-panel-position-right.ui-panel-display-overlay{-webkit-box-shadow:-5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:-5px 0 5px rgba(0,0,0,.15);box-shadow:-5px 0 5px rgba(0,0,0,.15)}.ui-panel-display-push.ui-panel-open.ui-panel-position-left{border-right-width:1px;margin-right:-1px}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push{margin-left:1px}.ui-panel-display-push.ui-panel-open.ui-panel-position-right{border-left-width:1px;margin-left:-1px}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push{margin-right:1px}@media (min-width:55em){.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-push.ui-panel-content-fixed-toolbar-position-left,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-reveal.ui-panel-content-fixed-toolbar-position-left,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-push.ui-panel-content-wrap-position-left,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-reveal.ui-panel-content-wrap-position-left{margin-right:17em}.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-push.ui-panel-content-fixed-toolbar-position-right,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-reveal.ui-panel-content-fixed-toolbar-position-right,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-push.ui-panel-content-wrap-position-right,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-reveal.ui-panel-content-wrap-position-right{margin-left:17em}.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-push,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-reveal{width:auto}.ui-responsive-panel .ui-panel-dismiss-display-push{display:none}} \ No newline at end of file
diff --git a/web/favicon.ico b/web/favicon.ico
deleted file mode 100644
index b34133fbaa1..00000000000
--- a/web/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/web/images/logo-mame-small.png b/web/images/logo-mame-small.png
deleted file mode 100644
index 1b2bcaff0b3..00000000000
--- a/web/images/logo-mame-small.png
+++ /dev/null
Binary files differ
diff --git a/web/index.html b/web/index.html
deleted file mode 100644
index d12f4c38526..00000000000
--- a/web/index.html
+++ /dev/null
@@ -1,917 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <meta charset="utf-8">
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="expires" content="-1">
- <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
- <meta name="apple-mobile-web-app-capable" content="yes">
- <meta name="apple-mobile-web-app-status-bar-style" content="black">
- <title>MAME</title>
- <link rel="shortcut icon" href="favicon.ico">
- <link rel="stylesheet" href="css/jquery.mobile.css">
- <!-- jQuery and jQuery Mobile -->
- <script src="js/jquery.js"></script>
- <script src="js/jquery.mobile.js"></script>
-</head>
-<body>
-<script language="javascript" type="text/javascript">
-
- function updateStatusBar(connectionStatus, isPaused, driverText) {
- if (connectionStatus) {
- // Update every page's connection statusbar.
- $("td#main_statusbar_connectionstatus").html(connectionStatus);
- $("td#command_statusbar_connectionstatus").html(connectionStatus);
- $("td#option_statusbar_connectionstatus").html(connectionStatus);
- $("td#slider_statusbar_connectionstatus").html(connectionStatus);
- $("td#driver_statusbar_connectionstatus").html(connectionStatus);
- $("td#image_statusbar_connectionstatus").html(connectionStatus);
- $("td#info_statusbar_connectionstatus").html(connectionStatus);
- $("td#logs_statusbar_connectionstatus").html(connectionStatus);
- }
- if (isPaused) {
- // Update every page's running/paused statusbar.
- $("td#main_statusbar_ispaused").html(isPaused);
- $("td#command_statusbar_ispaused").html(isPaused);
- $("td#option_statusbar_ispaused").html(isPaused);
- $("td#slider_statusbar_ispaused").html(isPaused);
- $("td#driver_statusbar_ispaused").html(isPaused);
- $("td#image_statusbar_ispaused").html(isPaused);
- $("td#info_statusbar_ispaused").html(isPaused);
- $("td#logs_statusbar_ispaused").html(isPaused);
- }
- if (driverText) {
- // Update every page's running driver statusbar.
- $("td#main_statusbar_runningdriver").html(driverText);
- $("td#command_statusbar_runningdriver").html(driverText);
- $("td#option_statusbar_runningdriver").html(driverText);
- $("td#slider_statusbar_runningdriver").html(driverText);
- $("td#driver_statusbar_runningdriver").html(driverText);
- $("td#image_statusbar_runningdriver").html(driverText);
- $("td#info_statusbar_runningdriver").html(driverText);
- $("td#logs_statusbar_runningdriver").html(driverText);
- }
-
- }
-
- function takeScreenshot()
- {
- // First, we need to generate a random number to make absolutely sure we bypass browser caching.
- var random=Math.floor(Math.random()*999999999)
- $("#screenshot").html('<img height="240" width="320" src="/screenshot.png?cachebreaker='+random.toString()+'"/>');
- // Navigate back to home so we can see the screenshot.
- window.location.hash='#mainmenu';
- }
-
- function executeCommands(command)
- {
- $.ajax({
- url: "/cmd?name="+command,
- cache: false,
- dataType: "text",
- success: function(data) {
- },
- error: function (request, status, error) { alert(status + ", " + error); }
- });
- if (command !== 'exit') {
- startWebSocket();
- } else {
- updateStatusBar('<b style="color: red;">Disconnected</b>','Exited','No Driver');
- }
- }
-
- function executeHardReset()
- {
- executeCommands("hardreset");
- startWebSocket();
- $('.ui-dialog').dialog('close');
- }
-
- function executeSoftReset()
- {
- executeCommands("softreset");
- startWebSocket();
- $('.ui-dialog').dialog('close');
- }
-
- function executeExit()
- {
- executeCommands("exit");
- $('.ui-dialog').dialog('close');
- }
-
- function executeSlider()
- {
- $.ajax({
- url: "/json/slider",
- cache: false,
- dataType: "json",
- success: function(data) {
- var items = [];
- for (var i in data) {
- items.push('<label for="slider-mini-'+i+'">'+data[i].description +':</label>');
- items.push('<input type="range" name="slider-mini-'+i+'" id="slider-mini-'+i+'" value="'+data[i].curval+'" min="'+data[i].minval+'" max="'+data[i].maxval+'" step=="'+data[i].incval+'" data-highlight="true" data-mini="true" />');
- }
- $('#sliders').html('');
- $('#sliders').append(items.join('')).trigger('create');
- for (var i in data) {
- $('#slider-mini-' + i).bind( "slidestop", function(event, ui) { setSliderValue($(this).attr('id').replace('slider-mini-',''),$(this).slider().val()); });
- }
-
- },
- error: function (request, status, error) { alert(status + ", " + error); }
- });
- window.location.hash='#slidermenu'; // Just making sure we're on the slider screen.
- }
-
- function setSliderValue(id,val)
- {
- $.ajax({
- url: "/slider?id="+id+"&val="+val,
- cache: false,
- dataType: "text",
- success: function(data) {
- },
- error: function (request, status, error) { alert(status + ", " + error); }
- });
- }
-
- function startWebSocket() {
- var docbase = window.location.href.toString().split('#')[0]; // We strip the fragment from the URL using split.
- var url = docbase.replace("http://","ws://");
- websocket = new WebSocket(url);
- websocket.onopen = function(ev) {
- updateStatusBar('<b style="color: green;">Connected</b>','','');
- };
- websocket.onclose = function(ev) {
- updateStatusBar('<b style="color: red;">Disconnected</b>','','');
- };
- websocket.onmessage = function(ev) {
- if (ev.data=='update_machine')
- {
- $.ajax({
- url: "json/game",
- cache: false,
- dataType: "json",
- success: function(data) {
- var maindesc_name = [];
- var maindesc_description = [];
- var maindesc_year = [];
- var maindesc_manufacturer = [];
- var maindesc_parent = [];
- var maindesc_sourcefile = [];
- var statusbar_ispaused = [];
- var statusbar_runningdriver = [];
- if(data.ispaused) {
- statusbar_ispaused.push('<b style="color: red; ">Paused</b>');
- } else {
- statusbar_ispaused.push('<b style="color: green; ">Running</b>');
- }
- if(data.name =='__empty') {
- statusbar_runningdriver.push('No driver');
- } else {
- statusbar_runningdriver.push(data.description + ' [' + data.manufacturer+']');
- }
- maindesc_name.push(data.name);
- maindesc_description.push(data.description);
- maindesc_year.push(data.year);
- maindesc_manufacturer.push(data.manufacturer);
- maindesc_parent.push(data.parent);
- maindesc_sourcefile.push(data.source_file);
- $("#maindesc_name").html(maindesc_name.join(''));
- $("#maindesc_description").html(maindesc_description.join(''));
- $("#maindesc_year").html(maindesc_year.join(''));
- $("#maindesc_manufacturer").html(maindesc_manufacturer.join(''));
- $("#maindesc_parent").html(maindesc_parent.join(''));
- $("#maindesc_sourcefile").html(maindesc_sourcefile.join(''));
-
- // Now, actually update the status bar..
- updateStatusBar('',statusbar_ispaused.join(''),statusbar_runningdriver.join(''));
- takeScreenshot();
- },
- error: function (request, status, error) { alert(status + ", " + error); }
- });
- }
-
- };
- websocket.onerror = function(ev) {
- updateStatusBar('<b style="color: red; ">Error</b>',' ',' ');
- };
- }
-
- window.onload = function() {
- startWebSocket();
- };
-
-$(document).ready(function() {
- $( '#pasteTextForm' ).submit(function( event )
- {
- $.ajax({
- url: "/keypost",
- type:'POST',
- data:
- {
- val: pasteText.value
- },
- success: function(msg)
- {
- }
- });
- event.preventDefault(); // This prevents it trying to load a /keypost page after doing the Ajax post.
- });
-});
-
-</script>
-
-<!-- This begins the MAIN MENU page ------------------------------------------------------------------->
-<div data-role="page" id="mainmenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#drivermenumenu" data-transition="fade" data-icon="bars">Driver</a>
- </li>
- <li>
- <a href="#optionmenu" data-transition="fade" data-icon="gear">Options</a>
- </li>
- <li>
- <a href="#imagemenu" data-transition="fade" data-icon="grid">Image</a>
- </li>
- <li>
- <a href="#commandmenu" data-transition="fade" data-icon="star">Commands</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="mainmenucontent">
- <table style="tablelayout: auto; width: 100%" border="0">
- <tr>
- <td style="padding: 0px; vertical-align:top; width: 1px"><div id="screenshot"><img height="240" width="320" src="/screenshot.png"></div></td>
- <td style="padding: 0px; vertical-align:top">
- <table border="0"><div id="drivertext"></div>
- <tr>
- <th style="text-align:left;">Name</th>
- <td><div id="maindesc_name"></div></td>
- </tr>
- <tr>
- <th style="text-align:left;">Description</th>
- <td><div id="maindesc_description"></div></td>
- </tr>
- <tr>
- <th style="text-align:left;">Year</th>
- <td><div id="maindesc_year"></div></td>
- </tr>
- <tr>
- <th style="text-align:left;">Manufacturer</th>
- <td><div id="maindesc_manufacturer"></div></td>
- </tr>
- <tr>
- <th style="text-align:left;">Parent</th>
- <td><div id="maindesc_parent"></div></td>
- </tr>
- <tr>
- <th style="text-align:left;">Source File</th>
- <td><div id="maindesc_sourcefile"></div></td>
- </tr>
- </table>
- </td>
- </tr>
- </table>
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#infomenu" data-transition="fade" data-icon="info">Info</a>
- </li>
- <li>
- <a href="#logsmenu" data-transition="fade" data-icon="check">Logs</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="main_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="main_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="main_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-</div>
-
-<!-- This begins the COMMAND MENU page ------------------------------------------------------------------->
-<div data-role="page" id="commandmenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#drivermenumenu" data-transition="fade" data-icon="bars">Driver</a>
- </li>
- <li>
- <a href="#optionmenu" data-transition="fade" data-icon="gear">Options</a>
- </li>
- <li>
- <a href="#imagemenu" data-transition="fade" data-icon="grid">Image</a>
- </li>
- <li>
- <a href="#mainmenu" data-transition="fade" data-icon="home">Main Menu</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="menu_commandmenu">
- <h2>Savestate Control</h2>
- <div class="ui-grid-a">
- <div class="ui-block-a"><a href="#savestatepanel" data-transition="fade" data-role="button">Save State</a></div>
- <div class="ui-block-b"><a href="#loadstatepanel" data-transition="fade" data-role="button">Load State</a></div>
- </div>
- <h2>Paste/Upload Text</h2>
- <div class="ui-grid-a">
- <div class="ui-block-a"><a href="#pastepanel" data-transition="fade" data-role="button">Paste Text</a></div>
- <div class="ui-block-b"><a href="#uploadpastepanel" data-transition="fade" data-role="button">Upload Text</a></div>
- </div>
- <h2>Execution Control</h2>
- <div class="ui-grid-a">
- <div class="ui-block-a"><a href="#dialogConfirmSoftReset" data-rel="dialog" data-role="button">Soft reset</a></div>
- <div class="ui-block-b"><a href="#dialogConfirmHardReset" data-rel="dialog" data-role="button">Hard reset</a></div>
- </div>
- <div class="ui-grid-a">
- <div class="ui-block-b"><a href="javascript:executeCommands('togglepause');" data-role="button">Toggle Pause</a></div>
- <div class="ui-block-b"><a href="#dialogConfirmExit" data-rel="dialog" data-role="button">Exit</a></div>
- </div>
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#infomenu" data-transition="fade" data-icon="info">Info</a>
- </li>
- <li>
- <a href="#logsmenu" data-transition="fade" data-icon="check">Logs</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="command_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="command_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="command_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-
- <!-- This begins the Save State panel -------------------------------------------------------->
- <div data-role="panel" id="savestatepanel" data-position="left" data-display="overlay" data-theme="a">
- <h3>Select position to save to</h3><br>
-
- <!-- Yes, it's a little ugly. I could redo this more cleanly with a little javascript, but not right now. -->
- <div data-role="controlgroup" data-type="horizontal">
- <a href="" data-rel="close" data-role="button">Cancel</a>
- <a href="javascript:executeCommands('savestate&val=auto');" data-role="button">Auto Slot</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=0');" data-role="button">0</a>
- <a href="javascript:executeCommands('savestate&val=1');" data-role="button">1</a>
- <a href="javascript:executeCommands('savestate&val=2');" data-role="button">2</a>
- <a href="javascript:executeCommands('savestate&val=3');" data-role="button">3</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=4');" data-role="button">4</a>
- <a href="javascript:executeCommands('savestate&val=5');" data-role="button">5</a>
- <a href="javascript:executeCommands('savestate&val=6');" data-role="button">6</a>
- <a href="javascript:executeCommands('savestate&val=7');" data-role="button">7</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=8');" data-role="button">8</a>
- <a href="javascript:executeCommands('savestate&val=9');" data-role="button">9</a>
- <a href="javascript:executeCommands('savestate&val=a');" data-role="button">A</a>
- <a href="javascript:executeCommands('savestate&val=b');" data-role="button">B</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=c');" data-role="button">C</a>
- <a href="javascript:executeCommands('savestate&val=d');" data-role="button">D</a>
- <a href="javascript:executeCommands('savestate&val=e');" data-role="button">E</a>
- <a href="javascript:executeCommands('savestate&val=f');" data-role="button">F</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=g');" data-role="button">G</a>
- <a href="javascript:executeCommands('savestate&val=h');" data-role="button">H</a>
- <a href="javascript:executeCommands('savestate&val=i');" data-role="button">I</a>
- <a href="javascript:executeCommands('savestate&val=j');" data-role="button">J</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=k');" data-role="button">K</a>
- <a href="javascript:executeCommands('savestate&val=l');" data-role="button">L</a>
- <a href="javascript:executeCommands('savestate&val=m');" data-role="button">M</a>
- <a href="javascript:executeCommands('savestate&val=n');" data-role="button">N</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=o');" data-role="button">O</a>
- <a href="javascript:executeCommands('savestate&val=p');" data-role="button">P</a>
- <a href="javascript:executeCommands('savestate&val=q');" data-role="button">Q</a>
- <a href="javascript:executeCommands('savestate&val=r');" data-role="button">R</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=s');" data-role="button">S</a>
- <a href="javascript:executeCommands('savestate&val=t');" data-role="button">T</a>
- <a href="javascript:executeCommands('savestate&val=u');" data-role="button">U</a>
- <a href="javascript:executeCommands('savestate&val=v');" data-role="button">V</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('savestate&val=w');" data-role="button">W</a>
- <a href="javascript:executeCommands('savestate&val=x');" data-role="button">X</a>
- <a href="javascript:executeCommands('savestate&val=y');" data-role="button">Y</a>
- <a href="javascript:executeCommands('savestate&val=z');" data-role="button">Z</a>
- </div>
- <!-- This is here to prevent webkit from trying to put the last row of states under the bottom menu on small screens like phone-->
- <br><br><br><br><br>
- </div>
-
- <!-- This begins the Load State panel -------------------------------------------------------->
- <div data-role="panel" id="loadstatepanel" data-position="left" data-display="overlay" data-theme="a">
- <h3>Select position to load from</h3><br>
-
- <!-- Yes, it's a little ugly. I could redo this more cleanly with a little javascript, but not right now. -->
- <div data-role="controlgroup" data-type="horizontal">
- <a href="" data-rel="close" data-role="button">Cancel</a>
- <a href="javascript:executeCommands('loadstate&val=auto');" data-role="button">Auto Slot</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=0');" data-role="button">0</a>
- <a href="javascript:executeCommands('loadstate&val=1');" data-role="button">1</a>
- <a href="javascript:executeCommands('loadstate&val=2');" data-role="button">2</a>
- <a href="javascript:executeCommands('loadstate&val=3');" data-role="button">3</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=4');" data-role="button">4</a>
- <a href="javascript:executeCommands('loadstate&val=5');" data-role="button">5</a>
- <a href="javascript:executeCommands('loadstate&val=6');" data-role="button">6</a>
- <a href="javascript:executeCommands('loadstate&val=7');" data-role="button">7</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=8');" data-role="button">8</a>
- <a href="javascript:executeCommands('loadstate&val=9');" data-role="button">9</a>
- <a href="javascript:executeCommands('loadstate&val=a');" data-role="button">A</a>
- <a href="javascript:executeCommands('loadstate&val=b');" data-role="button">B</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=c');" data-role="button">C</a>
- <a href="javascript:executeCommands('loadstate&val=d');" data-role="button">D</a>
- <a href="javascript:executeCommands('loadstate&val=e');" data-role="button">E</a>
- <a href="javascript:executeCommands('loadstate&val=f');" data-role="button">F</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=g');" data-role="button">G</a>
- <a href="javascript:executeCommands('loadstate&val=h');" data-role="button">H</a>
- <a href="javascript:executeCommands('loadstate&val=i');" data-role="button">I</a>
- <a href="javascript:executeCommands('loadstate&val=j');" data-role="button">J</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=k');" data-role="button">K</a>
- <a href="javascript:executeCommands('loadstate&val=l');" data-role="button">L</a>
- <a href="javascript:executeCommands('loadstate&val=m');" data-role="button">M</a>
- <a href="javascript:executeCommands('loadstate&val=n');" data-role="button">N</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=o');" data-role="button">O</a>
- <a href="javascript:executeCommands('loadstate&val=p');" data-role="button">P</a>
- <a href="javascript:executeCommands('loadstate&val=q');" data-role="button">Q</a>
- <a href="javascript:executeCommands('loadstate&val=r');" data-role="button">R</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=s');" data-role="button">S</a>
- <a href="javascript:executeCommands('loadstate&val=t');" data-role="button">T</a>
- <a href="javascript:executeCommands('loadstate&val=u');" data-role="button">U</a>
- <a href="javascript:executeCommands('loadstate&val=v');" data-role="button">V</a>
- </div>
- <div data-role="controlgroup" data-type="horizontal">
- <a href="javascript:executeCommands('loadstate&val=w');" data-role="button">W</a>
- <a href="javascript:executeCommands('loadstate&val=x');" data-role="button">X</a>
- <a href="javascript:executeCommands('loadstate&val=y');" data-role="button">Y</a>
- <a href="javascript:executeCommands('loadstate&val=z');" data-role="button">Z</a>
- </div>
- <!-- This is here to prevent webkit from trying to put the last row of states under the bottom menu on small screens like phone-->
- <br><br><br><br><br>
- </div>
-
- <!-- This begins the Paste Text panel -------------------------------------------------------->
- <div data-role="panel" id="pastepanel" data-position="left" data-display="overlay" data-theme="a">
- <h4>Paste Text to Keyboard</h4>
-
- <form id="pasteTextForm" action="#pastepanel" method="post">
- <div data-role="controlgroup" data-type="horizontal">
- <a href="" data-rel="close" data-role="button">Exit</a>
- <input type="submit" value="Send">
- <input type="reset" value="Clear">
- </div>
- <br>
- <textarea id="pasteText" name="val"></textarea>
- </form>
- <!-- This is here to prevent webkit from trying to put the last row of states under the bottom menu on small screens like phone-->
- <br><br><br><br><br>
- </div>
-
- <!-- This begins the Upload Text panel -------------------------------------------------------->
- <div data-role="panel" id="uploadpastepanel" data-position="left" data-display="overlay" data-theme="a">
- <h4>Upload Text to Keyboard</h4>
-
- <form method="post" action="/keyupload" enctype="multipart/form-data" target="uploadpastelog" data-ajax="false">
- <!-- note that we can't do file uploads via Ajax -->
- <div data-role="controlgroup" data-type="horizontal">
- <a href="" data-rel="close" data-role="button">Exit</a>
- <input type="submit" value="Upload" />
- </div>
- <input type="file" name="file" /> <br/>
- </form>
- <!-- This is here to prevent webkit from trying to put the last row of states under the bottom menu on small screens like phone-->
- <br><br><br><br><br>
- </div>
-</div>
-
-<!-- This begins the SLIDERS page ------------------------------------------------------------------->
-<div data-role="page" id="slidermenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#drivermenumenu" data-transition="fade" data-icon="bars">Driver</a>
- </li>
- <li>
- <a href="#optionmenu" data-transition="fade" data-icon="gear">Options</a>
- </li>
- <li>
- <a href="#imagemenu" data-transition="fade" data-icon="grid">Image</a>
- </li>
- <li>
- <a href="#commandmenu" data-transition="fade" data-icon="star">Commands</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="sliders">
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#infomenu" data-transition="fade" data-icon="info">Info</a>
- </li>
- <li>
- <a href="#logsmenu" data-transition="fade" data-icon="check">Logs</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="option_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="option_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="option_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-</div>
-
-<!-- This begins the OPTION MENU page ------------------------------------------------------------------->
-<div data-role="page" id="optionmenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#drivermenumenu" data-transition="fade" data-icon="bars">Driver</a>
- </li>
- <li>
- <a href="#mainmenu" data-transition="fade" data-icon="home">Main Menu</a>
- </li>
- <li>
- <a href="#imagemenu" data-transition="fade" data-icon="grid">Image</a>
- </li>
- <li>
- <a href="#commandmenu" data-transition="fade" data-icon="star">Commands</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="menu_optionmenu">
- <a href="javascript:executeSlider();" data-role="button">Sliders</a>
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#infomenu" data-transition="fade" data-icon="info">Info</a>
- </li>
- <li>
- <a href="#logsmenu" data-transition="fade" data-icon="check">Logs</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="slider_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="slider_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="slider_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-</div>
-
-<!-- This begins the DRIVER MENU page ------------------------------------------------------------------->
-<div data-role="page" id="drivermenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#mainmenu" data-transition="fade" data-icon="home">Main Menu</a>
- </li>
- <li>
- <a href="#optionmenu" data-transition="fade" data-icon="gear">Options</a>
- </li>
- <li>
- <a href="#imagemenu" data-transition="fade" data-icon="grid">Image</a>
- </li>
- <li>
- <a href="#commandmenu" data-transition="fade" data-icon="star">Commands</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="drivermenucontent">
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#infomenu" data-transition="fade" data-icon="info">Info</a>
- </li>
- <li>
- <a href="#logsmenu" data-transition="fade" data-icon="check">Logs</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="driver_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="driver_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="driver_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-</div>
-
-<!-- This begins the IMAGE MENU page ------------------------------------------------------------------->
-<div data-role="page" id="imagemenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#drivermenu" data-transition="fade" data-icon="bars">Driver</a>
- </li>
- <li>
- <a href="#optionmenu" data-transition="fade" data-icon="gear">Options</a>
- </li>
- <li>
- <a href="#mainmenu" data-transition="fade" data-icon="home">Main Menu</a>
- </li>
- <li>
- <a href="#commandmenu" data-transition="fade" data-icon="star">Commands</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="imagemenucontent">
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#infomenu" data-transition="fade" data-icon="info">Info</a>
- </li>
- <li>
- <a href="#logsmenu" data-transition="fade" data-icon="check">Logs</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="image_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="image_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="image_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-</div>
-
-<!-- This begins the INFO MENU page ------------------------------------------------------------------->
-<div data-role="page" id="infomenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#drivermenu" data-transition="fade" data-icon="bars">Driver</a>
- </li>
- <li>
- <a href="#optionmenu" data-transition="fade" data-icon="gear">Options</a>
- </li>
- <li>
- <a href="#imagemenu" data-transition="fade" data-icon="grid">Image</a>
- </li>
- <li>
- <a href="#commandmenu" data-transition="fade" data-icon="star">Commands</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="infomenucontent">
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#mainmenu" data-transition="fade" data-icon="home">Main Menu</a>
- </li>
- <li>
- <a href="#logsmenu" data-transition="fade" data-icon="check">Logs</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="info_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="info_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="info_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-</div>
-
-<!-- This begins the LOGS MENU page ------------------------------------------------------------------->
-<div data-role="page" id="logsmenu">
- <div data-theme="a" data-role="header">
- <div style="width: 100%; height: 120px; position: relative;">
- <img src="images/logo-mame-small.png" alt="image" style="position: absolute; top: 50%; left: 50%; margin-left: -158px; margin-top: -50px">
- </div>
- <a data-role="button" href="#mainmenu" data-icon="home" data-iconpos="left" class="ui-btn-right">Home</a>
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#drivermenu" data-transition="fade" data-icon="bars">Driver</a>
- </li>
- <li>
- <a href="#optionmenu" data-transition="fade" data-icon="gear">Options</a>
- </li>
- <li>
- <a href="#imagemenu" data-transition="fade" data-icon="grid">Image</a>
- </li>
- <li>
- <a href="#commandmenu" data-transition="fade" data-icon="star">Commands</a>
- </li>
- </ul>
- </div>
- </div>
- <div data-role="content" id="logsmenucontent">
- <p>Paste Upload Log</p> <!-- Yeah, this'll need reworking later. Still considering how this will work in the end. -->
- <iframe name="uploadpastelog" width="250" height="250"></iframe>
- </div>
- <div data-theme="a" data-role="footer" data-position="fixed">
- <div data-role="navbar" data-iconpos="top">
- <ul>
- <li>
- <a href="#infomenu" data-transition="fade" data-icon="info">Info</a>
- </li>
- <li>
- <a href="#mainmenu" data-transition="fade" data-icon="home">Main Menu</a>
- </li>
- <li>
- <a href="javascript:takeScreenshot();" data-transition="fade" data-icon="search">Screenshot</a>
- </li>
- <li>
- <a href="javascript:startWebSocket();" data-transition="fade" data-icon="refresh">Reconnect</a>
- </li>
- </ul>
- </div>
- <h3>
- <table style="tablelayout: fixed; width: 100%; height: 10px; border-collapse:collapse;" border="0">
- <tr>
- <td style="width: 10%; padding: 0px;" id="logs_statusbar_connectionstatus"></td>
- <td style="width: 10%; padding: 0px;" id="logs_statusbar_ispaused"></td>
- <td style="width: 80%; padding: 0px;" id="logs_statusbar_runningdriver"></td>
- </tr>
- </table>
- </h3>
- </div>
-</div>
-
-<!-- This begins the EXIT dialog ---------------------------------------------------------------------->
-<div data-role="dialog" id="dialogConfirmExit">
- <div data-role="header">
- <h1>Confirm: Exit emulator?</h1>
- </div>
- <a href="javascript:executeExit();" data-theme="a" data-role="button">Yes</a>
- <a href="javascript:$('.ui-dialog').dialog('close');" data-role="button">Cancel</a>
-</div>
-
-<!-- This begins the HARD RESET dialog ---------------------------------------------------------------->
-<div data-role="page" data-close-btn="none" id="dialogConfirmHardReset">
- <div data-role="header">
- <h1>Confirm: Hard Reset?</h1>
- </div>
- <a href="javascript:executeHardReset();" data-theme="a" data-role="button">Yes</a>
- <a href="javascript:$('.ui-dialog').dialog('close');" data-role="button">Cancel</a>
-</div>
-
-<!-- This begins the SOFT RESET dialog ---------------------------------------------------------------->
-<div data-role="page" data-close-btn="none" id="dialogConfirmSoftReset">
- <div data-role="header">
- <h1>Confirm: Soft Reset?</h1>
- </div>
- <a href="javascript:executeSoftReset();" data-theme="a" data-role="button">Yes</a>
- <a href="javascript:$('.ui-dialog').dialog('close');" data-role="button">Cancel</a>
-</div>
-
-</body>
-</html>
-
diff --git a/web/js/jquery.js b/web/js/jquery.js
deleted file mode 100644
index da4170647dd..00000000000
--- a/web/js/jquery.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
-//@ sourceMappingURL=jquery-1.10.2.min.map
-*/
-(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t
-}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);
-u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
diff --git a/web/js/jquery.mobile.js b/web/js/jquery.mobile.js
deleted file mode 100644
index e06e5902e1e..00000000000
--- a/web/js/jquery.mobile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*! jQuery Mobile 1.3.2 | Git HEAD hash: 528cf0e <> 2013-07-19T22:17:57Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b,c){"function"==typeof define&&define.amd?define(["jquery"],function(d){return c(d,a,b),d.mobile}):c(a.jQuery,a,b)}(this,document,function(a,b,c,d){!function(a){a.mobile={}}(a),function(a,b,d){var e={};a.mobile=a.extend(a.mobile,{version:"1.3.2",ns:"",subPageUrlKey:"ui-page",activePageClass:"ui-page-active",activeBtnClass:"ui-btn-active",focusClass:"ui-focus",ajaxEnabled:!0,hashListeningEnabled:!0,linkBindingEnabled:!0,defaultPageTransition:"fade",maxTransitionWidth:!1,minScrollBack:250,touchOverflowEnabled:!1,defaultDialogTransition:"pop",pageLoadErrorMessage:"Error Loading Page",pageLoadErrorMessageTheme:"e",phonegapNavigationEnabled:!1,autoInitializePage:!0,pushStateEnabled:!0,ignoreContentEnabled:!1,orientationChangeEnabled:!0,buttonMarkup:{hoverDelay:200},window:a(b),document:a(c),keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},behaviors:{},silentScroll:function(c){"number"!==a.type(c)&&(c=a.mobile.defaultHomeScroll),a.event.special.scrollstart.enabled=!1,setTimeout(function(){b.scrollTo(0,c),a.mobile.document.trigger("silentscroll",{x:0,y:c})},20),setTimeout(function(){a.event.special.scrollstart.enabled=!0},150)},nsNormalizeDict:e,nsNormalize:function(b){return b?e[b]||(e[b]=a.camelCase(a.mobile.ns+b)):void 0},getInheritedTheme:function(a,b){for(var c,d,e=a[0],f="",g=/ui-(bar|body|overlay)-([a-z])\b/;e&&(c=e.className||"",!(c&&(d=g.exec(c))&&(f=d[2])));)e=e.parentNode;return f||b||"a"},closestPageData:function(a){return a.closest(':jqmData(role="page"), :jqmData(role="dialog")').data("mobile-page")},enhanceable:function(a){return this.haveParents(a,"enhance")},hijackable:function(a){return this.haveParents(a,"ajax")},haveParents:function(b,c){if(!a.mobile.ignoreContentEnabled)return b;for(var d,e,f,g=b.length,h=a(),i=0;g>i;i++){for(e=b.eq(i),f=!1,d=b[i];d;){var j=d.getAttribute?d.getAttribute("data-"+a.mobile.ns+c):"";if("false"===j){f=!0;break}d=d.parentNode}f||(h=h.add(e))}return h},getScreenHeight:function(){return b.innerHeight||a.mobile.window.height()}},a.mobile),a.fn.jqmData=function(b,c){var e;return"undefined"!=typeof b&&(b&&(b=a.mobile.nsNormalize(b)),e=arguments.length<2||c===d?this.data(b):this.data(b,c)),e},a.jqmData=function(b,c,d){var e;return"undefined"!=typeof c&&(e=a.data(b,c?a.mobile.nsNormalize(c):c,d)),e},a.fn.jqmRemoveData=function(b){return this.removeData(a.mobile.nsNormalize(b))},a.jqmRemoveData=function(b,c){return a.removeData(b,a.mobile.nsNormalize(c))},a.fn.removeWithDependents=function(){a.removeWithDependents(this)},a.removeWithDependents=function(b){var c=a(b);(c.jqmData("dependents")||a()).remove(),c.remove()},a.fn.addDependents=function(b){a.addDependents(a(this),b)},a.addDependents=function(b,c){var d=a(b).jqmData("dependents")||a();a(b).jqmData("dependents",a.merge(d,c))},a.fn.getEncodedText=function(){return a("<div/>").text(a(this).text()).html()},a.fn.jqmEnhanceable=function(){return a.mobile.enhanceable(this)},a.fn.jqmHijackable=function(){return a.mobile.hijackable(this)};var f=a.find,g=/:jqmData\(([^)]*)\)/g;a.find=function(b,c,d,e){return b=b.replace(g,"[data-"+(a.mobile.ns||"")+"$1]"),f.call(this,b,c,d,e)},a.extend(a.find,f),a.find.matches=function(b,c){return a.find(b,null,null,c)},a.find.matchesSelector=function(b,c){return a.find(c,null,null,[b]).length>0}}(a,this),function(a,b){var c=0,d=Array.prototype.slice,e=a.cleanData;a.cleanData=function(b){for(var c,d=0;null!=(c=b[d]);d++)try{a(c).triggerHandler("remove")}catch(f){}e(b)},a.widget=function(b,c,d){var e,f,g,h,i=b.split(".")[0];b=b.split(".")[1],e=i+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][e.toLowerCase()]=function(b){return!!a.data(b,e)},a[i]=a[i]||{},f=a[i][b],g=a[i][b]=function(a,b){return this._createWidget?(arguments.length&&this._createWidget(a,b),void 0):new g(a,b)},a.extend(g,f,{version:d.version,_proto:a.extend({},d),_childConstructors:[]}),h=new c,h.options=a.widget.extend({},h.options),a.each(d,function(b,e){a.isFunction(e)&&(d[b]=function(){var a=function(){return c.prototype[b].apply(this,arguments)},d=function(a){return c.prototype[b].apply(this,a)};return function(){var b,c=this._super,f=this._superApply;return this._super=a,this._superApply=d,b=e.apply(this,arguments),this._super=c,this._superApply=f,b}}())}),g.prototype=a.widget.extend(h,{widgetEventPrefix:f?h.widgetEventPrefix:b},d,{constructor:g,namespace:i,widgetName:b,widgetFullName:e}),f?(a.each(f._childConstructors,function(b,c){var d=c.prototype;a.widget(d.namespace+"."+d.widgetName,g,c._proto)}),delete f._childConstructors):c._childConstructors.push(g),a.widget.bridge(b,g)},a.widget.extend=function(c){for(var e,f,g=d.call(arguments,1),h=0,i=g.length;i>h;h++)for(e in g[h])f=g[h][e],g[h].hasOwnProperty(e)&&f!==b&&(c[e]=a.isPlainObject(f)?a.isPlainObject(c[e])?a.widget.extend({},c[e],f):a.widget.extend({},f):f);return c},a.widget.bridge=function(c,e){var f=e.prototype.widgetFullName||c;a.fn[c]=function(g){var h="string"==typeof g,i=d.call(arguments,1),j=this;return g=!h&&i.length?a.widget.extend.apply(null,[g].concat(i)):g,h?this.each(function(){var d,e=a.data(this,f);return e?a.isFunction(e[g])&&"_"!==g.charAt(0)?(d=e[g].apply(e,i),d!==e&&d!==b?(j=d&&d.jquery?j.pushStack(d.get()):d,!1):void 0):a.error("no such method '"+g+"' for "+c+" widget instance"):a.error("cannot call methods on "+c+" prior to initialization; "+"attempted to call method '"+g+"'")}):this.each(function(){var b=a.data(this,f);b?b.option(g||{})._init():a.data(this,f,new e(g,this))}),j}},a.Widget=function(){},a.Widget._childConstructors=[],a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(b,d){d=a(d||this.defaultElement||this)[0],this.element=a(d),this.uuid=c++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=a.widget.extend({},this.options,this._getCreateOptions(),b),this.bindings=a(),this.hoverable=a(),this.focusable=a(),d!==this&&(a.data(d,this.widgetFullName,this),this._on(!0,this.element,{remove:function(a){a.target===d&&this.destroy()}}),this.document=a(d.style?d.ownerDocument:d.document||d),this.window=a(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:a.noop,_getCreateEventData:a.noop,_create:a.noop,_init:a.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(a.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:a.noop,widget:function(){return this.element},option:function(c,d){var e,f,g,h=c;if(0===arguments.length)return a.widget.extend({},this.options);if("string"==typeof c)if(h={},e=c.split("."),c=e.shift(),e.length){for(f=h[c]=a.widget.extend({},this.options[c]),g=0;g<e.length-1;g++)f[e[g]]=f[e[g]]||{},f=f[e[g]];if(c=e.pop(),d===b)return f[c]===b?null:f[c];f[c]=d}else{if(d===b)return this.options[c]===b?null:this.options[c];h[c]=d}return this._setOptions(h),this},_setOptions:function(a){var b;for(b in a)this._setOption(b,a[b]);return this},_setOption:function(a,b){return this.options[a]=b,"disabled"===a&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!b).attr("aria-disabled",b),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(b,c,d){var e,f=this;"boolean"!=typeof b&&(d=c,c=b,b=!1),d?(c=e=a(c),this.bindings=this.bindings.add(c)):(d=c,c=this.element,e=this.widget()),a.each(d,function(d,g){function h(){return b||f.options.disabled!==!0&&!a(this).hasClass("ui-state-disabled")?("string"==typeof g?f[g]:g).apply(f,arguments):void 0}"string"!=typeof g&&(h.guid=g.guid=g.guid||h.guid||a.guid++);var i=d.match(/^(\w+)\s*(.*)$/),j=i[1]+f.eventNamespace,k=i[2];k?e.delegate(k,j,h):c.bind(j,h)})},_off:function(a,b){b=(b||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,a.unbind(b).undelegate(b)},_delay:function(a,b){function c(){return("string"==typeof a?d[a]:a).apply(d,arguments)}var d=this;return setTimeout(c,b||0)},_hoverable:function(b){this.hoverable=this.hoverable.add(b),this._on(b,{mouseenter:function(b){a(b.currentTarget).addClass("ui-state-hover")},mouseleave:function(b){a(b.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(b){this.focusable=this.focusable.add(b),this._on(b,{focusin:function(b){a(b.currentTarget).addClass("ui-state-focus")},focusout:function(b){a(b.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(b,c,d){var e,f,g=this.options[b];if(d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent)for(e in f)e in c||(c[e]=f[e]);return this.element.trigger(c,d),!(a.isFunction(g)&&g.apply(this.element[0],[c].concat(d))===!1||c.isDefaultPrevented())}},a.each({show:"fadeIn",hide:"fadeOut"},function(b,c){a.Widget.prototype["_"+b]=function(d,e,f){"string"==typeof e&&(e={effect:e});var g,h=e?e===!0||"number"==typeof e?c:e.effect||c:b;e=e||{},"number"==typeof e&&(e={duration:e}),g=!a.isEmptyObject(e),e.complete=f,e.delay&&d.delay(e.delay),g&&a.effects&&a.effects.effect[h]?d[b](e):h!==b&&d[h]?d[h](e.duration,e.easing,f):d.queue(function(c){a(this)[b](),f&&f.call(d[0]),c()})}})}(a),function(a,b){a.widget("mobile.widget",{_createWidget:function(){a.Widget.prototype._createWidget.apply(this,arguments),this._trigger("init")},_getCreateOptions:function(){var c=this.element,d={};return a.each(this.options,function(a){var e=c.jqmData(a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()}));e!==b&&(d[a]=e)}),d},enhanceWithin:function(b,c){this.enhance(a(this.options.initSelector,a(b)),c)},enhance:function(b,c){var d,e,f=a(b);f=a.mobile.enhanceable(f),c&&f.length&&(d=a.mobile.closestPageData(f),e=d&&d.keepNativeSelector()||"",f=f.not(e)),f[this.widgetName]()},raise:function(a){throw"Widget ["+this.widgetName+"]: "+a}})}(a),function(a){a.extend(a.mobile,{loadingMessageTextVisible:d,loadingMessageTheme:d,loadingMessage:d,showPageLoadingMsg:function(b,c,d){a.mobile.loading("show",b,c,d)},hidePageLoadingMsg:function(){a.mobile.loading("hide")},loading:function(){this.loaderWidget.loader.apply(this.loaderWidget,arguments)}});var b="ui-loader",c=a("html"),e=a.mobile.window;a.widget("mobile.loader",{options:{theme:"a",textVisible:!1,html:"",text:"loading"},defaultHtml:"<div class='"+b+"'>"+"<span class='ui-icon ui-icon-loading'></span>"+"<h1></h1>"+"</div>",fakeFixLoader:function(){var b=a("."+a.mobile.activeBtnClass).first();this.element.css({top:a.support.scrollTop&&e.scrollTop()+e.height()/2||b.length&&b.offset().top||100})},checkLoaderPosition:function(){var b=this.element.offset(),c=e.scrollTop(),d=a.mobile.getScreenHeight();(b.top<c||b.top-c>d)&&(this.element.addClass("ui-loader-fakefix"),this.fakeFixLoader(),e.unbind("scroll",this.checkLoaderPosition).bind("scroll",a.proxy(this.fakeFixLoader,this)))},resetHtml:function(){this.element.html(a(this.defaultHtml).html())},show:function(f,g,h){var i,j,k;this.resetHtml(),"object"===a.type(f)?(k=a.extend({},this.options,f),f=k.theme||a.mobile.loadingMessageTheme):(k=this.options,f=f||a.mobile.loadingMessageTheme||k.theme),j=g||a.mobile.loadingMessage||k.text,c.addClass("ui-loading"),(a.mobile.loadingMessage!==!1||k.html)&&(i=a.mobile.loadingMessageTextVisible!==d?a.mobile.loadingMessageTextVisible:k.textVisible,this.element.attr("class",b+" ui-corner-all ui-body-"+f+" ui-loader-"+(i||g||f.text?"verbose":"default")+(k.textonly||h?" ui-loader-textonly":"")),k.html?this.element.html(k.html):this.element.find("h1").text(j),this.element.appendTo(a.mobile.pageContainer),this.checkLoaderPosition(),e.bind("scroll",a.proxy(this.checkLoaderPosition,this)))},hide:function(){c.removeClass("ui-loading"),a.mobile.loadingMessage&&this.element.removeClass("ui-loader-fakefix"),a.mobile.window.unbind("scroll",this.fakeFixLoader),a.mobile.window.unbind("scroll",this.checkLoaderPosition)}}),e.bind("pagecontainercreate",function(){a.mobile.loaderWidget=a.mobile.loaderWidget||a(a.mobile.loader.prototype.defaultHtml).loader()})}(a,this),function(a,b,d){function e(a){return a=a||location.href,"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var f,g="hashchange",h=c,i=a.event.special,j=h.documentMode,k="on"+g in b&&(j===d||j>7);a.fn[g]=function(a){return a?this.bind(g,a):this.trigger(g)},a.fn[g].delay=50,i[g]=a.extend(i[g],{setup:function(){return k?!1:(a(f.start),void 0)},teardown:function(){return k?!1:(a(f.stop),void 0)}}),f=function(){function c(){var d=e(),h=n(j);d!==j?(m(j=d,h),a(b).trigger(g)):h!==j&&(location.href=location.href.replace(/#.*/,"")+h),f=setTimeout(c,a.fn[g].delay)}var f,i={},j=e(),l=function(a){return a},m=l,n=l;return i.start=function(){f||c()},i.stop=function(){f&&clearTimeout(f),f=d},b.attachEvent&&!b.addEventListener&&!k&&function(){var b,d;i.start=function(){b||(d=a.fn[g].src,d=d&&d+e(),b=a('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){d||m(e()),c()}).attr("src",d||"javascript:0").insertAfter("body")[0].contentWindow,h.onpropertychange=function(){try{"title"===event.propertyName&&(b.document.title=h.title)}catch(a){}})},i.stop=l,n=function(){return e(b.location.href)},m=function(c,d){var e=b.document,f=a.fn[g].domain;c!==d&&(e.title=h.title,e.open(),f&&e.write('<script>document.domain="'+f+'"</script>'),e.close(),b.location.hash=c)}}(),i}()}(a,this),function(a){b.matchMedia=b.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(c),a.mobile.media=function(a){return b.matchMedia(a).matches}}(a),function(a){var b={touch:"ontouchend"in c};a.mobile.support=a.mobile.support||{},a.extend(a.support,b),a.extend(a.mobile.support,b)}(a),function(a){a.extend(a.support,{orientation:"orientation"in b&&"onorientationchange"in b})}(a),function(a,d){function e(a){var b=a.charAt(0).toUpperCase()+a.substr(1),c=(a+" "+n.join(b+" ")+b).split(" ");for(var e in c)if(m[c[e]]!==d)return!0}function f(a,b,d){for(var e,f=c.createElement("div"),g=function(a){return a.charAt(0).toUpperCase()+a.substr(1)},h=function(a){return""===a?"":"-"+a.charAt(0).toLowerCase()+a.substr(1)+"-"},i=function(c){var d=h(c)+a+": "+b+";",i=g(c),j=i+(""===i?a:g(a));f.setAttribute("style",d),f.style[j]&&(e=!0)},j=d?d:n,k=0;k<j.length;k++)i(j[k]);return!!e}function g(){var e="transform-3d",f=a.mobile.media("(-"+n.join("-"+e+"),(-")+"-"+e+"),("+e+")");if(f)return!!f;var g=c.createElement("div"),h={MozTransform:"-moz-transform",transform:"transform"};l.append(g);for(var i in h)g.style[i]!==d&&(g.style[i]="translate3d( 100px, 1px, 1px )",f=b.getComputedStyle(g).getPropertyValue(h[i]));return!!f&&"none"!==f}function h(){var b,c,d=location.protocol+"//"+location.host+location.pathname+"ui-dir/",e=a("head base"),f=null,g="";return e.length?g=e.attr("href"):e=f=a("<base>",{href:d}).appendTo("head"),b=a("<a href='testurl' />").prependTo(l),c=b[0].href,e[0].href=g||location.pathname,f&&f.remove(),0===c.indexOf(d)}function i(){var a,d=c.createElement("x"),e=c.documentElement,f=b.getComputedStyle;return"pointerEvents"in d.style?(d.style.pointerEvents="auto",d.style.pointerEvents="x",e.appendChild(d),a=f&&"auto"===f(d,"").pointerEvents,e.removeChild(d),!!a):!1}function j(){var a=c.createElement("div");return"undefined"!=typeof a.getBoundingClientRect}function k(){var a=b,c=navigator.userAgent,d=navigator.platform,e=c.match(/AppleWebKit\/([0-9]+)/),f=!!e&&e[1],g=c.match(/Fennec\/([0-9]+)/),h=!!g&&g[1],i=c.match(/Opera Mobi\/([0-9]+)/),j=!!i&&i[1];return(d.indexOf("iPhone")>-1||d.indexOf("iPad")>-1||d.indexOf("iPod")>-1)&&f&&534>f||a.operamini&&"[object OperaMini]"==={}.toString.call(a.operamini)||i&&7458>j||c.indexOf("Android")>-1&&f&&533>f||h&&6>h||"palmGetResource"in b&&f&&534>f||c.indexOf("MeeGo")>-1&&c.indexOf("NokiaBrowser/8.5.0")>-1?!1:!0}var l=a("<body>").prependTo("html"),m=l[0].style,n=["Webkit","Moz","O"],o="palmGetResource"in b,p=b.opera,q=b.operamini&&"[object OperaMini]"==={}.toString.call(b.operamini),r=b.blackberry&&!e("-webkit-transform");a.extend(a.mobile,{browser:{}}),a.mobile.browser.oldIE=function(){var a=3,b=c.createElement("div"),d=b.all||[];do b.innerHTML="<!--[if gt IE "+ ++a+"]><br><![endif]-->";while(d[0]);return a>4?a:!a}(),a.extend(a.support,{cssTransitions:"WebKitTransitionEvent"in b||f("transition","height 100ms linear",["Webkit","Moz",""])&&!a.mobile.browser.oldIE&&!p,pushState:"pushState"in history&&"replaceState"in history&&!(b.navigator.userAgent.indexOf("Firefox")>=0&&b.top!==b)&&-1===b.navigator.userAgent.search(/CriOS/),mediaquery:a.mobile.media("only all"),cssPseudoElement:!!e("content"),touchOverflow:!!e("overflowScrolling"),cssTransform3d:g(),boxShadow:!!e("boxShadow")&&!r,fixedPosition:k(),scrollTop:("pageXOffset"in b||"scrollTop"in c.documentElement||"scrollTop"in l[0])&&!o&&!q,dynamicBaseTag:h(),cssPointerEvents:i(),boundingRect:j()}),l.remove();var s=function(){var a=b.navigator.userAgent;return a.indexOf("Nokia")>-1&&(a.indexOf("Symbian/3")>-1||a.indexOf("Series60/5")>-1)&&a.indexOf("AppleWebKit")>-1&&a.match(/(BrowserNG|NokiaBrowser)\/7\.[0-3]/)}();a.mobile.gradeA=function(){return(a.support.mediaquery||a.mobile.browser.oldIE&&a.mobile.browser.oldIE>=7)&&(a.support.boundingRect||null!==a.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/))},a.mobile.ajaxBlacklist=b.blackberry&&!b.WebKitPoint||q||s,s&&a(function(){a("head link[rel='stylesheet']").attr("rel","alternate stylesheet").attr("rel","stylesheet")}),a.support.boxShadow||a("html").addClass("ui-mobile-nosupport-boxshadow")}(a),function(a,b){var c,d=a.mobile.window;a.event.special.navigate=c={bound:!1,pushStateEnabled:!0,originalEventName:b,isPushStateEnabled:function(){return a.support.pushState&&a.mobile.pushStateEnabled===!0&&this.isHashChangeEnabled()},isHashChangeEnabled:function(){return a.mobile.hashListeningEnabled===!0},popstate:function(b){var c=new a.Event("navigate"),e=new a.Event("beforenavigate"),f=b.originalEvent.state||{};location.href,d.trigger(e),e.isDefaultPrevented()||(b.historyState&&a.extend(f,b.historyState),c.originalEvent=b,setTimeout(function(){d.trigger(c,{state:f})},0))},hashchange:function(b){var c=new a.Event("navigate"),e=new a.Event("beforenavigate");d.trigger(e),e.isDefaultPrevented()||(c.originalEvent=b,d.trigger(c,{state:b.hashchangeState||{}}))},setup:function(){c.bound||(c.bound=!0,c.isPushStateEnabled()?(c.originalEventName="popstate",d.bind("popstate.navigate",c.popstate)):c.isHashChangeEnabled()&&(c.originalEventName="hashchange",d.bind("hashchange.navigate",c.hashchange)))}}}(a),function(a,c){var d,e,f="&ui-state=dialog";a.mobile.path=d={uiStateKey:"&ui-state",urlParseRE:/^\s*(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,getLocation:function(a){var b=a?this.parseUrl(a):location,c=this.parseUrl(a||location.href).hash;return c="#"===c?"":c,b.protocol+"//"+b.host+b.pathname+b.search+c},parseLocation:function(){return this.parseUrl(this.getLocation())},parseUrl:function(b){if("object"===a.type(b))return b;var c=d.urlParseRE.exec(b||"")||[];return{href:c[0]||"",hrefNoHash:c[1]||"",hrefNoSearch:c[2]||"",domain:c[3]||"",protocol:c[4]||"",doubleSlash:c[5]||"",authority:c[6]||"",username:c[8]||"",password:c[9]||"",host:c[10]||"",hostname:c[11]||"",port:c[12]||"",pathname:c[13]||"",directory:c[14]||"",filename:c[15]||"",search:c[16]||"",hash:c[17]||""}},makePathAbsolute:function(a,b){if(a&&"/"===a.charAt(0))return a;a=a||"",b=b?b.replace(/^\/|(\/[^\/]*|[^\/]+)$/g,""):"";for(var c=b?b.split("/"):[],d=a.split("/"),e=0;e<d.length;e++){var f=d[e];switch(f){case".":break;case"..":c.length&&c.pop();break;default:c.push(f)}}return"/"+c.join("/")},isSameDomain:function(a,b){return d.parseUrl(a).domain===d.parseUrl(b).domain},isRelativeUrl:function(a){return""===d.parseUrl(a).protocol},isAbsoluteUrl:function(a){return""!==d.parseUrl(a).protocol},makeUrlAbsolute:function(a,b){if(!d.isRelativeUrl(a))return a;b===c&&(b=this.documentBase);var e=d.parseUrl(a),f=d.parseUrl(b),g=e.protocol||f.protocol,h=e.protocol?e.doubleSlash:e.doubleSlash||f.doubleSlash,i=e.authority||f.authority,j=""!==e.pathname,k=d.makePathAbsolute(e.pathname||f.filename,f.pathname),l=e.search||!j&&f.search||"",m=e.hash;return g+h+i+k+l+m},addSearchParams:function(b,c){var e=d.parseUrl(b),f="object"==typeof c?a.param(c):c,g=e.search||"?";return e.hrefNoSearch+g+("?"!==g.charAt(g.length-1)?"&":"")+f+(e.hash||"")},convertUrlToDataUrl:function(a){var c=d.parseUrl(a);return d.isEmbeddedPage(c)?c.hash.split(f)[0].replace(/^#/,"").replace(/\?.*$/,""):d.isSameDomain(c,this.documentBase)?c.hrefNoHash.replace(this.documentBase.domain,"").split(f)[0]:b.decodeURIComponent(a)},get:function(a){return a===c&&(a=d.parseLocation().hash),d.stripHash(a).replace(/[^\/]*\.[^\/*]+$/,"")},set:function(a){location.hash=a},isPath:function(a){return/\//.test(a)},clean:function(a){return a.replace(this.documentBase.domain,"")},stripHash:function(a){return a.replace(/^#/,"")},stripQueryParams:function(a){return a.replace(/\?.*$/,"")},cleanHash:function(a){return d.stripHash(a.replace(/\?.*$/,"").replace(f,""))},isHashValid:function(a){return/^#[^#]+$/.test(a)},isExternal:function(a){var b=d.parseUrl(a);return b.protocol&&b.domain!==this.documentUrl.domain?!0:!1},hasProtocol:function(a){return/^(:?\w+:)/.test(a)},isEmbeddedPage:function(a){var b=d.parseUrl(a);return""!==b.protocol?!this.isPath(b.hash)&&b.hash&&(b.hrefNoHash===this.documentUrl.hrefNoHash||this.documentBaseDiffers&&b.hrefNoHash===this.documentBase.hrefNoHash):/^#/.test(b.href)},squash:function(a,b){var c,e,f,g,h=this.isPath(a),i=this.parseUrl(a),j=i.hash,k="";return b=b||(d.isPath(a)?d.getLocation():d.getDocumentUrl()),e=h?d.stripHash(a):a,e=d.isPath(i.hash)?d.stripHash(i.hash):e,g=e.indexOf(this.uiStateKey),g>-1&&(k=e.slice(g),e=e.slice(0,g)),c=d.makeUrlAbsolute(e,b),f=this.parseUrl(c).search,h?((d.isPath(j)||0===j.replace("#","").indexOf(this.uiStateKey))&&(j=""),k&&-1===j.indexOf(this.uiStateKey)&&(j+=k),-1===j.indexOf("#")&&""!==j&&(j="#"+j),c=d.parseUrl(c),c=c.protocol+"//"+c.host+c.pathname+f+j):c+=c.indexOf("#")>-1?k:"#"+k,c},isPreservableHash:function(a){return 0===a.replace("#","").indexOf(this.uiStateKey)}},d.documentUrl=d.parseLocation(),e=a("head").find("base"),d.documentBase=e.length?d.parseUrl(d.makeUrlAbsolute(e.attr("href"),d.documentUrl.href)):d.documentUrl,d.documentBaseDiffers=d.documentUrl.hrefNoHash!==d.documentBase.hrefNoHash,d.getDocumentUrl=function(b){return b?a.extend({},d.documentUrl):d.documentUrl.href},d.getDocumentBase=function(b){return b?a.extend({},d.documentBase):d.documentBase.href}}(a),function(a,b){a.mobile.path,a.mobile.History=function(a,b){this.stack=a||[],this.activeIndex=b||0},a.extend(a.mobile.History.prototype,{getActive:function(){return this.stack[this.activeIndex]},getLast:function(){return this.stack[this.previousIndex]},getNext:function(){return this.stack[this.activeIndex+1]},getPrev:function(){return this.stack[this.activeIndex-1]},add:function(a,b){b=b||{},this.getNext()&&this.clearForward(),b.hash&&-1===b.hash.indexOf("#")&&(b.hash="#"+b.hash),b.url=a,this.stack.push(b),this.activeIndex=this.stack.length-1},clearForward:function(){this.stack=this.stack.slice(0,this.activeIndex+1)},find:function(a,b,c){b=b||this.stack;var d,e,f,g=b.length;for(e=0;g>e;e++)if(d=b[e],(decodeURIComponent(a)===decodeURIComponent(d.url)||decodeURIComponent(a)===decodeURIComponent(d.hash))&&(f=e,c))return f;return f},closest:function(a){var c,d=this.activeIndex;return c=this.find(a,this.stack.slice(0,d)),c===b&&(c=this.find(a,this.stack.slice(d),!0),c=c===b?c:c+d),c},direct:function(c){var d=this.closest(c.url),e=this.activeIndex;d!==b&&(this.activeIndex=d,this.previousIndex=e),e>d?(c.present||c.back||a.noop)(this.getActive(),"back"):d>e?(c.present||c.forward||a.noop)(this.getActive(),"forward"):d===b&&c.missing&&c.missing(this.getActive())}})}(a),function(a){var d=a.mobile.path,e=location.href;a.mobile.Navigator=function(b){this.history=b,this.ignoreInitialHashChange=!0,a.mobile.window.bind({"popstate.history":a.proxy(this.popstate,this),"hashchange.history":a.proxy(this.hashchange,this)})},a.extend(a.mobile.Navigator.prototype,{squash:function(e,f){var g,h,i=d.isPath(e)?d.stripHash(e):e;return h=d.squash(e),g=a.extend({hash:i,url:h},f),b.history.replaceState(g,g.title||c.title,h),g},hash:function(a,b){var c,e,f;if(c=d.parseUrl(a),e=d.parseLocation(),e.pathname+e.search===c.pathname+c.search)f=c.hash?c.hash:c.pathname+c.search;else if(d.isPath(a)){var g=d.parseUrl(b);f=g.pathname+g.search+(d.isPreservableHash(g.hash)?g.hash.replace("#",""):"")}else f=a;return f},go:function(e,f,g){var h,i,j,k,l=a.event.special.navigate.isPushStateEnabled();i=d.squash(e),j=this.hash(e,i),g&&j!==d.stripHash(d.parseLocation().hash)&&(this.preventNextHashChange=g),this.preventHashAssignPopState=!0,b.location.hash=j,this.preventHashAssignPopState=!1,h=a.extend({url:i,hash:j,title:c.title},f),l&&(k=new a.Event("popstate"),k.originalEvent={type:"popstate",state:null},this.squash(e,h),g||(this.ignorePopState=!0,a.mobile.window.trigger(k))),this.history.add(h.url,h)},popstate:function(b){var c,f;if(a.event.special.navigate.isPushStateEnabled())return this.preventHashAssignPopState?(this.preventHashAssignPopState=!1,b.stopImmediatePropagation(),void 0):this.ignorePopState?(this.ignorePopState=!1,void 0):!b.originalEvent.state&&1===this.history.stack.length&&this.ignoreInitialHashChange&&(this.ignoreInitialHashChange=!1,location.href===e)?(b.preventDefault(),void 0):(c=d.parseLocation().hash,!b.originalEvent.state&&c?(f=this.squash(c),this.history.add(f.url,f),b.historyState=f,void 0):(this.history.direct({url:(b.originalEvent.state||{}).url||c,present:function(c,d){b.historyState=a.extend({},c),b.historyState.direction=d}}),void 0))},hashchange:function(b){var e,f;if(a.event.special.navigate.isHashChangeEnabled()&&!a.event.special.navigate.isPushStateEnabled()){if(this.preventNextHashChange)return this.preventNextHashChange=!1,b.stopImmediatePropagation(),void 0;e=this.history,f=d.parseLocation().hash,this.history.direct({url:f,present:function(c,d){b.hashchangeState=a.extend({},c),b.hashchangeState.direction=d},missing:function(){e.add(f,{hash:f,title:c.title})}})}}})}(a),function(a){a.mobile.navigate=function(b,c,d){a.mobile.navigate.navigator.go(b,c,d)},a.mobile.navigate.history=new a.mobile.History,a.mobile.navigate.navigator=new a.mobile.Navigator(a.mobile.navigate.history);var b=a.mobile.path.parseLocation();a.mobile.navigate.history.add(b.href,{hash:b.hash})}(a),function(a,b,c,d){function e(a){for(;a&&"undefined"!=typeof a.originalEvent;)a=a.originalEvent;return a}function f(b,c){var f,g,h,i,j,k,l,m,n,o=b.type;if(b=a.Event(b),b.type=c,f=b.originalEvent,g=a.event.props,o.search(/^(mouse|click)/)>-1&&(g=D),f)for(l=g.length,i;l;)i=g[--l],b[i]=f[i];if(o.search(/mouse(down|up)|click/)>-1&&!b.which&&(b.which=1),-1!==o.search(/^touch/)&&(h=e(f),o=h.touches,j=h.changedTouches,k=o&&o.length?o[0]:j&&j.length?j[0]:d))for(m=0,n=B.length;n>m;m++)i=B[m],b[i]=k[i];return b}function g(b){for(var c,d,e={};b;){c=a.data(b,y);for(d in c)c[d]&&(e[d]=e.hasVirtualBinding=!0);b=b.parentNode}return e}function h(b,c){for(var d;b;){if(d=a.data(b,y),d&&(!c||d[c]))return b;b=b.parentNode}return null}function i(){L=!1}function j(){L=!0}function k(){P=0,J.length=0,K=!1,j()}function l(){i()}function m(){n(),F=setTimeout(function(){F=0,k()},a.vmouse.resetTimerDuration)}function n(){F&&(clearTimeout(F),F=0)}function o(b,c,d){var e;return(d&&d[b]||!d&&h(c.target,b))&&(e=f(c,b),a(c.target).trigger(e)),e}function p(b){var c=a.data(b.target,z);if(!(K||P&&P===c)){var d=o("v"+b.type,b);d&&(d.isDefaultPrevented()&&b.preventDefault(),d.isPropagationStopped()&&b.stopPropagation(),d.isImmediatePropagationStopped()&&b.stopImmediatePropagation())}}function q(b){var c,d,f=e(b).touches;if(f&&1===f.length&&(c=b.target,d=g(c),d.hasVirtualBinding)){P=O++,a.data(c,z,P),n(),l(),I=!1;var h=e(b).touches[0];G=h.pageX,H=h.pageY,o("vmouseover",b,d),o("vmousedown",b,d)}}function r(a){L||(I||o("vmousecancel",a,g(a.target)),I=!0,m())}function s(b){if(!L){var c=e(b).touches[0],d=I,f=a.vmouse.moveDistanceThreshold,h=g(b.target);I=I||Math.abs(c.pageX-G)>f||Math.abs(c.pageY-H)>f,I&&!d&&o("vmousecancel",b,h),o("vmousemove",b,h),m()}}function t(a){if(!L){j();var b,c=g(a.target);if(o("vmouseup",a,c),!I){var d=o("vclick",a,c);d&&d.isDefaultPrevented()&&(b=e(a).changedTouches[0],J.push({touchID:P,x:b.clientX,y:b.clientY}),K=!0)}o("vmouseout",a,c),I=!1,m()}}function u(b){var c,d=a.data(b,y);if(d)for(c in d)if(d[c])return!0;return!1}function v(){}function w(b){var c=b.substr(1);return{setup:function(){u(this)||a.data(this,y,{});var d=a.data(this,y);d[b]=!0,E[b]=(E[b]||0)+1,1===E[b]&&N.bind(c,p),a(this).bind(c,v),M&&(E.touchstart=(E.touchstart||0)+1,1===E.touchstart&&N.bind("touchstart",q).bind("touchend",t).bind("touchmove",s).bind("scroll",r))},teardown:function(){--E[b],E[b]||N.unbind(c,p),M&&(--E.touchstart,E.touchstart||N.unbind("touchstart",q).unbind("touchmove",s).unbind("touchend",t).unbind("scroll",r));var d=a(this),e=a.data(this,y);e&&(e[b]=!1),d.unbind(c,v),u(this)||d.removeData(y)}}}var x,y="virtualMouseBindings",z="virtualTouchID",A="vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "),B="clientX clientY pageX pageY screenX screenY".split(" "),C=a.event.mouseHooks?a.event.mouseHooks.props:[],D=a.event.props.concat(C),E={},F=0,G=0,H=0,I=!1,J=[],K=!1,L=!1,M="addEventListener"in c,N=a(c),O=1,P=0;a.vmouse={moveDistanceThreshold:10,clickDistanceThreshold:10,resetTimerDuration:1500};for(var Q=0;Q<A.length;Q++)a.event.special[A[Q]]=w(A[Q]);M&&c.addEventListener("click",function(b){var c,d,e,f,g,h,i=J.length,j=b.target;if(i)for(c=b.clientX,d=b.clientY,x=a.vmouse.clickDistanceThreshold,e=j;e;){for(f=0;i>f;f++)if(g=J[f],h=0,e===j&&Math.abs(g.x-c)<x&&Math.abs(g.y-d)<x||a.data(e,z)===g.touchID)return b.preventDefault(),b.stopPropagation(),void 0;e=e.parentNode}},!0)}(a,b,c),function(a,b,d){function e(b,c,d){var e=d.type;d.type=c,a.event.dispatch.call(b,d),d.type=e}var f=a(c);a.each("touchstart touchmove touchend tap taphold swipe swipeleft swiperight scrollstart scrollstop".split(" "),function(b,c){a.fn[c]=function(a){return a?this.bind(c,a):this.trigger(c)},a.attrFn&&(a.attrFn[c]=!0)});var g=a.mobile.support.touch,h="touchmove scroll",i=g?"touchstart":"mousedown",j=g?"touchend":"mouseup",k=g?"touchmove":"mousemove";a.event.special.scrollstart={enabled:!0,setup:function(){function b(a,b){c=b,e(f,c?"scrollstart":"scrollstop",a)}var c,d,f=this,g=a(f);g.bind(h,function(e){a.event.special.scrollstart.enabled&&(c||b(e,!0),clearTimeout(d),d=setTimeout(function(){b(e,!1)},50))})}},a.event.special.tap={tapholdThreshold:750,setup:function(){var b=this,c=a(b);c.bind("vmousedown",function(d){function g(){clearTimeout(j)}function h(){g(),c.unbind("vclick",i).unbind("vmouseup",g),f.unbind("vmousecancel",h)}function i(a){h(),k===a.target&&e(b,"tap",a)
-}if(d.which&&1!==d.which)return!1;var j,k=d.target;d.originalEvent,c.bind("vmouseup",g).bind("vclick",i),f.bind("vmousecancel",h),j=setTimeout(function(){e(b,"taphold",a.Event("taphold",{target:k}))},a.event.special.tap.tapholdThreshold)})}},a.event.special.swipe={scrollSupressionThreshold:30,durationThreshold:1e3,horizontalDistanceThreshold:30,verticalDistanceThreshold:75,start:function(b){var c=b.originalEvent.touches?b.originalEvent.touches[0]:b;return{time:(new Date).getTime(),coords:[c.pageX,c.pageY],origin:a(b.target)}},stop:function(a){var b=a.originalEvent.touches?a.originalEvent.touches[0]:a;return{time:(new Date).getTime(),coords:[b.pageX,b.pageY]}},handleSwipe:function(b,c){c.time-b.time<a.event.special.swipe.durationThreshold&&Math.abs(b.coords[0]-c.coords[0])>a.event.special.swipe.horizontalDistanceThreshold&&Math.abs(b.coords[1]-c.coords[1])<a.event.special.swipe.verticalDistanceThreshold&&b.origin.trigger("swipe").trigger(b.coords[0]>c.coords[0]?"swipeleft":"swiperight")},setup:function(){var b=this,c=a(b);c.bind(i,function(b){function e(b){g&&(f=a.event.special.swipe.stop(b),Math.abs(g.coords[0]-f.coords[0])>a.event.special.swipe.scrollSupressionThreshold&&b.preventDefault())}var f,g=a.event.special.swipe.start(b);c.bind(k,e).one(j,function(){c.unbind(k,e),g&&f&&a.event.special.swipe.handleSwipe(g,f),g=f=d})})}},a.each({scrollstop:"scrollstart",taphold:"tap",swipeleft:"swipe",swiperight:"swipe"},function(b,c){a.event.special[b]={setup:function(){a(this).bind(c,a.noop)}}})}(a,this),function(a){a.event.special.throttledresize={setup:function(){a(this).bind("resize",f)},teardown:function(){a(this).unbind("resize",f)}};var b,c,d,e=250,f=function(){c=(new Date).getTime(),d=c-g,d>=e?(g=c,a(this).trigger("throttledresize")):(b&&clearTimeout(b),b=setTimeout(f,e-d))},g=0}(a),function(a,b){function d(){var a=e();a!==f&&(f=a,i.trigger(j))}var e,f,g,h,i=a(b),j="orientationchange",k={0:!0,180:!0};if(a.support.orientation){var l=b.innerWidth||i.width(),m=b.innerHeight||i.height(),n=50;g=l>m&&l-m>n,h=k[b.orientation],(g&&h||!g&&!h)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=a.extend({},a.event.special.orientationchange,{setup:function(){return a.support.orientation&&!a.event.special.orientationchange.disabled?!1:(f=e(),i.bind("throttledresize",d),void 0)},teardown:function(){return a.support.orientation&&!a.event.special.orientationchange.disabled?!1:(i.unbind("throttledresize",d),void 0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=e(),b.apply(this,arguments)}}}),a.event.special.orientationchange.orientation=e=function(){var d=!0,e=c.documentElement;return d=a.support.orientation?k[b.orientation]:e&&e.clientWidth/e.clientHeight<1.1,d?"portrait":"landscape"},a.fn[j]=function(a){return a?this.bind(j,a):this.trigger(j)},a.attrFn&&(a.attrFn[j]=!0)}(a,this),function(a){a.widget("mobile.page",a.mobile.widget,{options:{theme:"c",domCache:!1,keepNativeDefault:":jqmData(role='none'), :jqmData(role='nojs')"},_create:function(){return this._trigger("beforecreate")===!1?!1:(this.element.attr("tabindex","0").addClass("ui-page ui-body-"+this.options.theme),this._on(this.element,{pagebeforehide:"removeContainerBackground",pagebeforeshow:"_handlePageBeforeShow"}),void 0)},_handlePageBeforeShow:function(){this.setContainerBackground()},removeContainerBackground:function(){a.mobile.pageContainer.removeClass("ui-overlay-"+a.mobile.getInheritedTheme(this.element.parent()))},setContainerBackground:function(b){this.options.theme&&a.mobile.pageContainer.addClass("ui-overlay-"+(b||this.options.theme))},keepNativeSelector:function(){var b=this.options,c=b.keepNative&&a.trim(b.keepNative);return c&&b.keepNative!==b.keepNativeDefault?[b.keepNative,b.keepNativeDefault].join(", "):b.keepNativeDefault}})}(a),function(a,b,c){var d=function(d){return d===c&&(d=!0),function(c,e,f,g){var h=new a.Deferred,i=e?" reverse":"",j=a.mobile.urlHistory.getActive(),k=j.lastScroll||a.mobile.defaultHomeScroll,l=a.mobile.getScreenHeight(),m=a.mobile.maxTransitionWidth!==!1&&a.mobile.window.width()>a.mobile.maxTransitionWidth,n=!a.support.cssTransitions||m||!c||"none"===c||Math.max(a.mobile.window.scrollTop(),k)>a.mobile.getMaxScrollForTransition(),o=" ui-page-pre-in",p=function(){a.mobile.pageContainer.toggleClass("ui-mobile-viewport-transitioning viewport-"+c)},q=function(){a.event.special.scrollstart.enabled=!1,b.scrollTo(0,k),setTimeout(function(){a.event.special.scrollstart.enabled=!0},150)},r=function(){g.removeClass(a.mobile.activePageClass+" out in reverse "+c).height("")},s=function(){d?g.animationComplete(t):t(),g.height(l+a.mobile.window.scrollTop()).addClass(c+" out"+i)},t=function(){g&&d&&r(),u()},u=function(){f.css("z-index",-10),f.addClass(a.mobile.activePageClass+o),a.mobile.focusPage(f),f.height(l+k),q(),f.css("z-index",""),n||f.animationComplete(v),f.removeClass(o).addClass(c+" in"+i),n&&v()},v=function(){d||g&&r(),f.removeClass("out in reverse "+c).height(""),p(),a.mobile.window.scrollTop()!==k&&q(),h.resolve(c,e,f,g,!0)};return p(),g&&!n?s():t(),h.promise()}},e=d(),f=d(!1),g=function(){return 3*a.mobile.getScreenHeight()};a.mobile.defaultTransitionHandler=e,a.mobile.transitionHandlers={"default":a.mobile.defaultTransitionHandler,sequential:e,simultaneous:f},a.mobile.transitionFallbacks={},a.mobile._maybeDegradeTransition=function(b){return b&&!a.support.cssTransform3d&&a.mobile.transitionFallbacks[b]&&(b=a.mobile.transitionFallbacks[b]),b},a.mobile.getMaxScrollForTransition=a.mobile.getMaxScrollForTransition||g}(a,this),function(a,d){function e(b){!p||p.closest("."+a.mobile.activePageClass).length&&!b||p.removeClass(a.mobile.activeBtnClass),p=null}function f(){t=!1,s.length>0&&a.mobile.changePage.apply(null,s.pop())}function g(b,c,d,e){c&&c.data("mobile-page")._trigger("beforehide",null,{nextPage:b}),b.data("mobile-page")._trigger("beforeshow",null,{prevPage:c||a("")}),a.mobile.hidePageLoadingMsg(),d=a.mobile._maybeDegradeTransition(d);var f=a.mobile.transitionHandlers[d||"default"]||a.mobile.defaultTransitionHandler,g=f(d,e,b,c);return g.done(function(){c&&c.data("mobile-page")._trigger("hide",null,{nextPage:b}),b.data("mobile-page")._trigger("show",null,{prevPage:c||a("")})}),g}function h(b,c){c&&b.attr("data-"+a.mobile.ns+"role",c),b.page()}function i(){var b=a.mobile.activePage&&k(a.mobile.activePage);return b||x.hrefNoHash}function j(a){for(;a&&("string"!=typeof a.nodeName||"a"!==a.nodeName.toLowerCase());)a=a.parentNode;return a}function k(b){var c=a(b).closest(".ui-page").jqmData("url"),d=x.hrefNoHash;return c&&n.isPath(c)||(c=d),n.makeUrlAbsolute(c,d)}var l=a.mobile.window,m=(a("html"),a("head")),n=a.extend(a.mobile.path,{getFilePath:function(b){var c="&"+a.mobile.subPageUrlKey;return b&&b.split(c)[0].split(u)[0]},isFirstPageUrl:function(b){var c=n.parseUrl(n.makeUrlAbsolute(b,this.documentBase)),e=c.hrefNoHash===this.documentUrl.hrefNoHash||this.documentBaseDiffers&&c.hrefNoHash===this.documentBase.hrefNoHash,f=a.mobile.firstPage,g=f&&f[0]?f[0].id:d;return e&&(!c.hash||"#"===c.hash||g&&c.hash.replace(/^#/,"")===g)},isPermittedCrossDomainRequest:function(b,c){return a.mobile.allowCrossDomainPages&&"file:"===b.protocol&&-1!==c.search(/^https?:/)}}),o=null,p=null,q=a.Deferred(),r=a.mobile.navigate.history,s=[],t=!1,u="&ui-state=dialog",v=m.children("base"),w=n.documentUrl,x=n.documentBase,y=(n.documentBaseDiffers,a.mobile.getScreenHeight),z=a.support.dynamicBaseTag?{element:v.length?v:a("<base>",{href:x.hrefNoHash}).prependTo(m),set:function(a){a=n.parseUrl(a).hrefNoHash,z.element.attr("href",n.makeUrlAbsolute(a,x))},reset:function(){z.element.attr("href",x.hrefNoSearch)}}:d;a.mobile.getDocumentUrl=n.getDocumentUrl,a.mobile.getDocumentBase=n.getDocumentBase,a.mobile.back=function(){var a=b.navigator;this.phonegapNavigationEnabled&&a&&a.app&&a.app.backHistory?a.app.backHistory():b.history.back()},a.mobile.focusPage=function(a){var b=a.find("[autofocus]"),c=a.find(".ui-title:eq(0)");return b.length?(b.focus(),void 0):(c.length?c.focus():a.focus(),void 0)};var A,B,C=!0;A=function(){if(C){var b=a.mobile.urlHistory.getActive();if(b){var c=l.scrollTop();b.lastScroll=c<a.mobile.minScrollBack?a.mobile.defaultHomeScroll:c}}},B=function(){setTimeout(A,100)},l.bind(a.support.pushState?"popstate":"hashchange",function(){C=!1}),l.one(a.support.pushState?"popstate":"hashchange",function(){C=!0}),l.one("pagecontainercreate",function(){a.mobile.pageContainer.bind("pagechange",function(){C=!0,l.unbind("scrollstop",B),l.bind("scrollstop",B)})}),l.bind("scrollstop",B),a.mobile._maybeDegradeTransition=a.mobile._maybeDegradeTransition||function(a){return a},a.mobile.resetActivePageHeight=function(b){var c=a("."+a.mobile.activePageClass),d=parseFloat(c.css("padding-top")),e=parseFloat(c.css("padding-bottom")),f=parseFloat(c.css("border-top-width")),g=parseFloat(c.css("border-bottom-width"));b="number"==typeof b?b:y(),c.css("min-height",b-d-e-f-g)},a.fn.animationComplete=function(b){return a.support.cssTransitions?a(this).one("webkitAnimationEnd animationend",b):(setTimeout(b,0),a(this))},a.mobile.path=n,a.mobile.base=z,a.mobile.urlHistory=r,a.mobile.dialogHashKey=u,a.mobile.allowCrossDomainPages=!1,a.mobile._bindPageRemove=function(){var b=a(this);!b.data("mobile-page").options.domCache&&b.is(":jqmData(external-page='true')")&&b.bind("pagehide.remove",function(){var b=a(this),c=new a.Event("pageremove");b.trigger(c),c.isDefaultPrevented()||b.removeWithDependents()})},a.mobile.loadPage=function(b,c){var e=a.Deferred(),f=a.extend({},a.mobile.loadPage.defaults,c),g=null,j=null,k=n.makeUrlAbsolute(b,i());f.data&&"get"===f.type&&(k=n.addSearchParams(k,f.data),f.data=d),f.data&&"post"===f.type&&(f.reloadPage=!0);var l=n.getFilePath(k),m=n.convertUrlToDataUrl(k);if(f.pageContainer=f.pageContainer||a.mobile.pageContainer,g=f.pageContainer.children("[data-"+a.mobile.ns+"url='"+m+"']"),0===g.length&&m&&!n.isPath(m)&&(g=f.pageContainer.children("#"+m).attr("data-"+a.mobile.ns+"url",m).jqmData("url",m)),0===g.length)if(a.mobile.firstPage&&n.isFirstPageUrl(l))a.mobile.firstPage.parent().length&&(g=a(a.mobile.firstPage));else if(n.isEmbeddedPage(l))return e.reject(k,c),e.promise();if(g.length){if(!f.reloadPage)return h(g,f.role),e.resolve(k,c,g),z&&!c.prefetch&&z.set(b),e.promise();j=g}var o=f.pageContainer,p=new a.Event("pagebeforeload"),q={url:b,absUrl:k,dataUrl:m,deferred:e,options:f};if(o.trigger(p,q),p.isDefaultPrevented())return e.promise();if(f.showLoadMsg)var r=setTimeout(function(){a.mobile.showPageLoadingMsg()},f.loadMsgDelay),s=function(){clearTimeout(r),a.mobile.hidePageLoadingMsg()};return!z||"undefined"!=typeof c&&"undefined"!=typeof c.prefetch||z.reset(),a.mobile.allowCrossDomainPages||n.isSameDomain(w,k)?a.ajax({url:l,type:f.type,data:f.data,contentType:f.contentType,dataType:"html",success:function(d,i,o){var p=a("<div></div>"),r=d.match(/<title[^>]*>([^<]*)/)&&RegExp.$1,t=new RegExp("(<[^>]+\\bdata-"+a.mobile.ns+"role=[\"']?page[\"']?[^>]*>)"),u=new RegExp("\\bdata-"+a.mobile.ns+"url=[\"']?([^\"'>]*)[\"']?");if(t.test(d)&&RegExp.$1&&u.test(RegExp.$1)&&RegExp.$1&&(b=l=n.getFilePath(a("<div>"+RegExp.$1+"</div>").text())),!z||"undefined"!=typeof c&&"undefined"!=typeof c.prefetch||z.set(l),p.get(0).innerHTML=d,g=p.find(":jqmData(role='page'), :jqmData(role='dialog')").first(),g.length||(g=a("<div data-"+a.mobile.ns+"role='page'>"+(d.split(/<\/?body[^>]*>/gim)[1]||"")+"</div>")),r&&!g.jqmData("title")&&(~r.indexOf("&")&&(r=a("<div>"+r+"</div>").text()),g.jqmData("title",r)),!a.support.dynamicBaseTag){var v=n.get(l);g.find("[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]").each(function(){var b=a(this).is("[href]")?"href":a(this).is("[src]")?"src":"action",c=a(this).attr(b);c=c.replace(location.protocol+"//"+location.host+location.pathname,""),/^(\w+:|#|\/)/.test(c)||a(this).attr(b,v+c)})}g.attr("data-"+a.mobile.ns+"url",n.convertUrlToDataUrl(l)).attr("data-"+a.mobile.ns+"external-page",!0).appendTo(f.pageContainer),g.one("pagecreate",a.mobile._bindPageRemove),h(g,f.role),k.indexOf("&"+a.mobile.subPageUrlKey)>-1&&(g=f.pageContainer.children("[data-"+a.mobile.ns+"url='"+m+"']")),f.showLoadMsg&&s(),q.xhr=o,q.textStatus=i,q.page=g,f.pageContainer.trigger("pageload",q),e.resolve(k,c,g,j)},error:function(b,d,g){z&&z.set(n.get()),q.xhr=b,q.textStatus=d,q.errorThrown=g;var h=new a.Event("pageloadfailed");f.pageContainer.trigger(h,q),h.isDefaultPrevented()||(f.showLoadMsg&&(s(),a.mobile.showPageLoadingMsg(a.mobile.pageLoadErrorMessageTheme,a.mobile.pageLoadErrorMessage,!0),setTimeout(a.mobile.hidePageLoadingMsg,1500)),e.reject(k,c))}}):e.reject(k,c),e.promise()},a.mobile.loadPage.defaults={type:"get",data:d,reloadPage:!1,role:d,showLoadMsg:!1,pageContainer:d,loadMsgDelay:50},a.mobile.changePage=function(b,j){if(t)return s.unshift(arguments),void 0;var k,l=a.extend({},a.mobile.changePage.defaults,j);l.pageContainer=l.pageContainer||a.mobile.pageContainer,l.fromPage=l.fromPage||a.mobile.activePage,k="string"==typeof b;var m=l.pageContainer,o=new a.Event("pagebeforechange"),p={toPage:b,options:l};if(p.absUrl=k?n.makeUrlAbsolute(b,i()):b.data("absUrl"),m.trigger(o,p),!o.isDefaultPrevented()){if(b=p.toPage,k="string"==typeof b,t=!0,k)return l.target=b,a.mobile.loadPage(b,l).done(function(b,c,d,e){t=!1,c.duplicateCachedPage=e,d.data("absUrl",p.absUrl),a.mobile.changePage(d,c)}).fail(function(){e(!0),f(),l.pageContainer.trigger("pagechangefailed",p)}),void 0;b[0]!==a.mobile.firstPage[0]||l.dataUrl||(l.dataUrl=w.hrefNoHash);var q=l.fromPage,v=l.dataUrl&&n.convertUrlToDataUrl(l.dataUrl)||b.jqmData("url"),x=v,y=(n.getFilePath(v),r.getActive()),z=0===r.activeIndex,A=0,B=c.title,C="dialog"===l.role||"dialog"===b.jqmData("role");if(q&&q[0]===b[0]&&!l.allowSamePageTransition)return t=!1,m.trigger("pagechange",p),l.fromHashChange&&r.direct({url:v}),void 0;h(b,l.role),l.fromHashChange&&(A="back"===j.direction?-1:1);try{c.activeElement&&"body"!==c.activeElement.nodeName.toLowerCase()?a(c.activeElement).blur():a("input:focus, textarea:focus, select:focus").blur()}catch(D){}var E=!1;C&&y&&(y.url&&y.url.indexOf(u)>-1&&a.mobile.activePage&&!a.mobile.activePage.is(".ui-dialog")&&r.activeIndex>0&&(l.changeHash=!1,E=!0),v=y.url||"",v+=!E&&v.indexOf("#")>-1?u:"#"+u,0===r.activeIndex&&v===r.initialDst&&(v+=u));var F=y?b.jqmData("title")||b.children(":jqmData(role='header')").find(".ui-title").text():B;if(F&&B===c.title&&(B=F),b.jqmData("title")||b.jqmData("title",B),l.transition=l.transition||(A&&!z?y.transition:d)||(C?a.mobile.defaultDialogTransition:a.mobile.defaultPageTransition),!A&&E&&(r.getActive().pageUrl=x),v&&!l.fromHashChange){var G;!n.isPath(v)&&v.indexOf("#")<0&&(v="#"+v),G={transition:l.transition,title:B,pageUrl:x,role:l.role},l.changeHash!==!1&&a.mobile.hashListeningEnabled?a.mobile.navigate(v,G,!0):b[0]!==a.mobile.firstPage[0]&&a.mobile.navigate.history.add(v,G)}c.title=B,a.mobile.activePage=b,l.reverse=l.reverse||0>A,g(b,q,l.transition,l.reverse).done(function(c,d,g,h,i){e(),l.duplicateCachedPage&&l.duplicateCachedPage.remove(),i||a.mobile.focusPage(b),f(),m.trigger("pagechange",p)})}},a.mobile.changePage.defaults={transition:d,reverse:!1,changeHash:!0,fromHashChange:!1,role:d,duplicateCachedPage:d,pageContainer:d,showLoadMsg:!0,dataUrl:d,fromPage:d,allowSamePageTransition:!1},a.mobile.navreadyDeferred=a.Deferred(),a.mobile._registerInternalEvents=function(){var c=function(b,c){var d,e,f,g,h=!0;return!a.mobile.ajaxEnabled||b.is(":jqmData(ajax='false')")||!b.jqmHijackable().length||b.attr("target")?!1:(d=b.attr("action"),g=(b.attr("method")||"get").toLowerCase(),d||(d=k(b),"get"===g&&(d=n.parseUrl(d).hrefNoSearch),d===x.hrefNoHash&&(d=w.hrefNoSearch)),d=n.makeUrlAbsolute(d,k(b)),n.isExternal(d)&&!n.isPermittedCrossDomainRequest(w,d)?!1:(c||(e=b.serializeArray(),o&&o[0].form===b[0]&&(f=o.attr("name"),f&&(a.each(e,function(a,b){return b.name===f?(f="",!1):void 0}),f&&e.push({name:f,value:o.attr("value")}))),h={url:d,options:{type:g,data:a.param(e),transition:b.jqmData("transition"),reverse:"reverse"===b.jqmData("direction"),reloadPage:!0}}),h))};a.mobile.document.delegate("form","submit",function(b){var d=c(a(this));d&&(a.mobile.changePage(d.url,d.options),b.preventDefault())}),a.mobile.document.bind("vclick",function(b){var d,f,g=b.target,h=!1;if(!(b.which>1)&&a.mobile.linkBindingEnabled){if(o=a(g),a.data(g,"mobile-button")){if(!c(a(g).closest("form"),!0))return;g.parentNode&&(g=g.parentNode)}else{if(g=j(g),!g||"#"===n.parseUrl(g.getAttribute("href")||"#").hash)return;if(!a(g).jqmHijackable().length)return}~g.className.indexOf("ui-link-inherit")?g.parentNode&&(f=a.data(g.parentNode,"buttonElements")):f=a.data(g,"buttonElements"),f?g=f.outer:h=!0,d=a(g),h&&(d=d.closest(".ui-btn")),d.length>0&&!d.hasClass("ui-disabled")&&(e(!0),p=d,p.addClass(a.mobile.activeBtnClass))}}),a.mobile.document.bind("click",function(c){if(a.mobile.linkBindingEnabled&&!c.isDefaultPrevented()){var f,g=j(c.target),h=a(g);if(g&&!(c.which>1)&&h.jqmHijackable().length){if(f=function(){b.setTimeout(function(){e(!0)},200)},h.is(":jqmData(rel='back')"))return a.mobile.back(),!1;var i=k(h),l=n.makeUrlAbsolute(h.attr("href")||"#",i);if(!a.mobile.ajaxEnabled&&!n.isEmbeddedPage(l))return f(),void 0;if(-1!==l.search("#")){if(l=l.replace(/[^#]*#/,""),!l)return c.preventDefault(),void 0;l=n.isPath(l)?n.makeUrlAbsolute(l,i):n.makeUrlAbsolute("#"+l,w.hrefNoHash)}var m=h.is("[rel='external']")||h.is(":jqmData(ajax='false')")||h.is("[target]"),o=m||n.isExternal(l)&&!n.isPermittedCrossDomainRequest(w,l);if(o)return f(),void 0;var p=h.jqmData("transition"),q="reverse"===h.jqmData("direction")||h.jqmData("back"),r=h.attr("data-"+a.mobile.ns+"rel")||d;a.mobile.changePage(l,{transition:p,reverse:q,role:r,link:h}),c.preventDefault()}}}),a.mobile.document.delegate(".ui-page","pageshow.prefetch",function(){var b=[];a(this).find("a:jqmData(prefetch)").each(function(){var c=a(this),d=c.attr("href");d&&-1===a.inArray(d,b)&&(b.push(d),a.mobile.loadPage(d,{role:c.attr("data-"+a.mobile.ns+"rel"),prefetch:!0}))})}),a.mobile._handleHashChange=function(c,e){var f=n.stripHash(c),g=0===a.mobile.urlHistory.stack.length?"none":d,h={changeHash:!1,fromHashChange:!0,reverse:"back"===e.direction};if(a.extend(h,e,{transition:(r.getLast()||{}).transition||g}),r.activeIndex>0&&f.indexOf(u)>-1&&r.initialDst!==f){if(a.mobile.activePage&&!a.mobile.activePage.is(".ui-dialog"))return"back"===e.direction?a.mobile.back():b.history.forward(),void 0;f=e.pageUrl;var i=a.mobile.urlHistory.getActive();a.extend(h,{role:i.role,transition:i.transition,reverse:"back"===e.direction})}f?(f=n.isPath(f)?f:n.makeUrlAbsolute("#"+f,x),f===n.makeUrlAbsolute("#"+r.initialDst,x)&&r.stack.length&&r.stack[0].url!==r.initialDst.replace(u,"")&&(f=a.mobile.firstPage),a.mobile.changePage(f,h)):a.mobile.changePage(a.mobile.firstPage,h)},l.bind("navigate",function(b,c){var d;b.originalEvent&&b.originalEvent.isDefaultPrevented()||(d=a.event.special.navigate.originalEventName.indexOf("hashchange")>-1?c.state.hash:c.state.url,d||(d=a.mobile.path.parseLocation().hash),d&&"#"!==d&&0!==d.indexOf("#"+a.mobile.path.uiStateKey)||(d=location.href),a.mobile._handleHashChange(d,c.state))}),a.mobile.document.bind("pageshow",a.mobile.resetActivePageHeight),a.mobile.window.bind("throttledresize",a.mobile.resetActivePageHeight)},a(function(){q.resolve()}),a.when(q,a.mobile.navreadyDeferred).done(function(){a.mobile._registerInternalEvents()})}(a),function(a){a.mobile.transitionFallbacks.flip="fade"}(a,this),function(a){a.mobile.transitionFallbacks.flow="fade"}(a,this),function(a){a.mobile.transitionFallbacks.pop="fade"}(a,this),function(a){a.mobile.transitionHandlers.slide=a.mobile.transitionHandlers.simultaneous,a.mobile.transitionFallbacks.slide="fade"}(a,this),function(a){a.mobile.transitionFallbacks.slidedown="fade"}(a,this),function(a){a.mobile.transitionFallbacks.slidefade="fade"}(a,this),function(a){a.mobile.transitionFallbacks.slideup="fade"}(a,this),function(a){a.mobile.transitionFallbacks.turn="fade"}(a,this),function(a){a.mobile.page.prototype.options.degradeInputs={color:!1,date:!1,datetime:!1,"datetime-local":!1,email:!1,month:!1,number:!1,range:"number",search:"text",tel:!1,time:!1,url:!1,week:!1},a.mobile.document.bind("pagecreate create",function(b){var c,d=a.mobile.closestPageData(a(b.target));d&&(c=d.options,a(b.target).find("input").not(d.keepNativeSelector()).each(function(){var b=a(this),d=this.getAttribute("type"),e=c.degradeInputs[d]||"text";if(c.degradeInputs[d]){var f=a("<div>").html(b.clone()).html(),g=f.indexOf(" type=")>-1,h=g?/\s+type=["']?\w+['"]?/:/\/?>/,i=' type="'+e+'" data-'+a.mobile.ns+'type="'+d+'"'+(g?"":">");b.replaceWith(f.replace(h,i))}}))})}(a),function(a){a.widget("mobile.dialog",a.mobile.widget,{options:{closeBtn:"left",closeBtnText:"Close",overlayTheme:"a",corners:!0,initSelector:":jqmData(role='dialog')"},_handlePageBeforeShow:function(){this._isCloseable=!0,this.options.overlayTheme&&this.element.page("removeContainerBackground").page("setContainerBackground",this.options.overlayTheme)},_handlePageBeforeHide:function(){this._isCloseable=!1},_create:function(){var b=this.element,c=this.options.corners?" ui-corner-all":"",d=a("<div/>",{role:"dialog","class":"ui-dialog-contain ui-overlay-shadow"+c});b.addClass("ui-dialog ui-overlay-"+this.options.overlayTheme),b.wrapInner(d),b.bind("vclick submit",function(b){var c,d=a(b.target).closest("vclick"===b.type?"a":"form");d.length&&!d.jqmData("transition")&&(c=a.mobile.urlHistory.getActive()||{},d.attr("data-"+a.mobile.ns+"transition",c.transition||a.mobile.defaultDialogTransition).attr("data-"+a.mobile.ns+"direction","reverse"))}),this._on(b,{pagebeforeshow:"_handlePageBeforeShow",pagebeforehide:"_handlePageBeforeHide"}),a.extend(this,{_createComplete:!1}),this._setCloseBtn(this.options.closeBtn)},_setCloseBtn:function(b){var c,d,e=this;this._headerCloseButton&&(this._headerCloseButton.remove(),this._headerCloseButton=null),"none"!==b&&(d="left"===b?"left":"right",c=a("<a href='#' class='ui-btn-"+d+"' data-"+a.mobile.ns+"icon='delete' data-"+a.mobile.ns+"iconpos='notext'>"+this.options.closeBtnText+"</a>"),this.element.children().find(":jqmData(role='header')").first().prepend(c),this._createComplete&&a.fn.buttonMarkup&&c.buttonMarkup(),this._createComplete=!0,c.bind("click",function(){e.close()}),this._headerCloseButton=c)},_setOption:function(a,b){"closeBtn"===a&&this._setCloseBtn(b),this._super(a,b)},close:function(){var b,c,d=a.mobile.navigate.history;this._isCloseable&&(this._isCloseable=!1,a.mobile.hashListeningEnabled&&d.activeIndex>0?a.mobile.back():(b=Math.max(0,d.activeIndex-1),c=d.stack[b].pageUrl||d.stack[b].url,d.previousIndex=d.activeIndex,d.activeIndex=b,a.mobile.path.isPath(c)||(c=a.mobile.path.makeUrlAbsolute("#"+c)),a.mobile.changePage(c,{direction:"back",changeHash:!1,fromHashChange:!0})))}}),a.mobile.document.delegate(a.mobile.dialog.prototype.options.initSelector,"pagecreate",function(){a.mobile.dialog.prototype.enhance(this)})}(a,this),function(a){a.mobile.page.prototype.options.backBtnText="Back",a.mobile.page.prototype.options.addBackBtn=!1,a.mobile.page.prototype.options.backBtnTheme=null,a.mobile.page.prototype.options.headerTheme="a",a.mobile.page.prototype.options.footerTheme="a",a.mobile.page.prototype.options.contentTheme=null,a.mobile.document.bind("pagecreate",function(b){var c=a(b.target),d=c.data("mobile-page").options,e=c.jqmData("role"),f=d.theme;a(":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')",c).jqmEnhanceable().each(function(){var b,g,h,i,j=a(this),k=j.jqmData("role"),l=j.jqmData("theme"),m=l||d.contentTheme||"dialog"===e&&f;if(j.addClass("ui-"+k),"header"===k||"footer"===k){var n=l||("header"===k?d.headerTheme:d.footerTheme)||f;j.addClass("ui-bar-"+n).attr("role","header"===k?"banner":"contentinfo"),"header"===k&&(b=j.children("a, button"),g=b.hasClass("ui-btn-left"),h=b.hasClass("ui-btn-right"),g=g||b.eq(0).not(".ui-btn-right").addClass("ui-btn-left").length,h=h||b.eq(1).addClass("ui-btn-right").length),d.addBackBtn&&"header"===k&&a(".ui-page").length>1&&c.jqmData("url")!==a.mobile.path.stripHash(location.hash)&&!g&&(i=a("<a href='javascript:void(0);' class='ui-btn-left' data-"+a.mobile.ns+"rel='back' data-"+a.mobile.ns+"icon='arrow-l'>"+d.backBtnText+"</a>").attr("data-"+a.mobile.ns+"theme",d.backBtnTheme||n).prependTo(j)),j.children("h1, h2, h3, h4, h5, h6").addClass("ui-title").attr({role:"heading","aria-level":"1"})}else"content"===k&&(m&&j.addClass("ui-body-"+m),j.attr("role","main"))})})}(a),function(a,b){function d(a){for(var b;a&&(b="string"==typeof a.className&&a.className+" ",!(b&&b.indexOf("ui-btn ")>-1&&b.indexOf("ui-disabled ")<0));)a=a.parentNode;return a}function e(d,e,f,g,h){var i=a.data(d[0],"buttonElements");d.removeClass(e).addClass(f),i&&(i.bcls=a(c.createElement("div")).addClass(i.bcls+" "+f).removeClass(e).attr("class"),g!==b&&(i.hover=g),i.state=h)}var f=function(a,c){var d=a.getAttribute(c);return"true"===d?!0:"false"===d?!1:null===d?b:d};a.fn.buttonMarkup=function(d){var e,h=this,i="data-"+a.mobile.ns;d=d&&"object"===a.type(d)?d:{};for(var j=0;j<h.length;j++){var k,l,m,n,o,p,q=h.eq(j),r=q[0],s=a.extend({},a.fn.buttonMarkup.defaults,{icon:d.icon!==b?d.icon:f(r,i+"icon"),iconpos:d.iconpos!==b?d.iconpos:f(r,i+"iconpos"),theme:d.theme!==b?d.theme:f(r,i+"theme")||a.mobile.getInheritedTheme(q,"c"),inline:d.inline!==b?d.inline:f(r,i+"inline"),shadow:d.shadow!==b?d.shadow:f(r,i+"shadow"),corners:d.corners!==b?d.corners:f(r,i+"corners"),iconshadow:d.iconshadow!==b?d.iconshadow:f(r,i+"iconshadow"),mini:d.mini!==b?d.mini:f(r,i+"mini")},d),t="ui-btn-inner",u="ui-btn-text",v=!1,w="up";for(e in s)s[e]===b||null===s[e]?q.removeAttr(i+e):r.setAttribute(i+e,s[e]);for(p=a.data("INPUT"===r.tagName||"BUTTON"===r.tagName?r.parentNode:r,"buttonElements"),p?(r=p.outer,q=a(r),m=p.inner,n=p.text,a(p.icon).remove(),p.icon=null,v=p.hover,w=p.state):(m=c.createElement(s.wrapperEls),n=c.createElement(s.wrapperEls)),o=s.icon?c.createElement("span"):null,g&&!p&&g(),s.theme||(s.theme=a.mobile.getInheritedTheme(q,"c")),k="ui-btn ",k+=v?"ui-btn-hover-"+s.theme:"",k+=w?" ui-btn-"+w+"-"+s.theme:"",k+=s.shadow?" ui-shadow":"",k+=s.corners?" ui-btn-corner-all":"",s.mini!==b&&(k+=s.mini===!0?" ui-mini":" ui-fullsize"),s.inline!==b&&(k+=s.inline===!0?" ui-btn-inline":" ui-btn-block"),s.icon&&(s.icon="ui-icon-"+s.icon,s.iconpos=s.iconpos||"left",l="ui-icon "+s.icon,s.iconshadow&&(l+=" ui-icon-shadow")),s.iconpos&&(k+=" ui-btn-icon-"+s.iconpos,"notext"!==s.iconpos||q.attr("title")||q.attr("title",q.getEncodedText())),p&&q.removeClass(p.bcls||""),q.removeClass("ui-link").addClass(k),m.className=t,n.className=u,p||m.appendChild(n),o&&(o.className=l,p&&p.icon||(o.innerHTML="&#160;",m.appendChild(o)));r.firstChild&&!p;)n.appendChild(r.firstChild);p||r.appendChild(m),p={hover:v,state:w,bcls:k,outer:r,inner:m,text:n,icon:o},a.data(r,"buttonElements",p),a.data(m,"buttonElements",p),a.data(n,"buttonElements",p),o&&a.data(o,"buttonElements",p)}return this},a.fn.buttonMarkup.defaults={corners:!0,shadow:!0,iconshadow:!0,wrapperEls:"span"};var g=function(){var c,f,h=a.mobile.buttonMarkup.hoverDelay;a.mobile.document.bind({"vmousedown vmousecancel vmouseup vmouseover vmouseout focus blur scrollstart":function(g){var i,j=a(d(g.target)),k=g.originalEvent&&/^touch/.test(g.originalEvent.type),l=g.type;j.length&&(i=j.attr("data-"+a.mobile.ns+"theme"),"vmousedown"===l?k?c=setTimeout(function(){e(j,"ui-btn-up-"+i,"ui-btn-down-"+i,b,"down")},h):e(j,"ui-btn-up-"+i,"ui-btn-down-"+i,b,"down"):"vmousecancel"===l||"vmouseup"===l?e(j,"ui-btn-down-"+i,"ui-btn-up-"+i,b,"up"):"vmouseover"===l||"focus"===l?k?f=setTimeout(function(){e(j,"ui-btn-up-"+i,"ui-btn-hover-"+i,!0,"")},h):e(j,"ui-btn-up-"+i,"ui-btn-hover-"+i,!0,""):("vmouseout"===l||"blur"===l||"scrollstart"===l)&&(e(j,"ui-btn-hover-"+i+" ui-btn-down-"+i,"ui-btn-up-"+i,!1,"up"),c&&clearTimeout(c),f&&clearTimeout(f)))},"focusin focus":function(b){a(d(b.target)).addClass(a.mobile.focusClass)},"focusout blur":function(b){a(d(b.target)).removeClass(a.mobile.focusClass)}}),g=null};a.mobile.document.bind("pagecreate create",function(b){a(":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a, .ui-bar > :jqmData(role='controlgroup') > a",b.target).jqmEnhanceable().not("button, input, .ui-btn, :jqmData(role='none'), :jqmData(role='nojs')").buttonMarkup()})}(a),function(a,b){a.widget("mobile.collapsible",a.mobile.widget,{options:{expandCueText:" click to expand contents",collapseCueText:" click to collapse contents",collapsed:!0,heading:"h1,h2,h3,h4,h5,h6,legend",collapsedIcon:"plus",expandedIcon:"minus",iconpos:"left",theme:null,contentTheme:null,inset:!0,corners:!0,mini:!1,initSelector:":jqmData(role='collapsible')"},_create:function(){var c=this.element,d=this.options,e=c.addClass("ui-collapsible"),f=c.children(d.heading).first(),g=e.wrapInner("<div class='ui-collapsible-content'></div>").children(".ui-collapsible-content"),h=c.closest(":jqmData(role='collapsible-set')").addClass("ui-collapsible-set"),i="";f.is("legend")&&(f=a("<div role='heading'>"+f.html()+"</div>").insertBefore(f),f.next().remove()),h.length?(d.theme||(d.theme=h.jqmData("theme")||a.mobile.getInheritedTheme(h,"c")),d.contentTheme||(d.contentTheme=h.jqmData("content-theme")),d.collapsedIcon=c.jqmData("collapsed-icon")||h.jqmData("collapsed-icon")||d.collapsedIcon,d.expandedIcon=c.jqmData("expanded-icon")||h.jqmData("expanded-icon")||d.expandedIcon,d.iconpos=c.jqmData("iconpos")||h.jqmData("iconpos")||d.iconpos,d.inset=h.jqmData("inset")!==b?h.jqmData("inset"):!0,d.corners=!1,d.mini||(d.mini=h.jqmData("mini"))):d.theme||(d.theme=a.mobile.getInheritedTheme(c,"c")),d.inset&&(i+=" ui-collapsible-inset",d.corners&&(i+=" ui-corner-all")),d.contentTheme&&(i+=" ui-collapsible-themed-content",g.addClass("ui-body-"+d.contentTheme)),""!==i&&e.addClass(i),f.insertBefore(g).addClass("ui-collapsible-heading").append("<span class='ui-collapsible-heading-status'></span>").wrapInner("<a href='#' class='ui-collapsible-heading-toggle'></a>").find("a").first().buttonMarkup({shadow:!1,corners:!1,iconpos:d.iconpos,icon:d.collapsedIcon,mini:d.mini,theme:d.theme}),e.bind("expand collapse",function(b){if(!b.isDefaultPrevented()){var c=a(this),e="collapse"===b.type;b.preventDefault(),f.toggleClass("ui-collapsible-heading-collapsed",e).find(".ui-collapsible-heading-status").text(e?d.expandCueText:d.collapseCueText).end().find(".ui-icon").toggleClass("ui-icon-"+d.expandedIcon,!e).toggleClass("ui-icon-"+d.collapsedIcon,e||d.expandedIcon===d.collapsedIcon).end().find("a").first().removeClass(a.mobile.activeBtnClass),c.toggleClass("ui-collapsible-collapsed",e),g.toggleClass("ui-collapsible-content-collapsed",e).attr("aria-hidden",e),g.trigger("updatelayout")}}).trigger(d.collapsed?"collapse":"expand"),f.bind("tap",function(){f.find("a").first().addClass(a.mobile.activeBtnClass)}).bind("click",function(a){var b=f.is(".ui-collapsible-heading-collapsed")?"expand":"collapse";e.trigger(b),a.preventDefault(),a.stopPropagation()})}}),a.mobile.document.bind("pagecreate create",function(b){a.mobile.collapsible.prototype.enhanceWithin(b.target)})}(a),function(a){a.mobile.behaviors.addFirstLastClasses={_getVisibles:function(a,b){var c;return b?c=a.not(".ui-screen-hidden"):(c=a.filter(":visible"),0===c.length&&(c=a.not(".ui-screen-hidden"))),c},_addFirstLastClasses:function(a,b,c){a.removeClass("ui-first-child ui-last-child"),b.eq(0).addClass("ui-first-child").end().last().addClass("ui-last-child"),c||this.element.trigger("updatelayout")}}}(a),function(a,b){a.widget("mobile.collapsibleset",a.mobile.widget,a.extend({options:{initSelector:":jqmData(role='collapsible-set')"},_create:function(){var c=this.element.addClass("ui-collapsible-set"),d=this.options;d.theme||(d.theme=a.mobile.getInheritedTheme(c,"c")),d.contentTheme||(d.contentTheme=c.jqmData("content-theme")),d.corners||(d.corners=c.jqmData("corners")),c.jqmData("inset")!==b&&(d.inset=c.jqmData("inset")),d.inset=d.inset!==b?d.inset:!0,d.corners=d.corners!==b?d.corners:!0,d.corners&&d.inset&&c.addClass("ui-corner-all"),c.jqmData("collapsiblebound")||c.jqmData("collapsiblebound",!0).bind("expand",function(b){var c=a(b.target).closest(".ui-collapsible");
-c.parent().is(":jqmData(role='collapsible-set')")&&c.siblings(".ui-collapsible").trigger("collapse")})},_init:function(){var a=this.element,b=a.children(":jqmData(role='collapsible')"),c=b.filter(":jqmData(collapsed='false')");this._refresh("true"),c.trigger("expand")},_refresh:function(b){var c=this.element.children(":jqmData(role='collapsible')");a.mobile.collapsible.prototype.enhance(c.not(".ui-collapsible")),this._addFirstLastClasses(c,this._getVisibles(c,b),b)},refresh:function(){this._refresh(!1)}},a.mobile.behaviors.addFirstLastClasses)),a.mobile.document.bind("pagecreate create",function(b){a.mobile.collapsibleset.prototype.enhanceWithin(b.target)})}(a),function(a){a.fn.fieldcontain=function(){return this.addClass("ui-field-contain ui-body ui-br").contents().filter(function(){return 3===this.nodeType&&!/\S/.test(this.nodeValue)}).remove()},a(c).bind("pagecreate create",function(b){a(":jqmData(role='fieldcontain')",b.target).jqmEnhanceable().fieldcontain()})}(a),function(a){a.fn.grid=function(b){return this.each(function(){var c,d=a(this),e=a.extend({grid:null},b),f=d.children(),g={solo:1,a:2,b:3,c:4,d:5},h=e.grid;if(!h)if(f.length<=5)for(var i in g)g[i]===f.length&&(h=i);else h="a",d.addClass("ui-grid-duo");c=g[h],d.addClass("ui-grid-"+h),f.filter(":nth-child("+c+"n+1)").addClass("ui-block-a"),c>1&&f.filter(":nth-child("+c+"n+2)").addClass("ui-block-b"),c>2&&f.filter(":nth-child("+c+"n+3)").addClass("ui-block-c"),c>3&&f.filter(":nth-child("+c+"n+4)").addClass("ui-block-d"),c>4&&f.filter(":nth-child("+c+"n+5)").addClass("ui-block-e")})}}(a),function(a,b){a.widget("mobile.navbar",a.mobile.widget,{options:{iconpos:"top",grid:null,initSelector:":jqmData(role='navbar')"},_create:function(){var d=this.element,e=d.find("a"),f=e.filter(":jqmData(icon)").length?this.options.iconpos:b;d.addClass("ui-navbar ui-mini").attr("role","navigation").find("ul").jqmEnhanceable().grid({grid:this.options.grid}),e.buttonMarkup({corners:!1,shadow:!1,inline:!0,iconpos:f}),d.delegate("a","vclick",function(b){var d=a(b.target).is("a")?a(this):a(this).parent("a");if(!d.is(".ui-disabled, .ui-btn-active")){e.removeClass(a.mobile.activeBtnClass),a(this).addClass(a.mobile.activeBtnClass);var f=a(this);a(c).one("pagehide",function(){f.removeClass(a.mobile.activeBtnClass)})}}),d.closest(".ui-page").bind("pagebeforeshow",function(){e.filter(".ui-state-persist").addClass(a.mobile.activeBtnClass)})}}),a.mobile.document.bind("pagecreate create",function(b){a.mobile.navbar.prototype.enhanceWithin(b.target)})}(a),function(a){var b={};a.widget("mobile.listview",a.mobile.widget,a.extend({options:{theme:null,countTheme:"c",headerTheme:"b",dividerTheme:"b",icon:"arrow-r",splitIcon:"arrow-r",splitTheme:"b",corners:!0,shadow:!0,inset:!1,initSelector:":jqmData(role='listview')"},_create:function(){var a=this,b="";b+=a.options.inset?" ui-listview-inset":"",a.options.inset&&(b+=a.options.corners?" ui-corner-all":"",b+=a.options.shadow?" ui-shadow":""),a.element.addClass(function(a,c){return c+" ui-listview"+b}),a.refresh(!0)},_findFirstElementByTagName:function(a,b,c,d){var e={};for(e[c]=e[d]=!0;a;){if(e[a.nodeName])return a;a=a[b]}return null},_getChildrenByTagName:function(b,c,d){var e=[],f={};for(f[c]=f[d]=!0,b=b.firstChild;b;)f[b.nodeName]&&e.push(b),b=b.nextSibling;return a(e)},_addThumbClasses:function(b){var c,d,e=b.length;for(c=0;e>c;c++)d=a(this._findFirstElementByTagName(b[c].firstChild,"nextSibling","img","IMG")),d.length&&(d.addClass("ui-li-thumb"),a(this._findFirstElementByTagName(d[0].parentNode,"parentNode","li","LI")).addClass(d.is(".ui-li-icon")?"ui-li-has-icon":"ui-li-has-thumb"))},refresh:function(b){this.parentPage=this.element.closest(".ui-page"),this._createSubPages();var d,e,f,g,h,i,j,k,l,m,n,o,p=this.options,q=this.element,r=q.jqmData("dividertheme")||p.dividerTheme,s=q.jqmData("splittheme"),t=q.jqmData("spliticon"),u=q.jqmData("icon"),v=this._getChildrenByTagName(q[0],"li","LI"),w=!!a.nodeName(q[0],"ol"),x=!a.support.cssPseudoElement,y=q.attr("start"),z={};w&&x&&q.find(".ui-li-dec").remove(),w&&(y||0===y?x?j=parseInt(y,10):(k=parseInt(y,10)-1,q.css("counter-reset","listnumbering "+k)):x&&(j=1)),p.theme||(p.theme=a.mobile.getInheritedTheme(this.element,"c"));for(var A=0,B=v.length;B>A;A++){if(d=v.eq(A),e="ui-li",b||!d.hasClass("ui-li")){f=d.jqmData("theme")||p.theme,g=this._getChildrenByTagName(d[0],"a","A");var C="list-divider"===d.jqmData("role");g.length&&!C?(n=d.jqmData("icon"),d.buttonMarkup({wrapperEls:"div",shadow:!1,corners:!1,iconpos:"right",icon:g.length>1||n===!1?!1:n||u||p.icon,theme:f}),n!==!1&&1===g.length&&d.addClass("ui-li-has-arrow"),g.first().removeClass("ui-link").addClass("ui-link-inherit"),g.length>1&&(e+=" ui-li-has-alt",h=g.last(),i=s||h.jqmData("theme")||p.splitTheme,o=h.jqmData("icon"),h.appendTo(d).attr("title",a.trim(h.getEncodedText())).addClass("ui-li-link-alt").empty().buttonMarkup({shadow:!1,corners:!1,theme:f,icon:!1,iconpos:"notext"}).find(".ui-btn-inner").append(a(c.createElement("span")).buttonMarkup({shadow:!0,corners:!0,theme:i,iconpos:"notext",icon:o||n||t||p.splitIcon})))):C?(e+=" ui-li-divider ui-bar-"+(d.jqmData("theme")||r),d.attr("role","heading"),w&&(y||0===y?x?j=parseInt(y,10):(l=parseInt(y,10)-1,d.css("counter-reset","listnumbering "+l)):x&&(j=1))):e+=" ui-li-static ui-btn-up-"+f}w&&x&&e.indexOf("ui-li-divider")<0&&(m=e.indexOf("ui-li-static")>0?d:d.find(".ui-link-inherit"),m.addClass("ui-li-jsnumbering").prepend("<span class='ui-li-dec'>"+j++ +". </span>")),z[e]||(z[e]=[]),z[e].push(d[0])}for(e in z)a(z[e]).addClass(e).children(".ui-btn-inner").addClass(e);q.find("h1, h2, h3, h4, h5, h6").addClass("ui-li-heading").end().find("p, dl").addClass("ui-li-desc").end().find(".ui-li-aside").each(function(){var b=a(this);b.prependTo(b.parent())}).end().find(".ui-li-count").each(function(){a(this).closest("li").addClass("ui-li-has-count")}).addClass("ui-btn-up-"+(q.jqmData("counttheme")||this.options.countTheme)+" ui-btn-corner-all"),this._addThumbClasses(v),this._addThumbClasses(q.find(".ui-link-inherit")),this._addFirstLastClasses(v,this._getVisibles(v,b),b),this._trigger("afterrefresh")},_idStringEscape:function(a){return a.replace(/[^a-zA-Z0-9]/g,"-")},_createSubPages:function(){var c,d=this.element,e=d.closest(".ui-page"),f=e.jqmData("url"),g=f||e[0][a.expando],h=d.attr("id"),i=this.options,j="data-"+a.mobile.ns,k=this,l=e.find(":jqmData(role='footer')").jqmData("id");if("undefined"==typeof b[g]&&(b[g]=-1),h=h||++b[g],a(d.find("li>ul, li>ol").toArray().reverse()).each(function(b){var e,g,k=a(this),m=k.attr("id")||h+"-"+b,n=k.parent(),o=a(k.prevAll().toArray().reverse()),p=o.length?o:a("<span>"+a.trim(n.contents()[0].nodeValue)+"</span>"),q=p.first().getEncodedText(),r=(f||"")+"&"+a.mobile.subPageUrlKey+"="+m,s=k.jqmData("theme")||i.theme,t=k.jqmData("counttheme")||d.jqmData("counttheme")||i.countTheme;c=!0,e=k.detach().wrap("<div "+j+"role='page' "+j+"url='"+r+"' "+j+"theme='"+s+"' "+j+"count-theme='"+t+"'><div "+j+"role='content'></div></div>").parent().before("<div "+j+"role='header' "+j+"theme='"+i.headerTheme+"'><div class='ui-title'>"+q+"</div></div>").after(l?a("<div "+j+"role='footer' "+j+"id='"+l+"'>"):"").parent().appendTo(a.mobile.pageContainer),e.page(),g=n.find("a:first"),g.length||(g=a("<a/>").html(p||q).prependTo(n.empty())),g.attr("href","#"+r)}).listview(),c&&e.is(":jqmData(external-page='true')")&&e.data("mobile-page").options.domCache===!1){var m=function(b,c){var d,g=c.nextPage,h=new a.Event("pageremove");c.nextPage&&(d=g.jqmData("url"),0!==d.indexOf(f+"&"+a.mobile.subPageUrlKey)&&(k.childPages().remove(),e.trigger(h),h.isDefaultPrevented()||e.removeWithDependents()))};e.unbind("pagehide.remove").bind("pagehide.remove",m)}},childPages:function(){var b=this.parentPage.jqmData("url");return a(":jqmData(url^='"+b+"&"+a.mobile.subPageUrlKey+"')")}},a.mobile.behaviors.addFirstLastClasses)),a.mobile.document.bind("pagecreate create",function(b){a.mobile.listview.prototype.enhanceWithin(b.target)})}(a),function(a){var b=a("meta[name=viewport]"),c=b.attr("content"),d=c+",maximum-scale=1, user-scalable=no",e=c+",maximum-scale=10, user-scalable=yes",f=/(user-scalable[\s]*=[\s]*no)|(maximum-scale[\s]*=[\s]*1)[$,\s]/.test(c);a.mobile.zoom=a.extend({},{enabled:!f,locked:!1,disable:function(c){f||a.mobile.zoom.locked||(b.attr("content",d),a.mobile.zoom.enabled=!1,a.mobile.zoom.locked=c||!1)},enable:function(c){f||a.mobile.zoom.locked&&c!==!0||(b.attr("content",e),a.mobile.zoom.enabled=!0,a.mobile.zoom.locked=!1)},restore:function(){f||(b.attr("content",c),a.mobile.zoom.enabled=!0)}})}(a),function(a){a.widget("mobile.textinput",a.mobile.widget,{options:{theme:null,mini:!1,preventFocusZoom:/iPhone|iPad|iPod/.test(navigator.platform)&&navigator.userAgent.indexOf("AppleWebKit")>-1,initSelector:"input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='time'], input[type='date'], input[type='month'], input[type='week'], input[type='datetime'], input[type='datetime-local'], input[type='color'], input:not([type]), input[type='file']",clearBtn:!1,clearSearchButtonText:null,clearBtnText:"clear text",disabled:!1},_create:function(){function b(){setTimeout(function(){d.toggleClass("ui-input-clear-hidden",!f.val())},0)}var c,d,e=this,f=this.element,g=this.options,h=g.theme||a.mobile.getInheritedTheme(this.element,"c"),i=" ui-body-"+h,j=g.mini?" ui-mini":"",k=f.is("[type='search'], :jqmData(type='search')"),l=g.clearSearchButtonText||g.clearBtnText,m=f.is("textarea, :jqmData(type='range')"),n=!!g.clearBtn&&!m,o=f.is("input")&&!f.is(":jqmData(type='range')");if(a("label[for='"+f.attr("id")+"']").addClass("ui-input-text"),c=f.addClass("ui-input-text ui-body-"+h),"undefined"==typeof f[0].autocorrect||a.support.touchOverflow||(f[0].setAttribute("autocorrect","off"),f[0].setAttribute("autocomplete","off")),k?c=f.wrap("<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield"+i+j+"'></div>").parent():o&&(c=f.wrap("<div class='ui-input-text ui-shadow-inset ui-corner-all ui-btn-shadow"+i+j+"'></div>").parent()),n||k?(d=a("<a href='#' class='ui-input-clear' title='"+l+"'>"+l+"</a>").bind("click",function(a){f.val("").focus().trigger("change"),d.addClass("ui-input-clear-hidden"),a.preventDefault()}).appendTo(c).buttonMarkup({icon:"delete",iconpos:"notext",corners:!0,shadow:!0,mini:g.mini}),k||c.addClass("ui-input-has-clear"),b(),f.bind("paste cut keyup input focus change blur",b)):o||k||f.addClass("ui-corner-all ui-shadow-inset"+i+j),f.focus(function(){g.preventFocusZoom&&a.mobile.zoom.disable(!0),c.addClass(a.mobile.focusClass)}).blur(function(){c.removeClass(a.mobile.focusClass),g.preventFocusZoom&&a.mobile.zoom.enable(!0)}),f.is("textarea")){var p,q=15,r=100;this._keyup=function(){var a=f[0].scrollHeight,b=f[0].clientHeight;if(a>b){var c=parseFloat(f.css("padding-top")),d=parseFloat(f.css("padding-bottom")),e=c+d;f.height(a-e+q)}},f.on("keyup change input paste",function(){clearTimeout(p),p=setTimeout(e._keyup,r)}),this._on(!0,a.mobile.document,{pagechange:"_keyup"}),a.trim(f.val())&&this._on(!0,a.mobile.window,{load:"_keyup"})}f.attr("disabled")&&this.disable()},disable:function(){var a,b=this.element.is("[type='search'], :jqmData(type='search')"),c=this.element.is("input")&&!this.element.is(":jqmData(type='range')"),d=this.element.attr("disabled",!0)&&(c||b);return a=d?this.element.parent():this.element,a.addClass("ui-disabled"),this._setOption("disabled",!0)},enable:function(){var a,b=this.element.is("[type='search'], :jqmData(type='search')"),c=this.element.is("input")&&!this.element.is(":jqmData(type='range')"),d=this.element.attr("disabled",!1)&&(c||b);return a=d?this.element.parent():this.element,a.removeClass("ui-disabled"),this._setOption("disabled",!1)}}),a.mobile.document.bind("pagecreate create",function(b){a.mobile.textinput.prototype.enhanceWithin(b.target,!0)})}(a),function(a){a.mobile.listview.prototype.options.filter=!1,a.mobile.listview.prototype.options.filterPlaceholder="Filter items...",a.mobile.listview.prototype.options.filterTheme="c",a.mobile.listview.prototype.options.filterReveal=!1;var b=function(a,b){return-1===a.toString().toLowerCase().indexOf(b)};a.mobile.listview.prototype.options.filterCallback=b,a.mobile.document.delegate("ul, ol","listviewcreate",function(){var c=a(this),d=c.data("mobile-listview");if(d&&d.options.filter){d.options.filterReveal&&c.children().addClass("ui-screen-hidden");var e=a("<form>",{"class":"ui-listview-filter ui-bar-"+d.options.filterTheme,role:"search"}).submit(function(a){a.preventDefault(),g.blur()}),f=function(){var e,f=a(this),g=this.value.toLowerCase(),h=null,i=c.children(),j=f.jqmData("lastval")+"",k=!1,l="",m=d.options.filterCallback!==b;if(!j||j!==g){if(d._trigger("beforefilter","beforefilter",{input:this}),f.jqmData("lastval",g),m||g.length<j.length||0!==g.indexOf(j)?h=c.children():(h=c.children(":not(.ui-screen-hidden)"),!h.length&&d.options.filterReveal&&(h=c.children(".ui-screen-hidden"))),g){for(var n=h.length-1;n>=0;n--)e=a(h[n]),l=e.jqmData("filtertext")||e.text(),e.is("li:jqmData(role=list-divider)")?(e.toggleClass("ui-filter-hidequeue",!k),k=!1):d.options.filterCallback(l,g,e)?e.toggleClass("ui-filter-hidequeue",!0):k=!0;h.filter(":not(.ui-filter-hidequeue)").toggleClass("ui-screen-hidden",!1),h.filter(".ui-filter-hidequeue").toggleClass("ui-screen-hidden",!0).toggleClass("ui-filter-hidequeue",!1)}else h.toggleClass("ui-screen-hidden",!!d.options.filterReveal);d._addFirstLastClasses(i,d._getVisibles(i,!1),!1)}},g=a("<input>",{placeholder:d.options.filterPlaceholder}).attr("data-"+a.mobile.ns+"type","search").jqmData("lastval","").bind("keyup change input",f).appendTo(e).textinput();d.options.inset&&e.addClass("ui-listview-filter-inset"),e.bind("submit",function(){return!1}).insertBefore(c)}})}(a),function(a){a.mobile.listview.prototype.options.autodividers=!1,a.mobile.listview.prototype.options.autodividersSelector=function(b){var c=a.trim(b.text())||null;return c?c=c.slice(0,1).toUpperCase():null},a.mobile.document.delegate("ul,ol","listviewcreate",function(){var b=a(this),d=b.data("mobile-listview");if(d&&d.options.autodividers){var e=function(){b.find("li:jqmData(role='list-divider')").remove();for(var e,f,g=b.find("li"),h=null,i=0;i<g.length;i++){if(e=g[i],f=d.options.autodividersSelector(a(e)),f&&h!==f){var j=c.createElement("li");j.appendChild(c.createTextNode(f)),j.setAttribute("data-"+a.mobile.ns+"role","list-divider"),e.parentNode.insertBefore(j,e)}h=f}},f=function(){b.unbind("listviewafterrefresh",f),e(),d.refresh(),b.bind("listviewafterrefresh",f)};f()}})}(a),function(a){a(c).bind("pagecreate create",function(b){a(":jqmData(role='nojs')",b.target).addClass("ui-nojs")})}(a),function(a){a.mobile.behaviors.formReset={_handleFormReset:function(){this._on(this.element.closest("form"),{reset:function(){this._delay("_reset")}})}}}(a),function(a){a.widget("mobile.checkboxradio",a.mobile.widget,a.extend({options:{theme:null,mini:!1,initSelector:"input[type='checkbox'],input[type='radio']"},_create:function(){var b=this,d=this.element,e=this.options,f=function(a,b){return a.jqmData(b)||a.closest("form, fieldset").jqmData(b)},g=a(d).closest("label"),h=g.length?g:a(d).closest("form, fieldset, :jqmData(role='page'), :jqmData(role='dialog')").find("label").filter("[for='"+d[0].id+"']").first(),i=d[0].type,j=f(d,"mini")||e.mini,k=i+"-on",l=i+"-off",m=f(d,"iconpos"),n="ui-"+k,o="ui-"+l;if("checkbox"===i||"radio"===i){a.extend(this,{label:h,inputtype:i,checkedClass:n,uncheckedClass:o,checkedicon:k,uncheckedicon:l}),e.theme||(e.theme=a.mobile.getInheritedTheme(this.element,"c")),h.buttonMarkup({theme:e.theme,icon:l,shadow:!1,mini:j,iconpos:m});var p=c.createElement("div");p.className="ui-"+i,d.add(h).wrapAll(p),h.bind({vmouseover:function(b){a(this).parent().is(".ui-disabled")&&b.stopPropagation()},vclick:function(a){return d.is(":disabled")?(a.preventDefault(),void 0):(b._cacheVals(),d.prop("checked","radio"===i&&!0||!d.prop("checked")),d.triggerHandler("click"),b._getInputSet().not(d).prop("checked",!1),b._updateAll(),!1)}}),d.bind({vmousedown:function(){b._cacheVals()},vclick:function(){var c=a(this);c.is(":checked")?(c.prop("checked",!0),b._getInputSet().not(c).prop("checked",!1)):c.prop("checked",!1),b._updateAll()},focus:function(){h.addClass(a.mobile.focusClass)},blur:function(){h.removeClass(a.mobile.focusClass)}}),this._handleFormReset(),this.refresh()}},_cacheVals:function(){this._getInputSet().each(function(){a(this).jqmData("cacheVal",this.checked)})},_getInputSet:function(){return"checkbox"===this.inputtype?this.element:this.element.closest("form, :jqmData(role='page'), :jqmData(role='dialog')").find("input[name='"+this.element[0].name+"'][type='"+this.inputtype+"']")},_updateAll:function(){var b=this;this._getInputSet().each(function(){var c=a(this);(this.checked||"checkbox"===b.inputtype)&&c.trigger("change")}).checkboxradio("refresh")},_reset:function(){this.refresh()},refresh:function(){var b=this.element[0],c=" "+a.mobile.activeBtnClass,d=this.checkedClass+(this.element.parents(".ui-controlgroup-horizontal").length?c:""),e=this.label;b.checked?e.removeClass(this.uncheckedClass+c).addClass(d).buttonMarkup({icon:this.checkedicon}):e.removeClass(d).addClass(this.uncheckedClass).buttonMarkup({icon:this.uncheckedicon}),b.disabled?this.disable():this.enable()},disable:function(){this.element.prop("disabled",!0).parent().addClass("ui-disabled")},enable:function(){this.element.prop("disabled",!1).parent().removeClass("ui-disabled")}},a.mobile.behaviors.formReset)),a.mobile.document.bind("pagecreate create",function(b){a.mobile.checkboxradio.prototype.enhanceWithin(b.target,!0)})}(a),function(a){a.widget("mobile.button",a.mobile.widget,{options:{theme:null,icon:null,iconpos:null,corners:!0,shadow:!0,iconshadow:!0,inline:null,mini:null,initSelector:"button, [type='button'], [type='submit'], [type='reset']"},_create:function(){var b,c=this.element,d=function(a){var b,c={};for(b in a)null!==a[b]&&"initSelector"!==b&&(c[b]=a[b]);return c}(this.options),e="";return"A"===c[0].tagName?(c.hasClass("ui-btn")||c.buttonMarkup(),void 0):(this.options.theme||(this.options.theme=a.mobile.getInheritedTheme(this.element,"c")),~c[0].className.indexOf("ui-btn-left")&&(e="ui-btn-left"),~c[0].className.indexOf("ui-btn-right")&&(e="ui-btn-right"),("submit"===c.attr("type")||"reset"===c.attr("type"))&&(e?e+=" ui-submit":e="ui-submit"),a("label[for='"+c.attr("id")+"']").addClass("ui-submit"),this.button=a("<div></div>")[c.html()?"html":"text"](c.html()||c.val()).insertBefore(c).buttonMarkup(d).addClass(e).append(c.addClass("ui-btn-hidden")),b=this.button,c.bind({focus:function(){b.addClass(a.mobile.focusClass)},blur:function(){b.removeClass(a.mobile.focusClass)}}),this.refresh(),void 0)},_setOption:function(b,c){var d={};d[b]=c,"initSelector"!==b&&(this.button.buttonMarkup(d),this.element.attr("data-"+(a.mobile.ns||"")+b.replace(/([A-Z])/,"-$1").toLowerCase(),c)),this._super("_setOption",b,c)},enable:function(){return this.element.attr("disabled",!1),this.button.removeClass("ui-disabled").attr("aria-disabled",!1),this._setOption("disabled",!1)},disable:function(){return this.element.attr("disabled",!0),this.button.addClass("ui-disabled").attr("aria-disabled",!0),this._setOption("disabled",!0)},refresh:function(){var b=this.element;b.prop("disabled")?this.disable():this.enable(),a(this.button.data("buttonElements").text)[b.html()?"html":"text"](b.html()||b.val())}}),a.mobile.document.bind("pagecreate create",function(b){a.mobile.button.prototype.enhanceWithin(b.target,!0)})}(a),function(a,d){a.widget("mobile.slider",a.mobile.widget,a.extend({widgetEventPrefix:"slide",options:{theme:null,trackTheme:null,disabled:!1,initSelector:"input[type='range'], :jqmData(type='range'), :jqmData(role='slider')",mini:!1,highlight:!1},_create:function(){var e,f,g=this,h=this.element,i=a.mobile.getInheritedTheme(h,"c"),j=this.options.theme||i,k=this.options.trackTheme||i,l=h[0].nodeName.toLowerCase(),m=(this.isToggleSwitch="select"===l,h.parent().is(":jqmData(role='rangeslider')")),n=this.isToggleSwitch?"ui-slider-switch":"",o=h.attr("id"),p=a("[for='"+o+"']"),q=p.attr("id")||o+"-label",r=p.attr("id",q),s=this.isToggleSwitch?0:parseFloat(h.attr("min")),t=this.isToggleSwitch?h.find("option").length-1:parseFloat(h.attr("max")),u=b.parseFloat(h.attr("step")||1),v=this.options.mini||h.jqmData("mini")?" ui-mini":"",w=c.createElement("a"),x=a(w),y=c.createElement("div"),z=a(y),A=this.options.highlight&&!this.isToggleSwitch?function(){var b=c.createElement("div");return b.className="ui-slider-bg "+a.mobile.activeBtnClass+" ui-btn-corner-all",a(b).prependTo(z)}():!1;if(w.setAttribute("href","#"),y.setAttribute("role","application"),y.className=[this.isToggleSwitch?"ui-slider ":"ui-slider-track ",n," ui-btn-down-",k," ui-btn-corner-all",v].join(""),w.className="ui-slider-handle",y.appendChild(w),x.buttonMarkup({corners:!0,theme:j,shadow:!0}).attr({role:"slider","aria-valuemin":s,"aria-valuemax":t,"aria-valuenow":this._value(),"aria-valuetext":this._value(),title:this._value(),"aria-labelledby":q}),a.extend(this,{slider:z,handle:x,type:l,step:u,max:t,min:s,valuebg:A,isRangeslider:m,dragging:!1,beforeStart:null,userModified:!1,mouseMoved:!1}),this.isToggleSwitch){f=c.createElement("div"),f.className="ui-slider-inneroffset";for(var B=0,C=y.childNodes.length;C>B;B++)f.appendChild(y.childNodes[B]);y.appendChild(f),x.addClass("ui-slider-handle-snapping"),e=h.find("option");for(var D=0,E=e.length;E>D;D++){var F=D?"a":"b",G=D?" "+a.mobile.activeBtnClass:" ui-btn-down-"+k,H=(c.createElement("div"),c.createElement("span"));H.className=["ui-slider-label ui-slider-label-",F,G," ui-btn-corner-all"].join(""),H.setAttribute("role","img"),H.appendChild(c.createTextNode(e[D].innerHTML)),a(H).prependTo(z)}g._labels=a(".ui-slider-label",z)}r.addClass("ui-slider"),h.addClass(this.isToggleSwitch?"ui-slider-switch":"ui-slider-input"),this._on(h,{change:"_controlChange",keyup:"_controlKeyup",blur:"_controlBlur",vmouseup:"_controlVMouseUp"}),z.bind("vmousedown",a.proxy(this._sliderVMouseDown,this)).bind("vclick",!1),this._on(c,{vmousemove:"_preventDocumentDrag"}),this._on(z.add(c),{vmouseup:"_sliderVMouseUp"}),z.insertAfter(h),this.isToggleSwitch||m||(f=this.options.mini?"<div class='ui-slider ui-mini'>":"<div class='ui-slider'>",h.add(z).wrapAll(f)),this.isToggleSwitch&&this.handle.bind({focus:function(){z.addClass(a.mobile.focusClass)},blur:function(){z.removeClass(a.mobile.focusClass)}}),this._on(this.handle,{vmousedown:"_handleVMouseDown",keydown:"_handleKeydown",keyup:"_handleKeyup"}),this.handle.bind("vclick",!1),this._handleFormReset(),this.refresh(d,d,!0)},_controlChange:function(a){return this._trigger("controlchange",a)===!1?!1:(this.mouseMoved||this.refresh(this._value(),!0),void 0)},_controlKeyup:function(){this.refresh(this._value(),!0,!0)},_controlBlur:function(){this.refresh(this._value(),!0)},_controlVMouseUp:function(){this._checkedRefresh()},_handleVMouseDown:function(){this.handle.focus()},_handleKeydown:function(b){var c=this._value();if(!this.options.disabled){switch(b.keyCode){case a.mobile.keyCode.HOME:case a.mobile.keyCode.END:case a.mobile.keyCode.PAGE_UP:case a.mobile.keyCode.PAGE_DOWN:case a.mobile.keyCode.UP:case a.mobile.keyCode.RIGHT:case a.mobile.keyCode.DOWN:case a.mobile.keyCode.LEFT:b.preventDefault(),this._keySliding||(this._keySliding=!0,this.handle.addClass("ui-state-active"))}switch(b.keyCode){case a.mobile.keyCode.HOME:this.refresh(this.min);break;case a.mobile.keyCode.END:this.refresh(this.max);break;case a.mobile.keyCode.PAGE_UP:case a.mobile.keyCode.UP:case a.mobile.keyCode.RIGHT:this.refresh(c+this.step);break;case a.mobile.keyCode.PAGE_DOWN:case a.mobile.keyCode.DOWN:case a.mobile.keyCode.LEFT:this.refresh(c-this.step)}}},_handleKeyup:function(){this._keySliding&&(this._keySliding=!1,this.handle.removeClass("ui-state-active"))},_sliderVMouseDown:function(a){return this.options.disabled||1!==a.which&&0!==a.which&&a.which!==d?!1:this._trigger("beforestart",a)===!1?!1:(this.dragging=!0,this.userModified=!1,this.mouseMoved=!1,this.isToggleSwitch&&(this.beforeStart=this.element[0].selectedIndex),this.refresh(a),this._trigger("start"),!1)},_sliderVMouseUp:function(){return this.dragging?(this.dragging=!1,this.isToggleSwitch&&(this.handle.addClass("ui-slider-handle-snapping"),this.mouseMoved?this.userModified?this.refresh(0===this.beforeStart?1:0):this.refresh(this.beforeStart):this.refresh(0===this.beforeStart?1:0)),this.mouseMoved=!1,this._trigger("stop"),!1):void 0},_preventDocumentDrag:function(a){return this._trigger("drag",a)===!1?!1:this.dragging&&!this.options.disabled?(this.mouseMoved=!0,this.isToggleSwitch&&this.handle.removeClass("ui-slider-handle-snapping"),this.refresh(a),this.userModified=this.beforeStart!==this.element[0].selectedIndex,!1):void 0},_checkedRefresh:function(){this.value!==this._value()&&this.refresh(this._value())},_value:function(){return this.isToggleSwitch?this.element[0].selectedIndex:parseFloat(this.element.val())},_reset:function(){this.refresh(d,!1,!0)},refresh:function(b,d,e){var f,g,h,i,j=this,k=a.mobile.getInheritedTheme(this.element,"c"),l=this.options.theme||k,m=this.options.trackTheme||k;j.slider[0].className=[this.isToggleSwitch?"ui-slider ui-slider-switch":"ui-slider-track"," ui-btn-down-"+m," ui-btn-corner-all",this.options.mini?" ui-mini":""].join(""),(this.options.disabled||this.element.attr("disabled"))&&this.disable(),this.value=this._value(),this.options.highlight&&!this.isToggleSwitch&&0===this.slider.find(".ui-slider-bg").length&&(this.valuebg=function(){var b=c.createElement("div");return b.className="ui-slider-bg "+a.mobile.activeBtnClass+" ui-btn-corner-all",a(b).prependTo(j.slider)}()),this.handle.buttonMarkup({corners:!0,theme:l,shadow:!0});var n,o,p=this.element,q=!this.isToggleSwitch,r=q?[]:p.find("option"),s=q?parseFloat(p.attr("min")):0,t=q?parseFloat(p.attr("max")):r.length-1,u=q&&parseFloat(p.attr("step"))>0?parseFloat(p.attr("step")):1;if("object"==typeof b){if(h=b,i=8,f=this.slider.offset().left,g=this.slider.width(),n=g/((t-s)/u),!this.dragging||h.pageX<f-i||h.pageX>f+g+i)return;o=n>1?100*((h.pageX-f)/g):Math.round(100*((h.pageX-f)/g))}else null==b&&(b=q?parseFloat(p.val()||0):p[0].selectedIndex),o=100*((parseFloat(b)-s)/(t-s));if(!isNaN(o)){var v=o/100*(t-s)+s,w=(v-s)%u,x=v-w;2*Math.abs(w)>=u&&(x+=w>0?u:-u);var y=100/((t-s)/u);if(v=parseFloat(x.toFixed(5)),"undefined"==typeof n&&(n=g/((t-s)/u)),n>1&&q&&(o=(v-s)*y*(1/u)),0>o&&(o=0),o>100&&(o=100),s>v&&(v=s),v>t&&(v=t),this.handle.css("left",o+"%"),this.handle[0].setAttribute("aria-valuenow",q?v:r.eq(v).attr("value")),this.handle[0].setAttribute("aria-valuetext",q?v:r.eq(v).getEncodedText()),this.handle[0].setAttribute("title",q?v:r.eq(v).getEncodedText()),this.valuebg&&this.valuebg.css("width",o+"%"),this._labels){var z=100*(this.handle.width()/this.slider.width()),A=o&&z+(100-z)*o/100,B=100===o?0:Math.min(z+100-A,100);this._labels.each(function(){var b=a(this).is(".ui-slider-label-a");a(this).width((b?A:B)+"%")})}if(!e){var C=!1;if(q?(C=p.val()!==v,p.val(v)):(C=p[0].selectedIndex!==v,p[0].selectedIndex=v),this._trigger("beforechange",b)===!1)return!1;!d&&C&&p.trigger("change")}}},enable:function(){return this.element.attr("disabled",!1),this.slider.removeClass("ui-disabled").attr("aria-disabled",!1),this._setOption("disabled",!1)},disable:function(){return this.element.attr("disabled",!0),this.slider.addClass("ui-disabled").attr("aria-disabled",!0),this._setOption("disabled",!0)}},a.mobile.behaviors.formReset)),a.mobile.document.bind("pagecreate create",function(b){a.mobile.slider.prototype.enhanceWithin(b.target,!0)})}(a),function(a){a.widget("mobile.rangeslider",a.mobile.widget,{options:{theme:null,trackTheme:null,disabled:!1,initSelector:":jqmData(role='rangeslider')",mini:!1,highlight:!0},_create:function(){var b,c=this.element,d=this.options.mini?"ui-rangeslider ui-mini":"ui-rangeslider",e=c.find("input").first(),f=c.find("input").last(),g=c.find("label").first(),h=a.data(e.get(0),"mobileSlider").slider,i=a.data(f.get(0),"mobileSlider").slider,j=a.data(e.get(0),"mobileSlider").handle,k=a('<div class="ui-rangeslider-sliders" />').appendTo(c);c.find("label").length>1&&(b=c.find("label").last().hide()),e.addClass("ui-rangeslider-first"),f.addClass("ui-rangeslider-last"),c.addClass(d),h.appendTo(k),i.appendTo(k),g.prependTo(c),j.prependTo(i),a.extend(this,{_inputFirst:e,_inputLast:f,_sliderFirst:h,_sliderLast:i,_targetVal:null,_sliderTarget:!1,_sliders:k,_proxy:!1}),this.refresh(),this._on(this.element.find("input.ui-slider-input"),{slidebeforestart:"_slidebeforestart",slidestop:"_slidestop",slidedrag:"_slidedrag",slidebeforechange:"_change",blur:"_change",keyup:"_change"}),this._on({mousedown:"_change"}),this._on(this.element.closest("form"),{reset:"_handleReset"}),this._on(j,{vmousedown:"_dragFirstHandle"})},_handleReset:function(){var a=this;setTimeout(function(){a._updateHighlight()},0)},_dragFirstHandle:function(b){return a.data(this._inputFirst.get(0),"mobileSlider").dragging=!0,a.data(this._inputFirst.get(0),"mobileSlider").refresh(b),!1},_slidedrag:function(b){var c=a(b.target).is(this._inputFirst),d=c?this._inputLast:this._inputFirst;return this._sliderTarget=!1,"first"===this._proxy&&c||"last"===this._proxy&&!c?(a.data(d.get(0),"mobileSlider").dragging=!0,a.data(d.get(0),"mobileSlider").refresh(b),!1):void 0},_slidestop:function(b){var c=a(b.target).is(this._inputFirst);this._proxy=!1,this.element.find("input").trigger("vmouseup"),this._sliderFirst.css("z-index",c?1:"")},_slidebeforestart:function(b){this._sliderTarget=!1,a(b.originalEvent.target).hasClass("ui-slider-track")&&(this._sliderTarget=!0,this._targetVal=a(b.target).val())},_setOption:function(a){this._superApply(a),this.refresh()},refresh:function(){var a=this.element,b=this.options;a.find("input").slider({theme:b.theme,trackTheme:b.trackTheme,disabled:b.disabled,mini:b.mini,highlight:b.highlight}).slider("refresh"),this._updateHighlight()},_change:function(b){if("keyup"===b.type)return this._updateHighlight(),!1;var c=this,d=parseFloat(this._inputFirst.val(),10),e=parseFloat(this._inputLast.val(),10),f=a(b.target).hasClass("ui-rangeslider-first"),g=f?this._inputFirst:this._inputLast,h=f?this._inputLast:this._inputFirst;if(this._inputFirst.val()>this._inputLast.val()&&"mousedown"===b.type&&!a(b.target).hasClass("ui-slider-handle"))g.blur();else if("mousedown"===b.type)return;return d>e&&!this._sliderTarget?(g.val(f?e:d).slider("refresh"),this._trigger("normalize")):d>e&&(g.val(this._targetVal).slider("refresh"),setTimeout(function(){h.val(f?d:e).slider("refresh"),a.data(h.get(0),"mobileSlider").handle.focus(),c._sliderFirst.css("z-index",f?"":1),c._trigger("normalize")},0),this._proxy=f?"first":"last"),d===e?(a.data(g.get(0),"mobileSlider").handle.css("z-index",1),a.data(h.get(0),"mobileSlider").handle.css("z-index",0)):(a.data(h.get(0),"mobileSlider").handle.css("z-index",""),a.data(g.get(0),"mobileSlider").handle.css("z-index","")),this._updateHighlight(),d>=e?!1:void 0},_updateHighlight:function(){var b=parseInt(a.data(this._inputFirst.get(0),"mobileSlider").handle.get(0).style.left,10),c=parseInt(a.data(this._inputLast.get(0),"mobileSlider").handle.get(0).style.left,10),d=c-b;this.element.find(".ui-slider-bg").css({"margin-left":b+"%",width:d+"%"})},_destroy:function(){this.element.removeClass("ui-rangeslider ui-mini").find("label").show(),this._inputFirst.after(this._sliderFirst),this._inputLast.after(this._sliderLast),this._sliders.remove(),this.element.find("input").removeClass("ui-rangeslider-first ui-rangeslider-last").slider("destroy")}}),a.widget("mobile.rangeslider",a.mobile.rangeslider,a.mobile.behaviors.formReset),a(c).bind("pagecreate create",function(b){a.mobile.rangeslider.prototype.enhanceWithin(b.target,!0)})}(a),function(a){a.widget("mobile.selectmenu",a.mobile.widget,a.extend({options:{theme:null,disabled:!1,icon:"arrow-d",iconpos:"right",inline:!1,corners:!0,shadow:!0,iconshadow:!0,overlayTheme:"a",dividerTheme:"b",hidePlaceholderMenuItems:!0,closeText:"Close",nativeMenu:!0,preventFocusZoom:/iPhone|iPad|iPod/.test(navigator.platform)&&navigator.userAgent.indexOf("AppleWebKit")>-1,initSelector:"select:not( :jqmData(role='slider') )",mini:!1},_button:function(){return a("<div/>")
-},_setDisabled:function(a){return this.element.attr("disabled",a),this.button.attr("aria-disabled",a),this._setOption("disabled",a)},_focusButton:function(){var a=this;setTimeout(function(){a.button.focus()},40)},_selectOptions:function(){return this.select.find("option")},_preExtension:function(){var b="";~this.element[0].className.indexOf("ui-btn-left")&&(b=" ui-btn-left"),~this.element[0].className.indexOf("ui-btn-right")&&(b=" ui-btn-right"),this.select=this.element.removeClass("ui-btn-left ui-btn-right").wrap("<div class='ui-select"+b+"'>"),this.selectID=this.select.attr("id"),this.label=a("label[for='"+this.selectID+"']").addClass("ui-select"),this.isMultiple=this.select[0].multiple,this.options.theme||(this.options.theme=a.mobile.getInheritedTheme(this.select,"c"))},_destroy:function(){var a=this.element.parents(".ui-select");a.length>0&&(a.is(".ui-btn-left, .ui-btn-right")&&this.element.addClass(a.is(".ui-btn-left")?"ui-btn-left":"ui-btn-right"),this.element.insertAfter(a),a.remove())},_create:function(){this._preExtension(),this._trigger("beforeCreate"),this.button=this._button();var c=this,d=this.options,e=d.inline||this.select.jqmData("inline"),f=d.mini||this.select.jqmData("mini"),g=d.icon?d.iconpos||this.select.jqmData("iconpos"):!1,h=(-1===this.select[0].selectedIndex?0:this.select[0].selectedIndex,this.button.insertBefore(this.select).buttonMarkup({theme:d.theme,icon:d.icon,iconpos:g,inline:e,corners:d.corners,shadow:d.shadow,iconshadow:d.iconshadow,mini:f}));this.setButtonText(),d.nativeMenu&&b.opera&&b.opera.version&&h.addClass("ui-select-nativeonly"),this.isMultiple&&(this.buttonCount=a("<span>").addClass("ui-li-count ui-btn-up-c ui-btn-corner-all").hide().appendTo(h.addClass("ui-li-has-count"))),(d.disabled||this.element.attr("disabled"))&&this.disable(),this.select.change(function(){c.refresh(),d.nativeMenu&&this.blur()}),this._handleFormReset(),this.build()},build:function(){var b=this;this.select.appendTo(b.button).bind("vmousedown",function(){b.button.addClass(a.mobile.activeBtnClass)}).bind("focus",function(){b.button.addClass(a.mobile.focusClass)}).bind("blur",function(){b.button.removeClass(a.mobile.focusClass)}).bind("focus vmouseover",function(){b.button.trigger("vmouseover")}).bind("vmousemove",function(){b.button.removeClass(a.mobile.activeBtnClass)}).bind("change blur vmouseout",function(){b.button.trigger("vmouseout").removeClass(a.mobile.activeBtnClass)}).bind("change blur",function(){b.button.removeClass("ui-btn-down-"+b.options.theme)}),b.button.bind("vmousedown",function(){b.options.preventFocusZoom&&a.mobile.zoom.disable(!0)}),b.label.bind("click focus",function(){b.options.preventFocusZoom&&a.mobile.zoom.disable(!0)}),b.select.bind("focus",function(){b.options.preventFocusZoom&&a.mobile.zoom.disable(!0)}),b.button.bind("mouseup",function(){b.options.preventFocusZoom&&setTimeout(function(){a.mobile.zoom.enable(!0)},0)}),b.select.bind("blur",function(){b.options.preventFocusZoom&&a.mobile.zoom.enable(!0)})},selected:function(){return this._selectOptions().filter(":selected")},selectedIndices:function(){var a=this;return this.selected().map(function(){return a._selectOptions().index(this)}).get()},setButtonText:function(){var b=this,d=this.selected(),e=this.placeholder,f=a(c.createElement("span"));this.button.find(".ui-btn-text").html(function(){return e=d.length?d.map(function(){return a(this).text()}).get().join(", "):b.placeholder,f.text(e).addClass(b.select.attr("class")).addClass(d.attr("class"))})},setButtonCount:function(){var a=this.selected();this.isMultiple&&this.buttonCount[a.length>1?"show":"hide"]().text(a.length)},_reset:function(){this.refresh()},refresh:function(){this.setButtonText(),this.setButtonCount()},open:a.noop,close:a.noop,disable:function(){this._setDisabled(!0),this.button.addClass("ui-disabled")},enable:function(){this._setDisabled(!1),this.button.removeClass("ui-disabled")}},a.mobile.behaviors.formReset)),a.mobile.document.bind("pagecreate create",function(b){a.mobile.selectmenu.prototype.enhanceWithin(b.target,!0)})}(a),function(a,d){function e(a,b,c,d){var e=d;return e=b>a?c+(a-b)/2:Math.min(Math.max(c,d-b/2),c+a-b)}function f(){var c=a.mobile.window;return{x:c.scrollLeft(),y:c.scrollTop(),cx:b.innerWidth||c.width(),cy:b.innerHeight||c.height()}}a.widget("mobile.popup",a.mobile.widget,{options:{theme:null,overlayTheme:null,shadow:!0,corners:!0,transition:"none",positionTo:"origin",tolerance:null,initSelector:":jqmData(role='popup')",closeLinkSelector:"a:jqmData(rel='back')",closeLinkEvents:"click.popup",navigateEvents:"navigate.popup",closeEvents:"navigate.popup pagebeforechange.popup",dismissible:!0,history:!a.mobile.browser.oldIE},_eatEventAndClose:function(a){return a.preventDefault(),a.stopImmediatePropagation(),this.options.dismissible&&this.close(),!1},_resizeScreen:function(){var a=this._ui.container.outerHeight(!0);this._ui.screen.removeAttr("style"),a>this._ui.screen.height()&&this._ui.screen.height(a)},_handleWindowKeyUp:function(b){return this._isOpen&&b.keyCode===a.mobile.keyCode.ESCAPE?this._eatEventAndClose(b):void 0},_expectResizeEvent:function(){var b=f();if(this._resizeData){if(b.x===this._resizeData.winCoords.x&&b.y===this._resizeData.winCoords.y&&b.cx===this._resizeData.winCoords.cx&&b.cy===this._resizeData.winCoords.cy)return!1;clearTimeout(this._resizeData.timeoutId)}return this._resizeData={timeoutId:setTimeout(a.proxy(this,"_resizeTimeout"),200),winCoords:b},!0},_resizeTimeout:function(){this._isOpen?this._expectResizeEvent()||(this._ui.container.hasClass("ui-popup-hidden")&&(this._ui.container.removeClass("ui-popup-hidden"),this.reposition({positionTo:"window"}),this._ignoreResizeEvents()),this._resizeScreen(),this._resizeData=null,this._orientationchangeInProgress=!1):(this._resizeData=null,this._orientationchangeInProgress=!1)},_ignoreResizeEvents:function(){var a=this;this._ignoreResizeTo&&clearTimeout(this._ignoreResizeTo),this._ignoreResizeTo=setTimeout(function(){a._ignoreResizeTo=0},1e3)},_handleWindowResize:function(){this._isOpen&&0===this._ignoreResizeTo&&(!this._expectResizeEvent()&&!this._orientationchangeInProgress||this._ui.container.hasClass("ui-popup-hidden")||this._ui.container.addClass("ui-popup-hidden").removeAttr("style"))},_handleWindowOrientationchange:function(){!this._orientationchangeInProgress&&this._isOpen&&0===this._ignoreResizeTo&&(this._expectResizeEvent(),this._orientationchangeInProgress=!0)},_handleDocumentFocusIn:function(b){var d,e=b.target,f=this._ui;if(this._isOpen){if(e!==f.container[0]){if(d=a(b.target),0===d.parents().filter(f.container[0]).length)return a(c.activeElement).one("focus",function(){d.blur()}),f.focusElement.focus(),b.preventDefault(),b.stopImmediatePropagation(),!1;f.focusElement[0]===f.container[0]&&(f.focusElement=d)}this._ignoreResizeEvents()}},_create:function(){var b={screen:a("<div class='ui-screen-hidden ui-popup-screen'></div>"),placeholder:a("<div style='display: none;'><!-- placeholder --></div>"),container:a("<div class='ui-popup-container ui-popup-hidden'></div>")},c=this.element.closest(".ui-page"),d=this.element.attr("id"),e=this.options;e.history=e.history&&a.mobile.ajaxEnabled&&a.mobile.hashListeningEnabled,0===c.length&&(c=a("body")),e.container=e.container||a.mobile.pageContainer||c,c.append(b.screen),b.container.insertAfter(b.screen),b.placeholder.insertAfter(this.element),d&&(b.screen.attr("id",d+"-screen"),b.container.attr("id",d+"-popup"),b.placeholder.html("<!-- placeholder for "+d+" -->")),b.container.append(this.element),b.focusElement=b.container,this.element.addClass("ui-popup"),a.extend(this,{_scrollTop:0,_page:c,_ui:b,_fallbackTransition:"",_currentTransition:!1,_prereqs:null,_isOpen:!1,_tolerance:null,_resizeData:null,_ignoreResizeTo:0,_orientationchangeInProgress:!1}),this._applyTheme(this.element,e.theme,"body"),this._applyTheme(this._ui.screen,e.overlayTheme,"overlay"),this._applyTransition(e.transition),this.element.toggleClass("ui-overlay-shadow",e.shadow).toggleClass("ui-corner-all",e.corners),this._setTolerance(e.tolerance),b.screen.bind("vclick",a.proxy(this,"_eatEventAndClose")),this._on(a.mobile.window,{orientationchange:a.proxy(this,"_handleWindowOrientationchange"),resize:a.proxy(this,"_handleWindowResize"),keyup:a.proxy(this,"_handleWindowKeyUp")}),this._on(a.mobile.document,{focusin:a.proxy(this,"_handleDocumentFocusIn")})},_applyTheme:function(a,b,c){for(var d,e=(a.attr("class")||"").split(" "),f=null,g=String(b);e.length>0;){if(f=e.pop(),d=new RegExp("^ui-"+c+"-([a-z])$").exec(f),d&&d.length>1){f=d[1];break}f=null}b!==f&&(a.removeClass("ui-"+c+"-"+f),null!==b&&"none"!==b&&a.addClass("ui-"+c+"-"+g))},_setTheme:function(a){this._applyTheme(this.element,a,"body")},_setOverlayTheme:function(a){this._applyTheme(this._ui.screen,a,"overlay"),this._isOpen&&this._ui.screen.addClass("in")},_setShadow:function(a){this.element.toggleClass("ui-overlay-shadow",a)},_setCorners:function(a){this.element.toggleClass("ui-corner-all",a)},_applyTransition:function(b){this._ui.container.removeClass(this._fallbackTransition),b&&"none"!==b&&(this._fallbackTransition=a.mobile._maybeDegradeTransition(b),"none"===this._fallbackTransition&&(this._fallbackTransition=""),this._ui.container.addClass(this._fallbackTransition))},_setTransition:function(a){this._currentTransition||this._applyTransition(a)},_setTolerance:function(b){var c={t:30,r:15,b:30,l:15};if(b!==d){var e=String(b).split(",");switch(a.each(e,function(a,b){e[a]=parseInt(b,10)}),e.length){case 1:isNaN(e[0])||(c.t=c.r=c.b=c.l=e[0]);break;case 2:isNaN(e[0])||(c.t=c.b=e[0]),isNaN(e[1])||(c.l=c.r=e[1]);break;case 4:isNaN(e[0])||(c.t=e[0]),isNaN(e[1])||(c.r=e[1]),isNaN(e[2])||(c.b=e[2]),isNaN(e[3])||(c.l=e[3])}}this._tolerance=c},_setOption:function(a,b){var c="_set"+a.charAt(0).toUpperCase()+a.slice(1);this[c]!==d&&this[c](b),this._super(a,b)},_placementCoords:function(a){var b,d,g=f(),h={x:this._tolerance.l,y:g.y+this._tolerance.t,cx:g.cx-this._tolerance.l-this._tolerance.r,cy:g.cy-this._tolerance.t-this._tolerance.b};this._ui.container.css("max-width",h.cx),b={cx:this._ui.container.outerWidth(!0),cy:this._ui.container.outerHeight(!0)},d={x:e(h.cx,b.cx,h.x,a.x),y:e(h.cy,b.cy,h.y,a.y)},d.y=Math.max(0,d.y);var i=c.documentElement,j=c.body,k=Math.max(i.clientHeight,j.scrollHeight,j.offsetHeight,i.scrollHeight,i.offsetHeight);return d.y-=Math.min(d.y,Math.max(0,d.y+b.cy-k)),{left:d.x,top:d.y}},_createPrereqs:function(b,c,d){var e,f=this;e={screen:a.Deferred(),container:a.Deferred()},e.screen.then(function(){e===f._prereqs&&b()}),e.container.then(function(){e===f._prereqs&&c()}),a.when(e.screen,e.container).done(function(){e===f._prereqs&&(f._prereqs=null,d())}),f._prereqs=e},_animate:function(b){return this._ui.screen.removeClass(b.classToRemove).addClass(b.screenClassToAdd),b.prereqs.screen.resolve(),b.transition&&"none"!==b.transition&&(b.applyTransition&&this._applyTransition(b.transition),this._fallbackTransition)?(this._ui.container.animationComplete(a.proxy(b.prereqs.container,"resolve")).addClass(b.containerClassToAdd).removeClass(b.classToRemove),void 0):(this._ui.container.removeClass(b.classToRemove),b.prereqs.container.resolve(),void 0)},_desiredCoords:function(b){var c,d=null,e=f(),g=b.x,h=b.y,i=b.positionTo;if(i&&"origin"!==i)if("window"===i)g=e.cx/2+e.x,h=e.cy/2+e.y;else{try{d=a(i)}catch(j){d=null}d&&(d.filter(":visible"),0===d.length&&(d=null))}return d&&(c=d.offset(),g=c.left+d.outerWidth()/2,h=c.top+d.outerHeight()/2),("number"!==a.type(g)||isNaN(g))&&(g=e.cx/2+e.x),("number"!==a.type(h)||isNaN(h))&&(h=e.cy/2+e.y),{x:g,y:h}},_reposition:function(a){a={x:a.x,y:a.y,positionTo:a.positionTo},this._trigger("beforeposition",d,a),this._ui.container.offset(this._placementCoords(this._desiredCoords(a)))},reposition:function(a){this._isOpen&&this._reposition(a)},_openPrereqsComplete:function(){this._ui.container.addClass("ui-popup-active"),this._isOpen=!0,this._resizeScreen(),this._ui.container.attr("tabindex","0").focus(),this._ignoreResizeEvents(),this._trigger("afteropen")},_open:function(b){var c=a.extend({},this.options,b),d=function(){var a=navigator.userAgent,b=a.match(/AppleWebKit\/([0-9\.]+)/),c=!!b&&b[1],d=a.match(/Android (\d+(?:\.\d+))/),e=!!d&&d[1],f=a.indexOf("Chrome")>-1;return null!==d&&"4.0"===e&&c&&c>534.13&&!f?!0:!1}();this._createPrereqs(a.noop,a.noop,a.proxy(this,"_openPrereqsComplete")),this._currentTransition=c.transition,this._applyTransition(c.transition),this.options.theme||this._setTheme(this._page.jqmData("theme")||a.mobile.getInheritedTheme(this._page,"c")),this._ui.screen.removeClass("ui-screen-hidden"),this._ui.container.removeClass("ui-popup-hidden"),this._reposition(c),this.options.overlayTheme&&d&&this.element.closest(".ui-page").addClass("ui-popup-open"),this._animate({additionalCondition:!0,transition:c.transition,classToRemove:"",screenClassToAdd:"in",containerClassToAdd:"in",applyTransition:!1,prereqs:this._prereqs})},_closePrereqScreen:function(){this._ui.screen.removeClass("out").addClass("ui-screen-hidden")},_closePrereqContainer:function(){this._ui.container.removeClass("reverse out").addClass("ui-popup-hidden").removeAttr("style")},_closePrereqsDone:function(){var b=this._ui.container;b.removeAttr("tabindex"),a.mobile.popup.active=d,a(":focus",b[0]).add(b[0]).blur(),this._trigger("afterclose")},_close:function(b){this._ui.container.removeClass("ui-popup-active"),this._page.removeClass("ui-popup-open"),this._isOpen=!1,this._createPrereqs(a.proxy(this,"_closePrereqScreen"),a.proxy(this,"_closePrereqContainer"),a.proxy(this,"_closePrereqsDone")),this._animate({additionalCondition:this._ui.screen.hasClass("in"),transition:b?"none":this._currentTransition,classToRemove:"in",screenClassToAdd:"out",containerClassToAdd:"reverse out",applyTransition:!0,prereqs:this._prereqs})},_unenhance:function(){this._setTheme("none"),this.element.detach().insertAfter(this._ui.placeholder).removeClass("ui-popup ui-overlay-shadow ui-corner-all"),this._ui.screen.remove(),this._ui.container.remove(),this._ui.placeholder.remove()},_destroy:function(){a.mobile.popup.active===this?(this.element.one("popupafterclose",a.proxy(this,"_unenhance")),this.close()):this._unenhance()},_closePopup:function(c,d){var e,f,g=this.options,h=!1;b.scrollTo(0,this._scrollTop),c&&"pagebeforechange"===c.type&&d&&(e="string"==typeof d.toPage?d.toPage:d.toPage.jqmData("url"),e=a.mobile.path.parseUrl(e),f=e.pathname+e.search+e.hash,this._myUrl!==a.mobile.path.makeUrlAbsolute(f)?h=!0:c.preventDefault()),g.container.unbind(g.closeEvents),this.element.undelegate(g.closeLinkSelector,g.closeLinkEvents),this._close(h)},_bindContainerClose:function(){this.options.container.one(this.options.closeEvents,a.proxy(this,"_closePopup"))},open:function(c){var d,e,f,g,h,i,j=this,k=this.options;if(!a.mobile.popup.active){if(a.mobile.popup.active=this,this._scrollTop=a.mobile.window.scrollTop(),!k.history)return j._open(c),j._bindContainerClose(),j.element.delegate(k.closeLinkSelector,k.closeLinkEvents,function(a){j.close(),a.preventDefault()}),void 0;if(i=a.mobile.urlHistory,e=a.mobile.dialogHashKey,f=a.mobile.activePage,g=f.is(".ui-dialog"),this._myUrl=d=i.getActive().url,h=d.indexOf(e)>-1&&!g&&i.activeIndex>0)return j._open(c),j._bindContainerClose(),void 0;-1!==d.indexOf(e)||g?d=a.mobile.path.parseLocation().hash+e:d+=d.indexOf("#")>-1?e:"#"+e,0===i.activeIndex&&d===i.initialDst&&(d+=e),a(b).one("beforenavigate",function(a){a.preventDefault(),j._open(c),j._bindContainerClose()}),this.urlAltered=!0,a.mobile.navigate(d,{role:"dialog"})}},close:function(){a.mobile.popup.active===this&&(this._scrollTop=a.mobile.window.scrollTop(),this.options.history&&this.urlAltered?(a.mobile.back(),this.urlAltered=!1):this._closePopup())}}),a.mobile.popup.handleLink=function(b){var c,d=b.closest(":jqmData(role='page')"),e=0===d.length?a("body"):d,f=a(a.mobile.path.parseUrl(b.attr("href")).hash,e[0]);f.data("mobile-popup")&&(c=b.offset(),f.popup("open",{x:c.left+b.outerWidth()/2,y:c.top+b.outerHeight()/2,transition:b.jqmData("transition"),positionTo:b.jqmData("position-to")})),setTimeout(function(){var c=b.parent().parent();c.hasClass("ui-li")&&(b=c.parent()),b.removeClass(a.mobile.activeBtnClass)},300)},a.mobile.document.bind("pagebeforechange",function(b,c){"popup"===c.options.role&&(a.mobile.popup.handleLink(c.options.link),b.preventDefault())}),a.mobile.document.bind("pagecreate create",function(b){a.mobile.popup.prototype.enhanceWithin(b.target,!0)})}(a),function(a,b){var d=function(d){var e,f,g,h=(d.select,d._destroy),i=d.selectID,j=i?i:(a.mobile.ns||"")+"uuid-"+d.uuid,k=j+"-listbox",l=j+"-dialog",m=d.label,n=d.select.closest(".ui-page"),o=d._selectOptions(),p=d.isMultiple=d.select[0].multiple,q=i+"-button",r=i+"-menu",s=a("<div data-"+a.mobile.ns+"role='dialog' id='"+l+"' data-"+a.mobile.ns+"theme='"+d.options.theme+"' data-"+a.mobile.ns+"overlay-theme='"+d.options.overlayTheme+"'>"+"<div data-"+a.mobile.ns+"role='header'>"+"<div class='ui-title'>"+m.getEncodedText()+"</div>"+"</div>"+"<div data-"+a.mobile.ns+"role='content'></div>"+"</div>"),t=a("<div id='"+k+"' class='ui-selectmenu'>").insertAfter(d.select).popup({theme:d.options.overlayTheme}),u=a("<ul>",{"class":"ui-selectmenu-list",id:r,role:"listbox","aria-labelledby":q}).attr("data-"+a.mobile.ns+"theme",d.options.theme).attr("data-"+a.mobile.ns+"divider-theme",d.options.dividerTheme).appendTo(t),v=a("<div>",{"class":"ui-header ui-bar-"+d.options.theme}).prependTo(t),w=a("<h1>",{"class":"ui-title"}).appendTo(v);d.isMultiple&&(g=a("<a>",{text:d.options.closeText,href:"#","class":"ui-btn-left"}).attr("data-"+a.mobile.ns+"iconpos","notext").attr("data-"+a.mobile.ns+"icon","delete").appendTo(v).buttonMarkup()),a.extend(d,{select:d.select,selectID:i,buttonId:q,menuId:r,popupID:k,dialogID:l,thisPage:n,menuPage:s,label:m,selectOptions:o,isMultiple:p,theme:d.options.theme,listbox:t,list:u,header:v,headerTitle:w,headerClose:g,menuPageContent:e,menuPageClose:f,placeholder:"",build:function(){var c=this,e=function(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g,"\\$1")};c.refresh(),c._origTabIndex===b&&(c._origTabIndex=null===c.select[0].getAttribute("tabindex")?!1:c.select.attr("tabindex")),c.select.attr("tabindex","-1").focus(function(){a(this).blur(),c.button.focus()}),c.button.bind("vclick keydown",function(b){c.options.disabled||c.isOpen||("vclick"===b.type||b.keyCode&&(b.keyCode===a.mobile.keyCode.ENTER||b.keyCode===a.mobile.keyCode.SPACE))&&(c._decideFormat(),"overlay"===c.menuType?c.button.attr("href","#"+e(c.popupID)).attr("data-"+(a.mobile.ns||"")+"rel","popup"):c.button.attr("href","#"+e(c.dialogID)).attr("data-"+(a.mobile.ns||"")+"rel","dialog"),c.isOpen=!0)}),c.list.attr("role","listbox").bind("focusin",function(b){a(b.target).attr("tabindex","0").trigger("vmouseover")}).bind("focusout",function(b){a(b.target).attr("tabindex","-1").trigger("vmouseout")}).delegate("li:not(.ui-disabled, .ui-li-divider)","click",function(b){var e=c.select[0].selectedIndex,f=c.list.find("li:not(.ui-li-divider)").index(this),g=c._selectOptions().eq(f)[0];g.selected=c.isMultiple?!g.selected:!0,c.isMultiple&&a(this).find(".ui-icon").toggleClass("ui-icon-checkbox-on",g.selected).toggleClass("ui-icon-checkbox-off",!g.selected),(c.isMultiple||e!==f)&&c.select.trigger("change"),c.isMultiple?c.list.find("li:not(.ui-li-divider)").eq(f).addClass("ui-btn-down-"+d.options.theme).find("a").first().focus():c.close(),b.preventDefault()}).keydown(function(b){var c,e,f=a(b.target),g=f.closest("li");switch(b.keyCode){case 38:return c=g.prev().not(".ui-selectmenu-placeholder"),c.is(".ui-li-divider")&&(c=c.prev()),c.length&&(f.blur().attr("tabindex","-1"),c.addClass("ui-btn-down-"+d.options.theme).find("a").first().focus()),!1;case 40:return e=g.next(),e.is(".ui-li-divider")&&(e=e.next()),e.length&&(f.blur().attr("tabindex","-1"),e.addClass("ui-btn-down-"+d.options.theme).find("a").first().focus()),!1;case 13:case 32:return f.trigger("click"),!1}}),c.menuPage.bind("pagehide",function(){a.mobile._bindPageRemove.call(c.thisPage)}),c.listbox.bind("popupafterclose",function(){c.close()}),c.isMultiple&&c.headerClose.click(function(){return"overlay"===c.menuType?(c.close(),!1):void 0}),c.thisPage.addDependents(this.menuPage)},_isRebuildRequired:function(){var a=this.list.find("li"),b=this._selectOptions();return b.text()!==a.text()},selected:function(){return this._selectOptions().filter(":selected:not( :jqmData(placeholder='true') )")},refresh:function(b){var c,d=this;this.element,this.isMultiple,(b||this._isRebuildRequired())&&d._buildList(),c=this.selectedIndices(),d.setButtonText(),d.setButtonCount(),d.list.find("li:not(.ui-li-divider)").removeClass(a.mobile.activeBtnClass).attr("aria-selected",!1).each(function(b){if(a.inArray(b,c)>-1){var e=a(this);e.attr("aria-selected",!0),d.isMultiple?e.find(".ui-icon").removeClass("ui-icon-checkbox-off").addClass("ui-icon-checkbox-on"):e.is(".ui-selectmenu-placeholder")?e.next().addClass(a.mobile.activeBtnClass):e.addClass(a.mobile.activeBtnClass)}})},close:function(){if(!this.options.disabled&&this.isOpen){var a=this;"page"===a.menuType?(a.menuPage.dialog("close"),a.list.appendTo(a.listbox)):a.listbox.popup("close"),a._focusButton(),a.isOpen=!1}},open:function(){this.button.click()},_decideFormat:function(){function b(){var b=c.list.find("."+a.mobile.activeBtnClass+" a");0===b.length&&(b=c.list.find("li.ui-btn:not( :jqmData(placeholder='true') ) a")),b.first().focus().closest("li").addClass("ui-btn-down-"+d.options.theme)}var c=this,e=a.mobile.window,f=c.list.parent(),g=f.outerHeight(),h=(f.outerWidth(),a("."+a.mobile.activePageClass),e.scrollTop()),i=c.button.offset().top,j=e.height();e.width(),g>j-80||!a.support.scrollTop?(c.menuPage.appendTo(a.mobile.pageContainer).page(),c.menuPageContent=s.find(".ui-content"),c.menuPageClose=s.find(".ui-header a"),c.thisPage.unbind("pagehide.remove"),0===h&&i>j&&c.thisPage.one("pagehide",function(){a(this).jqmData("lastScroll",i)}),c.menuPage.one("pageshow",function(){b()}).one("pagehide",function(){c.close()}),c.menuType="page",c.menuPageContent.append(c.list),c.menuPage.find("div .ui-title").text(c.label.text())):(c.menuType="overlay",c.listbox.one("popupafteropen",b))},_buildList:function(){var b=this,d=this.options,e=this.placeholder,f=!0,g=b.isMultiple?"checkbox-off":"false";b.list.empty().filter(".ui-listview").listview("destroy");for(var h,i=b.select.find("option"),j=i.length,k=this.select[0],l="data-"+a.mobile.ns,m=l+"option-index",n=l+"icon",o=l+"role",p=l+"placeholder",q=c.createDocumentFragment(),r=!1,s=0;j>s;s++,r=!1){var t=i[s],u=a(t),v=t.parentNode,w=u.text(),x=c.createElement("a"),y=[];if(x.setAttribute("href","#"),x.appendChild(c.createTextNode(w)),v!==k&&"optgroup"===v.nodeName.toLowerCase()){var z=v.getAttribute("label");if(z!==h){var A=c.createElement("li");A.setAttribute(o,"list-divider"),A.setAttribute("role","option"),A.setAttribute("tabindex","-1"),A.appendChild(c.createTextNode(z)),q.appendChild(A),h=z}}!f||t.getAttribute("value")&&0!==w.length&&!u.jqmData("placeholder")||(f=!1,r=!0,null===t.getAttribute(p)&&(this._removePlaceholderAttr=!0),t.setAttribute(p,!0),d.hidePlaceholderMenuItems&&y.push("ui-selectmenu-placeholder"),e!==w&&(e=b.placeholder=w));var B=c.createElement("li");t.disabled&&(y.push("ui-disabled"),B.setAttribute("aria-disabled",!0)),B.setAttribute(m,s),B.setAttribute(n,g),r&&B.setAttribute(p,!0),B.className=y.join(" "),B.setAttribute("role","option"),x.setAttribute("tabindex","-1"),B.appendChild(x),q.appendChild(B)}b.list[0].appendChild(q),this.isMultiple||e.length?this.headerTitle.text(this.placeholder):this.header.hide(),b.list.listview()},_button:function(){return a("<a>",{href:"#",role:"button",id:this.buttonId,"aria-haspopup":"true","aria-owns":this.menuId})},_destroy:function(){this.close(),this._origTabIndex!==b&&(this._origTabIndex!==!1?this.select.attr("tabindex",this._origTabIndex):this.select.removeAttr("tabindex")),this._removePlaceholderAttr&&this._selectOptions().removeAttr("data-"+a.mobile.ns+"placeholder"),this.listbox.remove(),this.menuPage.remove(),h.apply(this,arguments)}})};a.mobile.document.bind("selectmenubeforecreate",function(b){var c=a(b.target).data("mobile-selectmenu");c.options.nativeMenu||0!==c.element.parents(":jqmData(role='popup')").length||d(c)})}(a),function(a,b){a.widget("mobile.controlgroup",a.mobile.widget,a.extend({options:{shadow:!1,corners:!0,excludeInvisible:!0,type:"vertical",mini:!1,initSelector:":jqmData(role='controlgroup')"},_create:function(){var c=this.element,d={inner:a("<div class='ui-controlgroup-controls'></div>"),legend:a("<div role='heading' class='ui-controlgroup-label'></div>")},e=c.children("legend"),f=this;c.wrapInner(d.inner),e.length&&d.legend.append(e).insertBefore(c.children(0)),c.addClass("ui-corner-all ui-controlgroup"),a.extend(this,{_initialRefresh:!0}),a.each(this.options,function(a,c){f.options[a]=b,f._setOption(a,c,!0)})},_init:function(){this.refresh()},_setOption:function(c,d){var e="_set"+c.charAt(0).toUpperCase()+c.slice(1);this[e]!==b&&this[e](d),this._super(c,d),this.element.attr("data-"+(a.mobile.ns||"")+c.replace(/([A-Z])/,"-$1").toLowerCase(),d)},_setType:function(a){this.element.removeClass("ui-controlgroup-horizontal ui-controlgroup-vertical").addClass("ui-controlgroup-"+a),this.refresh()},_setCorners:function(a){this.element.toggleClass("ui-corner-all",a)},_setShadow:function(a){this.element.toggleClass("ui-shadow",a)},_setMini:function(a){this.element.toggleClass("ui-mini",a)},container:function(){return this.element.children(".ui-controlgroup-controls")},refresh:function(){var b=this.element.find(".ui-btn").not(".ui-slider-handle"),c=this._initialRefresh;a.mobile.checkboxradio&&this.element.find(":mobile-checkboxradio").checkboxradio("refresh"),this._addFirstLastClasses(b,this.options.excludeInvisible?this._getVisibles(b,c):b,c),this._initialRefresh=!1}},a.mobile.behaviors.addFirstLastClasses)),a(function(){a.mobile.document.bind("pagecreate create",function(b){a.mobile.controlgroup.prototype.enhanceWithin(b.target,!0)})})}(a),function(a){a(c).bind("pagecreate create",function(b){a(b.target).find("a").jqmEnhanceable().filter(":jqmData(rel='popup')[href][href!='']").each(function(){var b=this,d=a(this).attr("href"),e=d.substring(1);b.setAttribute("aria-haspopup",!0),b.setAttribute("aria-owns",e),b.setAttribute("aria-expanded",!1),a(c).on("popupafteropen",d,function(){b.setAttribute("aria-expanded",!0)}).on("popupafterclose",d,function(){b.setAttribute("aria-expanded",!1)})}).end().not(".ui-btn, .ui-link-inherit, :jqmData(role='none'), :jqmData(role='nojs')").addClass("ui-link")})}(a),function(a,b){a.widget("mobile.fixedtoolbar",a.mobile.widget,{options:{visibleOnPageShow:!0,disablePageZoom:!0,transition:"slide",fullscreen:!1,tapToggle:!0,tapToggleBlacklist:"a, button, input, select, textarea, .ui-header-fixed, .ui-footer-fixed, .ui-popup, .ui-panel, .ui-panel-dismiss-open",hideDuringFocus:"input, textarea, select",updatePagePadding:!0,trackPersistentToolbars:!0,supportBlacklist:function(){return!a.support.fixedPosition},initSelector:":jqmData(position='fixed')"},_create:function(){var b=this,c=b.options,d=b.element,e=d.is(":jqmData(role='header')")?"header":"footer",f=d.closest(".ui-page");return c.supportBlacklist()?(b.destroy(),void 0):(d.addClass("ui-"+e+"-fixed"),c.fullscreen?(d.addClass("ui-"+e+"-fullscreen"),f.addClass("ui-page-"+e+"-fullscreen")):f.addClass("ui-page-"+e+"-fixed"),a.extend(this,{_thisPage:null}),b._addTransitionClass(),b._bindPageEvents(),b._bindToggleHandlers(),void 0)},_addTransitionClass:function(){var a=this.options.transition;a&&"none"!==a&&("slide"===a&&(a=this.element.is(".ui-header")?"slidedown":"slideup"),this.element.addClass(a))},_bindPageEvents:function(){this._thisPage=this.element.closest(".ui-page"),this._on(this._thisPage,{pagebeforeshow:"_handlePageBeforeShow",webkitAnimationStart:"_handleAnimationStart",animationstart:"_handleAnimationStart",updatelayout:"_handleAnimationStart",pageshow:"_handlePageShow",pagebeforehide:"_handlePageBeforeHide"})},_handlePageBeforeShow:function(){var b=this.options;b.disablePageZoom&&a.mobile.zoom.disable(!0),b.visibleOnPageShow||this.hide(!0)},_handleAnimationStart:function(){this.options.updatePagePadding&&this.updatePagePadding(this._thisPage)},_handlePageShow:function(){this.updatePagePadding(this._thisPage),this.options.updatePagePadding&&this._on(a.mobile.window,{throttledresize:"updatePagePadding"})},_handlePageBeforeHide:function(b,c){var d=this.options;if(d.disablePageZoom&&a.mobile.zoom.enable(!0),d.updatePagePadding&&this._off(a.mobile.window,"throttledresize"),d.trackPersistentToolbars){var e=a(".ui-footer-fixed:jqmData(id)",this._thisPage),f=a(".ui-header-fixed:jqmData(id)",this._thisPage),g=e.length&&c.nextPage&&a(".ui-footer-fixed:jqmData(id='"+e.jqmData("id")+"')",c.nextPage)||a(),h=f.length&&c.nextPage&&a(".ui-header-fixed:jqmData(id='"+f.jqmData("id")+"')",c.nextPage)||a();(g.length||h.length)&&(g.add(h).appendTo(a.mobile.pageContainer),c.nextPage.one("pageshow",function(){h.prependTo(this),g.appendTo(this)}))}},_visible:!0,updatePagePadding:function(c){var d=this.element,e=d.is(".ui-header"),f=parseFloat(d.css(e?"top":"bottom"));this.options.fullscreen||(c=c&&c.type===b&&c||this._thisPage||d.closest(".ui-page"),a(c).css("padding-"+(e?"top":"bottom"),d.outerHeight()+f))},_useTransition:function(b){var c=a.mobile.window,d=this.element,e=c.scrollTop(),f=d.height(),g=d.closest(".ui-page").height(),h=a.mobile.getScreenHeight(),i=d.is(":jqmData(role='header')")?"header":"footer";return!b&&(this.options.transition&&"none"!==this.options.transition&&("header"===i&&!this.options.fullscreen&&e>f||"footer"===i&&!this.options.fullscreen&&g-f>e+h)||this.options.fullscreen)},show:function(a){var b="ui-fixed-hidden",c=this.element;this._useTransition(a)?c.removeClass("out "+b).addClass("in").animationComplete(function(){c.removeClass("in")}):c.removeClass(b),this._visible=!0},hide:function(a){var b="ui-fixed-hidden",c=this.element,d="out"+("slide"===this.options.transition?" reverse":"");this._useTransition(a)?c.addClass(d).removeClass("in").animationComplete(function(){c.addClass(b).removeClass(d)}):c.addClass(b).removeClass(d),this._visible=!1},toggle:function(){this[this._visible?"hide":"show"]()},_bindToggleHandlers:function(){var b,c,d=this,e=d.options,f=d.element,g=!0;f.closest(".ui-page").bind("vclick",function(b){e.tapToggle&&!a(b.target).closest(e.tapToggleBlacklist).length&&d.toggle()}).bind("focusin focusout",function(f){screen.width<1025&&a(f.target).is(e.hideDuringFocus)&&!a(f.target).closest(".ui-header-fixed, .ui-footer-fixed").length&&("focusout"!==f.type||g?"focusin"===f.type&&g&&(clearTimeout(b),g=!1,c=setTimeout(function(){d.hide()},0)):(g=!0,clearTimeout(c),b=setTimeout(function(){d.show()},0)))})},_destroy:function(){var a=this.element,b=a.is(".ui-header");a.closest(".ui-page").css("padding-"+(b?"top":"bottom"),""),a.removeClass("ui-header-fixed ui-footer-fixed ui-header-fullscreen ui-footer-fullscreen in out fade slidedown slideup ui-fixed-hidden"),a.closest(".ui-page").removeClass("ui-page-header-fixed ui-page-footer-fixed ui-page-header-fullscreen ui-page-footer-fullscreen")}}),a.mobile.document.bind("pagecreate create",function(b){a(b.target).jqmData("fullscreen")&&a(a.mobile.fixedtoolbar.prototype.options.initSelector,b.target).not(":jqmData(fullscreen)").jqmData("fullscreen",!0),a.mobile.fixedtoolbar.prototype.enhanceWithin(b.target)})}(a),function(a){a.widget("mobile.fixedtoolbar",a.mobile.fixedtoolbar,{_create:function(){this._super(),this._workarounds()},_workarounds:function(){var a=navigator.userAgent,b=navigator.platform,c=a.match(/AppleWebKit\/([0-9]+)/),d=!!c&&c[1],e=null,f=this;if(b.indexOf("iPhone")>-1||b.indexOf("iPad")>-1||b.indexOf("iPod")>-1)e="ios";else{if(!(a.indexOf("Android")>-1))return;e="android"}if("ios"===e)f._bindScrollWorkaround();else{if(!("android"===e&&d&&534>d))return;f._bindScrollWorkaround(),f._bindListThumbWorkaround()}},_viewportOffset:function(){var b=this.element,c=b.is(".ui-header"),d=Math.abs(b.offset().top-a.mobile.window.scrollTop());
-return c||(d=Math.round(d-a.mobile.window.height()+b.outerHeight())-60),d},_bindScrollWorkaround:function(){var b=this;this._on(a.mobile.window,{scrollstop:function(){var a=b._viewportOffset();a>2&&b._visible&&b._triggerRedraw()}})},_bindListThumbWorkaround:function(){this.element.closest(".ui-page").addClass("ui-android-2x-fixed")},_triggerRedraw:function(){var b=parseFloat(a(".ui-page-active").css("padding-bottom"));a(".ui-page-active").css("padding-bottom",b+1+"px"),setTimeout(function(){a(".ui-page-active").css("padding-bottom",b+"px")},0)},destroy:function(){this._super(),this.element.closest(".ui-page-active").removeClass("ui-android-2x-fix")}})}(a),function(a,d){a.widget("mobile.panel",a.mobile.widget,{options:{classes:{panel:"ui-panel",panelOpen:"ui-panel-open",panelClosed:"ui-panel-closed",panelFixed:"ui-panel-fixed",panelInner:"ui-panel-inner",modal:"ui-panel-dismiss",modalOpen:"ui-panel-dismiss-open",pagePanel:"ui-page-panel",pagePanelOpen:"ui-page-panel-open",contentWrap:"ui-panel-content-wrap",contentWrapOpen:"ui-panel-content-wrap-open",contentWrapClosed:"ui-panel-content-wrap-closed",contentFixedToolbar:"ui-panel-content-fixed-toolbar",contentFixedToolbarOpen:"ui-panel-content-fixed-toolbar-open",contentFixedToolbarClosed:"ui-panel-content-fixed-toolbar-closed",animate:"ui-panel-animate"},animate:!0,theme:"c",position:"left",dismissible:!0,display:"reveal",initSelector:":jqmData(role='panel')",swipeClose:!0,positionFixed:!1},_panelID:null,_closeLink:null,_page:null,_modal:null,_panelInner:null,_wrapper:null,_fixedToolbar:null,_create:function(){var b=this,c=b.element,d=c.closest(":jqmData(role='page')"),e=function(){var b=a.data(d[0],"mobilePage").options.theme,c="ui-body-"+b;return c},f=function(){var a=c.find("."+b.options.classes.panelInner);return 0===a.length&&(a=c.children().wrapAll('<div class="'+b.options.classes.panelInner+'" />').parent()),a},g=function(){var c=d.find("."+b.options.classes.contentWrap);return 0===c.length&&(c=d.children(".ui-header:not(:jqmData(position='fixed')), .ui-content:not(:jqmData(role='popup')), .ui-footer:not(:jqmData(position='fixed'))").wrapAll('<div class="'+b.options.classes.contentWrap+" "+e()+'" />').parent(),a.support.cssTransform3d&&b.options.animate&&c.addClass(b.options.classes.animate)),c},h=function(){var c=d.find("."+b.options.classes.contentFixedToolbar);return 0===c.length&&(c=d.find(".ui-header:jqmData(position='fixed'), .ui-footer:jqmData(position='fixed')").addClass(b.options.classes.contentFixedToolbar),a.support.cssTransform3d&&b.options.animate&&c.addClass(b.options.classes.animate)),c};a.extend(this,{_panelID:c.attr("id"),_closeLink:c.find(":jqmData(rel='close')"),_page:c.closest(":jqmData(role='page')"),_pageTheme:e(),_panelInner:f(),_wrapper:g(),_fixedToolbar:h()}),b._addPanelClasses(),b._wrapper.addClass(this.options.classes.contentWrapClosed),b._fixedToolbar.addClass(this.options.classes.contentFixedToolbarClosed),b._page.addClass(b.options.classes.pagePanel),a.support.cssTransform3d&&b.options.animate&&this.element.addClass(b.options.classes.animate),b._bindUpdateLayout(),b._bindCloseEvents(),b._bindLinkListeners(),b._bindPageEvents(),b.options.dismissible&&b._createModal(),b._bindSwipeEvents()},_createModal:function(){var b=this;b._modal=a("<div class='"+b.options.classes.modal+"' data-panelid='"+b._panelID+"'></div>").on("mousedown",function(){b.close()}).appendTo(this._page)},_getPosDisplayClasses:function(a){return a+"-position-"+this.options.position+" "+a+"-display-"+this.options.display},_getPanelClasses:function(){var a=this.options.classes.panel+" "+this._getPosDisplayClasses(this.options.classes.panel)+" "+this.options.classes.panelClosed;return this.options.theme&&(a+=" ui-body-"+this.options.theme),this.options.positionFixed&&(a+=" "+this.options.classes.panelFixed),a},_addPanelClasses:function(){this.element.addClass(this._getPanelClasses())},_bindCloseEvents:function(){var a=this;a._closeLink.on("click.panel",function(b){return b.preventDefault(),a.close(),!1}),a.element.on("click.panel","a:jqmData(ajax='false')",function(){a.close()})},_positionPanel:function(){var b=this,c=b._panelInner.outerHeight(),d=c>a.mobile.getScreenHeight();d||!b.options.positionFixed?(d&&(b._unfixPanel(),a.mobile.resetActivePageHeight(c)),b._scrollIntoView(c)):b._fixPanel()},_scrollIntoView:function(c){c<a(b).scrollTop()&&b.scrollTo(0,0)},_bindFixListener:function(){this._on(a(b),{throttledresize:"_positionPanel"})},_unbindFixListener:function(){this._off(a(b),"throttledresize")},_unfixPanel:function(){this.options.positionFixed&&a.support.fixedPosition&&this.element.removeClass(this.options.classes.panelFixed)},_fixPanel:function(){this.options.positionFixed&&a.support.fixedPosition&&this.element.addClass(this.options.classes.panelFixed)},_bindUpdateLayout:function(){var a=this;a.element.on("updatelayout",function(){a._open&&a._positionPanel()})},_bindLinkListeners:function(){var b=this;b._page.on("click.panel","a",function(c){if(this.href.split("#")[1]===b._panelID&&b._panelID!==d){c.preventDefault();var e,f=a(this);return f.hasClass("ui-link")||(e=f.parent().parent(),e.hasClass("ui-li")&&(f=e.parent()),f.addClass(a.mobile.activeBtnClass),b.element.one("panelopen panelclose",function(){f.removeClass(a.mobile.activeBtnClass)})),b.toggle(),!1}})},_bindSwipeEvents:function(){var a=this,b=a._modal?a.element.add(a._modal):a.element;a.options.swipeClose&&("left"===a.options.position?b.on("swipeleft.panel",function(){a.close()}):b.on("swiperight.panel",function(){a.close()}))},_bindPageEvents:function(){var a=this;a._page.on("panelbeforeopen",function(b){a._open&&b.target!==a.element[0]&&a.close()}).on("pagehide",function(){a._open&&a.close(!0)}).on("keyup.panel",function(b){27===b.keyCode&&a._open&&a.close()})},_open:!1,_contentWrapOpenClasses:null,_fixedToolbarOpenClasses:null,_modalOpenClasses:null,open:function(b){if(!this._open){var c=this,d=c.options,e=function(){c._page.off("panelclose"),c._page.jqmData("panel","open"),!b&&a.support.cssTransform3d&&d.animate?c.element.add(c._wrapper).on(c._transitionEndEvents,f):setTimeout(f,0),c.options.theme&&"overlay"!==c.options.display&&c._page.removeClass(c._pageTheme).addClass("ui-body-"+c.options.theme),c.element.removeClass(d.classes.panelClosed).addClass(d.classes.panelOpen),c._positionPanel(),c.options.theme&&"overlay"!==c.options.display&&c._wrapper.css("min-height",c._page.css("min-height")),c._contentWrapOpenClasses=c._getPosDisplayClasses(d.classes.contentWrap),c._wrapper.removeClass(d.classes.contentWrapClosed).addClass(c._contentWrapOpenClasses+" "+d.classes.contentWrapOpen),c._fixedToolbarOpenClasses=c._getPosDisplayClasses(d.classes.contentFixedToolbar),c._fixedToolbar.removeClass(d.classes.contentFixedToolbarClosed).addClass(c._fixedToolbarOpenClasses+" "+d.classes.contentFixedToolbarOpen),c._modalOpenClasses=c._getPosDisplayClasses(d.classes.modal)+" "+d.classes.modalOpen,c._modal&&c._modal.addClass(c._modalOpenClasses)},f=function(){c.element.add(c._wrapper).off(c._transitionEndEvents,f),c._page.addClass(d.classes.pagePanelOpen),c._bindFixListener(),c._trigger("open")};this.element.closest(".ui-page-active").length<0&&(b=!0),c._trigger("beforeopen"),"open"===c._page.jqmData("panel")?c._page.on("panelclose",function(){e()}):e(),c._open=!0}},close:function(b){if(this._open){var c=this.options,d=this,e=function(){!b&&a.support.cssTransform3d&&c.animate?d.element.add(d._wrapper).on(d._transitionEndEvents,f):setTimeout(f,0),d._page.removeClass(c.classes.pagePanelOpen),d.element.removeClass(c.classes.panelOpen),d._wrapper.removeClass(c.classes.contentWrapOpen),d._fixedToolbar.removeClass(c.classes.contentFixedToolbarOpen),d._modal&&d._modal.removeClass(d._modalOpenClasses)},f=function(){d.options.theme&&"overlay"!==d.options.display&&(d._page.removeClass("ui-body-"+d.options.theme).addClass(d._pageTheme),d._wrapper.css("min-height","")),d.element.add(d._wrapper).off(d._transitionEndEvents,f),d.element.addClass(c.classes.panelClosed),d._wrapper.removeClass(d._contentWrapOpenClasses).addClass(c.classes.contentWrapClosed),d._fixedToolbar.removeClass(d._fixedToolbarOpenClasses).addClass(c.classes.contentFixedToolbarClosed),d._fixPanel(),d._unbindFixListener(),a.mobile.resetActivePageHeight(),d._page.jqmRemoveData("panel"),d._trigger("close")};this.element.closest(".ui-page-active").length<0&&(b=!0),d._trigger("beforeclose"),e(),d._open=!1}},toggle:function(){this[this._open?"close":"open"]()},_transitionEndEvents:"webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd",_destroy:function(){var b=this.options.classes,c=this.options.theme,d=this.element.siblings("."+b.panel).length;d?this._open&&(this._wrapper.removeClass(b.contentWrapOpen),this._fixedToolbar.removeClass(b.contentFixedToolbarOpen),this._page.jqmRemoveData("panel"),this._page.removeClass(b.pagePanelOpen),c&&this._page.removeClass("ui-body-"+c).addClass(this._pageTheme)):(this._wrapper.children().unwrap(),this._page.find("a").unbind("panelopen panelclose"),this._page.removeClass(b.pagePanel),this._open&&(this._page.jqmRemoveData("panel"),this._page.removeClass(b.pagePanelOpen),c&&this._page.removeClass("ui-body-"+c).addClass(this._pageTheme),a.mobile.resetActivePageHeight())),this._panelInner.children().unwrap(),this.element.removeClass([this._getPanelClasses(),b.panelAnimate].join(" ")).off("swipeleft.panel swiperight.panel").off("panelbeforeopen").off("panelhide").off("keyup.panel").off("updatelayout"),this._closeLink.off("click.panel"),this._modal&&this._modal.remove(),this.element.off(this._transitionEndEvents).removeClass([b.panelUnfixed,b.panelClosed,b.panelOpen].join(" "))}}),a(c).bind("pagecreate create",function(b){a.mobile.panel.prototype.enhanceWithin(b.target)})}(a),function(a,b){a.widget("mobile.table",a.mobile.widget,{options:{classes:{table:"ui-table"},initSelector:":jqmData(role='table')"},_create:function(){var a=this;a.refresh(!0)},refresh:function(c){var d=this,e=this.element.find("thead tr");c&&this.element.addClass(this.options.classes.table),d.headers=this.element.find("tr:eq(0)").children(),d.allHeaders=d.headers.add(e.children()),e.each(function(){var f=0;a(this).children().each(function(){var g=parseInt(a(this).attr("colspan"),10),h=":nth-child("+(f+1)+")";if(a(this).jqmData("colstart",f+1),g)for(var i=0;g-1>i;i++)f++,h+=", :nth-child("+(f+1)+")";c===b&&a(this).jqmData("cells",""),a(this).jqmData("cells",d.element.find("tr").not(e.eq(0)).not(this).children(h)),f++})}),c===b&&this.element.trigger("refresh")}}),a.mobile.document.bind("pagecreate create",function(b){a.mobile.table.prototype.enhanceWithin(b.target)})}(a),function(a,b){a.mobile.table.prototype.options.mode="columntoggle",a.mobile.table.prototype.options.columnBtnTheme=null,a.mobile.table.prototype.options.columnPopupTheme=null,a.mobile.table.prototype.options.columnBtnText="Columns...",a.mobile.table.prototype.options.classes=a.extend(a.mobile.table.prototype.options.classes,{popup:"ui-table-columntoggle-popup",columnBtn:"ui-table-columntoggle-btn",priorityPrefix:"ui-table-priority-",columnToggleTable:"ui-table-columntoggle"}),a.mobile.document.delegate(":jqmData(role='table')","tablecreate refresh",function(c){var d,e,f,g,h=a(this),i=h.data("mobile-table"),j=c.type,k=i.options,l=a.mobile.ns,m=(h.attr("id")||k.classes.popup)+"-popup";"columntoggle"===k.mode&&("refresh"!==j&&(i.element.addClass(k.classes.columnToggleTable),d=a("<a href='#"+m+"' class='"+k.classes.columnBtn+"' data-"+l+"rel='popup' data-"+l+"mini='true'>"+k.columnBtnText+"</a>"),e=a("<div data-"+l+"role='popup' data-"+l+"role='fieldcontain' class='"+k.classes.popup+"' id='"+m+"'></div>"),f=a("<fieldset data-"+l+"role='controlgroup'></fieldset>")),i.headers.not("td").each(function(b){var c=a(this).jqmData("priority"),d=a(this).add(a(this).jqmData("cells"));c&&(d.addClass(k.classes.priorityPrefix+c),"refresh"!==j?a("<label><input type='checkbox' checked />"+a(this).text()+"</label>").appendTo(f).children(0).jqmData("cells",d).checkboxradio({theme:k.columnPopupTheme}):a("#"+m+" fieldset div:eq("+b+")").find("input").jqmData("cells",d))}),"refresh"!==j&&f.appendTo(e),g=f===b?a("#"+m+" fieldset"):f,"refresh"!==j&&(g.on("change","input",function(){this.checked?a(this).jqmData("cells").removeClass("ui-table-cell-hidden").addClass("ui-table-cell-visible"):a(this).jqmData("cells").removeClass("ui-table-cell-visible").addClass("ui-table-cell-hidden")}),d.insertBefore(h).buttonMarkup({theme:k.columnBtnTheme}),e.insertBefore(h).popup()),i.update=function(){g.find("input").each(function(){this.checked?(this.checked="table-cell"===a(this).jqmData("cells").eq(0).css("display"),"refresh"===j&&a(this).jqmData("cells").addClass("ui-table-cell-visible")):a(this).jqmData("cells").addClass("ui-table-cell-hidden"),a(this).checkboxradio("refresh")})},a.mobile.window.on("throttledresize",i.update),i.update())})}(a),function(a){a.mobile.table.prototype.options.mode="reflow",a.mobile.table.prototype.options.classes=a.extend(a.mobile.table.prototype.options.classes,{reflowTable:"ui-table-reflow",cellLabels:"ui-table-cell-label"}),a.mobile.document.delegate(":jqmData(role='table')","tablecreate refresh",function(b){var c=a(this),d=b.type,e=c.data("mobile-table"),f=e.options;if("reflow"===f.mode){"refresh"!==d&&e.element.addClass(f.classes.reflowTable);var g=a(e.allHeaders.get().reverse());g.each(function(){var b=a(this).jqmData("cells"),c=a(this).jqmData("colstart"),d=b.not(this).filter("thead th").length&&" ui-table-cell-label-top",e=a(this).text();if(""!==e)if(d){var g=parseInt(a(this).attr("colspan"),10),h="";g&&(h="td:nth-child("+g+"n + "+c+")"),b.filter(h).prepend("<b class='"+f.classes.cellLabels+d+"'>"+e+"</b>")}else b.prepend("<b class='"+f.classes.cellLabels+"'>"+e+"</b>")})}})}(a),function(a,b){function c(a){e=a.originalEvent,i=e.accelerationIncludingGravity,f=Math.abs(i.x),g=Math.abs(i.y),h=Math.abs(i.z),!b.orientation&&(f>7||(h>6&&8>g||8>h&&g>6)&&f>5)?j.enabled&&j.disable():j.enabled||j.enable()}a.mobile.iosorientationfixEnabled=!0;var d=navigator.userAgent;if(!(/iPhone|iPad|iPod/.test(navigator.platform)&&/OS [1-5]_[0-9_]* like Mac OS X/i.test(d)&&d.indexOf("AppleWebKit")>-1))return a.mobile.iosorientationfixEnabled=!1,void 0;var e,f,g,h,i,j=a.mobile.zoom;a.mobile.document.on("mobileinit",function(){a.mobile.iosorientationfixEnabled&&a.mobile.window.bind("orientationchange.iosorientationfix",j.enable).bind("devicemotion.iosorientationfix",c)})}(a,this),function(a,b){function d(){e.removeClass("ui-mobile-rendering")}var e=a("html"),f=(a("head"),a.mobile.window);a(b.document).trigger("mobileinit"),a.mobile.gradeA()&&(a.mobile.ajaxBlacklist&&(a.mobile.ajaxEnabled=!1),e.addClass("ui-mobile ui-mobile-rendering"),setTimeout(d,5e3),a.extend(a.mobile,{initializePage:function(){var b=a.mobile.path,e=a(":jqmData(role='page'), :jqmData(role='dialog')"),g=b.stripHash(b.stripQueryParams(b.parseLocation().hash)),h=c.getElementById(g);e.length||(e=a("body").wrapInner("<div data-"+a.mobile.ns+"role='page'></div>").children(0)),e.each(function(){var b=a(this);b.jqmData("url")||b.attr("data-"+a.mobile.ns+"url",b.attr("id")||location.pathname+location.search)}),a.mobile.firstPage=e.first(),a.mobile.pageContainer=a.mobile.firstPage.parent().addClass("ui-mobile-viewport"),a.mobile.navreadyDeferred.resolve(),f.trigger("pagecontainercreate"),a.mobile.showPageLoadingMsg(),d(),a.mobile.hashListeningEnabled&&a.mobile.path.isHashValid(location.hash)&&(a(h).is(':jqmData(role="page")')||a.mobile.path.isPath(g)||g===a.mobile.dialogHashKey)?a.event.special.navigate.isPushStateEnabled()?(a.mobile.navigate.history.stack=[],a.mobile.navigate(a.mobile.path.isPath(location.hash)?location.hash:location.href)):f.trigger("hashchange",[!0]):(a.mobile.path.isHashValid(location.hash)&&(a.mobile.urlHistory.initialDst=g.replace("#","")),a.event.special.navigate.isPushStateEnabled()&&a.mobile.navigate.navigator.squash(b.parseLocation().href),a.mobile.changePage(a.mobile.firstPage,{transition:"none",reverse:!0,changeHash:!1,fromHashChange:!0}))}}),a(function(){b.scrollTo(0,1),a.mobile.defaultHomeScroll=a.support.scrollTop&&1!==a.mobile.window.scrollTop()?1:0,a.mobile.autoInitializePage&&a.mobile.initializePage(),f.load(a.mobile.silentScroll),a.support.cssPointerEvents||a.mobile.document.delegate(".ui-disabled","vclick",function(a){a.preventDefault(),a.stopImmediatePropagation()})}))}(a,this)});
-/*
-//@ sourceMappingURL=jquery.mobile-1.3.2.min.map
-*/ \ No newline at end of file