Merge branch 'develop' into node-shm
|
@ -1,5 +1,8 @@
|
|||
variables:
|
||||
GIT_STRATEGY: clone
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
PREFIX: /usr/
|
||||
RSYNC_OPTS: --recursive --ignore-missing-args --chown $DEPLOY_USER:$DEPLOY_USER
|
||||
|
||||
stages:
|
||||
- prepare
|
||||
|
@ -15,13 +18,11 @@ docker-dev:
|
|||
stage: prepare
|
||||
before_script:
|
||||
- docker info
|
||||
- git submodule sync --recursive
|
||||
- git submodule update --init --recursive
|
||||
script:
|
||||
- docker pull fedora:latest
|
||||
- make docker-dev
|
||||
- docker tag -f villas-dev $DOCKER_REGISTRY/villas-dev:latest
|
||||
- docker push $DOCKER_REGISTRY/villas-dev:latest
|
||||
- docker build -f Dockerfile.dev -t villas-node-dev .
|
||||
- docker tag -f villas-node-dev $DOCKER_REGISTRY/villas-node-dev:latest
|
||||
- docker push $DOCKER_REGISTRY/villas-node-dev:latest
|
||||
tags:
|
||||
- shell
|
||||
- linux
|
||||
|
@ -38,7 +39,7 @@ build:
|
|||
name: "${CI_PROJECT_NAME}-${CI_BUILD_REF}"
|
||||
paths:
|
||||
- build/release/
|
||||
image: $DOCKER_REGISTRY/villas-dev
|
||||
image: $DOCKER_REGISTRY/villas-node-dev
|
||||
tags:
|
||||
- docker
|
||||
|
||||
|
@ -50,7 +51,7 @@ docs:
|
|||
- build/release/doc/
|
||||
script:
|
||||
- make doc
|
||||
image: $DOCKER_REGISTRY/villas-dev
|
||||
image: $DOCKER_REGISTRY/villas-node-dev
|
||||
tags:
|
||||
- docker
|
||||
|
||||
|
@ -70,7 +71,7 @@ packages:
|
|||
paths:
|
||||
- build/release/packaging/*.tar.gz
|
||||
- build/release/packaging/rpm/RPMS/
|
||||
image: $DOCKER_REGISTRY/villas-dev
|
||||
image: $DOCKER_REGISTRY/villas-node-dev
|
||||
tags:
|
||||
- docker
|
||||
|
||||
|
@ -88,7 +89,7 @@ coverage:
|
|||
- build/release-coverage/coverage/
|
||||
- build/release-coverage/coverage.txt
|
||||
- build/release-coverage/coverage.xml
|
||||
image: $DOCKER_REGISTRY/villas-dev
|
||||
image: $DOCKER_REGISTRY/villas-node-dev
|
||||
coverage: '/lines: (\d+\.\d+\%)/'
|
||||
tags:
|
||||
- docker
|
||||
|
@ -99,7 +100,7 @@ unit:
|
|||
- build
|
||||
script:
|
||||
- make run-unit-tests
|
||||
image: $DOCKER_REGISTRY/villas-dev
|
||||
image: $DOCKER_REGISTRY/villas-node-dev
|
||||
tags:
|
||||
- docker
|
||||
|
||||
|
@ -116,7 +117,7 @@ integration:
|
|||
when: always
|
||||
paths:
|
||||
- build/release/tests/integration/
|
||||
image: $DOCKER_REGISTRY/villas-dev
|
||||
image: $DOCKER_REGISTRY/villas-node-dev
|
||||
tags:
|
||||
- docker
|
||||
|
||||
|
@ -150,8 +151,9 @@ website:
|
|||
deliver:
|
||||
stage: deploy
|
||||
script:
|
||||
- rsync --recursive --ignore-missing-args build/release-coverage/coverage/ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/coverage/$CI_BUILD_REF_NAME/
|
||||
- rsync --recursive --ignore-missing-args build/release/doc/html/ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/doc/$CI_BUILD_REF_NAME/
|
||||
- ssh $DEPLOY_USER@$DEPLOY_HOST mkdir -pf $DEPLOY_PATH/{coverage,doc}/$CI_BUILD_REF_NAME/
|
||||
- rsync $RSYNC_OPTS build/release-coverage/coverage/ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/coverage/$CI_BUILD_REF_NAME/
|
||||
- rsync $RSYNC_OPTS build/release/doc/html/ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/doc/$CI_BUILD_REF_NAME/
|
||||
dependencies:
|
||||
- docs
|
||||
- coverage
|
||||
|
@ -162,8 +164,9 @@ deliver:
|
|||
deliver-packages:
|
||||
stage: deploy
|
||||
script:
|
||||
- rsync --recursive --ignore-missing-args build/release/packaging/rpm/RPMS/ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/../packages/
|
||||
- rsync --ignore-missing-args build/release/packaging/*.tar.gz $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/dist/
|
||||
- ssh $DEPLOY_USER@$DEPLOY_HOST mkdir -p $DEPLOY_PATH/{dist,../packages}
|
||||
- rsync $RSYNC_OPTS build/release/packaging/rpm/RPMS/ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/../packages/
|
||||
- rsync $RSYNC_OPTS build/release/packaging/*.tar.gz $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/dist/
|
||||
- ssh $DEPLOY_USER@$DEPLOY_HOST createrepo $DEPLOY_PATH/../packages
|
||||
dependencies:
|
||||
- packages
|
||||
|
|
2
.gitmodules
vendored
|
@ -21,4 +21,4 @@
|
|||
url = https://github.com/curl/curl.git
|
||||
[submodule "thirdparty/libxil"]
|
||||
path = thirdparty/libxil
|
||||
url = git@git.rwth-aachen.de:VILLASframework/libxil.git
|
||||
url = ../libxil.git
|
||||
|
|
|
@ -18,18 +18,16 @@ MAINTAINER Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
|||
# Toolchain
|
||||
RUN dnf -y update && \
|
||||
dnf -y install \
|
||||
gcc pkgconfig make cmake \
|
||||
git \
|
||||
gcc-c++ \
|
||||
gcc gcc-c++ \
|
||||
pkgconfig make cmake \
|
||||
autoconf automake autogen libtool \
|
||||
flex bison \
|
||||
texinfo
|
||||
texinfo git
|
||||
|
||||
# Dependencies
|
||||
RUN dnf -y update && \
|
||||
dnf -y install \
|
||||
openssl \
|
||||
openssl-devel \
|
||||
openssl openssl-devel \
|
||||
libconfig-devel \
|
||||
libnl3-devel \
|
||||
libcurl-devel \
|
||||
|
@ -38,12 +36,9 @@ RUN dnf -y update && \
|
|||
# Several tools only needed for developement and testing
|
||||
RUN dnf -y update && \
|
||||
dnf -y install \
|
||||
doxygen \
|
||||
dia \
|
||||
graphviz \
|
||||
doxygen dia graphviz \
|
||||
openssh-clients \
|
||||
rpmdevtools \
|
||||
rpm-build \
|
||||
rpmdevtools rpm-build \
|
||||
jq \
|
||||
iproute \
|
||||
python-pip \
|
||||
|
|
|
@ -35,23 +35,65 @@ This technique, also called 'pinning', improves the determinism of the server by
|
|||
The `priority` setting allows to adjust the scheduling priority of the deamon processes.
|
||||
By default, the daemon uses a real-time optimized FIFO scheduling algorithm.
|
||||
|
||||
#### `name` *(integer)*
|
||||
#### `name` *(string)*
|
||||
|
||||
By default the `name` of a VILLASnode instance is equalt to the hostname of the machine it is running on.
|
||||
Some node types are using this name to identify themselves agains their remotes.
|
||||
An example is the `ngsi` node type which adds a metadata attribute `source` to its updates.
|
||||
|
||||
## Log
|
||||
|
||||
```
|
||||
log = {
|
||||
file = "/var/log/villas-node.log";
|
||||
level = 5;
|
||||
facilities = "socket,log,mem"; // log socket node-type, log and memory sub-system
|
||||
facilities = "nodes,!websocket"; // log all node-type but not the websocket node-type
|
||||
//facilities = "all,!nodes"; // log everything but not the node-types
|
||||
}
|
||||
```
|
||||
|
||||
#### Available logging facilities
|
||||
|
||||
| Facility | Description |
|
||||
|:- |:- |
|
||||
| `pool` | Memory Pool for fixed size allocations |
|
||||
| `queue` | Multiple-producer / Multiple-consumer queue |
|
||||
| `config` | Configuration parser |
|
||||
| `hook` | Hook sub-system |
|
||||
| `path` | Send / Receive path |
|
||||
| `node` | Node-types |
|
||||
| `mem` | Memory management |
|
||||
| `web` | Web sub-system |
|
||||
| `api` | Remote API |
|
||||
| `log` | Logging sub-system |
|
||||
| `vfio` | Virtual Function Input/Output sub-system for access to PCI devices |
|
||||
| `pci` | PCI device detection |
|
||||
| `xil` | Xilinx drivers for FPGA components |
|
||||
| `tc` | Linux traffic control for network emulation |
|
||||
| `if` | Linux network interfaces |
|
||||
| `socket` | BSD Socket node-type |
|
||||
| `file` | File node-type |
|
||||
| `fpga` | VILLASfpga node-type |
|
||||
| `ngsi` | FIWARE NGSI node-type |
|
||||
| `websocket` | WebSocket node-type |
|
||||
| `opal` | OPAL-RT node-type |
|
||||
|
||||
## Web
|
||||
|
||||
## Nodes
|
||||
|
||||
The node section is a **directory** of nodes (clients) which are connected to the VILLASnode instance.
|
||||
The directory is indexed by the name of the node:
|
||||
|
||||
nodes = {
|
||||
"sintef_node" = {
|
||||
type = "socket"
|
||||
....
|
||||
```
|
||||
nodes = {
|
||||
"sintef_node" = {
|
||||
type = "socket";
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are multiple diffrent type of nodes. But all types have the following settings in common:
|
||||
|
||||
|
|
14
doc/DesignGoals.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Design Goals {#designgoals}
|
||||
|
||||
VILLASnode ...
|
||||
|
||||
- is written in C the programming language
|
||||
- is using features of the C11 standard
|
||||
- is using an object oriented programming paradigm
|
||||
- can be compiled with Clang / LLVM or GCC
|
||||
- is released under the LGPLv2 license
|
||||
- only relies on open source software libraries and the Linux kernel
|
||||
- is extensible with new node types & hooks
|
||||
- is heavily multi-threaded
|
||||
- follows the Unix philosophy
|
||||
- is separated into a library (libvillas) and a few binaries (villas-server, villas-pipe, villas-test-*, villas-signal, villas-hook) which link against the lib.
|
|
@ -1,9 +1,14 @@
|
|||
# Getting started
|
||||
|
||||
## Installation
|
||||
|
||||
We put some effort in getting you started as smooth as possible.
|
||||
|
||||
For first tests and development you can use the Docker platform to bootstrap your environment.
|
||||
Docker is a software to run containers (a.k.a images in Docker's terminology) on a Linux machine.
|
||||
We use for development as well as for testing or demonstrating VILLASnode's functionality.
|
||||
|
||||
**Note:** Please be aware that we do not recommend to use Docker for running VILLASnode in a real-time simulation.
|
||||
|
||||
We prepared a image which you can download and run out of the box:
|
||||
|
||||
|
@ -15,18 +20,12 @@ We prepared a image which you can download and run out of the box:
|
|||
|
||||
3. Start the latest VILLASnode container by running:
|
||||
|
||||
$ git clone --recursive git@git.rwth-aachen.de:VILLASframework/VILLASnode.git
|
||||
$ cd VILLASnode
|
||||
$ make docker
|
||||
```
|
||||
$ docker run rwth-acs/villas-node --help
|
||||
```
|
||||
|
||||
### To be added
|
||||
|
||||
VILLASnode ...
|
||||
@todo Add a ASCIIcinema screencast here
|
||||
|
||||
## Guide
|
||||
|
||||
- is written in object-oriented C11
|
||||
- is compiled with Clang / LLVM or GCC
|
||||
- is fully based on open source software
|
||||
- is extensible with new node types & hooks
|
||||
- is heavily multi-threaded
|
||||
- follows the Unix philosophy
|
||||
- is separated into a library (libvillas) and a few binaries (villas-server, villas-pipe, villas-test-*, villas-signal, villas-hook) which link against the lib.
|
|
@ -1,8 +1,14 @@
|
|||
# Setup
|
||||
|
||||
VILLASnode can be installed in multiple ways:
|
||||
|
||||
- Using a pre-build Docker image
|
||||
- Using pre-build RPM packages for Redhat based Linux distributions
|
||||
- or from source
|
||||
|
||||
## Prerequisites
|
||||
|
||||
For all features VILLASnode currently requires the following list of dependencies:
|
||||
VILLASnode currently has the following list of dependencies:
|
||||
|
||||
- [libconfig](http://www.hyperrealm.com/libconfig/) for parsing the configuration file.
|
||||
- [libnl3](http://www.infradead.org/~tgr/libnl/) for the network communication & emulation support of the `socket` node-type.
|
||||
|
@ -10,6 +16,7 @@ For all features VILLASnode currently requires the following list of dependencie
|
|||
- [libjansson](http://www.digip.org/jansson/) JSON parser for `websocket` and `ngsi` node-types.
|
||||
- [libwebsockets](http://libwebsockets.org) for the `websocket` node-type.
|
||||
- [libcurl](https://curl.haxx.se/libcurl/) for HTTP REST requests by the `ngsi` node-type.
|
||||
- [openssl]()
|
||||
|
||||
There are two ways to install these dependencies:
|
||||
|
||||
|
@ -17,18 +24,28 @@ There are two ways to install these dependencies:
|
|||
|
||||
Use the following command to install the dependencies under Debian-based distributions:
|
||||
|
||||
$ sudo apt-get install build-essential pkg-config wget tar cmake doxygen dia graphviz libconfig-dev libnl-3-dev libnl-route-3-dev libjansson-dev libcurl4-openssl-dev
|
||||
```
|
||||
$ sudo apt-get install build-essential pkg-config wget tar cmake doxygen dia graphviz libconfig-dev libnl-3-dev libnl-route-3-dev libjansson-dev libcurl4-openssl-dev
|
||||
```
|
||||
|
||||
or the following line for Fedora / CentOS / Redhat systems:
|
||||
|
||||
$ sudo yum install gcc pkgconfig make wget tar cmake openssl-devel doxygen dia graphviz libconfig-devel libnl3-devel libcurl-devel jansson-devel
|
||||
|
||||
2. Alternatively, you can use the make targets `make thirdparty` and `make install-thirdparty` which will compile and install all required dependencies from source.
|
||||
|
||||
## Fetching VILLASnode
|
||||
```
|
||||
$ sudo yum install gcc pkgconfig make wget tar cmake openssl-devel doxygen dia graphviz libconfig-devel libnl3-devel libcurl-devel jansson-devel
|
||||
```
|
||||
|
||||
$ git clone --recursive git@git.rwth-aachen.de:VILLASframework/VILLASnode.git
|
||||
$ cd VILLASnode
|
||||
2. Alternatively, you can use the build system to download, compile and install all dependencies:
|
||||
|
||||
```
|
||||
$ make install-thirdparty
|
||||
```
|
||||
|
||||
## Downloading VILLASnode
|
||||
|
||||
```
|
||||
$ git clone --recursive git@git.rwth-aachen.de:VILLASframework/VILLASnode.git
|
||||
$ cd VILLASnode
|
||||
```
|
||||
|
||||
## Compilation
|
||||
|
||||
|
@ -36,7 +53,10 @@ Checkout the `Makefile` and `include/config.h` for some options which have to be
|
|||
|
||||
Afterwards, start the compilation with:
|
||||
|
||||
$ make
|
||||
```
|
||||
$ make
|
||||
$ make run-tests
|
||||
```
|
||||
|
||||
Append `V=5` to `make` for a more verbose debugging output.
|
||||
Append `DEBUG=1` to `make` to add debug symbols.
|
||||
|
@ -45,7 +65,10 @@ Append `DEBUG=1` to `make` to add debug symbols.
|
|||
|
||||
Install the files to your search path:
|
||||
|
||||
$ make install
|
||||
```
|
||||
$ make install
|
||||
$ make install-doc
|
||||
```
|
||||
|
||||
Append `PREFIX=/opt/local` to change the installation destination.
|
||||
|
||||
|
@ -53,6 +76,8 @@ Append `PREFIX=/opt/local` to change the installation destination.
|
|||
|
||||
Verify everything is working and required node-types are compiled-in:
|
||||
|
||||
$ villas node
|
||||
```
|
||||
$ villas node --help
|
||||
```
|
||||
|
||||
Will show you the current version of the server including a list of all supported node-types.
|
||||
Will print the current version including a list of all supported node-types, hooks, etc.
|
||||
|
|
124
doc/RemoteAPI.md
|
@ -1,124 +0,0 @@
|
|||
#Remote Application Programming Interface (API) {#API}
|
||||
|
||||
VILLASnode can be controlled remotely over a HTTP REST / WebSocket API.
|
||||
This page documents this API.
|
||||
|
||||
## Transports
|
||||
|
||||
The API is accessible via multiple transports:
|
||||
|
||||
- via HTTP POST requests
|
||||
- via a WebSocket protocol
|
||||
- via a Unix socket
|
||||
|
||||
All transports use the same JSON based protocol to handle requests.
|
||||
|
||||
### HTTP REST
|
||||
|
||||
**Endpoint URL:** http[s]://localhost:80/api/v1
|
||||
**HTTP Method:** POST
|
||||
|
||||
### WebSockets
|
||||
|
||||
**WebSocket Protocol:** `api`
|
||||
|
||||
### Unix socket
|
||||
|
||||
_This transport is not implemented yet_
|
||||
|
||||
## Commands
|
||||
|
||||
### `restart`
|
||||
|
||||
Restart VILLASnode with a new configuration file.
|
||||
|
||||
**Request:** _application/json_
|
||||
|
||||
{
|
||||
"request": "restart",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a"
|
||||
"args" : {
|
||||
"configuration": "smb://MY-WINDOWS-HOST/SHARE1/path/to/config.conf"
|
||||
}
|
||||
}
|
||||
|
||||
**Response:** _application/json_
|
||||
|
||||
{
|
||||
"response": "reload",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a"
|
||||
}
|
||||
|
||||
### `config`
|
||||
|
||||
Retrieve the contents of the current configuration.
|
||||
|
||||
**Request:** _application/json_
|
||||
|
||||
{
|
||||
"request": "config",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a"
|
||||
}
|
||||
|
||||
**Response:** _application/json_
|
||||
|
||||
{
|
||||
"response": "config",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a",
|
||||
"response" : {
|
||||
"nodes" : {
|
||||
"socket_node" : {
|
||||
"type": "socket",
|
||||
"layer": "udp",
|
||||
...
|
||||
}
|
||||
},
|
||||
"paths" : [
|
||||
{
|
||||
"in": "socket_node",
|
||||
"out": "socket_node"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
### `nodes`
|
||||
|
||||
Get a list of currently active nodes.
|
||||
|
||||
**Request:** _application/json_
|
||||
|
||||
{
|
||||
"request": "nodes",
|
||||
"id": "5a786626-fbc6-4c04-98c2-48027e68c2fa"
|
||||
}
|
||||
|
||||
**Response:** _application/json_
|
||||
|
||||
{
|
||||
"command": "nodes",
|
||||
"response": [
|
||||
{
|
||||
"name": "ws",
|
||||
"state": 4,
|
||||
"vectorize": 1,
|
||||
"affinity": 0,
|
||||
"id": 0,
|
||||
"type": "websocket",
|
||||
"description": "Demo Channel"
|
||||
}
|
||||
],
|
||||
"id": "5a786626-fbc6-4c04-98c2-48027e68c2fa"
|
||||
}
|
||||
|
||||
### `paths`
|
||||
|
||||
Get a list of currently active paths.
|
||||
|
||||
_This request is not implemented yet_
|
||||
|
||||
### `status`
|
||||
|
||||
The the status of this VILLASnode instance.
|
||||
|
||||
_This request is not implemented yet_
|
|
@ -1,12 +1,19 @@
|
|||
# Tuning {#tuning}
|
||||
|
||||
This page is not directly related to VILLASnode.
|
||||
It describes several ways to optimize the host system for running real-time applications like VILLASnode.
|
||||
|
||||
## Operating System and Kernel
|
||||
|
||||
For minimum latency several kernel and driver settings can be optimized.
|
||||
A [PREEMPT_RT patched Linux](https://rt.wiki.kernel.org/index.php/Main_Page) kernel is recommended.
|
||||
Precompiled kernels for Fedora can be found here: http://ccrma.stanford.edu/planetccrma/software/
|
||||
|
||||
1. **Important:** Tune overall system performance for real-time:
|
||||
1. Tune overall system performance for real-time:
|
||||
|
||||
1.1. Use the `tuned` tool for imprving general real-time performance.
|
||||
|
||||
Please adjust the setting `isolated_cpucores` according to your hardware.
|
||||
|
||||
```bash
|
||||
$ dnf install tuned-profiles-realtime
|
||||
|
@ -14,25 +21,28 @@ $ echo "realtime" > /etc/tuned/active_profile
|
|||
$ echo "isolated_cpucores=6-7" >> /etc/tuned/realtime-variables.conf
|
||||
$ systemctl enable tuned && systemctl start tuned
|
||||
```
|
||||
|
||||
This enables the following `tuned` profiles:
|
||||
- latency-performance
|
||||
- network-latency
|
||||
- realtime
|
||||
|
||||
2. Map NIC IRQs => see setting `affinity`
|
||||
3. Map Tasks => see setting `affinity`
|
||||
This enables the following `tuned` profiles:
|
||||
|
||||
4. Increase priority of server task (nice(2)) => see setting `priority`
|
||||
5. Increase BSD socket priority => see setting `priority` and node-type `socket`
|
||||
- latency-performance
|
||||
- network-latency
|
||||
- realtime
|
||||
|
||||
6. Configure NIC interrupt coalescence with `ethtool`:
|
||||
1.2 Install a `PREEMPT_RT` patched Linux kernel.
|
||||
|
||||
2. Optimize the VILLASnode configuration
|
||||
2.1. Map NIC IRQs (see global setting `affinity`)
|
||||
2.2. Map Tasks (see global setting `affinity`)
|
||||
2.3. Increase priority of server task (nice(2)) (see global setting `priority`)
|
||||
2.4. Increase BSD socket priority (see global setting `priority` for node-type `socket`)
|
||||
|
||||
3. Configure NIC interrupt coalescence with `ethtool`:
|
||||
|
||||
```bash
|
||||
$ ethtool -C|--coalesce devname [adaptive-rx on|off] [adaptive-tx on|off] ...
|
||||
$ ethtool --coalesce eth0 adaptive-rx off adaptive-tx off
|
||||
```
|
||||
|
||||
7. Configure NIC kernel driver in `/etc/modprobe.d/e1000e.conf`:
|
||||
4. Configure NIC kernel driver in `/etc/modprobe.d/e1000e.conf`:
|
||||
|
||||
```
|
||||
# More conservative interrupt throttling for better latency
|
||||
|
@ -45,7 +55,7 @@ option e1000e InterruptThrottleRate=
|
|||
This are some proposals for the selection of appropriate server hardware:
|
||||
|
||||
- Server-grade CPU: Intel Xeon
|
||||
- A multi-core systems allows parallization of send/receive paths.
|
||||
- A multi-core systems enable true paralell execution of multiple send / receive paths.
|
||||
|
||||
- Server-grade network cards: Intel PRO/1000
|
||||
- These allow offloading of UDP checksumming to the hardware
|
||||
|
|
114
doc/Usage.md
|
@ -1,86 +1,56 @@
|
|||
# Usage {#usage}
|
||||
|
||||
The core of VILLASnode is the `villas-node` server.
|
||||
# `villas signal`
|
||||
|
||||
# `villas pipe`
|
||||
|
||||
# `villas hook`
|
||||
|
||||
## `villas node`
|
||||
|
||||
The core of VILLASnode is the `villas-node` daemon.
|
||||
The folling usage information is provided when called like `villas-node --help`;
|
||||
|
||||
Usage: villas-node [CONFIG]
|
||||
CONFIG is the path to an optional configuration file
|
||||
if omitted, VILLASnode will start without a configuration
|
||||
and wait for provisioning over the web interface.
|
||||
```
|
||||
Usage: villas-node [CONFIG]
|
||||
CONFIG is the path to an optional configuration file
|
||||
if omitted, VILLASnode will start without a configuration
|
||||
and wait for provisioning over the web interface.
|
||||
|
||||
Supported node types:
|
||||
- file : support for file log / replay node type
|
||||
- cbuilder : RTDS CBuilder model
|
||||
- socket : BSD network sockets
|
||||
- fpga : VILLASfpga PCIe card (libxil)
|
||||
- ngsi : OMA Next Generation Services Interface 10 (libcurl, libjansson)
|
||||
- websocket : Send and receive samples of a WebSocket connection (libwebsockets)
|
||||
Supported node types:
|
||||
- file : support for file log / replay node type
|
||||
- cbuilder : RTDS CBuilder model
|
||||
- socket : BSD network sockets
|
||||
- fpga : VILLASfpga PCIe card (libxil)
|
||||
- ngsi : OMA Next Generation Services Interface 10 (libcurl, libjansson)
|
||||
- websocket : Send and receive samples of a WebSocket connection (libwebsockets)
|
||||
|
||||
Supported hooks:
|
||||
- restart : Call restart hooks for current path
|
||||
- print : Print the message to stdout
|
||||
- decimate : Downsamping by integer factor
|
||||
- fix_ts : Update timestamps of sample if not set
|
||||
- skip_first : Skip the first samples
|
||||
- drop : Drop messages with reordered sequence numbers
|
||||
- convert : Convert message from / to floating-point / integer
|
||||
- shift : Shift the origin timestamp of samples
|
||||
- ts : Update timestamp of message with current time
|
||||
- stats : Collect statistics for the current path
|
||||
- stats_send : Send path statistics to another node
|
||||
Supported hooks:
|
||||
- restart : Call restart hooks for current path
|
||||
- print : Print the message to stdout
|
||||
- decimate : Downsamping by integer factor
|
||||
- fix_ts : Update timestamps of sample if not set
|
||||
- skip_first : Skip the first samples
|
||||
- drop : Drop messages with reordered sequence numbers
|
||||
- convert : Convert message from / to floating-point / integer
|
||||
- shift : Shift the origin timestamp of samples
|
||||
- ts : Update timestamp of message with current time
|
||||
- stats : Collect statistics for the current path
|
||||
- stats_send : Send path statistics to another node
|
||||
|
||||
Supported API commands:
|
||||
- nodes : retrieve list of all known nodes
|
||||
- config : retrieve current VILLASnode configuration
|
||||
- reload : restart VILLASnode with new configuration
|
||||
Supported API commands:
|
||||
- nodes : retrieve list of all known nodes
|
||||
- config : retrieve current VILLASnode configuration
|
||||
- reload : restart VILLASnode with new configuration
|
||||
|
||||
VILLASnode v0.7-0.2-646-g59756e7-dirty-debug (built on Mar 12 2017 21:37:40)
|
||||
copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC
|
||||
Steffen Vogel <StVogel@eonerc.rwth-aachen.de>
|
||||
VILLASnode v0.7-0.2-646-g59756e7-dirty-debug (built on Mar 12 2017 21:37:40)
|
||||
copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC
|
||||
Steffen Vogel <StVogel@eonerc.rwth-aachen.de>
|
||||
```
|
||||
|
||||
The server requires root privileges for:
|
||||
|
||||
- Enable the realtime FIFO scheduler
|
||||
- Increase the task priority
|
||||
- Configure the network emulator (netem)
|
||||
- Change the SMP affinity of threads and network interrupts
|
||||
|
||||
## Step-by-step
|
||||
|
||||
1. Start putty.exe (SSH client for Windows)
|
||||
|
||||
- Should be already installed on most systems
|
||||
- Or load .exe from this website (no installation required)
|
||||
http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe
|
||||
|
||||
2. Connect to VILLASnode
|
||||
|
||||
| Setting | Value |
|
||||
| :------- | :-------------- |
|
||||
| IP | 130.134.169.31 |
|
||||
| Port | 22 |
|
||||
| Protocol | SSH |
|
||||
| User | root |
|
||||
| Password | *please ask msv |
|
||||
|
||||
3. Go to VILLASnode directory
|
||||
|
||||
$ cd /villas/
|
||||
|
||||
4. Edit configuration file
|
||||
|
||||
$ nano etc/loopback.conf
|
||||
|
||||
- Take a look at the examples and documentation for a detailed description
|
||||
- Move with: cursor keys
|
||||
- Save with: Ctrl+X => y => Enter
|
||||
|
||||
5. Start server
|
||||
|
||||
$ villas node etc/loopback.conf
|
||||
|
||||
6. Terminate server by pressing Ctrl+C
|
||||
|
||||
7. Logout
|
||||
|
||||
$ exit
|
||||
- Change the SMP affinity of threads and network interrupts
|
157
doc/development/RemoteAPI.md
Normal file
|
@ -0,0 +1,157 @@
|
|||
#Remote Application Programming Interface (API) {#API}
|
||||
|
||||
VILLASnode can be controlled remotely with an Application Programming Interface (API).
|
||||
|
||||
## Transports
|
||||
|
||||
The API is accessible via multiple transports:
|
||||
|
||||
- HTTP POST requests
|
||||
- WebSockets
|
||||
- Unix Domain sockets (planned)
|
||||
|
||||
### HTTP REST
|
||||
|
||||
**Endpoint URL:** `http[s]://server:port/api/v1`
|
||||
|
||||
**HTTP Method:** POST only
|
||||
|
||||
### WebSockets
|
||||
|
||||
**Protocol:** `api`
|
||||
|
||||
**Endpoint:** `ws[s]://server:port/v1`
|
||||
|
||||
### Unix socket
|
||||
|
||||
_This transport is not implemented yet_
|
||||
|
||||
## Protocol
|
||||
|
||||
All transports use the same JSON-based protocol to encode API requests and responses.
|
||||
Both requests and responses are JSON objects with the fields described below.
|
||||
Per API session multiple requests can be sent to the node.
|
||||
The order of the respective responses does not necessarily match the order of the requests.
|
||||
Requests and responses can be interleaved.
|
||||
The client must check the `id` field in order to find the matching response to a request.
|
||||
|
||||
#### Request
|
||||
|
||||
| Field | Description |
|
||||
|:------------------------ |:---------------------- |
|
||||
| `action` | The API action which is requested. See next section. |
|
||||
| `id` | A unique string which identifies the request. The same id will be used for the response. |
|
||||
| `request` | Any JSON data-type which will be passed as an argument to the respective API action. |
|
||||
|
||||
#### Response
|
||||
|
||||
The response is similar to the request object.
|
||||
The `id` field of the request will be copied to allow
|
||||
|
||||
| Field | Description |
|
||||
|:------------------------ |:---------------------- |
|
||||
| `action` | The API action which is requested. See next section. |
|
||||
| `id` | A unique string which identifies the request. The same id will be used for the response. |
|
||||
| `response` | Any JSON data-type which can be returned. |
|
||||
|
||||
## Actions
|
||||
|
||||
### `restart`
|
||||
|
||||
Restart VILLASnode with a new configuration file.
|
||||
|
||||
**Request:** _application/json_
|
||||
|
||||
{
|
||||
"action": "restart",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a"
|
||||
"request" : {
|
||||
"configuration": "smb://MY-WINDOWS-HOST/SHARE1/path/to/config.conf"
|
||||
}
|
||||
}
|
||||
|
||||
**Response:** _application/json_
|
||||
|
||||
{
|
||||
"action": "reload",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a"
|
||||
"response" : "success"
|
||||
}
|
||||
|
||||
### `config`
|
||||
|
||||
Retrieve the contents of the current configuration.
|
||||
|
||||
**Request:** _application/json_
|
||||
|
||||
{
|
||||
"action": "config",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a"
|
||||
}
|
||||
|
||||
**Response:** _application/json_
|
||||
|
||||
{
|
||||
"action": "config",
|
||||
"id": "66675eb4-6a0b-49e6-8e82-64d2b2504e7a",
|
||||
"response" : {
|
||||
"nodes" : {
|
||||
"socket_node" : {
|
||||
"type": "socket",
|
||||
"layer": "udp",
|
||||
...
|
||||
}
|
||||
},
|
||||
"paths" : [
|
||||
{
|
||||
"in": "socket_node",
|
||||
"out": "socket_node"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
### `nodes`
|
||||
|
||||
Get a list of currently active nodes.
|
||||
|
||||
**Request:** _application/json_
|
||||
|
||||
{
|
||||
"action": "nodes",
|
||||
"id": "5a786626-fbc6-4c04-98c2-48027e68c2fa"
|
||||
}
|
||||
|
||||
**Response:** _application/json_
|
||||
|
||||
{
|
||||
"action": "nodes",
|
||||
"response": [
|
||||
{
|
||||
"name": "ws",
|
||||
"state": 4,
|
||||
"vectorize": 1,
|
||||
"affinity": 0,
|
||||
"id": 0,
|
||||
"type": "websocket",
|
||||
"description": "Demo Channel"
|
||||
}
|
||||
],
|
||||
"id": "5a786626-fbc6-4c04-98c2-48027e68c2fa"
|
||||
}
|
||||
|
||||
### `capabilities`
|
||||
|
||||
Get a list of supported node-types, hooks and API actions.
|
||||
|
||||
### `paths`
|
||||
|
||||
Get a list of currently active paths.
|
||||
|
||||
_This request is not implemented yet_
|
||||
|
||||
### `status`
|
||||
|
||||
The the status of this VILLASnode instance.
|
||||
|
||||
_This request is not implemented yet_
|
|
@ -29,7 +29,7 @@ log = {
|
|||
};
|
||||
|
||||
http = {
|
||||
htdocs = "/villas/web/socket/", # Root directory of internal webserver
|
||||
htdocs = "/villas/web/", # Root directory of internal webserver
|
||||
port = 80 # Port for HTTP connections
|
||||
}
|
||||
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
#include "list.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "api/session.h"
|
||||
|
||||
/* Forward declarations */
|
||||
struct lws;
|
||||
struct super_node;
|
||||
|
||||
struct api;
|
||||
struct api_ressource;
|
||||
struct api_buffer;
|
||||
struct api_session;
|
||||
struct api_action;
|
||||
|
||||
/** Callback type of command function
|
||||
*
|
||||
|
@ -29,17 +29,7 @@ struct api_session;
|
|||
* @param[out] resp JSON command response.
|
||||
* @param[in] i Execution context.
|
||||
*/
|
||||
typedef int (*api_cb_t)(struct api_ressource *c, json_t *args, json_t **resp, struct api_session *s);
|
||||
|
||||
enum api_version {
|
||||
API_VERSION_UNKOWN = 0,
|
||||
API_VERSION_1 = 1
|
||||
};
|
||||
|
||||
enum api_mode {
|
||||
API_MODE_WS, /**< This API session was established over a WebSocket connection. */
|
||||
API_MODE_HTTP /**< This API session was established via a HTTP REST request. */
|
||||
};
|
||||
typedef int (*api_cb_t)(struct api_action *c, json_t *args, json_t **resp, struct api_session *s);
|
||||
|
||||
struct api {
|
||||
struct list sessions; /**< List of currently active connections */
|
||||
|
@ -49,38 +39,8 @@ struct api {
|
|||
struct super_node *super_node;
|
||||
};
|
||||
|
||||
struct api_buffer {
|
||||
char *buf; /**< A pointer to the buffer. Usually resized via realloc() */
|
||||
size_t size; /**< The allocated size of the buffer. */
|
||||
size_t len; /**< The used length of the buffer. */
|
||||
};
|
||||
|
||||
/** A connection via HTTP REST or WebSockets to issue API actions. */
|
||||
struct api_session {
|
||||
enum api_mode mode;
|
||||
enum api_version version;
|
||||
|
||||
int runs;
|
||||
|
||||
struct {
|
||||
struct api_buffer body; /**< HTTP body / WS payload */
|
||||
} request;
|
||||
|
||||
struct {
|
||||
struct api_buffer body; /**< HTTP body / WS payload */
|
||||
struct api_buffer headers; /**< HTTP headers */
|
||||
} response;
|
||||
|
||||
bool completed; /**< Did we receive the complete body yet? */
|
||||
|
||||
struct api *api;
|
||||
};
|
||||
|
||||
/** Command descriptor
|
||||
*
|
||||
* Every command is described by a descriptor.
|
||||
*/
|
||||
struct api_ressource {
|
||||
/** API action descriptor */
|
||||
struct api_action {
|
||||
api_cb_t cb;
|
||||
};
|
||||
|
||||
|
@ -96,18 +56,6 @@ int api_start(struct api *a);
|
|||
|
||||
int api_stop(struct api *a);
|
||||
|
||||
int api_session_init(struct api_session *s, struct api *a, enum api_mode m);
|
||||
|
||||
int api_session_destroy(struct api_session *s);
|
||||
|
||||
int api_session_run_command(struct api_session *s, json_t *req, json_t **resp);
|
||||
|
||||
/** Send contents of buffer over libwebsockets connection */
|
||||
int api_buffer_send(struct api_buffer *b, struct lws *w, enum lws_write_protocol prot);
|
||||
|
||||
/** Append received data to buffer. */
|
||||
int api_buffer_append(struct api_buffer *b, const char *in, size_t len);
|
||||
|
||||
/** Libwebsockets callback for "api" endpoint */
|
||||
int api_ws_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
|
||||
|
|
53
include/villas/api/session.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/** API session.
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "web/buffer.h"
|
||||
|
||||
enum api_version {
|
||||
API_VERSION_UNKOWN = 0,
|
||||
API_VERSION_1 = 1
|
||||
};
|
||||
|
||||
enum api_mode {
|
||||
API_MODE_WS, /**< This API session was established over a WebSocket connection. */
|
||||
API_MODE_HTTP /**< This API session was established via a HTTP REST request. */
|
||||
};
|
||||
|
||||
/** A connection via HTTP REST or WebSockets to issue API actions. */
|
||||
struct api_session {
|
||||
enum api_mode mode;
|
||||
enum api_version version;
|
||||
|
||||
int runs;
|
||||
|
||||
struct {
|
||||
struct web_buffer body; /**< HTTP body / WS payload */
|
||||
} request;
|
||||
|
||||
struct {
|
||||
struct web_buffer body; /**< HTTP body / WS payload */
|
||||
struct web_buffer headers; /**< HTTP headers */
|
||||
} response;
|
||||
|
||||
bool completed; /**< Did we receive the complete body yet? */
|
||||
|
||||
enum state state;
|
||||
|
||||
struct api *api;
|
||||
};
|
||||
|
||||
int api_session_init(struct api_session *s, struct api *a, enum api_mode m);
|
||||
|
||||
int api_session_destroy(struct api_session *s);
|
||||
|
||||
int api_session_run_command(struct api_session *s, json_t *req, json_t **resp);
|
11
include/villas/compat.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/** Compatability for different library versions.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
#if JANSSON_VERSION_HEX < 0x020A00
|
||||
size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags);
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
/** Sample value remapping for mux.
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
/* Forward declarations */
|
||||
struct node;
|
||||
struct super_node;
|
||||
struct sample;
|
||||
|
||||
/** C++ like vtable construct for node_types */
|
||||
|
@ -32,13 +33,10 @@ struct node_type {
|
|||
*
|
||||
* This callback is invoked once per node-type.
|
||||
*
|
||||
* @param argc Number of arguments passed to the server executable (see main()).
|
||||
* @param argv Array of arguments passed to the server executable (see main()).
|
||||
* @param cfg Root libconfig object of global configuration file.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*init)(int argc, char *argv[], config_setting_t *cfg);
|
||||
int (*init)(struct super_node *sn);
|
||||
|
||||
/** Global de-initialization per node type.
|
||||
*
|
||||
|
@ -135,7 +133,7 @@ struct node_type {
|
|||
*
|
||||
* @see node_type::init
|
||||
*/
|
||||
int node_type_start(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg);
|
||||
int node_type_start(struct node_type *vt, struct super_node *sn);
|
||||
|
||||
/** De-initialize node type subsystems.
|
||||
*
|
||||
|
|
|
@ -38,7 +38,7 @@ struct fpga {
|
|||
};
|
||||
|
||||
/** @see node_vtable::init */
|
||||
int fpga_init(int argc, char *argv[], config_setting_t *cfg);
|
||||
int fpga_init(struct super_node *sn);
|
||||
|
||||
/** @see node_vtable::deinit */
|
||||
int fpga_deinit();
|
||||
|
|
|
@ -52,7 +52,7 @@ struct ngsi {
|
|||
*
|
||||
* @see node_vtable::init
|
||||
*/
|
||||
int ngsi_init(int argc, char *argv[], config_setting_t *cfg);
|
||||
int ngsi_init(struct super_node *sn);
|
||||
|
||||
/** Free global NGSI settings and unmaps shared memory regions.
|
||||
*
|
||||
|
|
|
@ -42,7 +42,7 @@ struct opal {
|
|||
*
|
||||
* @see node_vtable::init
|
||||
*/
|
||||
int opal_init(int argc, char *argv[], config_setting_t *cfg);
|
||||
int opal_init(struct super_node *sn);
|
||||
|
||||
/** Free global OPAL settings and unmaps shared memory regions.
|
||||
*
|
||||
|
|
|
@ -58,7 +58,7 @@ struct socket {
|
|||
|
||||
|
||||
/** @see node_vtable::init */
|
||||
int socket_init(int argc, char *argv[], config_setting_t *cfg);
|
||||
int socket_init(struct super_node *sn);
|
||||
|
||||
/** @see node_vtable::deinit */
|
||||
int socket_deinit();
|
||||
|
|
|
@ -65,7 +65,7 @@ struct websocket_destination {
|
|||
int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
|
||||
/** @see node_vtable::init */
|
||||
int websocket_init(int argc, char *argv[], config_setting_t *cfg);
|
||||
int websocket_init(struct super_node *sn);
|
||||
|
||||
/** @see node_vtable::deinit */
|
||||
int websocket_deinit();
|
||||
|
|
|
@ -48,7 +48,7 @@ struct plugin {
|
|||
int (*unload)(struct plugin *p);
|
||||
|
||||
union {
|
||||
struct api_ressource api;
|
||||
struct api_action api;
|
||||
struct node_type node;
|
||||
struct fpga_ip_type ip;
|
||||
struct hook_type hook;
|
||||
|
|
|
@ -57,7 +57,7 @@ struct queue {
|
|||
|
||||
enum state state;
|
||||
|
||||
struct memtype * mem;
|
||||
struct memtype *mem;
|
||||
size_t buffer_mask;
|
||||
off_t buffer_off; /**< Relative pointer to struct queue_cell[] */
|
||||
|
||||
|
|
|
@ -70,6 +70,12 @@ int sample_get(struct sample *s);
|
|||
/** Decrease reference count and release memory if last reference was held. */
|
||||
int sample_put(struct sample *s);
|
||||
|
||||
int sample_copy(struct sample *dst, struct sample *src);
|
||||
|
||||
int sample_copy_many(struct sample *dsts[], struct sample *srcs[], int cnt);
|
||||
int sample_get_many(struct sample *smps[], int cnt);
|
||||
int sample_put_many(struct sample *smps[], int cnt);
|
||||
|
||||
/** Get number representation for a single value of a sample. */
|
||||
int sample_get_data_format(struct sample *s, int idx);
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <libconfig.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* Forward declarations */
|
||||
|
@ -24,6 +27,8 @@ struct web {
|
|||
const char *htdocs; /**< The root directory for files served via HTTP. */
|
||||
const char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS. */
|
||||
const char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS. */
|
||||
|
||||
pthread_t thread;
|
||||
};
|
||||
|
||||
/** Initialize the web interface.
|
||||
|
@ -39,7 +44,4 @@ int web_start(struct web *w);
|
|||
int web_stop(struct web *w);
|
||||
|
||||
/** Parse HTTPd and WebSocket related options */
|
||||
int web_parse(struct web *w, config_setting_t *lcs);
|
||||
|
||||
/** libwebsockets service routine. Call periodically */
|
||||
int web_service(struct web *w);
|
||||
int web_parse(struct web *w, config_setting_t *lcs);
|
56
include/villas/web/buffer.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/** WebSocket buffer.
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct web_buffer {
|
||||
char *buffer; /**< A pointer to the buffer. Usually resized via realloc() */
|
||||
size_t size; /**< The allocated size of the buffer. */
|
||||
size_t len; /**< The used length of the buffer. */
|
||||
size_t prefix; /**< The used length of the buffer. */
|
||||
|
||||
enum lws_write_protocol protocol;
|
||||
|
||||
enum state state;
|
||||
};
|
||||
|
||||
/** Initialize a libwebsockets buffer. */
|
||||
int web_buffer_init(struct web_buffer *b, enum lws_write_protocol prot);
|
||||
|
||||
/** Destroy a libwebsockets buffer. */
|
||||
int web_buffer_destroy(struct web_buffer *b);
|
||||
|
||||
/** Flush the buffers contents to lws_write() */
|
||||
int web_buffer_write(struct web_buffer *b, struct lws *w);
|
||||
|
||||
/** Copy \p len bytes from the beginning of the buffer and copy them to \p out.
|
||||
*
|
||||
* @param out The destination buffer. If NULL, we just remove \p len bytes from the buffer.
|
||||
*/
|
||||
int web_buffer_read(struct web_buffer *b, char *out, size_t len);
|
||||
|
||||
/** Parse JSON from the beginning of the buffer.
|
||||
*
|
||||
* @retval -1 The buffer is empty.
|
||||
* @retval -2 The buffer contains malformed JSON.
|
||||
*/
|
||||
int web_buffer_read_json(struct web_buffer *b, json_t **req);
|
||||
|
||||
/** Append \p len bytes of \p in at the end of the buffer.
|
||||
*
|
||||
* The buffer is automatically resized.
|
||||
*/
|
||||
int web_buffer_append(struct web_buffer *b, const char *in, size_t len);
|
||||
|
||||
/** Append the serialized represetnation of the JSON object \p res at the end of the buffer. */
|
||||
int web_buffer_append_json(struct web_buffer *b, json_t *res);
|
|
@ -5,7 +5,8 @@ LIBS = $(patsubst %, $(BUILDDIR)/lib%.so, $(SONAMES))
|
|||
LIB_CFLAGS = $(CFLAGS) -fPIC
|
||||
|
||||
-include lib/hooks/Makefile.inc
|
||||
-include lib/apis/Makefile.inc
|
||||
-include lib/api/Makefile.inc
|
||||
-include lib/web/Makefile.inc
|
||||
|
||||
-include $(patsubst %, lib/Makefile.%.inc, $(SONAMES))
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ LIB_SRCS += $(addprefix lib/nodes/, file.c cbuilder.c shmem.c) \
|
|||
log.c utils.c super_node.c hist.c timing.c pool.c \
|
||||
list.c queue.c queue_signalled.c memory.c advio.c web.c api.c \
|
||||
plugin.c node_type.c stats.c mapping.c sample_io.c shmem.c \
|
||||
json.c crypt.c \
|
||||
json.c crypt.c compat.c \
|
||||
)
|
||||
|
||||
LIB_LDFLAGS = -shared
|
||||
|
|
|
@ -80,7 +80,9 @@ AFILE * afopen(const char *uri, const char *mode)
|
|||
goto out1;
|
||||
|
||||
/* Setup libcurl handle */
|
||||
#if LIBCURL_VERSION_NUM >= 0x072d00
|
||||
curl_easy_setopt(af->curl, CURLOPT_DEFAULT_PROTOCOL, "file");
|
||||
#endif
|
||||
curl_easy_setopt(af->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(af->curl, CURLOPT_UPLOAD, 0L);
|
||||
curl_easy_setopt(af->curl, CURLOPT_USERAGENT, USER_AGENT);
|
||||
|
|
324
lib/api.c
|
@ -6,214 +6,70 @@
|
|||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include "plugin.h"
|
||||
#include "api.h"
|
||||
#include "log.h"
|
||||
#include "web.h"
|
||||
#include "config.h"
|
||||
|
||||
#if JANSSON_VERSION_HEX < 0x020A00
|
||||
size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags)
|
||||
{
|
||||
char *str;
|
||||
size_t len;
|
||||
|
||||
str = json_dumps(json, flags);
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
len = strlen(str); // not \0 terminated
|
||||
if (buffer && len <= size)
|
||||
memcpy(buffer, str, len);
|
||||
|
||||
free(str);
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int api_parse_request(struct api_buffer *b, json_t **req)
|
||||
{
|
||||
json_error_t e;
|
||||
|
||||
if (b->len <= 0)
|
||||
return -1;
|
||||
|
||||
*req = json_loadb(b->buf, b->len, JSON_DISABLE_EOF_CHECK, &e);
|
||||
if (!*req)
|
||||
return -1;
|
||||
|
||||
if (e.position < b->len) {
|
||||
void *dst = (void *) b->buf;
|
||||
void *src = (void *) (b->buf + e.position);
|
||||
|
||||
memmove(dst, src, b->len - e.position);
|
||||
|
||||
b->len -= e.position;
|
||||
}
|
||||
else
|
||||
b->len = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int api_unparse_response(struct api_buffer *b, json_t *res)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
retry: len = json_dumpb(res, b->buf + b->len, b->size - b->len, 0);
|
||||
if (len > b->size - b->len) {
|
||||
b->buf = realloc(b->buf, b->len + len);
|
||||
b->size += len;
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
b->len += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int api_session_run_command(struct api_session *s, json_t *json_in, json_t **json_out)
|
||||
{
|
||||
int ret;
|
||||
const char *rstr;
|
||||
char *id;
|
||||
struct plugin *p;
|
||||
|
||||
json_t *json_args = NULL, *json_resp;
|
||||
|
||||
ret = json_unpack(json_in, "{ s: s, s: s, s?: o }",
|
||||
"request", &rstr,
|
||||
"id", &id,
|
||||
"args", &json_args);
|
||||
if (ret) {
|
||||
*json_out = json_pack("{ s: s, s: s, s: i, s: s }",
|
||||
"command", rstr,
|
||||
"error", "invalid request",
|
||||
"code", -1,
|
||||
"id", id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = plugin_lookup(PLUGIN_TYPE_API, rstr);
|
||||
if (!p) {
|
||||
*json_out = json_pack("{ s: s, s: s, s: d, s: s, s: s }",
|
||||
"command", rstr,
|
||||
"error", "command not found",
|
||||
"code", -2,
|
||||
"command", rstr,
|
||||
"id", id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
debug(LOG_API, "Running API request: %s", p->name);
|
||||
|
||||
ret = p->api.cb(&p->api, json_args, &json_resp, s);
|
||||
if (ret)
|
||||
*json_out = json_pack("{ s: s, s: s, s: s }",
|
||||
"command", rstr,
|
||||
"error", "command failed",
|
||||
"code", ret,
|
||||
"id", id);
|
||||
else
|
||||
*json_out = json_pack("{ s: s, s: o, s: s }",
|
||||
"command", rstr,
|
||||
"response", json_resp,
|
||||
"id", id);
|
||||
|
||||
out: debug(LOG_API, "API request completed with code: %d", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include "assert.h"
|
||||
#include "compat.h"
|
||||
|
||||
int api_ws_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
||||
{
|
||||
//struct api_session *s = (struct api_session *) user;
|
||||
|
||||
switch (reason) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int api_http_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
struct web *w = lws_context_user(lws_get_context(wsi));
|
||||
struct api_session *s = (struct api_session *) user;
|
||||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_ESTABLISHED: {
|
||||
struct web *w = (struct web *) lws_context_user(lws_get_context(wsi));
|
||||
|
||||
if (w->api == NULL)
|
||||
return -1; /** @todo return error message */
|
||||
|
||||
api_session_init(s, w->api, API_MODE_WS);
|
||||
break;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_HTTP: {
|
||||
struct web *w = (struct web *) lws_context_user(lws_get_context(wsi));
|
||||
|
||||
char *uri = (char *) in;
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
if (w->api == NULL) {
|
||||
lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (unsigned char *) "API disabled", strlen("API disabled"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse request URI */
|
||||
ret = sscanf(uri, "/api/v%d", (int *) &s->version);
|
||||
char uri[64];
|
||||
lws_hdr_copy(wsi, uri, sizeof(uri), WSI_TOKEN_GET_URI); /* The path component of the*/
|
||||
|
||||
ret = sscanf(uri, "/v%d", (int *) &s->version);
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
|
||||
debug(LOG_API, "New REST API session initiated: version = %d", s->version);
|
||||
|
||||
api_session_init(s, w->api, API_MODE_HTTP);
|
||||
|
||||
/* Prepare HTTP response header */
|
||||
const char headers[] = "HTTP/1.1 200 OK\r\n"
|
||||
"Content-type: application/json\r\n"
|
||||
"User-agent: " USER_AGENT "\r\n"
|
||||
"\r\n";
|
||||
|
||||
api_buffer_append(&s->response.headers, headers, sizeof(headers)-1);
|
||||
|
||||
/* book us a LWS_CALLBACK_HTTP_WRITEABLE callback */
|
||||
lws_callback_on_writable(wsi);
|
||||
ret = api_session_init(s, w->api, API_MODE_WS);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
debug(LOG_API, "New API session initiated: version=%d, mode=websocket", s->version);
|
||||
break;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_CLIENT_RECEIVE:
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
case LWS_CALLBACK_HTTP_BODY: {
|
||||
api_buffer_append(&s->request.body, in, len);
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
ret = api_session_destroy(s);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
json_t *req, *resp;
|
||||
while (api_parse_request(&s->request.body, &req) == 1) {
|
||||
api_session_run_command(s, req, &resp);
|
||||
api_unparse_response(&s->response.body, resp);
|
||||
|
||||
lws_callback_on_writable(wsi);
|
||||
}
|
||||
debug(LOG_API, "Closed API session");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_HTTP_BODY_COMPLETION:
|
||||
s->completed = true;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||
case LWS_CALLBACK_HTTP_WRITEABLE:
|
||||
/* We send headers only in HTTP mode */
|
||||
if (s->mode == API_MODE_HTTP)
|
||||
api_buffer_send(&s->response.headers, wsi, LWS_WRITE_HTTP_HEADERS);
|
||||
web_buffer_write(&s->response.body, wsi);
|
||||
|
||||
api_buffer_send(&s->response.body, wsi, LWS_WRITE_HTTP);
|
||||
|
||||
if (s->completed && s->response.body.len == 0)
|
||||
return -1;
|
||||
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
web_buffer_append(&s->request.body, in, len);
|
||||
|
||||
json_t *req, *resp;
|
||||
while (web_buffer_read_json(&s->request.body, &req) >= 0) {
|
||||
api_session_run_command(s, req, &resp);
|
||||
|
||||
web_buffer_append_json(&s->response.body, resp);
|
||||
lws_callback_on_writable(wsi);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
@ -222,32 +78,75 @@ int api_http_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void
|
|||
return 0;
|
||||
}
|
||||
|
||||
int api_buffer_send(struct api_buffer *b, struct lws *w, enum lws_write_protocol prot)
|
||||
int api_http_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
||||
{
|
||||
int sent;
|
||||
|
||||
if (b->len <= 0)
|
||||
return 0;
|
||||
int ret;
|
||||
|
||||
sent = lws_write(w, (unsigned char *) b->buf, b->len, prot);
|
||||
if (sent > 0) {
|
||||
memmove(b->buf, b->buf + sent, sent);
|
||||
b->len -= sent;
|
||||
struct web *w = lws_context_user(lws_get_context(wsi));
|
||||
struct api_session *s = (struct api_session *) user;
|
||||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_HTTP:
|
||||
if (w->api == NULL) {
|
||||
lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (unsigned char *) "API disabled", strlen("API disabled"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse request URI */
|
||||
ret = sscanf(in, "/api/v%d", (int *) &s->version);
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
|
||||
ret = api_session_init(s, w->api, API_MODE_HTTP);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
debug(LOG_API, "New API session initiated: version=%d, mode=http", s->version);
|
||||
|
||||
/* Prepare HTTP response header */
|
||||
const char headers[] = "HTTP/1.1 200 OK\r\n"
|
||||
"Content-type: application/json\r\n"
|
||||
"User-agent: " USER_AGENT "\r\n"
|
||||
"\r\n";
|
||||
|
||||
web_buffer_append(&s->response.headers, headers, sizeof(headers)-1);
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLOSED_HTTP:
|
||||
ret = api_session_destroy(s);
|
||||
if (ret)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_HTTP_BODY:
|
||||
web_buffer_append(&s->request.body, in, len);
|
||||
|
||||
json_t *req, *resp;
|
||||
while (web_buffer_read_json(&s->request.body, &req) == 1) {
|
||||
api_session_run_command(s, req, &resp);
|
||||
|
||||
web_buffer_append_json(&s->response.body, resp);
|
||||
lws_callback_on_writable(wsi);
|
||||
}
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_HTTP_BODY_COMPLETION:
|
||||
s->completed = true;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_HTTP_WRITEABLE:
|
||||
web_buffer_write(&s->response.headers, wsi);
|
||||
web_buffer_write(&s->response.body, wsi);
|
||||
|
||||
if (s->completed && s->response.body.len == 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
int api_buffer_append(struct api_buffer *b, const char *in, size_t len)
|
||||
{
|
||||
b->buf = realloc(b->buf, b->len + len);
|
||||
if (!b->buf)
|
||||
return -1;
|
||||
|
||||
memcpy(b->buf + b->len, in, len);
|
||||
|
||||
b->len += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -291,26 +190,3 @@ int api_stop(struct api *a)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int api_session_init(struct api_session *s, struct api *a, enum api_mode m)
|
||||
{
|
||||
s->mode = m;
|
||||
s->api = a;
|
||||
|
||||
s->completed = false;
|
||||
|
||||
s->request.body =
|
||||
s->response.body =
|
||||
s->response.headers = (struct api_buffer) {
|
||||
.buf = NULL,
|
||||
.size = 0,
|
||||
.len = 0
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int api_session_destroy(struct api_session *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
3
lib/api/Makefile.inc
Normal file
|
@ -0,0 +1,3 @@
|
|||
LIB_SRCS += $(wildcard lib/api/*.c)
|
||||
|
||||
-include lib/api/actions/Makefile.inc
|
1
lib/api/actions/Makefile.inc
Normal file
|
@ -0,0 +1 @@
|
|||
LIB_SRCS += $(wildcard lib/api/actions/*.c)
|
45
lib/api/actions/capabiltities.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/** The "capabiltities" API ressource.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
static int api_capabilities(struct api_action *h, json_t *args, json_t **resp, struct api_session *s)
|
||||
{
|
||||
json_t *json_hooks = json_array();
|
||||
json_t *json_apis = json_array();
|
||||
json_t *json_nodes = json_array();
|
||||
json_t *json_name;
|
||||
|
||||
for (size_t i = 0; i < list_length(&plugins); i++) {
|
||||
struct plugin *p = list_at(&plugins, i);
|
||||
|
||||
json_name = json_string(p->name);
|
||||
|
||||
switch (p->type) {
|
||||
case PLUGIN_TYPE_NODE: json_array_append_new(json_nodes, json_name); break;
|
||||
case PLUGIN_TYPE_HOOK: json_array_append_new(json_hooks, json_name); break;
|
||||
case PLUGIN_TYPE_API: json_array_append_new(json_apis, json_name); break;
|
||||
default: { }
|
||||
}
|
||||
}
|
||||
|
||||
*resp = json_pack("{ s: s, s: o, s: o, s: o }",
|
||||
"build", BUILDID,
|
||||
"hooks", json_hooks,
|
||||
"node-types", json_nodes,
|
||||
"apis", json_apis);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct plugin p = {
|
||||
.name = "capabilities",
|
||||
.description = "get capabiltities and details about this VILLASnode instance",
|
||||
.type = PLUGIN_TYPE_API,
|
||||
.api.cb = api_capabilities
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN(&p)
|
|
@ -1,9 +1,7 @@
|
|||
/** The "config" command
|
||||
/** The "config" API ressource.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <libconfig.h>
|
||||
|
@ -13,7 +11,7 @@
|
|||
#include "plugin.h"
|
||||
#include "json.h"
|
||||
|
||||
static int api_config(struct api_ressource *h, json_t *args, json_t **resp, struct api_session *s)
|
||||
static int api_config(struct api_action *h, json_t *args, json_t **resp, struct api_session *s)
|
||||
{
|
||||
config_setting_t *cfg_root = config_root_setting(&s->api->super_node->cfg);
|
||||
|
||||
|
@ -29,4 +27,4 @@ static struct plugin p = {
|
|||
.api.cb = api_config
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN(&p)
|
||||
REGISTER_PLUGIN(&p)
|
|
@ -1,22 +1,21 @@
|
|||
/** The "nodes" command
|
||||
/** The "nodes" API ressource.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
#include "plugin.h"
|
||||
#include "api.h"
|
||||
#include "node.h"
|
||||
#include "utils.h"
|
||||
#include "json.h"
|
||||
|
||||
#include "api.h"
|
||||
|
||||
extern struct list nodes;
|
||||
|
||||
static int api_nodes(struct api_ressource *r, json_t *args, json_t **resp, struct api_session *s)
|
||||
static int api_nodes(struct api_action *r, json_t *args, json_t **resp, struct api_session *s)
|
||||
{
|
||||
json_t *json_nodes = json_array();
|
||||
|
|
@ -1,25 +1,23 @@
|
|||
/** The "reload" command
|
||||
/** The "restart" API ressource.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include "plugin.h"
|
||||
#include "api.h"
|
||||
|
||||
/** @todo not implemented yet */
|
||||
static int api_reload(struct api_ressource *h, json_t *args, json_t **resp, struct api_session *s)
|
||||
static int api_restart(struct api_action *h, json_t *args, json_t **resp, struct api_session *s)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct plugin p = {
|
||||
.name = "reload",
|
||||
.name = "restart",
|
||||
.description = "restart VILLASnode with new configuration",
|
||||
.type = PLUGIN_TYPE_API,
|
||||
.api.cb = api_reload
|
||||
.api.cb = api_restart
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN(&p)
|
94
lib/api/session.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/** API session.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include "api/session.h"
|
||||
|
||||
#include "web.h"
|
||||
#include "plugin.h"
|
||||
|
||||
int api_session_init(struct api_session *s, struct api *a, enum api_mode m)
|
||||
{
|
||||
s->mode = m;
|
||||
s->api = a;
|
||||
|
||||
s->completed = false;
|
||||
|
||||
web_buffer_init(&s->request.body, s->mode == API_MODE_HTTP ? LWS_WRITE_HTTP : LWS_WRITE_TEXT);
|
||||
web_buffer_init(&s->response.body, s->mode == API_MODE_HTTP ? LWS_WRITE_HTTP : LWS_WRITE_TEXT);
|
||||
|
||||
if (s->mode == API_MODE_HTTP)
|
||||
web_buffer_init(&s->response.headers, LWS_WRITE_HTTP_HEADERS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int api_session_destroy(struct api_session *s)
|
||||
{
|
||||
if (s->state == STATE_DESTROYED)
|
||||
return 0;
|
||||
|
||||
web_buffer_destroy(&s->request.body);
|
||||
web_buffer_destroy(&s->response.body);
|
||||
|
||||
if (s->mode == API_MODE_HTTP)
|
||||
web_buffer_destroy(&s->response.headers);
|
||||
|
||||
s->state = STATE_DESTROYED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int api_session_run_command(struct api_session *s, json_t *json_in, json_t **json_out)
|
||||
{
|
||||
int ret;
|
||||
const char *action;
|
||||
char *id;
|
||||
struct plugin *p;
|
||||
|
||||
json_t *json_args = NULL, *json_resp;
|
||||
|
||||
ret = json_unpack(json_in, "{ s: s, s: s, s?: o }",
|
||||
"action", &action,
|
||||
"id", &id,
|
||||
"request", &json_args);
|
||||
if (ret) {
|
||||
ret = -100;
|
||||
*json_out = json_pack("{ s: s, s: i }",
|
||||
"error", "invalid request",
|
||||
"code", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = plugin_lookup(PLUGIN_TYPE_API, action);
|
||||
if (!p) {
|
||||
ret = -101;
|
||||
*json_out = json_pack("{ s: s, s: s, s: i, s: s }",
|
||||
"action", action,
|
||||
"id", id,
|
||||
"code", ret,
|
||||
"error", "command not found");
|
||||
goto out;
|
||||
}
|
||||
|
||||
debug(LOG_API, "Running API request: %s", p->name);
|
||||
|
||||
ret = p->api.cb(&p->api, json_args, &json_resp, s);
|
||||
if (ret)
|
||||
*json_out = json_pack("{ s: s, s: s, s: i, s: s }",
|
||||
"action", action,
|
||||
"id", id,
|
||||
"code", ret,
|
||||
"error", "command failed");
|
||||
else
|
||||
*json_out = json_pack("{ s: s, s: s, s: o }",
|
||||
"action", action,
|
||||
"id", id,
|
||||
"response", json_resp);
|
||||
|
||||
out: debug(LOG_API, "API request completed with code: %d", ret);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
LIB_SRCS += $(wildcard lib/apis/*.c)
|
|
@ -1,19 +0,0 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "boolean.tab.h" // to get the token types that we return
|
||||
|
||||
%}
|
||||
|
||||
%option prefix="log_expression_"
|
||||
%option noyywrap
|
||||
|
||||
%%
|
||||
|
||||
[ \t\n] ; // ignore whitespace
|
||||
[&] ; //operators
|
||||
[a-b]+ { log_expression_lval.token = strdup(log_expression_text); return TOKEN; }
|
||||
[0-9]+ { log_expression_lval.constant = atoi(log_expression_text); return CONSTANT; }
|
||||
|
||||
%%
|
|
@ -1,241 +0,0 @@
|
|||
Grammatik
|
||||
|
||||
0 $accept: input $end
|
||||
|
||||
1 input: %empty
|
||||
2 | exp '\n'
|
||||
|
||||
3 exp: comp
|
||||
4 | exp '&' exp
|
||||
5 | exp '|' exp
|
||||
6 | exp '^' exp
|
||||
7 | '~' exp
|
||||
8 | '(' exp ')'
|
||||
|
||||
9 comp: CONSTANT
|
||||
10 | TOKEN
|
||||
|
||||
|
||||
Terminale und die Regeln, in denen sie verwendet werden
|
||||
|
||||
$end (0) 0
|
||||
'\n' (10) 2
|
||||
'&' (38) 4
|
||||
'(' (40) 8
|
||||
')' (41) 8
|
||||
'^' (94) 6
|
||||
'|' (124) 5
|
||||
'~' (126) 7
|
||||
error (256)
|
||||
TOKEN (258) 10
|
||||
CONSTANT (259) 9
|
||||
NEG (260)
|
||||
|
||||
|
||||
Nicht-Terminal und die Regeln, in denen sie verwendet werden
|
||||
|
||||
$accept (13)
|
||||
auf der linken Seite: 0
|
||||
input (14)
|
||||
auf der linken Seite: 1 2, auf der rechten Seite: 0
|
||||
exp (15)
|
||||
auf der linken Seite: 3 4 5 6 7 8, auf der rechten Seite: 2 4 5
|
||||
6 7 8
|
||||
comp (16)
|
||||
auf der linken Seite: 9 10, auf der rechten Seite: 3
|
||||
|
||||
|
||||
Zustand 0
|
||||
|
||||
0 $accept: . input $end
|
||||
|
||||
TOKEN schiebe und gehe zu Zustand 1 über
|
||||
CONSTANT schiebe und gehe zu Zustand 2 über
|
||||
'~' schiebe und gehe zu Zustand 3 über
|
||||
'(' schiebe und gehe zu Zustand 4 über
|
||||
|
||||
$default reduziere mit Regel 1 (input)
|
||||
|
||||
input gehe zu Zustand 5 über
|
||||
exp gehe zu Zustand 6 über
|
||||
comp gehe zu Zustand 7 über
|
||||
|
||||
|
||||
Zustand 1
|
||||
|
||||
10 comp: TOKEN .
|
||||
|
||||
$default reduziere mit Regel 10 (comp)
|
||||
|
||||
|
||||
Zustand 2
|
||||
|
||||
9 comp: CONSTANT .
|
||||
|
||||
$default reduziere mit Regel 9 (comp)
|
||||
|
||||
|
||||
Zustand 3
|
||||
|
||||
7 exp: '~' . exp
|
||||
|
||||
TOKEN schiebe und gehe zu Zustand 1 über
|
||||
CONSTANT schiebe und gehe zu Zustand 2 über
|
||||
'~' schiebe und gehe zu Zustand 3 über
|
||||
'(' schiebe und gehe zu Zustand 4 über
|
||||
|
||||
exp gehe zu Zustand 8 über
|
||||
comp gehe zu Zustand 7 über
|
||||
|
||||
|
||||
Zustand 4
|
||||
|
||||
8 exp: '(' . exp ')'
|
||||
|
||||
TOKEN schiebe und gehe zu Zustand 1 über
|
||||
CONSTANT schiebe und gehe zu Zustand 2 über
|
||||
'~' schiebe und gehe zu Zustand 3 über
|
||||
'(' schiebe und gehe zu Zustand 4 über
|
||||
|
||||
exp gehe zu Zustand 9 über
|
||||
comp gehe zu Zustand 7 über
|
||||
|
||||
|
||||
Zustand 5
|
||||
|
||||
0 $accept: input . $end
|
||||
|
||||
$end schiebe und gehe zu Zustand 10 über
|
||||
|
||||
|
||||
Zustand 6
|
||||
|
||||
2 input: exp . '\n'
|
||||
4 exp: exp . '&' exp
|
||||
5 | exp . '|' exp
|
||||
6 | exp . '^' exp
|
||||
|
||||
'&' schiebe und gehe zu Zustand 11 über
|
||||
'|' schiebe und gehe zu Zustand 12 über
|
||||
'^' schiebe und gehe zu Zustand 13 über
|
||||
'\n' schiebe und gehe zu Zustand 14 über
|
||||
|
||||
|
||||
Zustand 7
|
||||
|
||||
3 exp: comp .
|
||||
|
||||
$default reduziere mit Regel 3 (exp)
|
||||
|
||||
|
||||
Zustand 8
|
||||
|
||||
4 exp: exp . '&' exp
|
||||
5 | exp . '|' exp
|
||||
6 | exp . '^' exp
|
||||
7 | '~' exp .
|
||||
|
||||
$default reduziere mit Regel 7 (exp)
|
||||
|
||||
|
||||
Zustand 9
|
||||
|
||||
4 exp: exp . '&' exp
|
||||
5 | exp . '|' exp
|
||||
6 | exp . '^' exp
|
||||
8 | '(' exp . ')'
|
||||
|
||||
'&' schiebe und gehe zu Zustand 11 über
|
||||
'|' schiebe und gehe zu Zustand 12 über
|
||||
'^' schiebe und gehe zu Zustand 13 über
|
||||
')' schiebe und gehe zu Zustand 15 über
|
||||
|
||||
|
||||
Zustand 10
|
||||
|
||||
0 $accept: input $end .
|
||||
|
||||
$default annehmen
|
||||
|
||||
|
||||
Zustand 11
|
||||
|
||||
4 exp: exp '&' . exp
|
||||
|
||||
TOKEN schiebe und gehe zu Zustand 1 über
|
||||
CONSTANT schiebe und gehe zu Zustand 2 über
|
||||
'~' schiebe und gehe zu Zustand 3 über
|
||||
'(' schiebe und gehe zu Zustand 4 über
|
||||
|
||||
exp gehe zu Zustand 16 über
|
||||
comp gehe zu Zustand 7 über
|
||||
|
||||
|
||||
Zustand 12
|
||||
|
||||
5 exp: exp '|' . exp
|
||||
|
||||
TOKEN schiebe und gehe zu Zustand 1 über
|
||||
CONSTANT schiebe und gehe zu Zustand 2 über
|
||||
'~' schiebe und gehe zu Zustand 3 über
|
||||
'(' schiebe und gehe zu Zustand 4 über
|
||||
|
||||
exp gehe zu Zustand 17 über
|
||||
comp gehe zu Zustand 7 über
|
||||
|
||||
|
||||
Zustand 13
|
||||
|
||||
6 exp: exp '^' . exp
|
||||
|
||||
TOKEN schiebe und gehe zu Zustand 1 über
|
||||
CONSTANT schiebe und gehe zu Zustand 2 über
|
||||
'~' schiebe und gehe zu Zustand 3 über
|
||||
'(' schiebe und gehe zu Zustand 4 über
|
||||
|
||||
exp gehe zu Zustand 18 über
|
||||
comp gehe zu Zustand 7 über
|
||||
|
||||
|
||||
Zustand 14
|
||||
|
||||
2 input: exp '\n' .
|
||||
|
||||
$default reduziere mit Regel 2 (input)
|
||||
|
||||
|
||||
Zustand 15
|
||||
|
||||
8 exp: '(' exp ')' .
|
||||
|
||||
$default reduziere mit Regel 8 (exp)
|
||||
|
||||
|
||||
Zustand 16
|
||||
|
||||
4 exp: exp . '&' exp
|
||||
4 | exp '&' exp .
|
||||
5 | exp . '|' exp
|
||||
6 | exp . '^' exp
|
||||
|
||||
$default reduziere mit Regel 4 (exp)
|
||||
|
||||
|
||||
Zustand 17
|
||||
|
||||
4 exp: exp . '&' exp
|
||||
5 | exp . '|' exp
|
||||
5 | exp '|' exp .
|
||||
6 | exp . '^' exp
|
||||
|
||||
$default reduziere mit Regel 5 (exp)
|
||||
|
||||
|
||||
Zustand 18
|
||||
|
||||
4 exp: exp . '&' exp
|
||||
5 | exp . '|' exp
|
||||
6 | exp . '^' exp
|
||||
6 | exp '^' exp .
|
||||
|
||||
$default reduziere mit Regel 6 (exp)
|
|
@ -1,85 +0,0 @@
|
|||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_LOG_EXPRESSION_BOOLEAN_TAB_H_INCLUDED
|
||||
# define YY_LOG_EXPRESSION_BOOLEAN_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef LOG_EXPRESSION_DEBUG
|
||||
# if defined YYDEBUG
|
||||
#if YYDEBUG
|
||||
# define LOG_EXPRESSION_DEBUG 1
|
||||
# else
|
||||
# define LOG_EXPRESSION_DEBUG 0
|
||||
# endif
|
||||
# else /* ! defined YYDEBUG */
|
||||
# define LOG_EXPRESSION_DEBUG 0
|
||||
# endif /* ! defined YYDEBUG */
|
||||
#endif /* ! defined LOG_EXPRESSION_DEBUG */
|
||||
#if LOG_EXPRESSION_DEBUG
|
||||
extern int log_expression_debug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef LOG_EXPRESSION_TOKENTYPE
|
||||
# define LOG_EXPRESSION_TOKENTYPE
|
||||
enum log_expression_tokentype
|
||||
{
|
||||
TOKEN = 258,
|
||||
CONSTANT = 259,
|
||||
NEG = 260
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined LOG_EXPRESSION_STYPE && ! defined LOG_EXPRESSION_STYPE_IS_DECLARED
|
||||
|
||||
union LOG_EXPRESSION_STYPE
|
||||
{
|
||||
#line 12 "boolean.y" /* yacc.c:1909 */
|
||||
|
||||
char *token;
|
||||
unsigned long constant;
|
||||
|
||||
#line 73 "boolean.tab.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union LOG_EXPRESSION_STYPE LOG_EXPRESSION_STYPE;
|
||||
# define LOG_EXPRESSION_STYPE_IS_TRIVIAL 1
|
||||
# define LOG_EXPRESSION_STYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern LOG_EXPRESSION_STYPE log_expression_lval;
|
||||
|
||||
int log_expression_parse (void);
|
||||
|
||||
#endif /* !YY_LOG_EXPRESSION_BOOLEAN_TAB_H_INCLUDED */
|
|
@ -1,74 +0,0 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void log_expression_error(const char *s);
|
||||
int log_expression_lex();
|
||||
int log_expression_parse();
|
||||
long lookup_token(char *token);
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *token;
|
||||
unsigned long constant;
|
||||
}
|
||||
|
||||
%token <token> TOKEN
|
||||
%token <constant> CONSTANT
|
||||
|
||||
%type <constant> exp comp
|
||||
|
||||
|
||||
%left '&' '|' '^'
|
||||
%precedence NEG
|
||||
|
||||
%define api.prefix {log_expression_}
|
||||
|
||||
%%
|
||||
|
||||
input:
|
||||
| exp '\n' { printf("\n\nresult = %#lx\n", $1); }
|
||||
;
|
||||
|
||||
exp :
|
||||
comp
|
||||
| exp '&' exp { $$ = $1 & $3; }
|
||||
| exp '|' exp { $$ = $1 | $3; }
|
||||
| exp '^' exp { $$ = $1 ^ $3; }
|
||||
| '~' exp %prec NEG { $$ = ~$2; printf("neg\n"); }
|
||||
| '(' exp ')' { $$ = $2; printf("subex"); }
|
||||
;
|
||||
|
||||
comp :
|
||||
CONSTANT { $$ = $1; printf("const %ld", $1); }
|
||||
| TOKEN { $$ = lookup_token($1); printf("token '%s'", $1); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
long lookup_token(char *token)
|
||||
{
|
||||
if (!strcmp(token, "a"))
|
||||
return 201;
|
||||
else if (!strcmp(token, "b"))
|
||||
return 202;
|
||||
if (!strcmp(token, "c"))
|
||||
return 203;
|
||||
if (!strcmp(token, "d"))
|
||||
return 204;
|
||||
else
|
||||
return 1111;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
do {
|
||||
log_expression_parse();
|
||||
} while (!feof(stdin));
|
||||
}
|
||||
|
||||
void log_expression_error(const char *s) {
|
||||
printf("EEK, parse error! Message: %s", s);
|
||||
exit(-1);
|
||||
}
|
30
lib/compat.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/** Compatability for different library versions.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#if JANSSON_VERSION_HEX < 0x020A00
|
||||
size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags)
|
||||
{
|
||||
char *str;
|
||||
size_t len;
|
||||
|
||||
str = json_dumps(json, flags);
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
len = strlen(str); // not \0 terminated
|
||||
if (buffer && len <= size)
|
||||
memcpy(buffer, str, len);
|
||||
|
||||
free(str);
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif
|
|
@ -147,7 +147,6 @@ int hook_cmp_priority(const void *a, const void *b)
|
|||
|
||||
int hook_parse_list(struct list *list, config_setting_t *cfg, struct path *o)
|
||||
{
|
||||
struct hook h = {.state = STATE_DESTROYED};
|
||||
struct plugin *p;
|
||||
|
||||
int ret, priority = 10;
|
||||
|
@ -167,6 +166,8 @@ int hook_parse_list(struct list *list, config_setting_t *cfg, struct path *o)
|
|||
if (!config_setting_is_group(cfg_hook))
|
||||
cerror(cfg_hook, "The 'hooks' setting must be an array of strings.");
|
||||
|
||||
struct hook h = { .state = STATE_DESTROYED };
|
||||
|
||||
ret = hook_init(&h, &p->hook, o);
|
||||
if (ret)
|
||||
continue;
|
||||
|
|
|
@ -23,7 +23,7 @@ static int drop_read(struct hook *h, struct sample *smps[], size_t *cnt)
|
|||
if (h->prev) {
|
||||
dist = h->last->sequence - (int32_t) h->prev->sequence;
|
||||
if (dist <= 0) {
|
||||
warn("Dropped sample: dist = %d, i = %d", dist, i);
|
||||
warn("Dropped sample: sequence=%u, dist=%d, i=%d", h->last->sequence, dist, i);
|
||||
if (h->path && h->path->stats)
|
||||
stats_update(h->path->stats->delta, STATS_REORDERED, dist);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ int node_start(struct node *n)
|
|||
|
||||
info("Starting node %s", node_name_long(n));
|
||||
{ INDENT
|
||||
ret = n->_vt->start ? n->_vt->start(n) : -1;
|
||||
ret = n->_vt->start ? n->_vt->start(n) : 0;
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ int node_stop(struct node *n)
|
|||
|
||||
info("Stopping node %s", node_name(n));
|
||||
{ INDENT
|
||||
ret = n->_vt->stop ? n->_vt->stop(n) : -1;
|
||||
ret = n->_vt->stop ? n->_vt->stop(n) : 0;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "sample.h"
|
||||
#include "node.h"
|
||||
|
@ -14,16 +13,16 @@
|
|||
#include "config.h"
|
||||
#include "plugin.h"
|
||||
|
||||
int node_type_start(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg)
|
||||
int node_type_start(struct node_type *vt, struct super_node *sn)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (vt->state != STATE_STARTED)
|
||||
if (vt->state != STATE_DESTROYED)
|
||||
return 0;
|
||||
|
||||
info("Initializing " YEL("%s") " node type which is used by %zu nodes", plugin_name(vt), list_length(&vt->instances));
|
||||
{ INDENT
|
||||
ret = vt->init ? vt->init(argc, argv, cfg) : 0;
|
||||
ret = vt->init ? vt->init(sn) : 0;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
|
@ -41,7 +40,7 @@ int node_type_stop(struct node_type *vt)
|
|||
|
||||
info("De-initializing " YEL("%s") " node type", plugin_name(vt));
|
||||
{ INDENT
|
||||
ret = vt->deinit ? vt->deinit() : -1;
|
||||
ret = vt->deinit ? vt->deinit() : 0;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
|
|
|
@ -30,20 +30,21 @@ void fpga_dump(struct fpga *f)
|
|||
fpga_card_dump(c);
|
||||
}
|
||||
|
||||
int fpga_init(int argc, char *argv[], config_setting_t *cfg)
|
||||
int fpga_init(struct super_node *sn)
|
||||
{
|
||||
int ret;
|
||||
config_setting_t *cfg_fpgas;
|
||||
config_setting_t *cfg, *cfg_fpgas;
|
||||
|
||||
ret = pci_init(&pci);
|
||||
if (ret)
|
||||
cerror(cfg, "Failed to initialize PCI sub-system");
|
||||
error("Failed to initialize PCI sub-system");
|
||||
|
||||
ret = vfio_init(&vc);
|
||||
if (ret)
|
||||
cerror(cfg, "Failed to initiliaze VFIO sub-system");
|
||||
error("Failed to initiliaze VFIO sub-system");
|
||||
|
||||
/* Parse FPGA configuration */
|
||||
cfg = config_root_setting(&sn->cfg);
|
||||
cfg_fpgas = config_setting_lookup(cfg, "fpgas");
|
||||
if (!cfg_fpgas)
|
||||
cerror(cfg, "Config file is missing 'fpgas' section");
|
||||
|
|
|
@ -368,8 +368,12 @@ out: json_decref(request);
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ngsi_init(int argc, char *argv[], config_setting_t *cfg)
|
||||
int ngsi_init(struct super_node *sn)
|
||||
{
|
||||
config_setting_t *cfg;
|
||||
|
||||
cfg = config_root_setting(&sn->cfg);
|
||||
|
||||
const char *tname;
|
||||
if (config_setting_lookup_string(cfg, "name", &tname)) {
|
||||
name = strdup(tname);
|
||||
|
|
|
@ -25,18 +25,18 @@ static Opal_GenAsyncParam_Ctrl params; /** String and Float parameters, provided
|
|||
|
||||
static pthread_mutex_t lock; /** Big Global Lock for libOpalAsync API */
|
||||
|
||||
int opal_init(int argc, char *argv[], config_setting_t *cfg)
|
||||
int opal_init(struct super_node *sn)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (argc != 4)
|
||||
if (sn->cli.argc != 4)
|
||||
return -1;
|
||||
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
|
||||
async_shmem_name = argv[1];
|
||||
async_shmem_size = atoi(argv[2]);
|
||||
print_shmem_name = argv[3];
|
||||
async_shmem_name = sn->cli.argv[1];
|
||||
async_shmem_size = atoi(sn->cli.argv[2]);
|
||||
print_shmem_name = sn->cli.argv[3];
|
||||
|
||||
/* Enable the OpalPrint function. This prints to the OpalDisplay. */
|
||||
err = OpalSystemCtrl_Register(print_shmem_name);
|
||||
|
|
|
@ -122,9 +122,9 @@ int shmem_close(struct node *n)
|
|||
atomic_store_explicit(&shm->shared->node_stopped, 1, memory_order_relaxed);
|
||||
|
||||
if (!shm->polling) {
|
||||
pthread_mutex_lock(&shm->shared->out.qs.mt);
|
||||
pthread_mutex_lock(&shm->shared->out.qs.mutex);
|
||||
pthread_cond_broadcast(&shm->shared->out.qs.ready);
|
||||
pthread_mutex_unlock(&shm->shared->out.qs.mt);
|
||||
pthread_mutex_unlock(&shm->shared->out.qs.mutex);
|
||||
}
|
||||
|
||||
/* Don't destroy the data structures yet, since the other process might
|
||||
|
|
|
@ -34,9 +34,9 @@
|
|||
static struct plugin p;
|
||||
|
||||
/* Private static storage */
|
||||
struct list interfaces;
|
||||
struct list interfaces = { .state = STATE_DESTROYED };
|
||||
|
||||
int socket_init(int argc, char *argv[], config_setting_t *cfg)
|
||||
int socket_init(struct super_node *sn)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -71,7 +71,7 @@ int socket_init(int argc, char *argv[], config_setting_t *cfg)
|
|||
}
|
||||
|
||||
/* If not found, create a new interface */
|
||||
struct interface j;
|
||||
struct interface j = { .sockets.state = STATE_DESTROYED };
|
||||
|
||||
ret = if_init(&j, link);
|
||||
if (ret)
|
||||
|
@ -94,7 +94,7 @@ found: list_push(&i->sockets, s);
|
|||
|
||||
int socket_deinit()
|
||||
{
|
||||
for (size_t j = 0; list_length(&interfaces); j++) {
|
||||
for (size_t j = 0; j < list_length(&interfaces); j++) {
|
||||
struct interface *i = list_at(&interfaces, j);
|
||||
|
||||
if_stop(i);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "nodes/websocket.h"
|
||||
|
||||
/* Private static storage */
|
||||
struct list connections; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */
|
||||
static struct list connections = { .state = STATE_DESTROYED }; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */
|
||||
|
||||
/* Forward declarations */
|
||||
static struct plugin p;
|
||||
|
@ -150,7 +150,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
|
|||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_CLIENT_ESTABLISHED:
|
||||
case LWS_CALLBACK_ESTABLISHED: {
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
c->state = STATE_DESTROYED;
|
||||
|
||||
/* Get path of incoming request */
|
||||
|
@ -185,7 +185,6 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
|
|||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
websocket_connection_destroy(c);
|
||||
|
@ -224,7 +223,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
|
|||
return 0;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_RECEIVE:
|
||||
case LWS_CALLBACK_RECEIVE: {
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
w = c->node->_vd;
|
||||
|
||||
if (c->node->state != STATE_STARTED)
|
||||
|
@ -253,9 +252,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
|
|||
/* Next message */
|
||||
msg = (struct webmsg *) ((char *) msg + WEBMSG_LEN(msg->length));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
|
24
lib/path.c
|
@ -57,7 +57,7 @@ static void path_read(struct path *p)
|
|||
enqueue = hook_read_list(&p->hooks, smps, recv);
|
||||
if (enqueue != recv) {
|
||||
info("Hooks skipped %u out of %u samples for path %s", recv - enqueue, recv, path_name(p));
|
||||
|
||||
|
||||
if (p->stats)
|
||||
stats_update(p->stats->delta, STATS_SKIPPED, recv - enqueue);
|
||||
}
|
||||
|
@ -71,16 +71,15 @@ static void path_read(struct path *p)
|
|||
enqueued = queue_push_many(&pd->queue, (void **) smps, enqueue);
|
||||
if (enqueue != enqueued)
|
||||
warn("Queue overrun for path %s", path_name(p));
|
||||
|
||||
for (int i = 0; i < enqueued; i++) {
|
||||
sample_get(smps[i]); /* increase reference count */
|
||||
refd = i;
|
||||
}
|
||||
|
||||
if (refd < enqueued)
|
||||
refd = enqueued;
|
||||
|
||||
debug(LOG_PATH | 15, "Enqueued %u samples from %s to queue of %s", enqueued, node_name(ps->node), node_name(pd->node));
|
||||
}
|
||||
if (refd != recv-1)
|
||||
sample_free(smps+refd+1, recv-refd-1);
|
||||
|
||||
/* Release those samples which have not been pushed into a queue */
|
||||
sample_free(smps + refd, ready - refd);
|
||||
}
|
||||
|
||||
static void path_write(struct path *p)
|
||||
|
@ -118,11 +117,7 @@ static void path_write(struct path *p)
|
|||
|
||||
debug(LOG_PATH | 15, "Sent %u messages to node %s", sent, node_name(pd->node));
|
||||
|
||||
released = 0;
|
||||
for (int i = 0; i < sent; i++) {
|
||||
if (sample_put(smps[i]) == 0)
|
||||
released++; /* we had the last reference (0 remaining) */
|
||||
}
|
||||
released = sample_put_many(smps, sent);
|
||||
|
||||
debug(LOG_PATH | 15, "Released %d samples back to memory pool", released);
|
||||
}
|
||||
|
@ -347,6 +342,9 @@ int path_start(struct path *p)
|
|||
int path_stop(struct path *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (p->state != STATE_STARTED)
|
||||
return 0;
|
||||
|
||||
info("Stopping path: %s", path_name(p));
|
||||
|
||||
|
|
49
lib/sample.c
|
@ -4,8 +4,11 @@
|
|||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pool.h"
|
||||
#include "sample.h"
|
||||
#include "utils.h"
|
||||
|
||||
int sample_alloc(struct pool *p, struct sample *smps[], int cnt)
|
||||
{
|
||||
|
@ -19,6 +22,7 @@ int sample_alloc(struct pool *p, struct sample *smps[], int cnt)
|
|||
smps[i]->capacity = (p->blocksz - sizeof(**smps)) / sizeof(smps[0]->data[0]);
|
||||
smps[i]->pool_off = (char *) p - (char *) smps[i];
|
||||
smps[i]->format = 0; /* all sample values are float by default */
|
||||
smps[i]->refcnt = ATOMIC_VAR_INIT(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -32,6 +36,26 @@ void sample_free(struct sample *smps[], int cnt)
|
|||
}
|
||||
}
|
||||
|
||||
int sample_put_many(struct sample *smps[], int cnt)
|
||||
{
|
||||
int released = 0;
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (sample_put(smps[i]) == 0)
|
||||
released++;
|
||||
}
|
||||
|
||||
return released;
|
||||
}
|
||||
|
||||
int sample_get_many(struct sample *smps[], int cnt)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++)
|
||||
sample_get(smps[i]);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int sample_get(struct sample *s)
|
||||
{
|
||||
return atomic_fetch_add(&s->refcnt, 1) + 1;
|
||||
|
@ -50,6 +74,31 @@ int sample_put(struct sample *s)
|
|||
return prev - 1;
|
||||
}
|
||||
|
||||
int sample_copy(struct sample *dst, struct sample *src)
|
||||
{
|
||||
dst->length = MIN(src->length, dst->capacity);
|
||||
|
||||
dst->sequence = src->sequence;
|
||||
dst->format = src->format;
|
||||
dst->source = src->source;
|
||||
|
||||
dst->ts.origin = src->ts.origin;
|
||||
dst->ts.received = src->ts.received;
|
||||
dst->ts.sent = src->ts.sent;
|
||||
|
||||
memcpy(&dst->data, &src->data, SAMPLE_DATA_LEN(dst->length));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sample_copy_many(struct sample *dsts[], struct sample *srcs[], int cnt)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++)
|
||||
sample_copy(dsts[i], srcs[i]);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int sample_set_data_format(struct sample *s, int idx, enum sample_data_format fmt)
|
||||
{
|
||||
if (idx >= sizeof(s->format) * 8)
|
||||
|
|
|
@ -332,7 +332,7 @@ int super_node_start(struct super_node *sn)
|
|||
for (size_t i = 0; i < list_length(&sn->nodes); i++) { INDENT
|
||||
struct node *n = list_at(&sn->nodes, i);
|
||||
|
||||
node_type_start(n->_vt, sn->cli.argc, sn->cli.argv, config_root_setting(&sn->cfg));
|
||||
node_type_start(n->_vt, sn);
|
||||
}
|
||||
|
||||
info("Starting nodes");
|
||||
|
@ -365,28 +365,35 @@ int super_node_start(struct super_node *sn)
|
|||
|
||||
int super_node_stop(struct super_node *sn)
|
||||
{
|
||||
if (sn->state != STATE_STARTED)
|
||||
return 0;
|
||||
int ret;
|
||||
|
||||
info("Stopping paths");
|
||||
for (size_t i = 0; i < list_length(&sn->paths); i++) { INDENT
|
||||
struct path *p = list_at(&sn->paths, i);
|
||||
|
||||
path_stop(p);
|
||||
ret = path_stop(p);
|
||||
if (ret)
|
||||
error("Failed to stop path: %s", path_name(p));
|
||||
}
|
||||
|
||||
info("Stopping nodes");
|
||||
for (size_t i = 0; i < list_length(&sn->nodes); i++) { INDENT
|
||||
struct node *n = list_at(&sn->nodes, i);
|
||||
|
||||
node_stop(n);
|
||||
ret = node_stop(n);
|
||||
if (ret)
|
||||
error("Failed to stop node: %s", node_name(n));
|
||||
}
|
||||
|
||||
info("Stopping node types");
|
||||
for (size_t i = 0; i < list_length(&plugins); i++) { INDENT
|
||||
struct plugin *p = list_at(&plugins, i);
|
||||
if (p->type == PLUGIN_TYPE_NODE)
|
||||
node_type_stop(&p->node);
|
||||
|
||||
if (p->type == PLUGIN_TYPE_NODE) {
|
||||
ret = node_type_stop(&p->node);
|
||||
if (ret)
|
||||
error("Failed to stop node-type: %s", plugin_name(p));
|
||||
}
|
||||
}
|
||||
|
||||
web_stop(&sn->web);
|
||||
|
|
36
lib/web.c
|
@ -12,7 +12,7 @@
|
|||
#include "utils.h"
|
||||
#include "log.h"
|
||||
#include "web.h"
|
||||
#include "api.h"
|
||||
#include "api/session.h"
|
||||
|
||||
#include "nodes/websocket.h"
|
||||
|
||||
|
@ -122,6 +122,18 @@ static void logger(int level, const char *msg) {
|
|||
}
|
||||
}
|
||||
|
||||
static void * worker(void *ctx)
|
||||
{
|
||||
struct web *w = ctx;
|
||||
|
||||
assert(w->state == STATE_STARTED);
|
||||
|
||||
for (;;)
|
||||
lws_service(w->context, 100);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int web_init(struct web *w, struct api *a)
|
||||
{
|
||||
lws_set_log_level((1 << LLL_COUNT) - 1, logger);
|
||||
|
@ -154,6 +166,8 @@ int web_parse(struct web *w, config_setting_t *cfg)
|
|||
|
||||
int web_start(struct web *w)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Start server */
|
||||
struct lws_context_creation_info ctx_info = {
|
||||
.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT,
|
||||
|
@ -185,17 +199,28 @@ int web_start(struct web *w)
|
|||
if (w->vhost == NULL)
|
||||
error("WebSocket: failed to initialize server");
|
||||
}
|
||||
|
||||
ret = pthread_create(&w->thread, NULL, worker, w);
|
||||
if (ret)
|
||||
error("Failed to start Web worker");
|
||||
|
||||
w->state = STATE_STARTED;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int web_stop(struct web *w)
|
||||
{
|
||||
info("Stopping Web sub-system");
|
||||
|
||||
if (w->state == STATE_STARTED)
|
||||
lws_cancel_service(w->context);
|
||||
|
||||
/** @todo Wait for all connections to be closed */
|
||||
|
||||
pthread_cancel(w->thread);
|
||||
pthread_join(w->thread, NULL);
|
||||
|
||||
w->state = STATE_STOPPED;
|
||||
|
||||
return 0;
|
||||
|
@ -213,10 +238,3 @@ int web_destroy(struct web *w)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int web_service(struct web *w)
|
||||
{
|
||||
assert(w->state == STATE_STARTED);
|
||||
|
||||
return lws_service(w->context, 10);
|
||||
}
|
||||
|
|
1
lib/web/Makefile.inc
Normal file
|
@ -0,0 +1 @@
|
|||
LIB_SRCS += $(wildcard lib/web/*.c)
|
144
lib/web/buffer.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/** API buffer for sending and receiving data from libwebsockets.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "assert.h"
|
||||
#include "utils.h"
|
||||
#include "web/buffer.h"
|
||||
|
||||
int web_buffer_init(struct web_buffer *b, enum lws_write_protocol prot)
|
||||
{
|
||||
assert(b->state == STATE_DESTROYED);
|
||||
|
||||
b->protocol = prot;
|
||||
b->size = 0;
|
||||
b->len = 0;
|
||||
b->buffer = NULL;
|
||||
b->prefix = b->protocol == LWS_WRITE_TEXT || b->protocol == LWS_WRITE_BINARY ? LWS_PRE : 0;
|
||||
|
||||
b->state = STATE_INITIALIZED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int web_buffer_destroy(struct web_buffer *b)
|
||||
{
|
||||
if (b->state == STATE_DESTROYED)
|
||||
return 0;
|
||||
|
||||
if (b->buffer)
|
||||
free(b->buffer);
|
||||
|
||||
b->state = STATE_DESTROYED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int web_buffer_write(struct web_buffer *b, struct lws *w)
|
||||
{
|
||||
int ret, len, sent = 0;
|
||||
unsigned char *chunk;
|
||||
|
||||
assert(b->state == STATE_INITIALIZED);
|
||||
|
||||
if (b->len <= 0)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
chunk = (unsigned char *) b->buffer + b->prefix + sent;
|
||||
len = strlen(b->buffer + b->prefix);
|
||||
|
||||
ret = lws_write(w, chunk, len, b->protocol);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
sent += ret + 1;
|
||||
} while (sent < b->len);
|
||||
|
||||
web_buffer_read(b, NULL, sent); /* drop sent bytes from the buffer*/
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
int web_buffer_read(struct web_buffer *b, char *out, size_t len)
|
||||
{
|
||||
assert(b->state == STATE_INITIALIZED);
|
||||
|
||||
if (len > b->len)
|
||||
len = b->len;
|
||||
|
||||
if (out)
|
||||
memcpy(out, b->buffer + b->prefix, len);
|
||||
|
||||
memmove(b->buffer + b->prefix, b->buffer + b->prefix + len, b->len - len);
|
||||
b->len -= len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int web_buffer_read_json(struct web_buffer *b, json_t **req)
|
||||
{
|
||||
json_error_t e;
|
||||
|
||||
assert(b->state == STATE_INITIALIZED);
|
||||
|
||||
if (b->len <= 0)
|
||||
return -1;
|
||||
|
||||
*req = json_loadb(b->buffer + b->prefix, b->len, JSON_DISABLE_EOF_CHECK, &e);
|
||||
if (!*req)
|
||||
return -2;
|
||||
|
||||
web_buffer_read(b, NULL, e.position);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int web_buffer_append(struct web_buffer *b, const char *in, size_t len)
|
||||
{
|
||||
assert(b->state == STATE_INITIALIZED);
|
||||
|
||||
/* We append a \0 to split messages */
|
||||
len++;
|
||||
|
||||
if (b->size < b->len + len) {
|
||||
b->buffer = realloc(b->buffer, b->prefix + b->len + len);
|
||||
if (!b->buffer)
|
||||
return -1;
|
||||
|
||||
b->size = b->len + len;
|
||||
}
|
||||
|
||||
memcpy(b->buffer + b->prefix + b->len, in, len);
|
||||
b->len += len;
|
||||
b->buffer[b->len+b->prefix] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int web_buffer_append_json(struct web_buffer *b, json_t *res)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
assert(b->state == STATE_INITIALIZED);
|
||||
|
||||
retry: len = json_dumpb(res, b->buffer + b->prefix + b->len, b->size - b->len, 0) + 1;
|
||||
if (b->size < b->len + len) {
|
||||
b->buffer = realloc(b->buffer, b->prefix + b->len + len);
|
||||
if (!b->buffer)
|
||||
return -1;
|
||||
|
||||
b->size = b->len + len;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
b->len += len;
|
||||
b->buffer[b->len+b->prefix] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
TAROPTS = --exclude-ignore-recursive=.distignore --transform='s|^\.|villas-node-$(VERSION_NUM)|' --show-transformed-names
|
||||
|
||||
TAR_VILLAS = $(BUILDDIR)/packaging/villas-node-$(VERSION_NUM).tar.gz
|
||||
TAR_VILLAS = $(BUILDDIR)/packaging/villas-node-$(VERSION_NUM)-1.$(GIT_BRANCH)_$(subst -,_,$(VARIANT)).$(shell date +%Y%m%d)git$(GIT_REV).tar.gz
|
||||
|
||||
DEPLOY_HOST = root@villas.0l.de
|
||||
DEPLOY_PATH = /var/www/villas
|
||||
|
@ -24,13 +24,13 @@ deploy-rpm:
|
|||
|
||||
# Docker targets
|
||||
run-docker-dev:
|
||||
docker run -it -p 80:80 -p 443:443 -p 1234:1234 --privileged --security-opt seccomp:unconfined -v $(PWD):/villas villas-dev
|
||||
docker run -it -p 80:80 -p 443:443 -p 1234:1234 --privileged --security-opt seccomp:unconfined -v $(PWD):/villas villas-node-dev
|
||||
|
||||
docker-dev:
|
||||
docker build -f Dockerfile.dev -t villas-dev $(SRCDIR)
|
||||
docker build -f Dockerfile.dev -t villas-node-dev $(SRCDIR)
|
||||
|
||||
docker:
|
||||
docker build -f Dockerfile -t villas $(SRCDIR)
|
||||
docker build -f Dockerfile -t villas-node $(SRCDIR)
|
||||
|
||||
clean-packaging:
|
||||
rm -f $(BUILDDIR)/packaging/villas-node-$(VERSION_NUM).tar.gz
|
||||
|
|
|
@ -26,7 +26,7 @@ rpm-libwebsockets: | $(RPMDIR)/RPMS $(BUILDDIR)/thirdparty/libwebsockets/
|
|||
# We patch version number and release fields of the spec file based on the current Git commit
|
||||
$(SPEC_VILLAS): $(SRCDIR)/packaging/rpm/villas-node.spec | $$(dir $$@)
|
||||
sed -e "s/§VERSION§/$(VERSION_NUM)/g" \
|
||||
-e "s/§RELEASE§/1.$(GIT_BRANCH)_$(subst -,_,$(VARIANT)).$$(date +%Y%m%d)git$(GIT_REV)/g" < $^ > $@
|
||||
-e "s/§RELEASE§/1.$(GIT_BRANCH)_$(subst -,_,$(VARIANT)).$(shell date +%Y%m%d)git$(GIT_REV)/g" < $^ > $@
|
||||
|
||||
clean-rpm:
|
||||
rm -rf $(RPMDIR)
|
||||
|
|
|
@ -68,7 +68,7 @@ int main(int argc, char *argv[])
|
|||
memory_init(sn.hugepages);
|
||||
|
||||
/* Initialize VILLASfpga card */
|
||||
ret = fpga_init(argc, argv, config_root_setting(&sn.cfg));
|
||||
ret = fpga_init(&sn);
|
||||
if (ret)
|
||||
error("Failed to initialize FPGA card");
|
||||
|
||||
|
|
|
@ -123,8 +123,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
last = time_now();
|
||||
}
|
||||
|
||||
web_service(&sn.web); /** @todo Maybe we should move this to another thread */
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
28
src/pipe.c
|
@ -44,6 +44,8 @@ pthread_t ptid; /**< Parent thread id */
|
|||
|
||||
static void quit(int signal, siginfo_t *sinfo, void *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (recvv.started) {
|
||||
pthread_cancel(recvv.thread);
|
||||
pthread_join(recvv.thread, NULL);
|
||||
|
@ -55,13 +57,11 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx)
|
|||
pthread_join(sendd.thread, NULL);
|
||||
pool_destroy(&sendd.pool);
|
||||
}
|
||||
|
||||
if (node->_vt->start == websocket_start)
|
||||
web_stop(&sn.web);
|
||||
|
||||
node_stop(node);
|
||||
node_type_stop(node->_vt);
|
||||
|
||||
|
||||
ret = super_node_stop(&sn);
|
||||
if (ret)
|
||||
error("Failed to stop super-node");
|
||||
|
||||
super_node_destroy(&sn);
|
||||
|
||||
info(GRN("Goodbye!"));
|
||||
|
@ -208,7 +208,7 @@ int main(int argc, char *argv[])
|
|||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
log_init(&sn.log, level, LOG_ALL);
|
||||
log_start(&sn.log);
|
||||
|
||||
|
@ -225,14 +225,14 @@ int main(int argc, char *argv[])
|
|||
error("Node '%s' does not exist!", argv[optind+1]);
|
||||
|
||||
if (node->_vt->start == websocket_start) {
|
||||
web_init(&sn.web, NULL); /* API is disabled in villas-pipe */
|
||||
web_start(&sn.web);
|
||||
api_start(&sn.api);
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
node_reverse(node);
|
||||
|
||||
ret = node_type_start(node->_vt, argc, argv, config_root_setting(&sn.cfg));
|
||||
ret = node_type_start(node->_vt, &sn);
|
||||
if (ret)
|
||||
error("Failed to intialize node type: %s", node_name(node));
|
||||
|
||||
|
@ -248,12 +248,8 @@ int main(int argc, char *argv[])
|
|||
pthread_create(&recvv.thread, NULL, recv_loop, NULL);
|
||||
pthread_create(&sendd.thread, NULL, send_loop, NULL);
|
||||
|
||||
for (;;) {
|
||||
if (node->_vt->start == websocket_start)
|
||||
web_service(&sn.web);
|
||||
else
|
||||
sleep(1);
|
||||
}
|
||||
for (;;)
|
||||
sleep(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ int main(int argc, char *argv[])
|
|||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[3]);
|
||||
|
||||
node_type_start(node->_vt, argc-3, argv+3, config_root_setting(&sn.cfg));
|
||||
node_type_start(node->_vt, &sn);
|
||||
node_start(node);
|
||||
|
||||
/* Parse Arguments */
|
||||
|
|
11
thirdparty/Makefile.inc
vendored
|
@ -3,9 +3,18 @@ DEPS_AUTOCONF = libnl libconfig libcurl
|
|||
|
||||
DEPS = $(DEPS_CMAKE) $(DEPS_AUTOCONF)
|
||||
|
||||
ifdef DEBUG
|
||||
CMAKE_OPTS += -DCMAKE_BUILD_TYPE=DEBUG
|
||||
|
||||
AC_CPPFLAGS=-DDEBUG
|
||||
AC_CFLAGS=-g -O0
|
||||
AC_CXXFLAGS=-g -O0
|
||||
endif
|
||||
|
||||
thirdparty:
|
||||
|
||||
# Install & compile autotools based projects
|
||||
$(DEPS_AUTOCONF): CPPFLAGS=$(AC_CPPFLAGS) CFLAGS=$(AC_CFLAGS) CXXFLAGS=$(AC_CXXFLAGS)
|
||||
$(DEPS_AUTOCONF): | $(BUILDDIR)/thirdparty/$$@/
|
||||
autoreconf -fi $(SRCDIR)/thirdparty/$@
|
||||
cd $(BUILDDIR)/thirdparty/$@ && $(SRCDIR)/thirdparty/$@/configure --prefix=$(PREFIX) && make
|
||||
|
@ -35,6 +44,6 @@ libconfig: | libconfig-fix
|
|||
libconfig-fix:
|
||||
rm -f $(SRCDIR)/thirdparty/libconfig/lib/scanner.[hc]
|
||||
|
||||
libwebsockets: CMAKE_OPTS = -DLWS_IPV6=1 -DLWS_WITH_STATIC=0 -DLWS_WITHOUT_TESTAPPS=1 -DLWS_WITH_HTTP2=1
|
||||
libwebsockets: CMAKE_OPTS += -DLWS_IPV6=1 -DLWS_WITH_STATIC=0 -DLWS_WITHOUT_TESTAPPS=1 -DLWS_WITH_HTTP2=1
|
||||
|
||||
.PHONY: $(DEPS) thirdparty clean-thirdparty install-thirdparty
|
54
web/socket/api.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
function Api(v, connected, error)
|
||||
{
|
||||
this.version = v
|
||||
this.ids = new Object();
|
||||
|
||||
var url = wsUrl('v1');
|
||||
var self = this;
|
||||
|
||||
this.connection = new WebSocket(url, 'api');
|
||||
|
||||
this.connection.onopen = function() {
|
||||
console.log('API connected', this.url);
|
||||
connected();
|
||||
};
|
||||
|
||||
this.connection.onerror = function(e) {
|
||||
console.log('API request failed:', e);
|
||||
error(e);
|
||||
};
|
||||
|
||||
this.connection.onmessage = function(e) {
|
||||
var resp = JSON.parse(e.data);
|
||||
var handler;
|
||||
|
||||
console.log('API response received', resp);
|
||||
|
||||
handler = self.ids[resp.id];
|
||||
if (handler !== undefined) {
|
||||
handler(resp.response);
|
||||
|
||||
delete self.ids[resp.id];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Api.prototype.request = function(action, request, handler)
|
||||
{
|
||||
var req = {
|
||||
action : action,
|
||||
request: request,
|
||||
id : guid()
|
||||
};
|
||||
|
||||
this.ids[req.id] = handler;
|
||||
|
||||
console.log('API request sent', req);
|
||||
|
||||
this.connection.send(JSON.stringify(req))
|
||||
}
|
||||
|
||||
Api.prototype.close = function()
|
||||
{
|
||||
this.connection.close();
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
// global variables
|
||||
var api;
|
||||
var connection;
|
||||
var timer;
|
||||
|
||||
var seq = 0;
|
||||
|
||||
var nodes = [];
|
||||
var currentNode;
|
||||
var nodes = [ ];
|
||||
|
||||
var paused = false;
|
||||
var sequence = 0;
|
||||
|
||||
var plotData = [];
|
||||
var plotOptions = {
|
||||
|
@ -17,96 +19,145 @@ var plotOptions = {
|
|||
}
|
||||
};
|
||||
|
||||
var xDelta = 0.5*1000;
|
||||
var xPast = xDelta*0.9;
|
||||
var xFuture = xDelta*0.1;
|
||||
var updateRate = 25;
|
||||
var redrawPlot = true;
|
||||
|
||||
$(document).on('ready', function() {
|
||||
$.getJSON('/nodes.json', function(data) {
|
||||
nodes = data;
|
||||
|
||||
for (var i = 0; i < nodes.length; i++)
|
||||
if (nodes[i].name == getParameterByName("node"))
|
||||
currentNode = nodes[i];
|
||||
|
||||
if (currentNode === undefined)
|
||||
currentNode = nodes[0];
|
||||
|
||||
nodes.forEach(function(node, index) {
|
||||
$(".node-selector").append(
|
||||
$("<li>").append(
|
||||
$("<a>", {
|
||||
text: node.description ? node.description : node.name,
|
||||
title: node.name,
|
||||
href: "?node=" + node.name
|
||||
})
|
||||
).addClass(node.name == currentNode.name ? 'active' : '')
|
||||
);
|
||||
});
|
||||
|
||||
wsConnect(wsUrl(currentNode.name), ["live"]);
|
||||
});
|
||||
var xDelta = 5000;
|
||||
var xPast = xDelta * 0.9;
|
||||
var xFuture = xDelta * 0.1;
|
||||
|
||||
$(document).ready(function() {
|
||||
api = new Api('v1', apiConnected);
|
||||
|
||||
$('#play').click(function(e, ui) {
|
||||
wsConnect(wsUrl(currentNode.name), ["live"]);
|
||||
connection = wsConnect(currentNode);
|
||||
paused = false;
|
||||
});
|
||||
|
||||
$('#pause').click(function(e, ui) {
|
||||
connection.close();
|
||||
});
|
||||
|
||||
$('#slider').slider({
|
||||
min : 0,
|
||||
max : 100,
|
||||
slide : function(e, ui) {
|
||||
var msg = new Msg({
|
||||
timestamp : Date.now(),
|
||||
sequence : seq++
|
||||
}, [ ui.value ]);
|
||||
|
||||
|
||||
var blob = msg.toArrayBuffer()
|
||||
connection.send(blob);
|
||||
}
|
||||
paused = true;
|
||||
});
|
||||
|
||||
$('#timespan').slider({
|
||||
min : 200,
|
||||
min : 1000,
|
||||
max : 10000,
|
||||
value : xDelta,
|
||||
slide : function(e, ui) {
|
||||
plotUpdateWindow(ui.value);
|
||||
updatePlotWindow(ui.value);
|
||||
}
|
||||
});
|
||||
|
||||
$('#controls .buttons button').each(function(button) {
|
||||
$(button).addClass('on');
|
||||
|
||||
$(button).onClick(function(value) {
|
||||
var msg = new Msg({
|
||||
timestamp : Date.now(),
|
||||
sequence : seq++
|
||||
}, [ value ]);
|
||||
|
||||
connection.send(msg.toArrayBuffer());
|
||||
});
|
||||
$('#updaterate').slider({
|
||||
min : 1,
|
||||
max : 50,
|
||||
value : updateRate,
|
||||
slide : function(e, ui) {
|
||||
clearInterval(timer);
|
||||
timer = setInterval(updatePlot, 1000.0 / updateRate);
|
||||
updateRate = ui.value;
|
||||
}
|
||||
});
|
||||
|
||||
$('.inputs #slider').slider({
|
||||
min : 0,
|
||||
max : 100,
|
||||
slide : sendData
|
||||
});
|
||||
|
||||
plotUpdateWindow(10*1000); /* start plot refresh timer for 10sec window */
|
||||
$('.inputs-checkboxes input').checkboxradio()
|
||||
.each(function(idx, elm) {
|
||||
$(elm).change(sendData);
|
||||
});
|
||||
|
||||
timer = setInterval(updatePlot, 1000.0 / updateRate);
|
||||
});
|
||||
|
||||
$(window).on('beforeunload', function() {
|
||||
connection.close();
|
||||
api.close();
|
||||
});
|
||||
|
||||
function plotUpdateWindow(delta) {
|
||||
xDelta = delta
|
||||
xPast = xDelta*0.9;
|
||||
xFuture = xDelta*0.1;
|
||||
function sendData()
|
||||
{
|
||||
var slider = $('.inputs #slider');
|
||||
var checkboxes = $('.inputs-checkboxes input');
|
||||
|
||||
var data = [ $(slider).slider('value'), 0 ];
|
||||
|
||||
for (var i = 0; i < checkboxes.length; i++)
|
||||
data[1] += (checkboxes[i].checked ? 1 : 0) << i;
|
||||
|
||||
var msg = new Msg({
|
||||
timestamp : Date.now(),
|
||||
sequence : sequence++,
|
||||
id : currentNode.id,
|
||||
data : data
|
||||
});
|
||||
|
||||
console.log('Sending message', msg);
|
||||
|
||||
connection.send(msg.toArrayBuffer());
|
||||
}
|
||||
|
||||
function plotUpdate() {
|
||||
function apiConnected()
|
||||
{
|
||||
api.request('nodes', {},
|
||||
function(response) {
|
||||
nodes = response;
|
||||
|
||||
console.log("Found " + nodes.length + " nodes:", nodes);
|
||||
|
||||
for (var i = 0; i < nodes.length; i++)
|
||||
if (nodes[i].name == getParameterByName('node'))
|
||||
currentNode = nodes[i];
|
||||
|
||||
if (currentNode === undefined)
|
||||
currentNode = nodes[0];
|
||||
|
||||
if (currentNode !== undefined) {
|
||||
updateNodeList();
|
||||
|
||||
connection = wsConnect(currentNode);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function updateNodeList()
|
||||
{
|
||||
$('.node-selector').empty();
|
||||
|
||||
nodes.forEach(function(node, index) {
|
||||
if (node.type == 'websocket') {
|
||||
$('.node-selector').append(
|
||||
$('<button>')
|
||||
.addClass(node.name == currentNode.name ? 'ui-state-active' : '')
|
||||
.text(node.description ? node.description : node.name)
|
||||
.click(function() {
|
||||
var url = node.name;
|
||||
window.location = '?node=' + node.name;
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$('.node-selector').buttonset();
|
||||
}
|
||||
|
||||
function updatePlotWindow(delta)
|
||||
{
|
||||
xDelta = delta
|
||||
xPast = xDelta * 0.9;
|
||||
xFuture = xDelta * 0.1;
|
||||
}
|
||||
|
||||
function updatePlot()
|
||||
{
|
||||
var data = [];
|
||||
|
||||
if (!redrawPlot)
|
||||
return;
|
||||
|
||||
// add data to arrays
|
||||
for (var i = 0; i < plotData.length; i++) {
|
||||
|
@ -115,7 +166,7 @@ function plotUpdate() {
|
|||
data[i] = {
|
||||
data : plotData[i],
|
||||
shadowSize : 0,
|
||||
label : "Index " + String(i),
|
||||
label : 'Index ' + String(i),
|
||||
lines : {
|
||||
lineWidth: 2
|
||||
}
|
||||
|
@ -132,46 +183,54 @@ function plotUpdate() {
|
|||
},
|
||||
grid: {
|
||||
markings: [
|
||||
{ xaxis: { from: Date.now(), to: Date.now() }, color: "#ff0000" }
|
||||
{ xaxis: { from: Date.now(), to: Date.now() }, color: '#ff0000' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/* update plot */
|
||||
$.plot('.plot-container div', data, $.extend(true, options, plotOptions));
|
||||
|
||||
redrawPlot = false;
|
||||
}
|
||||
|
||||
function wsConnect(url, protocol) {
|
||||
connection = new WebSocket(url, protocol);
|
||||
connection.binaryType = 'arraybuffer';
|
||||
function wsConnect(node)
|
||||
{
|
||||
var url = wsUrl('');
|
||||
var conn = new WebSocket(url, 'live');
|
||||
|
||||
conn.binaryType = 'arraybuffer';
|
||||
|
||||
connection.onopen = function() {
|
||||
$('#connectionStatus')
|
||||
conn.onopen = function() {
|
||||
$('#status')
|
||||
.text('Connected')
|
||||
.css('color', 'green');
|
||||
|
||||
timer = setInterval(plotUpdate, 1000.0 / 25);
|
||||
console.log('WebSocket connection established');
|
||||
};
|
||||
|
||||
connection.onclose = function() {
|
||||
$('#connectionStatus')
|
||||
.text('Disconnected')
|
||||
conn.onclose = function(error) {
|
||||
console.log('WebSocket connection closed', error);
|
||||
|
||||
$('#status')
|
||||
.text('Disconnected (' + error.reason + ')')
|
||||
.css('color', 'red');
|
||||
|
||||
clearInterval(timer);
|
||||
/* Try connect if close reason was CLOSE_NORMAL */
|
||||
if (error.code == 1000 || error.code == 1001) {
|
||||
setTimeout(function() {
|
||||
wsConnect(currentNode);
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
conn.onerror = function(error) {
|
||||
console.log('WebSocket connection error', error);
|
||||
|
||||
setTimeout(function() {
|
||||
wsConnect(wsUrl(currentNode.name), ["live"]);
|
||||
}, 1000); // retry
|
||||
$('#status').text('Status: Error: ' + error.message);
|
||||
};
|
||||
|
||||
connection.onerror = function(error) {
|
||||
$('#connectionStatus').text(function() {
|
||||
return 'Status: Error: ' + error.message;
|
||||
});
|
||||
};
|
||||
|
||||
connection.onmessage = function(e) {
|
||||
conn.onmessage = function(e) {
|
||||
var msgs = Msg.fromArrayBufferVector(e.data);
|
||||
|
||||
console.log('Received ' + msgs.length + ' messages with ' + msgs[0].data.length + ' values from id ' + msgs[0].id + ' with timestamp ' + msgs[0].timestamp);
|
||||
|
@ -184,6 +243,9 @@ function wsConnect(url, protocol) {
|
|||
|
||||
for (var j = 0; j < msgs.length; j++) {
|
||||
var msg = msgs[j];
|
||||
|
||||
if (msg.id != currentNode.id)
|
||||
continue;
|
||||
|
||||
// add empty arrays for data series
|
||||
while (plotData.length < msg.length)
|
||||
|
@ -193,67 +255,32 @@ function wsConnect(url, protocol) {
|
|||
for (var i = 0; i < msg.length; i++)
|
||||
plotData[i].push([msg.timestamp, msg.data[i]]);
|
||||
}
|
||||
};
|
||||
|
||||
redrawPlot = true;
|
||||
};
|
||||
|
||||
return conn;
|
||||
};
|
||||
|
||||
/* Helpers */
|
||||
function wsUrl(endpoint) {
|
||||
function wsUrl(endpoint)
|
||||
{
|
||||
var l = window.location;
|
||||
var url = "";
|
||||
var url = '';
|
||||
|
||||
if (l.protocol === "https:")
|
||||
url += "wss://";
|
||||
if (l.protocol === 'https:')
|
||||
url += 'wss://';
|
||||
else
|
||||
url += "ws://";
|
||||
url += 'ws://';
|
||||
|
||||
url += l.hostname;
|
||||
|
||||
if ((l.port) && (l.port != 80) && (l.port != 443))
|
||||
url += ":" + l.port;
|
||||
url += ':'+ l.port;
|
||||
|
||||
url += "/" + endpoint;
|
||||
url += '/' + endpoint;
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
function fileStart(e) {
|
||||
var file = e.target.files[0];
|
||||
var reader = new FileReader();
|
||||
|
||||
var start;
|
||||
var msgs = [ ]
|
||||
var position = 0;
|
||||
|
||||
reader.onload = function(e) {
|
||||
var lines = e.target.result.split(/[\r\n]+/g); // tolerate both Windows and Unix linebreaks
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var msg = new Msg();
|
||||
msg.parse(lines[i]);
|
||||
msgs.push(msg);
|
||||
}
|
||||
|
||||
console.log("Read " + msgs.length + " samples from file");
|
||||
|
||||
if (msgs.length > 0) {
|
||||
var offset = Date.now() - msgs[0].ts;
|
||||
var data = [];
|
||||
|
||||
for (var i = 0; i < msgs.length; i++)
|
||||
data.push(msgs[i].ts + offset, msgs[i].data[0]);
|
||||
|
||||
plotData.push(data);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
||||
/* Some helpers */
|
||||
function getParameterByName(name) {
|
||||
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
|
||||
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
|
||||
}
|
||||
|
|
36
web/socket/file.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
function fileStart(e)
|
||||
{
|
||||
var file = e.target.files[0];
|
||||
var reader = new FileReader();
|
||||
|
||||
var start;
|
||||
var msgs = [ ]
|
||||
var position = 0;
|
||||
|
||||
reader.onload = function(e) {
|
||||
var lines = e.target.result.split(/[\r\n]+/g); // tolerate both Windows and Unix linebreaks
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var msg = new Msg();
|
||||
msg.parse(lines[i]);
|
||||
msgs.push(msg);
|
||||
}
|
||||
|
||||
console.log('Read ' + msgs.length + ' samples from file');
|
||||
|
||||
if (msgs.length > 0) {
|
||||
var offset = Date.now() - msgs[0].ts;
|
||||
var data = [];
|
||||
|
||||
for (var i = 0; i < msgs.length; i++)
|
||||
data.push(msgs[i].ts + offset, msgs[i].data[0]);
|
||||
|
||||
plotData.push(data);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
}
|
|
@ -4,15 +4,17 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>VILLASweb Mockup</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<link rel="stylesheet" href="jquery-ui/jquery-ui.theme.css" />
|
||||
<link rel="stylesheet" href="jquery-ui/jquery-ui.structure.css" />
|
||||
<link rel="stylesheet" href="jquery-ui-1.12.1/jquery-ui.theme.css" />
|
||||
<link rel="stylesheet" href="jquery-ui-1.12.1/jquery-ui.structure.css" />
|
||||
|
||||
<script src="jquery/jquery.js"></script>
|
||||
<script src="jquery-ui/jquery-ui.js"></script>
|
||||
<script src="jquery/jquery-3.2.0.js"></script>
|
||||
<script src="jquery-ui-1.12.1/jquery-ui.js"></script>
|
||||
<script src="flot/jquery.flot.js"></script>
|
||||
<script src="flot/jquery.flot.time.js"></script>
|
||||
<script src="msg.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="utils.js"></script>
|
||||
<script src="api.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
|
@ -21,7 +23,7 @@
|
|||
<h1>VILLASweb Mockup</h1>
|
||||
</div>
|
||||
<div id="container">
|
||||
<ul class="node-selector"></ul>
|
||||
<div class="node-selector"></div>
|
||||
|
||||
<div class="plot-container">
|
||||
<div id="placeholder" class="plot-placeholder"></div>
|
||||
|
@ -31,21 +33,21 @@
|
|||
<div class="left">
|
||||
<div class="inputs">
|
||||
<dl>
|
||||
<dt><label>Buttons</label></dt>
|
||||
<dd>
|
||||
<button>1</button>
|
||||
<button>2</button>
|
||||
<button>3</button>
|
||||
<button>4</button>
|
||||
<button>5</button>
|
||||
<dt><label>Switches</label></dt>
|
||||
<dd class="inputs-checkboxes">
|
||||
<label for="checkbox-1">1</label>
|
||||
<input type="checkbox" name="checkbox-1" id="checkbox-1">
|
||||
<label for="checkbox-2">2</label>
|
||||
<input type="checkbox" name="checkbox-2" id="checkbox-2">
|
||||
<label for="checkbox-3">3</label>
|
||||
<input type="checkbox" name="checkbox-3" id="checkbox-3">
|
||||
<label for="checkbox-4">4</label>
|
||||
<input type="checkbox" name="checkbox-4" id="checkbox-4">
|
||||
</dd>
|
||||
|
||||
|
||||
<dt><label for="slider">Slider</label></dt>
|
||||
<dd><div id="slider"></div></dd>
|
||||
|
||||
<dt><label for="text">Text</label></dt>
|
||||
<dd><input type="text" id="text" /></dd>
|
||||
|
||||
|
||||
<dt><label for="file">File</label></dt>
|
||||
<dd><input type="file" onchange="fileStart(event)" /></dd>
|
||||
</dl>
|
||||
|
@ -56,6 +58,9 @@
|
|||
<dl>
|
||||
<dt><label for="timespan">Plot timespan</label></dt>
|
||||
<dd><div id="timespan"></div></dd>
|
||||
|
||||
<dt><label for="updaterate">Plot update rate</label></dt>
|
||||
<dd><div id="updaterate"></div></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
|
@ -65,7 +70,7 @@
|
|||
<dd>
|
||||
<button id="pause">Pause</button>
|
||||
<button id="play">Play</button>
|
||||
<span id="connectionStatus"></span>
|
||||
<span id="status"></span>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
@ -74,13 +79,11 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<p>Copyright 2016: Institute for Automation of Complex Power Systems, </br>EON Energy Research Center, RWTH Aachen University, Germany</p>
|
||||
<p>Authors: <a href="mailto:stvogel@eonerc.rwth-aachen.de">Steffen Vogel</a>, <a href="mailto:mgrigul@eonerc.rwth-aachen.de">Markus Grigul</a></p>
|
||||
</div>
|
||||
<div class="right">
|
||||
<p><a style="font-size: 1.5em" href="/doc/index.html" style="float: right">Documentation</a></p>
|
||||
</div>
|
||||
<p>© 2017 Institute for Automation of Complex Power Systems<br>
|
||||
EON Energy Research Center<br>
|
||||
RWTH Aachen University<br>
|
||||
</p>
|
||||
<p>Authors: <a href="mailto:stvogel@eonerc.rwth-aachen.de">Steffen Vogel</a>, <a href="mailto:mgrigul@eonerc.rwth-aachen.de">Markus Grigul</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
333
web/socket/jquery-ui-1.12.1/AUTHORS.txt
Normal file
|
@ -0,0 +1,333 @@
|
|||
Authors ordered by first contribution
|
||||
A list of current team members is available at http://jqueryui.com/about
|
||||
|
||||
Paul Bakaus <paul.bakaus@gmail.com>
|
||||
Richard Worth <rdworth@gmail.com>
|
||||
Yehuda Katz <wycats@gmail.com>
|
||||
Sean Catchpole <sean@sunsean.com>
|
||||
John Resig <jeresig@gmail.com>
|
||||
Tane Piper <piper.tane@gmail.com>
|
||||
Dmitri Gaskin <dmitrig01@gmail.com>
|
||||
Klaus Hartl <klaus.hartl@gmail.com>
|
||||
Stefan Petre <stefan.petre@gmail.com>
|
||||
Gilles van den Hoven <gilles@webunity.nl>
|
||||
Micheil Bryan Smith <micheil@brandedcode.com>
|
||||
Jörn Zaefferer <joern.zaefferer@gmail.com>
|
||||
Marc Grabanski <m@marcgrabanski.com>
|
||||
Keith Wood <kbwood@iinet.com.au>
|
||||
Brandon Aaron <brandon.aaron@gmail.com>
|
||||
Scott González <scott.gonzalez@gmail.com>
|
||||
Eduardo Lundgren <eduardolundgren@gmail.com>
|
||||
Aaron Eisenberger <aaronchi@gmail.com>
|
||||
Joan Piedra <theneojp@gmail.com>
|
||||
Bruno Basto <b.basto@gmail.com>
|
||||
Remy Sharp <remy@leftlogic.com>
|
||||
Bohdan Ganicky <bohdan.ganicky@gmail.com>
|
||||
David Bolter <david.bolter@gmail.com>
|
||||
Chi Cheng <cloudream@gmail.com>
|
||||
Ca-Phun Ung <pazu2k@gmail.com>
|
||||
Ariel Flesler <aflesler@gmail.com>
|
||||
Maggie Wachs <maggie@filamentgroup.com>
|
||||
Scott Jehl <scottjehl@gmail.com>
|
||||
Todd Parker <todd@filamentgroup.com>
|
||||
Andrew Powell <andrew@shellscape.org>
|
||||
Brant Burnett <btburnett3@gmail.com>
|
||||
Douglas Neiner <doug@dougneiner.com>
|
||||
Paul Irish <paul.irish@gmail.com>
|
||||
Ralph Whitbeck <ralph.whitbeck@gmail.com>
|
||||
Thibault Duplessis <thibault.duplessis@gmail.com>
|
||||
Dominique Vincent <dominique.vincent@toitl.com>
|
||||
Jack Hsu <jack.hsu@gmail.com>
|
||||
Adam Sontag <ajpiano@ajpiano.com>
|
||||
Carl Fürstenberg <carl@excito.com>
|
||||
Kevin Dalman <development@allpro.net>
|
||||
Alberto Fernández Capel <afcapel@gmail.com>
|
||||
Jacek Jędrzejewski (http://jacek.jedrzejewski.name)
|
||||
Ting Kuei <ting@kuei.com>
|
||||
Samuel Cormier-Iijima <sam@chide.it>
|
||||
Jon Palmer <jonspalmer@gmail.com>
|
||||
Ben Hollis <bhollis@amazon.com>
|
||||
Justin MacCarthy <Justin@Rubystars.biz>
|
||||
Eyal Kobrigo <kobrigo@hotmail.com>
|
||||
Tiago Freire <tiago.freire@gmail.com>
|
||||
Diego Tres <diegotres@gmail.com>
|
||||
Holger Rüprich <holger@rueprich.de>
|
||||
Ziling Zhao <zilingzhao@gmail.com>
|
||||
Mike Alsup <malsup@gmail.com>
|
||||
Robson Braga Araujo <robsonbraga@gmail.com>
|
||||
Pierre-Henri Ausseil <ph.ausseil@gmail.com>
|
||||
Christopher McCulloh <cmcculloh@gmail.com>
|
||||
Andrew Newcomb <ext.github@preceptsoftware.co.uk>
|
||||
Lim Chee Aun <cheeaun@gmail.com>
|
||||
Jorge Barreiro <yortx.barry@gmail.com>
|
||||
Daniel Steigerwald <daniel@steigerwald.cz>
|
||||
John Firebaugh <john_firebaugh@bigfix.com>
|
||||
John Enters <github@darkdark.net>
|
||||
Andrey Kapitcyn <ru.m157y@gmail.com>
|
||||
Dmitry Petrov <dpetroff@gmail.com>
|
||||
Eric Hynds <eric@hynds.net>
|
||||
Chairat Sunthornwiphat <pipo@sixhead.com>
|
||||
Josh Varner <josh.varner@gmail.com>
|
||||
Stéphane Raimbault <stephane.raimbault@gmail.com>
|
||||
Jay Merrifield <fracmak@gmail.com>
|
||||
J. Ryan Stinnett <jryans@gmail.com>
|
||||
Peter Heiberg <peter@heiberg.se>
|
||||
Alex Dovenmuehle <adovenmuehle@gmail.com>
|
||||
Jamie Gegerson <git@jamiegegerson.com>
|
||||
Raymond Schwartz <skeetergraphics@gmail.com>
|
||||
Phillip Barnes <philbar@gmail.com>
|
||||
Kyle Wilkinson <kai@wikyd.org>
|
||||
Khaled AlHourani <me@khaledalhourani.com>
|
||||
Marian Rudzynski <mr@impaled.org>
|
||||
Jean-Francois Remy <jeff@melix.org>
|
||||
Doug Blood <dougblood@gmail.com>
|
||||
Filippo Cavallarin <filippo.cavallarin@codseq.it>
|
||||
Heiko Henning <heiko@thehennings.ch>
|
||||
Aliaksandr Rahalevich <saksmlz@gmail.com>
|
||||
Mario Visic <mario@mariovisic.com>
|
||||
Xavi Ramirez <xavi.rmz@gmail.com>
|
||||
Max Schnur <max.schnur@gmail.com>
|
||||
Saji Nediyanchath <saji89@gmail.com>
|
||||
Corey Frang <gnarf37@gmail.com>
|
||||
Aaron Peterson <aaronp123@yahoo.com>
|
||||
Ivan Peters <ivan@ivanpeters.com>
|
||||
Mohamed Cherif Bouchelaghem <cherifbouchelaghem@yahoo.fr>
|
||||
Marcos Sousa <falecomigo@marcossousa.com>
|
||||
Michael DellaNoce <mdellanoce@mailtrust.com>
|
||||
George Marshall <echosx@gmail.com>
|
||||
Tobias Brunner <tobias@strongswan.org>
|
||||
Martin Solli <msolli@gmail.com>
|
||||
David Petersen <public@petersendidit.com>
|
||||
Dan Heberden <danheberden@gmail.com>
|
||||
William Kevin Manire <williamkmanire@gmail.com>
|
||||
Gilmore Davidson <gilmoreorless@gmail.com>
|
||||
Michael Wu <michaelmwu@gmail.com>
|
||||
Adam Parod <mystic414@gmail.com>
|
||||
Guillaume Gautreau <guillaume+github@ghusse.com>
|
||||
Marcel Toele <EleotleCram@gmail.com>
|
||||
Dan Streetman <ddstreet@ieee.org>
|
||||
Matt Hoskins <matt@nipltd.com>
|
||||
Giovanni Giacobbi <giovanni@giacobbi.net>
|
||||
Kyle Florence <kyle.florence@gmail.com>
|
||||
Pavol Hluchý <lopo@losys.sk>
|
||||
Hans Hillen <hans.hillen@gmail.com>
|
||||
Mark Johnson <virgofx@live.com>
|
||||
Trey Hunner <treyhunner@gmail.com>
|
||||
Shane Whittet <whittet@gmail.com>
|
||||
Edward A Faulkner <ef@alum.mit.edu>
|
||||
Adam Baratz <adam@adambaratz.com>
|
||||
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
||||
Eike Send <eike.send@gmail.com>
|
||||
Kris Borchers <kris.borchers@gmail.com>
|
||||
Eddie Monge <eddie@eddiemonge.com>
|
||||
Israel Tsadok <itsadok@gmail.com>
|
||||
Carson McDonald <carson@ioncannon.net>
|
||||
Jason Davies <jason@jasondavies.com>
|
||||
Garrison Locke <gplocke@gmail.com>
|
||||
David Murdoch <david@davidmurdoch.com>
|
||||
Benjamin Scott Boyle <benjamins.boyle@gmail.com>
|
||||
Jesse Baird <jebaird@gmail.com>
|
||||
Jonathan Vingiano <jvingiano@gmail.com>
|
||||
Dylan Just <dev@ephox.com>
|
||||
Hiroshi Tomita <tomykaira@gmail.com>
|
||||
Glenn Goodrich <glenn.goodrich@gmail.com>
|
||||
Tarafder Ashek-E-Elahi <mail.ashek@gmail.com>
|
||||
Ryan Neufeld <ryan@neufeldmail.com>
|
||||
Marc Neuwirth <marc.neuwirth@gmail.com>
|
||||
Philip Graham <philip.robert.graham@gmail.com>
|
||||
Benjamin Sterling <benjamin.sterling@kenzomedia.com>
|
||||
Wesley Walser <waw325@gmail.com>
|
||||
Kouhei Sutou <kou@clear-code.com>
|
||||
Karl Kirch <karlkrch@gmail.com>
|
||||
Chris Kelly <ckdake@ckdake.com>
|
||||
Jason Oster <jay@kodewerx.org>
|
||||
Felix Nagel <info@felixnagel.com>
|
||||
Alexander Polomoshnov <alex.polomoshnov@gmail.com>
|
||||
David Leal <dgleal@gmail.com>
|
||||
Igor Milla <igor.fsp.milla@gmail.com>
|
||||
Dave Methvin <dave.methvin@gmail.com>
|
||||
Florian Gutmann <f.gutmann@chronimo.com>
|
||||
Marwan Al Jubeh <marwan.aljubeh@gmail.com>
|
||||
Milan Broum <midlis@googlemail.com>
|
||||
Sebastian Sauer <info@dynpages.de>
|
||||
Gaëtan Muller <m.gaetan89@gmail.com>
|
||||
Michel Weimerskirch <michel@weimerskirch.net>
|
||||
William Griffiths <william@ycymro.com>
|
||||
Stojce Slavkovski <stojce@gmail.com>
|
||||
David Soms <david.soms@gmail.com>
|
||||
David De Sloovere <david.desloovere@outlook.com>
|
||||
Michael P. Jung <michael.jung@terreon.de>
|
||||
Shannon Pekary <spekary@gmail.com>
|
||||
Dan Wellman <danwellman@hotmail.com>
|
||||
Matthew Edward Hutton <meh@corefiling.co.uk>
|
||||
James Khoury <james@jameskhoury.com>
|
||||
Rob Loach <robloach@gmail.com>
|
||||
Alberto Monteiro <betimbrasil@gmail.com>
|
||||
Alex Rhea <alex.rhea@gmail.com>
|
||||
Krzysztof Rosiński <rozwell69@gmail.com>
|
||||
Ryan Olton <oltonr@gmail.com>
|
||||
Genie <386@mail.com>
|
||||
Rick Waldron <waldron.rick@gmail.com>
|
||||
Ian Simpson <spoonlikesham@gmail.com>
|
||||
Lev Kitsis <spam4lev@gmail.com>
|
||||
TJ VanToll <tj.vantoll@gmail.com>
|
||||
Justin Domnitz <jdomnitz@gmail.com>
|
||||
Douglas Cerna <douglascerna@yahoo.com>
|
||||
Bert ter Heide <bertjh@hotmail.com>
|
||||
Jasvir Nagra <jasvir@gmail.com>
|
||||
Yuriy Khabarov <13real008@gmail.com>
|
||||
Harri Kilpiö <harri.kilpio@gmail.com>
|
||||
Lado Lomidze <lado.lomidze@gmail.com>
|
||||
Amir E. Aharoni <amir.aharoni@mail.huji.ac.il>
|
||||
Simon Sattes <simon.sattes@gmail.com>
|
||||
Jo Liss <joliss42@gmail.com>
|
||||
Guntupalli Karunakar <karunakarg@yahoo.com>
|
||||
Shahyar Ghobadpour <shahyar@gmail.com>
|
||||
Lukasz Lipinski <uzza17@gmail.com>
|
||||
Timo Tijhof <krinklemail@gmail.com>
|
||||
Jason Moon <jmoon@socialcast.com>
|
||||
Martin Frost <martinf55@hotmail.com>
|
||||
Eneko Illarramendi <eneko@illarra.com>
|
||||
EungJun Yi <semtlenori@gmail.com>
|
||||
Courtland Allen <courtlandallen@gmail.com>
|
||||
Viktar Varvanovich <non4eg@gmail.com>
|
||||
Danny Trunk <dtrunk90@gmail.com>
|
||||
Pavel Stetina <pavel.stetina@nangu.tv>
|
||||
Michael Stay <metaweta@gmail.com>
|
||||
Steven Roussey <sroussey@gmail.com>
|
||||
Michael Hollis <hollis21@gmail.com>
|
||||
Lee Rowlands <lee.rowlands@previousnext.com.au>
|
||||
Timmy Willison <timmywillisn@gmail.com>
|
||||
Karl Swedberg <kswedberg@gmail.com>
|
||||
Baoju Yuan <the_guy_1987@hotmail.com>
|
||||
Maciej Mroziński <maciej.k.mrozinski@gmail.com>
|
||||
Luis Dalmolin <luis.nh@gmail.com>
|
||||
Mark Aaron Shirley <maspwr@gmail.com>
|
||||
Martin Hoch <martin@fidion.de>
|
||||
Jiayi Yang <tr870829@gmail.com>
|
||||
Philipp Benjamin Köppchen <xgxtpbk@gws.ms>
|
||||
Sindre Sorhus <sindresorhus@gmail.com>
|
||||
Bernhard Sirlinger <bernhard.sirlinger@tele2.de>
|
||||
Jared A. Scheel <jared@jaredscheel.com>
|
||||
Rafael Xavier de Souza <rxaviers@gmail.com>
|
||||
John Chen <zhang.z.chen@intel.com>
|
||||
Robert Beuligmann <robertbeuligmann@gmail.com>
|
||||
Dale Kocian <dale.kocian@gmail.com>
|
||||
Mike Sherov <mike.sherov@gmail.com>
|
||||
Andrew Couch <andy@couchand.com>
|
||||
Marc-Andre Lafortune <github@marc-andre.ca>
|
||||
Nate Eagle <nate.eagle@teamaol.com>
|
||||
David Souther <davidsouther@gmail.com>
|
||||
Mathias Stenbom <mathias@stenbom.com>
|
||||
Sergey Kartashov <ebishkek@yandex.ru>
|
||||
Avinash R <nashpapa@gmail.com>
|
||||
Ethan Romba <ethanromba@gmail.com>
|
||||
Cory Gackenheimer <cory.gack@gmail.com>
|
||||
Juan Pablo Kaniefsky <jpkaniefsky@gmail.com>
|
||||
Roman Salnikov <bardt.dz@gmail.com>
|
||||
Anika Henke <anika@selfthinker.org>
|
||||
Samuel Bovée <samycookie2000@yahoo.fr>
|
||||
Fabrício Matté <ult_combo@hotmail.com>
|
||||
Viktor Kojouharov <vkojouharov@gmail.com>
|
||||
Pawel Maruszczyk (http://hrabstwo.net)
|
||||
Pavel Selitskas <p.selitskas@gmail.com>
|
||||
Bjørn Johansen <post@bjornjohansen.no>
|
||||
Matthieu Penant <thieum22@hotmail.com>
|
||||
Dominic Barnes <dominic@dbarnes.info>
|
||||
David Sullivan <david.sullivan@gmail.com>
|
||||
Thomas Jaggi <thomas@responsive.ch>
|
||||
Vahid Sohrabloo <vahid4134@gmail.com>
|
||||
Travis Carden <travis.carden@gmail.com>
|
||||
Bruno M. Custódio <bruno@brunomcustodio.com>
|
||||
Nathanael Silverman <nathanael.silverman@gmail.com>
|
||||
Christian Wenz <christian@wenz.org>
|
||||
Steve Urmston <steve@urm.st>
|
||||
Zaven Muradyan <megalivoithos@gmail.com>
|
||||
Woody Gilk <shadowhand@deviantart.com>
|
||||
Zbigniew Motyka <zbigniew.motyka@gmail.com>
|
||||
Suhail Alkowaileet <xsoh.k7@gmail.com>
|
||||
Toshi MARUYAMA <marutosijp2@yahoo.co.jp>
|
||||
David Hansen <hansede@gmail.com>
|
||||
Brian Grinstead <briangrinstead@gmail.com>
|
||||
Christian Klammer <christian314159@gmail.com>
|
||||
Steven Luscher <jquerycla@steveluscher.com>
|
||||
Gan Eng Chin <engchin.gan@gmail.com>
|
||||
Gabriel Schulhof <gabriel.schulhof@intel.com>
|
||||
Alexander Schmitz <arschmitz@gmail.com>
|
||||
Vilhjálmur Skúlason <vis@dmm.is>
|
||||
Siebrand Mazeland <siebrand@kitano.nl>
|
||||
Mohsen Ekhtiari <mohsenekhtiari@yahoo.com>
|
||||
Pere Orga <gotrunks@gmail.com>
|
||||
Jasper de Groot <mail@ugomobi.com>
|
||||
Stephane Deschamps <stephane.deschamps@gmail.com>
|
||||
Jyoti Deka <dekajp@gmail.com>
|
||||
Andrei Picus <office.nightcrawler@gmail.com>
|
||||
Ondrej Novy <novy@ondrej.org>
|
||||
Jacob McCutcheon <jacob.mccutcheon@gmail.com>
|
||||
Monika Piotrowicz <monika.piotrowicz@gmail.com>
|
||||
Imants Horsts <imants.horsts@inbox.lv>
|
||||
Eric Dahl <eric.c.dahl@gmail.com>
|
||||
Dave Stein <dave@behance.com>
|
||||
Dylan Barrell <dylan@barrell.com>
|
||||
Daniel DeGroff <djdegroff@gmail.com>
|
||||
Michael Wiencek <mwtuea@gmail.com>
|
||||
Thomas Meyer <meyertee@gmail.com>
|
||||
Ruslan Yakhyaev <ruslan@ruslan.io>
|
||||
Brian J. Dowling <bjd-dev@simplicity.net>
|
||||
Ben Higgins <ben@extrahop.com>
|
||||
Yermo Lamers <yml@yml.com>
|
||||
Patrick Stapleton <github@gdi2290.com>
|
||||
Trisha Crowley <trisha.crowley@gmail.com>
|
||||
Usman Akeju <akeju00+github@gmail.com>
|
||||
Rodrigo Menezes <rod333@gmail.com>
|
||||
Jacques Perrault <jacques_perrault@us.ibm.com>
|
||||
Frederik Elvhage <frederik.elvhage@googlemail.com>
|
||||
Will Holley <willholley@gmail.com>
|
||||
Uri Gilad <antishok@gmail.com>
|
||||
Richard Gibson <richard.gibson@gmail.com>
|
||||
Simen Bekkhus <sbekkhus91@gmail.com>
|
||||
Chen Eshchar <eshcharc@gmail.com>
|
||||
Bruno Pérel <brunoperel@gmail.com>
|
||||
Mohammed Alshehri <m@dralshehri.com>
|
||||
Lisa Seacat DeLuca <ldeluca@us.ibm.com>
|
||||
Anne-Gaelle Colom <coloma@westminster.ac.uk>
|
||||
Adam Foster <slimfoster@gmail.com>
|
||||
Luke Page <luke.a.page@gmail.com>
|
||||
Daniel Owens <daniel@matchstickmixup.com>
|
||||
Michael Orchard <morchard@scottlogic.co.uk>
|
||||
Marcus Warren <marcus@envoke.com>
|
||||
Nils Heuermann <nils@world-of-scripts.de>
|
||||
Marco Ziech <marco@ziech.net>
|
||||
Patricia Juarez <patrixd@gmail.com>
|
||||
Ben Mosher <me@benmosher.com>
|
||||
Ablay Keldibek <atomio.ak@gmail.com>
|
||||
Thomas Applencourt <thomas.applencourt@irsamc.ups-tlse.fr>
|
||||
Jiabao Wu <jiabao.foss@gmail.com>
|
||||
Eric Lee Carraway <github@ericcarraway.com>
|
||||
Victor Homyakov <vkhomyackov@gmail.com>
|
||||
Myeongjin Lee <aranet100@gmail.com>
|
||||
Liran Sharir <lsharir@gmail.com>
|
||||
Weston Ruter <weston@xwp.co>
|
||||
Mani Mishra <manimishra902@gmail.com>
|
||||
Hannah Methvin <hannahmethvin@gmail.com>
|
||||
Leonardo Balter <leonardo.balter@gmail.com>
|
||||
Benjamin Albert <benjamin_a5@yahoo.com>
|
||||
Michał Gołębiowski <m.goleb@gmail.com>
|
||||
Alyosha Pushak <alyosha.pushak@gmail.com>
|
||||
Fahad Ahmad <fahadahmad41@hotmail.com>
|
||||
Matt Brundage <github@mattbrundage.com>
|
||||
Francesc Baeta <francesc.baeta@gmail.com>
|
||||
Piotr Baran <piotros@wp.pl>
|
||||
Mukul Hase <mukulhase@gmail.com>
|
||||
Konstantin Dinev <kdinev@mail.bw.edu>
|
||||
Rand Scullard <rand@randscullard.com>
|
||||
Dan Strohl <dan@wjcg.net>
|
||||
Maksim Ryzhikov <rv.maksim@gmail.com>
|
||||
Amine HADDAD <haddad@allegorie.tv>
|
||||
Amanpreet Singh <apsdehal@gmail.com>
|
||||
Alexey Balchunas <bleshik@gmail.com>
|
||||
Peter Kehl <peter.kehl@gmail.com>
|
||||
Peter Dave Hello <hsu@peterdavehello.org>
|
||||
Johannes Schäfer <johnschaefer@gmx.de>
|
||||
Ville Skyttä <ville.skytta@iki.fi>
|
||||
Ryan Oriecuia <ryan.oriecuia@visioncritical.com>
|
43
web/socket/jquery-ui-1.12.1/LICENSE.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
Copyright jQuery Foundation and other contributors, https://jquery.org/
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals. For exact contribution history, see the revision history
|
||||
available at https://github.com/jquery/jquery-ui
|
||||
|
||||
The following license applies to all parts of this software except as
|
||||
documented below:
|
||||
|
||||
====
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
====
|
||||
|
||||
Copyright and related rights for sample code are waived via CC0. Sample
|
||||
code is defined as all source code contained within the demos directory.
|
||||
|
||||
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
====
|
||||
|
||||
All files located in the node_modules and external directories are
|
||||
externally maintained libraries used by this software which have their
|
||||
own licenses; we recommend you read them, as their terms may differ from
|
||||
the terms above.
|
BIN
web/socket/jquery-ui-1.12.1/images/ui-icons_444444_256x240.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
web/socket/jquery-ui-1.12.1/images/ui-icons_555555_256x240.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
web/socket/jquery-ui-1.12.1/images/ui-icons_777620_256x240.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
web/socket/jquery-ui-1.12.1/images/ui-icons_777777_256x240.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
web/socket/jquery-ui-1.12.1/images/ui-icons_cc0000_256x240.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
web/socket/jquery-ui-1.12.1/images/ui-icons_ffffff_256x240.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
559
web/socket/jquery-ui-1.12.1/index.html
Normal file
|
@ -0,0 +1,559 @@
|
|||
<!doctype html>
|
||||
<html lang="us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Example Page</title>
|
||||
<link href="jquery-ui.css" rel="stylesheet">
|
||||
<style>
|
||||
body{
|
||||
font-family: "Trebuchet MS", sans-serif;
|
||||
margin: 50px;
|
||||
}
|
||||
.demoHeaders {
|
||||
margin-top: 2em;
|
||||
}
|
||||
#dialog-link {
|
||||
padding: .4em 1em .4em 20px;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
#dialog-link span.ui-icon {
|
||||
margin: 0 5px 0 0;
|
||||
position: absolute;
|
||||
left: .2em;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
#icons {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#icons li {
|
||||
margin: 2px;
|
||||
position: relative;
|
||||
padding: 4px 0;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
#icons span.ui-icon {
|
||||
float: left;
|
||||
margin: 0 4px;
|
||||
}
|
||||
.fakewindowcontain .ui-widget-overlay {
|
||||
position: absolute;
|
||||
}
|
||||
select {
|
||||
width: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Welcome to jQuery UI!</h1>
|
||||
|
||||
<div class="ui-widget">
|
||||
<p>This page demonstrates the widgets and theme you selected in Download Builder. Please make sure you are using them with a compatible jQuery version.</p>
|
||||
</div>
|
||||
|
||||
<h1>YOUR COMPONENTS:</h1>
|
||||
|
||||
|
||||
<!-- Accordion -->
|
||||
<h2 class="demoHeaders">Accordion</h2>
|
||||
<div id="accordion">
|
||||
<h3>First</h3>
|
||||
<div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
|
||||
<h3>Second</h3>
|
||||
<div>Phasellus mattis tincidunt nibh.</div>
|
||||
<h3>Third</h3>
|
||||
<div>Nam dui erat, auctor a, dignissim quis.</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Autocomplete -->
|
||||
<h2 class="demoHeaders">Autocomplete</h2>
|
||||
<div>
|
||||
<input id="autocomplete" title="type "a"">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Button -->
|
||||
<h2 class="demoHeaders">Button</h2>
|
||||
<button id="button">A button element</button>
|
||||
<button id="button-icon">An icon-only button</button>
|
||||
|
||||
|
||||
|
||||
<!-- Checkboxradio -->
|
||||
<h2 class="demoHeaders">Checkboxradio</h2>
|
||||
<form style="margin-top: 1em;">
|
||||
<div id="radioset">
|
||||
<input type="radio" id="radio1" name="radio"><label for="radio1">Choice 1</label>
|
||||
<input type="radio" id="radio2" name="radio" checked="checked"><label for="radio2">Choice 2</label>
|
||||
<input type="radio" id="radio3" name="radio"><label for="radio3">Choice 3</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<!-- Controlgroup -->
|
||||
<h2 class="demoHeaders">Controlgroup</h2>
|
||||
<fieldset>
|
||||
<legend>Rental Car</legend>
|
||||
<div id="controlgroup">
|
||||
<select id="car-type">
|
||||
<option>Compact car</option>
|
||||
<option>Midsize car</option>
|
||||
<option>Full size car</option>
|
||||
<option>SUV</option>
|
||||
<option>Luxury</option>
|
||||
<option>Truck</option>
|
||||
<option>Van</option>
|
||||
</select>
|
||||
<label for="transmission-standard">Standard</label>
|
||||
<input type="radio" name="transmission" id="transmission-standard">
|
||||
<label for="transmission-automatic">Automatic</label>
|
||||
<input type="radio" name="transmission" id="transmission-automatic">
|
||||
<label for="insurance">Insurance</label>
|
||||
<input type="checkbox" name="insurance" id="insurance">
|
||||
<label for="horizontal-spinner" class="ui-controlgroup-label"># of cars</label>
|
||||
<input id="horizontal-spinner" class="ui-spinner-input">
|
||||
<button>Book Now!</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
||||
|
||||
<!-- Tabs -->
|
||||
<h2 class="demoHeaders">Tabs</h2>
|
||||
<div id="tabs">
|
||||
<ul>
|
||||
<li><a href="#tabs-1">First</a></li>
|
||||
<li><a href="#tabs-2">Second</a></li>
|
||||
<li><a href="#tabs-3">Third</a></li>
|
||||
</ul>
|
||||
<div id="tabs-1">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
|
||||
<div id="tabs-2">Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.</div>
|
||||
<div id="tabs-3">Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h2 class="demoHeaders">Dialog</h2>
|
||||
<p>
|
||||
<button id="dialog-link" class="ui-button ui-corner-all ui-widget">
|
||||
<span class="ui-icon ui-icon-newwin"></span>Open Dialog
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<h2 class="demoHeaders">Overlay and Shadow Classes</h2>
|
||||
<div style="position: relative; width: 96%; height: 200px; padding:1% 2%; overflow:hidden;" class="fakewindowcontain">
|
||||
<p>Lorem ipsum dolor sit amet, Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. </p><p>Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. </p><p>Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. </p><p>Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. </p>
|
||||
|
||||
<!-- ui-dialog -->
|
||||
<div class="ui-widget-overlay ui-front"></div>
|
||||
<div style="position: absolute; width: 320px; left: 50px; top: 30px; padding: 1.2em" class="ui-widget ui-front ui-widget-content ui-corner-all ui-widget-shadow">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ui-dialog -->
|
||||
<div id="dialog" title="Dialog Title">
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h2 class="demoHeaders">Framework Icons (content color preview)</h2>
|
||||
<ul id="icons" class="ui-widget ui-helper-clearfix">
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-n"><span class="ui-icon ui-icon-caret-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-ne"><span class="ui-icon ui-icon-caret-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-e"><span class="ui-icon ui-icon-caret-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-se"><span class="ui-icon ui-icon-caret-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-s"><span class="ui-icon ui-icon-caret-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-sw"><span class="ui-icon ui-icon-caret-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-w"><span class="ui-icon ui-icon-caret-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-nw"><span class="ui-icon ui-icon-caret-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-2-n-s"><span class="ui-icon ui-icon-caret-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-2-e-w"><span class="ui-icon ui-icon-caret-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-n"><span class="ui-icon ui-icon-triangle-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-ne"><span class="ui-icon ui-icon-triangle-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-e"><span class="ui-icon ui-icon-triangle-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-se"><span class="ui-icon ui-icon-triangle-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-s"><span class="ui-icon ui-icon-triangle-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-sw"><span class="ui-icon ui-icon-triangle-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-w"><span class="ui-icon ui-icon-triangle-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-nw"><span class="ui-icon ui-icon-triangle-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-n-s"><span class="ui-icon ui-icon-triangle-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-e-w"><span class="ui-icon ui-icon-triangle-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-n"><span class="ui-icon ui-icon-arrow-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-ne"><span class="ui-icon ui-icon-arrow-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-e"><span class="ui-icon ui-icon-arrow-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-se"><span class="ui-icon ui-icon-arrow-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-s"><span class="ui-icon ui-icon-arrow-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-sw"><span class="ui-icon ui-icon-arrow-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-w"><span class="ui-icon ui-icon-arrow-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-nw"><span class="ui-icon ui-icon-arrow-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-n-s"><span class="ui-icon ui-icon-arrow-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-ne-sw"><span class="ui-icon ui-icon-arrow-2-ne-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-e-w"><span class="ui-icon ui-icon-arrow-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-se-nw"><span class="ui-icon ui-icon-arrow-2-se-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-n"><span class="ui-icon ui-icon-arrowstop-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-e"><span class="ui-icon ui-icon-arrowstop-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-s"><span class="ui-icon ui-icon-arrowstop-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-w"><span class="ui-icon ui-icon-arrowstop-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-n"><span class="ui-icon ui-icon-arrowthick-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-ne"><span class="ui-icon ui-icon-arrowthick-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-e"><span class="ui-icon ui-icon-arrowthick-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-se"><span class="ui-icon ui-icon-arrowthick-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-s"><span class="ui-icon ui-icon-arrowthick-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-sw"><span class="ui-icon ui-icon-arrowthick-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-w"><span class="ui-icon ui-icon-arrowthick-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-nw"><span class="ui-icon ui-icon-arrowthick-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-n-s"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-ne-sw"><span class="ui-icon ui-icon-arrowthick-2-ne-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-e-w"><span class="ui-icon ui-icon-arrowthick-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-se-nw"><span class="ui-icon ui-icon-arrowthick-2-se-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-n"><span class="ui-icon ui-icon-arrowthickstop-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-e"><span class="ui-icon ui-icon-arrowthickstop-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-s"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-w"><span class="ui-icon ui-icon-arrowthickstop-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-w"><span class="ui-icon ui-icon-arrowreturnthick-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-n"><span class="ui-icon ui-icon-arrowreturnthick-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-e"><span class="ui-icon ui-icon-arrowreturnthick-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-s"><span class="ui-icon ui-icon-arrowreturnthick-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-w"><span class="ui-icon ui-icon-arrowreturn-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-n"><span class="ui-icon ui-icon-arrowreturn-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-e"><span class="ui-icon ui-icon-arrowreturn-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-s"><span class="ui-icon ui-icon-arrowreturn-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-w"><span class="ui-icon ui-icon-arrowrefresh-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-n"><span class="ui-icon ui-icon-arrowrefresh-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-e"><span class="ui-icon ui-icon-arrowrefresh-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-s"><span class="ui-icon ui-icon-arrowrefresh-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4"><span class="ui-icon ui-icon-arrow-4"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4-diag"><span class="ui-icon ui-icon-arrow-4-diag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-extlink"><span class="ui-icon ui-icon-extlink"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-newwin"><span class="ui-icon ui-icon-newwin"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-refresh"><span class="ui-icon ui-icon-refresh"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-shuffle"><span class="ui-icon ui-icon-shuffle"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-transfer-e-w"><span class="ui-icon ui-icon-transfer-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-transferthick-e-w"><span class="ui-icon ui-icon-transferthick-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-collapsed"><span class="ui-icon ui-icon-folder-collapsed"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-open"><span class="ui-icon ui-icon-folder-open"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-document"><span class="ui-icon ui-icon-document"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-document-b"><span class="ui-icon ui-icon-document-b"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-note"><span class="ui-icon ui-icon-note"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-mail-open"><span class="ui-icon ui-icon-mail-open"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-suitcase"><span class="ui-icon ui-icon-suitcase"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-comment"><span class="ui-icon ui-icon-comment"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-person"><span class="ui-icon ui-icon-person"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-print"><span class="ui-icon ui-icon-print"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-trash"><span class="ui-icon ui-icon-trash"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-locked"><span class="ui-icon ui-icon-locked"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-unlocked"><span class="ui-icon ui-icon-unlocked"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-bookmark"><span class="ui-icon ui-icon-bookmark"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-tag"><span class="ui-icon ui-icon-tag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-home"><span class="ui-icon ui-icon-home"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-flag"><span class="ui-icon ui-icon-flag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-calculator"><span class="ui-icon ui-icon-calculator"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-cart"><span class="ui-icon ui-icon-cart"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pencil"><span class="ui-icon ui-icon-pencil"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-clock"><span class="ui-icon ui-icon-clock"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-disk"><span class="ui-icon ui-icon-disk"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-calendar"><span class="ui-icon ui-icon-calendar"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-zoomin"><span class="ui-icon ui-icon-zoomin"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-zoomout"><span class="ui-icon ui-icon-zoomout"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-search"><span class="ui-icon ui-icon-search"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-wrench"><span class="ui-icon ui-icon-wrench"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-gear"><span class="ui-icon ui-icon-gear"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-heart"><span class="ui-icon ui-icon-heart"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-star"><span class="ui-icon ui-icon-star"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-link"><span class="ui-icon ui-icon-link"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-cancel"><span class="ui-icon ui-icon-cancel"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-plus"><span class="ui-icon ui-icon-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-minus"><span class="ui-icon ui-icon-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-minusthick"><span class="ui-icon ui-icon-minusthick"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-close"><span class="ui-icon ui-icon-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-closethick"><span class="ui-icon ui-icon-closethick"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-key"><span class="ui-icon ui-icon-key"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-lightbulb"><span class="ui-icon ui-icon-lightbulb"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-scissors"><span class="ui-icon ui-icon-scissors"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-clipboard"><span class="ui-icon ui-icon-clipboard"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-copy"><span class="ui-icon ui-icon-copy"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-contact"><span class="ui-icon ui-icon-contact"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-image"><span class="ui-icon ui-icon-image"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-video"><span class="ui-icon ui-icon-video"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-script"><span class="ui-icon ui-icon-script"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-alert"><span class="ui-icon ui-icon-alert"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-info"><span class="ui-icon ui-icon-info"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-notice"><span class="ui-icon ui-icon-notice"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-help"><span class="ui-icon ui-icon-help"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-bullet"><span class="ui-icon ui-icon-bullet"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-radio-off"><span class="ui-icon ui-icon-radio-off"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-radio-on"><span class="ui-icon ui-icon-radio-on"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pin-w"><span class="ui-icon ui-icon-pin-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pin-s"><span class="ui-icon ui-icon-pin-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-play"><span class="ui-icon ui-icon-play"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pause"><span class="ui-icon ui-icon-pause"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-next"><span class="ui-icon ui-icon-seek-next"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-prev"><span class="ui-icon ui-icon-seek-prev"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-end"><span class="ui-icon ui-icon-seek-end"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-first"><span class="ui-icon ui-icon-seek-first"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-stop"><span class="ui-icon ui-icon-stop"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-eject"><span class="ui-icon ui-icon-eject"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-off"><span class="ui-icon ui-icon-volume-off"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-on"><span class="ui-icon ui-icon-volume-on"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-power"><span class="ui-icon ui-icon-power"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-signal-diag"><span class="ui-icon ui-icon-signal-diag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-signal"><span class="ui-icon ui-icon-signal"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-0"><span class="ui-icon ui-icon-battery-0"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-1"><span class="ui-icon ui-icon-battery-1"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-2"><span class="ui-icon ui-icon-battery-2"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-3"><span class="ui-icon ui-icon-battery-3"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-plus"><span class="ui-icon ui-icon-circle-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-minus"><span class="ui-icon ui-icon-circle-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-close"><span class="ui-icon ui-icon-circle-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-e"><span class="ui-icon ui-icon-circle-triangle-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-s"><span class="ui-icon ui-icon-circle-triangle-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-w"><span class="ui-icon ui-icon-circle-triangle-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-n"><span class="ui-icon ui-icon-circle-triangle-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-e"><span class="ui-icon ui-icon-circle-arrow-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-s"><span class="ui-icon ui-icon-circle-arrow-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-w"><span class="ui-icon ui-icon-circle-arrow-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-n"><span class="ui-icon ui-icon-circle-arrow-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomin"><span class="ui-icon ui-icon-circle-zoomin"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomout"><span class="ui-icon ui-icon-circle-zoomout"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-check"><span class="ui-icon ui-icon-circle-check"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-plus"><span class="ui-icon ui-icon-circlesmall-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-minus"><span class="ui-icon ui-icon-circlesmall-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-close"><span class="ui-icon ui-icon-circlesmall-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-plus"><span class="ui-icon ui-icon-squaresmall-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-minus"><span class="ui-icon ui-icon-squaresmall-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-close"><span class="ui-icon ui-icon-squaresmall-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-vertical"><span class="ui-icon ui-icon-grip-dotted-vertical"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-horizontal"><span class="ui-icon ui-icon-grip-dotted-horizontal"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-vertical"><span class="ui-icon ui-icon-grip-solid-vertical"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-horizontal"><span class="ui-icon ui-icon-grip-solid-horizontal"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-gripsmall-diagonal-se"><span class="ui-icon ui-icon-gripsmall-diagonal-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-diagonal-se"><span class="ui-icon ui-icon-grip-diagonal-se"></span></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Slider -->
|
||||
<h2 class="demoHeaders">Slider</h2>
|
||||
<div id="slider"></div>
|
||||
|
||||
|
||||
|
||||
<!-- Datepicker -->
|
||||
<h2 class="demoHeaders">Datepicker</h2>
|
||||
<div id="datepicker"></div>
|
||||
|
||||
|
||||
|
||||
<!-- Progressbar -->
|
||||
<h2 class="demoHeaders">Progressbar</h2>
|
||||
<div id="progressbar"></div>
|
||||
|
||||
|
||||
|
||||
<!-- Progressbar -->
|
||||
<h2 class="demoHeaders">Selectmenu</h2>
|
||||
<select id="selectmenu">
|
||||
<option>Slower</option>
|
||||
<option>Slow</option>
|
||||
<option selected="selected">Medium</option>
|
||||
<option>Fast</option>
|
||||
<option>Faster</option>
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
<!-- Spinner -->
|
||||
<h2 class="demoHeaders">Spinner</h2>
|
||||
<input id="spinner">
|
||||
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
<h2 class="demoHeaders">Menu</h2>
|
||||
<ul style="width:100px;" id="menu">
|
||||
<li><div>Item 1</div></li>
|
||||
<li><div>Item 2</div></li>
|
||||
<li><div>Item 3</div>
|
||||
<ul>
|
||||
<li><div>Item 3-1</div></li>
|
||||
<li><div>Item 3-2</div></li>
|
||||
<li><div>Item 3-3</div></li>
|
||||
<li><div>Item 3-4</div></li>
|
||||
<li><div>Item 3-5</div></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><div>Item 4</div></li>
|
||||
<li><div>Item 5</div></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<!-- Tooltip -->
|
||||
<h2 class="demoHeaders">Tooltip</h2>
|
||||
<p id="tooltip">
|
||||
<a href="#" title="That's what this widget is">Tooltips</a> can be attached to any element. When you hover
|
||||
the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- Highlight / Error -->
|
||||
<h2 class="demoHeaders">Highlight / Error</h2>
|
||||
<div class="ui-widget">
|
||||
<div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;">
|
||||
<p><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
|
||||
<strong>Hey!</strong> Sample ui-state-highlight style.</p>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="ui-widget">
|
||||
<div class="ui-state-error ui-corner-all" style="padding: 0 .7em;">
|
||||
<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>
|
||||
<strong>Alert:</strong> Sample ui-state-error style.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="external/jquery/jquery.js"></script>
|
||||
<script src="jquery-ui.js"></script>
|
||||
<script>
|
||||
|
||||
$( "#accordion" ).accordion();
|
||||
|
||||
|
||||
|
||||
var availableTags = [
|
||||
"ActionScript",
|
||||
"AppleScript",
|
||||
"Asp",
|
||||
"BASIC",
|
||||
"C",
|
||||
"C++",
|
||||
"Clojure",
|
||||
"COBOL",
|
||||
"ColdFusion",
|
||||
"Erlang",
|
||||
"Fortran",
|
||||
"Groovy",
|
||||
"Haskell",
|
||||
"Java",
|
||||
"JavaScript",
|
||||
"Lisp",
|
||||
"Perl",
|
||||
"PHP",
|
||||
"Python",
|
||||
"Ruby",
|
||||
"Scala",
|
||||
"Scheme"
|
||||
];
|
||||
$( "#autocomplete" ).autocomplete({
|
||||
source: availableTags
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#button" ).button();
|
||||
$( "#button-icon" ).button({
|
||||
icon: "ui-icon-gear",
|
||||
showLabel: false
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#radioset" ).buttonset();
|
||||
|
||||
|
||||
|
||||
$( "#controlgroup" ).controlgroup();
|
||||
|
||||
|
||||
|
||||
$( "#tabs" ).tabs();
|
||||
|
||||
|
||||
|
||||
$( "#dialog" ).dialog({
|
||||
autoOpen: false,
|
||||
width: 400,
|
||||
buttons: [
|
||||
{
|
||||
text: "Ok",
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Cancel",
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Link to open the dialog
|
||||
$( "#dialog-link" ).click(function( event ) {
|
||||
$( "#dialog" ).dialog( "open" );
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#datepicker" ).datepicker({
|
||||
inline: true
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#slider" ).slider({
|
||||
range: true,
|
||||
values: [ 17, 67 ]
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#progressbar" ).progressbar({
|
||||
value: 20
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#spinner" ).spinner();
|
||||
|
||||
|
||||
|
||||
$( "#menu" ).menu();
|
||||
|
||||
|
||||
|
||||
$( "#tooltip" ).tooltip();
|
||||
|
||||
|
||||
|
||||
$( "#selectmenu" ).selectmenu();
|
||||
|
||||
|
||||
// Hover states on the static widgets
|
||||
$( "#dialog-link, #icons li" ).hover(
|
||||
function() {
|
||||
$( this ).addClass( "ui-state-hover" );
|
||||
},
|
||||
function() {
|
||||
$( this ).removeClass( "ui-state-hover" );
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,7 @@
|
|||
/*! jQuery UI - v1.11.4 - 2015-10-29
|
||||
/*! jQuery UI - v1.12.1 - 2016-09-14
|
||||
* http://jqueryui.com
|
||||
* Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px
|
||||
* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6
|
||||
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
||||
|
||||
/* Layout helpers
|
||||
|
@ -38,9 +38,6 @@
|
|||
.ui-helper-clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
.ui-helper-clearfix {
|
||||
min-height: 0; /* support: IE7 */
|
||||
}
|
||||
.ui-helper-zfix {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -60,20 +57,27 @@
|
|||
----------------------------------*/
|
||||
.ui-state-disabled {
|
||||
cursor: default !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon {
|
||||
display: block;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-top: -.25em;
|
||||
position: relative;
|
||||
text-indent: -99999px;
|
||||
overflow: hidden;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.ui-widget-icon-block {
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
@ -86,114 +90,14 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable {
|
||||
position: relative;
|
||||
}
|
||||
.ui-resizable-handle {
|
||||
position: absolute;
|
||||
font-size: 0.1px;
|
||||
display: block;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable-disabled .ui-resizable-handle,
|
||||
.ui-resizable-autohide .ui-resizable-handle {
|
||||
display: none;
|
||||
}
|
||||
.ui-resizable-n {
|
||||
cursor: n-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
top: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-resizable-s {
|
||||
cursor: s-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
bottom: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-resizable-e {
|
||||
cursor: e-resize;
|
||||
width: 7px;
|
||||
right: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-w {
|
||||
cursor: w-resize;
|
||||
width: 7px;
|
||||
left: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-se {
|
||||
cursor: se-resize;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
right: 1px;
|
||||
bottom: 1px;
|
||||
}
|
||||
.ui-resizable-sw {
|
||||
cursor: sw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
bottom: -5px;
|
||||
}
|
||||
.ui-resizable-nw {
|
||||
cursor: nw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-resizable-ne {
|
||||
cursor: ne-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-selectable {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-selectable-helper {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
border: 1px dotted black;
|
||||
}
|
||||
.ui-sortable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-accordion .ui-accordion-header {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
margin: 2px 0 0 0;
|
||||
padding: .5em .5em .5em .7em;
|
||||
min-height: 0; /* support: IE7 */
|
||||
font-size: 100%;
|
||||
}
|
||||
.ui-accordion .ui-accordion-icons {
|
||||
padding-left: 2.2em;
|
||||
}
|
||||
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
|
||||
padding-left: 2.2em;
|
||||
}
|
||||
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
|
||||
position: absolute;
|
||||
left: .5em;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.ui-accordion .ui-accordion-content {
|
||||
padding: 1em 2.2em;
|
||||
border-top: 0;
|
||||
|
@ -205,17 +109,78 @@
|
|||
left: 0;
|
||||
cursor: default;
|
||||
}
|
||||
.ui-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
outline: 0;
|
||||
}
|
||||
.ui-menu .ui-menu {
|
||||
position: absolute;
|
||||
}
|
||||
.ui-menu .ui-menu-item {
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
/* support: IE10, see #8844 */
|
||||
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
}
|
||||
.ui-menu .ui-menu-item-wrapper {
|
||||
position: relative;
|
||||
padding: 3px 1em 3px .4em;
|
||||
}
|
||||
.ui-menu .ui-menu-divider {
|
||||
margin: 5px 0;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
.ui-menu .ui-state-focus,
|
||||
.ui-menu .ui-state-active {
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons {
|
||||
position: relative;
|
||||
}
|
||||
.ui-menu-icons .ui-menu-item-wrapper {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: .2em;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
.ui-button {
|
||||
padding: .4em 1em;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
line-height: normal;
|
||||
margin-right: .1em;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
overflow: visible; /* removes extra width in IE */
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
/* Support: IE <= 11 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.ui-button,
|
||||
.ui-button:link,
|
||||
.ui-button:visited,
|
||||
|
@ -223,92 +188,130 @@
|
|||
.ui-button:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* to make room for the icon, a width needs to be set here */
|
||||
.ui-button-icon-only {
|
||||
width: 2.2em;
|
||||
}
|
||||
/* button elements seem to need a little more width */
|
||||
button.ui-button-icon-only {
|
||||
width: 2.4em;
|
||||
}
|
||||
.ui-button-icons-only {
|
||||
width: 3.4em;
|
||||
}
|
||||
button.ui-button-icons-only {
|
||||
width: 3.7em;
|
||||
width: 2em;
|
||||
box-sizing: border-box;
|
||||
text-indent: -9999px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* button text element */
|
||||
.ui-button .ui-button-text {
|
||||
display: block;
|
||||
line-height: normal;
|
||||
}
|
||||
.ui-button-text-only .ui-button-text {
|
||||
padding: .4em 1em;
|
||||
}
|
||||
.ui-button-icon-only .ui-button-text,
|
||||
.ui-button-icons-only .ui-button-text {
|
||||
padding: .4em;
|
||||
text-indent: -9999999px;
|
||||
}
|
||||
.ui-button-text-icon-primary .ui-button-text,
|
||||
.ui-button-text-icons .ui-button-text {
|
||||
padding: .4em 1em .4em 2.1em;
|
||||
}
|
||||
.ui-button-text-icon-secondary .ui-button-text,
|
||||
.ui-button-text-icons .ui-button-text {
|
||||
padding: .4em 2.1em .4em 1em;
|
||||
}
|
||||
.ui-button-text-icons .ui-button-text {
|
||||
padding-left: 2.1em;
|
||||
padding-right: 2.1em;
|
||||
}
|
||||
/* no icon support for input elements, provide padding by default */
|
||||
input.ui-button {
|
||||
padding: .4em 1em;
|
||||
/* no icon support for input elements */
|
||||
input.ui-button.ui-button-icon-only {
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
/* button icon element(s) */
|
||||
.ui-button-icon-only .ui-icon,
|
||||
.ui-button-text-icon-primary .ui-icon,
|
||||
.ui-button-text-icon-secondary .ui-icon,
|
||||
.ui-button-text-icons .ui-icon,
|
||||
.ui-button-icons-only .ui-icon {
|
||||
.ui-button-icon-only .ui-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.ui-button-icon-only .ui-icon {
|
||||
left: 50%;
|
||||
margin-top: -8px;
|
||||
margin-left: -8px;
|
||||
}
|
||||
.ui-button-text-icon-primary .ui-button-icon-primary,
|
||||
.ui-button-text-icons .ui-button-icon-primary,
|
||||
.ui-button-icons-only .ui-button-icon-primary {
|
||||
left: .5em;
|
||||
}
|
||||
.ui-button-text-icon-secondary .ui-button-icon-secondary,
|
||||
.ui-button-text-icons .ui-button-icon-secondary,
|
||||
.ui-button-icons-only .ui-button-icon-secondary {
|
||||
right: .5em;
|
||||
|
||||
.ui-button.ui-icon-notext .ui-icon {
|
||||
padding: 0;
|
||||
width: 2.1em;
|
||||
height: 2.1em;
|
||||
text-indent: -9999px;
|
||||
white-space: nowrap;
|
||||
|
||||
}
|
||||
|
||||
/* button sets */
|
||||
.ui-buttonset {
|
||||
margin-right: 7px;
|
||||
}
|
||||
.ui-buttonset .ui-button {
|
||||
margin-left: 0;
|
||||
margin-right: -.3em;
|
||||
input.ui-button.ui-icon-notext .ui-icon {
|
||||
width: auto;
|
||||
height: auto;
|
||||
text-indent: 0;
|
||||
white-space: normal;
|
||||
padding: .4em 1em;
|
||||
}
|
||||
|
||||
/* workarounds */
|
||||
/* reset extra padding in Firefox, see h5bp.com/l */
|
||||
/* Support: Firefox 5 - 40 */
|
||||
input.ui-button::-moz-focus-inner,
|
||||
button.ui-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ui-controlgroup {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
.ui-controlgroup > .ui-controlgroup-item {
|
||||
float: left;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.ui-controlgroup > .ui-controlgroup-item:focus,
|
||||
.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
|
||||
z-index: 9999;
|
||||
}
|
||||
.ui-controlgroup-vertical > .ui-controlgroup-item {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-item {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.ui-controlgroup .ui-controlgroup-label {
|
||||
padding: .4em 1em;
|
||||
}
|
||||
.ui-controlgroup .ui-controlgroup-label span {
|
||||
font-size: 80%;
|
||||
}
|
||||
.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
|
||||
border-left: none;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
|
||||
border-top: none;
|
||||
}
|
||||
.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
|
||||
border-right: none;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Spinner specific style fixes */
|
||||
.ui-controlgroup-vertical .ui-spinner-input {
|
||||
|
||||
/* Support: IE8 only, Android < 4.4 only */
|
||||
width: 75%;
|
||||
width: calc( 100% - 2.4em );
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
|
||||
border-top-style: solid;
|
||||
}
|
||||
|
||||
.ui-checkboxradio-label .ui-icon-background {
|
||||
box-shadow: inset 1px 1px 1px #ccc;
|
||||
border-radius: .12em;
|
||||
border: none;
|
||||
}
|
||||
.ui-checkboxradio-radio-label .ui-icon-background {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 1em;
|
||||
overflow: visible;
|
||||
border: none;
|
||||
}
|
||||
.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
|
||||
.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
|
||||
background-image: none;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
}
|
||||
.ui-checkboxradio-disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
.ui-datepicker {
|
||||
width: 17em;
|
||||
padding: .2em .2em 0;
|
||||
|
@ -474,8 +477,17 @@ button.ui-button::-moz-focus-inner {
|
|||
border-right-width: 0;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
.ui-dialog {
|
||||
|
||||
/* Icons */
|
||||
.ui-datepicker .ui-icon {
|
||||
display: block;
|
||||
text-indent: -99999px;
|
||||
overflow: hidden;
|
||||
background-repeat: no-repeat;
|
||||
left: .5em;
|
||||
top: .3em;
|
||||
}
|
||||
.ui-dialog {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
@ -524,68 +536,121 @@ button.ui-button::-moz-focus-inner {
|
|||
margin: .5em .4em .5em 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-dialog .ui-resizable-n {
|
||||
height: 2px;
|
||||
top: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-e {
|
||||
width: 2px;
|
||||
right: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-s {
|
||||
height: 2px;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-w {
|
||||
width: 2px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-se,
|
||||
.ui-dialog .ui-resizable-sw,
|
||||
.ui-dialog .ui-resizable-ne,
|
||||
.ui-dialog .ui-resizable-nw {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.ui-dialog .ui-resizable-se {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
right: -5px;
|
||||
bottom: -5px;
|
||||
background-position: 16px 16px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-sw {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-ne {
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-nw {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ui-draggable .ui-dialog-titlebar {
|
||||
cursor: move;
|
||||
}
|
||||
.ui-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
.ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable {
|
||||
position: relative;
|
||||
}
|
||||
.ui-resizable-handle {
|
||||
position: absolute;
|
||||
font-size: 0.1px;
|
||||
display: block;
|
||||
outline: none;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-menu .ui-menu {
|
||||
position: absolute;
|
||||
.ui-resizable-disabled .ui-resizable-handle,
|
||||
.ui-resizable-autohide .ui-resizable-handle {
|
||||
display: none;
|
||||
}
|
||||
.ui-menu .ui-menu-item {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 3px 1em 3px .4em;
|
||||
cursor: pointer;
|
||||
min-height: 0; /* support: IE7 */
|
||||
/* support: IE10, see #8844 */
|
||||
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
.ui-resizable-n {
|
||||
cursor: n-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
top: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-menu .ui-menu-divider {
|
||||
margin: 5px 0;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border-width: 1px 0 0 0;
|
||||
.ui-resizable-s {
|
||||
cursor: s-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
bottom: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-menu .ui-state-focus,
|
||||
.ui-menu .ui-state-active {
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons {
|
||||
position: relative;
|
||||
}
|
||||
.ui-menu-icons .ui-menu-item {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon {
|
||||
position: absolute;
|
||||
.ui-resizable-e {
|
||||
cursor: e-resize;
|
||||
width: 7px;
|
||||
right: -5px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: .2em;
|
||||
margin: auto 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon {
|
||||
left: auto;
|
||||
right: 0;
|
||||
.ui-resizable-w {
|
||||
cursor: w-resize;
|
||||
width: 7px;
|
||||
left: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-se {
|
||||
cursor: se-resize;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
right: 1px;
|
||||
bottom: 1px;
|
||||
}
|
||||
.ui-resizable-sw {
|
||||
cursor: sw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
bottom: -5px;
|
||||
}
|
||||
.ui-resizable-nw {
|
||||
cursor: nw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-resizable-ne {
|
||||
cursor: ne-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-progressbar {
|
||||
height: 2em;
|
||||
|
@ -605,6 +670,15 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-progressbar-indeterminate .ui-progressbar-value {
|
||||
background-image: none;
|
||||
}
|
||||
.ui-selectable {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-selectable-helper {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
border: 1px dotted black;
|
||||
}
|
||||
.ui-selectmenu-menu {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
@ -615,7 +689,6 @@ button.ui-button::-moz-focus-inner {
|
|||
}
|
||||
.ui-selectmenu-menu .ui-menu {
|
||||
overflow: auto;
|
||||
/* Support: IE7 */
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
@ -631,28 +704,20 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-selectmenu-open {
|
||||
display: block;
|
||||
}
|
||||
.ui-selectmenu-button {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-selectmenu-button span.ui-icon {
|
||||
right: 0.5em;
|
||||
left: auto;
|
||||
margin-top: -8px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
.ui-selectmenu-button span.ui-selectmenu-text {
|
||||
text-align: left;
|
||||
padding: 0.4em 2.1em 0.4em 1em;
|
||||
.ui-selectmenu-text {
|
||||
display: block;
|
||||
line-height: 1.4;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.ui-selectmenu-button.ui-button {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
width: 14em;
|
||||
}
|
||||
.ui-selectmenu-icon.ui-icon {
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
}
|
||||
.ui-slider {
|
||||
position: relative;
|
||||
|
@ -719,6 +784,10 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-slider-vertical .ui-slider-range-max {
|
||||
top: 0;
|
||||
}
|
||||
.ui-sortable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-spinner {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
@ -730,14 +799,14 @@ button.ui-button::-moz-focus-inner {
|
|||
border: none;
|
||||
background: none;
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
padding: .222em 0;
|
||||
margin: .2em 0;
|
||||
vertical-align: middle;
|
||||
margin-left: .4em;
|
||||
margin-right: 22px;
|
||||
margin-right: 2em;
|
||||
}
|
||||
.ui-spinner-button {
|
||||
width: 16px;
|
||||
width: 1.6em;
|
||||
height: 50%;
|
||||
font-size: .5em;
|
||||
padding: 0;
|
||||
|
@ -751,16 +820,9 @@ button.ui-button::-moz-focus-inner {
|
|||
}
|
||||
/* more specificity required here to override default borders */
|
||||
.ui-spinner a.ui-spinner-button {
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
border-right: none;
|
||||
}
|
||||
/* vertically center icon */
|
||||
.ui-spinner .ui-icon {
|
||||
position: absolute;
|
||||
margin-top: -8px;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
border-top-style: none;
|
||||
border-bottom-style: none;
|
||||
border-right-style: none;
|
||||
}
|
||||
.ui-spinner-up {
|
||||
top: 0;
|
||||
|
@ -768,12 +830,6 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-spinner-down {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* TR overrides */
|
||||
.ui-spinner .ui-icon-triangle-1-s {
|
||||
/* need to fix icons sprite */
|
||||
background-position: -65px -16px;
|
||||
}
|
||||
.ui-tabs {
|
||||
position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
||||
padding: .2em;
|
||||
|
@ -820,8 +876,6 @@ button.ui-button::-moz-focus-inner {
|
|||
position: absolute;
|
||||
z-index: 9999;
|
||||
max-width: 300px;
|
||||
-webkit-box-shadow: 0 0 5px #aaa;
|
||||
box-shadow: 0 0 5px #aaa;
|
||||
}
|
||||
body .ui-tooltip {
|
||||
border-width: 2px;
|
||||
|
@ -843,6 +897,9 @@ body .ui-tooltip {
|
|||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
.ui-widget.ui-widget-content {
|
||||
border: 1px solid #c5c5c5;
|
||||
}
|
||||
.ui-widget-content {
|
||||
border: 1px solid #dddddd;
|
||||
background: #ffffff;
|
||||
|
@ -865,7 +922,13 @@ body .ui-tooltip {
|
|||
----------------------------------*/
|
||||
.ui-state-default,
|
||||
.ui-widget-content .ui-state-default,
|
||||
.ui-widget-header .ui-state-default {
|
||||
.ui-widget-header .ui-state-default,
|
||||
.ui-button,
|
||||
|
||||
/* We use html here because we need a greater specificity to make sure disabled
|
||||
works properly when clicked or hovered */
|
||||
html .ui-button.ui-state-disabled:hover,
|
||||
html .ui-button.ui-state-disabled:active {
|
||||
border: 1px solid #c5c5c5;
|
||||
background: #f6f6f6;
|
||||
font-weight: normal;
|
||||
|
@ -873,7 +936,11 @@ body .ui-tooltip {
|
|||
}
|
||||
.ui-state-default a,
|
||||
.ui-state-default a:link,
|
||||
.ui-state-default a:visited {
|
||||
.ui-state-default a:visited,
|
||||
a.ui-button,
|
||||
a:link.ui-button,
|
||||
a:visited.ui-button,
|
||||
.ui-button {
|
||||
color: #454545;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -882,7 +949,9 @@ body .ui-tooltip {
|
|||
.ui-widget-header .ui-state-hover,
|
||||
.ui-state-focus,
|
||||
.ui-widget-content .ui-state-focus,
|
||||
.ui-widget-header .ui-state-focus {
|
||||
.ui-widget-header .ui-state-focus,
|
||||
.ui-button:hover,
|
||||
.ui-button:focus {
|
||||
border: 1px solid #cccccc;
|
||||
background: #ededed;
|
||||
font-weight: normal;
|
||||
|
@ -895,18 +964,32 @@ body .ui-tooltip {
|
|||
.ui-state-focus a,
|
||||
.ui-state-focus a:hover,
|
||||
.ui-state-focus a:link,
|
||||
.ui-state-focus a:visited {
|
||||
.ui-state-focus a:visited,
|
||||
a.ui-button:hover,
|
||||
a.ui-button:focus {
|
||||
color: #2b2b2b;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-visual-focus {
|
||||
box-shadow: 0 0 3px 1px rgb(94, 158, 214);
|
||||
}
|
||||
.ui-state-active,
|
||||
.ui-widget-content .ui-state-active,
|
||||
.ui-widget-header .ui-state-active {
|
||||
.ui-widget-header .ui-state-active,
|
||||
a.ui-button:active,
|
||||
.ui-button:active,
|
||||
.ui-button.ui-state-active:hover {
|
||||
border: 1px solid #003eff;
|
||||
background: #007fff;
|
||||
font-weight: normal;
|
||||
color: #ffffff;
|
||||
}
|
||||
.ui-icon-background,
|
||||
.ui-state-active .ui-icon-background {
|
||||
border: #003eff;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.ui-state-active a,
|
||||
.ui-state-active a:link,
|
||||
.ui-state-active a:visited {
|
||||
|
@ -923,6 +1006,10 @@ body .ui-tooltip {
|
|||
background: #fffa90;
|
||||
color: #777620;
|
||||
}
|
||||
.ui-state-checked {
|
||||
border: 1px solid #dad55e;
|
||||
background: #fffa90;
|
||||
}
|
||||
.ui-state-highlight a,
|
||||
.ui-widget-content .ui-state-highlight a,
|
||||
.ui-widget-header .ui-state-highlight a {
|
||||
|
@ -983,41 +1070,45 @@ body .ui-tooltip {
|
|||
.ui-widget-header .ui-icon {
|
||||
background-image: url("images/ui-icons_444444_256x240.png");
|
||||
}
|
||||
.ui-state-default .ui-icon {
|
||||
background-image: url("images/ui-icons_777777_256x240.png");
|
||||
}
|
||||
.ui-state-hover .ui-icon,
|
||||
.ui-state-focus .ui-icon {
|
||||
.ui-state-focus .ui-icon,
|
||||
.ui-button:hover .ui-icon,
|
||||
.ui-button:focus .ui-icon {
|
||||
background-image: url("images/ui-icons_555555_256x240.png");
|
||||
}
|
||||
.ui-state-active .ui-icon {
|
||||
.ui-state-active .ui-icon,
|
||||
.ui-button:active .ui-icon {
|
||||
background-image: url("images/ui-icons_ffffff_256x240.png");
|
||||
}
|
||||
.ui-state-highlight .ui-icon {
|
||||
.ui-state-highlight .ui-icon,
|
||||
.ui-button .ui-state-highlight.ui-icon {
|
||||
background-image: url("images/ui-icons_777620_256x240.png");
|
||||
}
|
||||
.ui-state-error .ui-icon,
|
||||
.ui-state-error-text .ui-icon {
|
||||
background-image: url("images/ui-icons_cc0000_256x240.png");
|
||||
}
|
||||
.ui-button .ui-icon {
|
||||
background-image: url("images/ui-icons_777777_256x240.png");
|
||||
}
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-blank { background-position: 16px 16px; }
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-caret-1-n { background-position: 0 0; }
|
||||
.ui-icon-caret-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-caret-1-e { background-position: -32px 0; }
|
||||
.ui-icon-caret-1-se { background-position: -48px 0; }
|
||||
.ui-icon-caret-1-s { background-position: -65px 0; }
|
||||
.ui-icon-caret-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-caret-1-w { background-position: -96px 0; }
|
||||
.ui-icon-caret-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-caret-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-caret-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -65px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
|
@ -1027,7 +1118,7 @@ body .ui-tooltip {
|
|||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -65px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
|
@ -1039,7 +1130,7 @@ body .ui-tooltip {
|
|||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 1px -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
|
@ -1212,14 +1303,10 @@ body .ui-tooltip {
|
|||
/* Overlays */
|
||||
.ui-widget-overlay {
|
||||
background: #aaaaaa;
|
||||
opacity: .3;
|
||||
filter: Alpha(Opacity=30); /* support: IE8 */
|
||||
opacity: .003;
|
||||
filter: Alpha(Opacity=.3); /* support: IE8 */
|
||||
}
|
||||
.ui-widget-shadow {
|
||||
margin: 0px 0 0 0px;
|
||||
padding: 5px;
|
||||
background: #666666;
|
||||
opacity: .3;
|
||||
filter: Alpha(Opacity=30); /* support: IE8 */
|
||||
border-radius: 8px;
|
||||
-webkit-box-shadow: 0px 0px 5px #666666;
|
||||
box-shadow: 0px 0px 5px #666666;
|
||||
}
|
7
web/socket/jquery-ui-1.12.1/jquery-ui.min.css
vendored
Normal file
13
web/socket/jquery-ui-1.12.1/jquery-ui.min.js
vendored
Normal file
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* jQuery UI CSS Framework 1.11.4
|
||||
* jQuery UI CSS Framework 1.12.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
|
@ -8,7 +8,6 @@
|
|||
*
|
||||
* http://api.jqueryui.com/category/theming/
|
||||
*/
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden {
|
||||
|
@ -43,9 +42,6 @@
|
|||
.ui-helper-clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
.ui-helper-clearfix {
|
||||
min-height: 0; /* support: IE7 */
|
||||
}
|
||||
.ui-helper-zfix {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -65,20 +61,27 @@
|
|||
----------------------------------*/
|
||||
.ui-state-disabled {
|
||||
cursor: default !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon {
|
||||
display: block;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-top: -.25em;
|
||||
position: relative;
|
||||
text-indent: -99999px;
|
||||
overflow: hidden;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.ui-widget-icon-block {
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
@ -91,114 +94,14 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable {
|
||||
position: relative;
|
||||
}
|
||||
.ui-resizable-handle {
|
||||
position: absolute;
|
||||
font-size: 0.1px;
|
||||
display: block;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable-disabled .ui-resizable-handle,
|
||||
.ui-resizable-autohide .ui-resizable-handle {
|
||||
display: none;
|
||||
}
|
||||
.ui-resizable-n {
|
||||
cursor: n-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
top: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-resizable-s {
|
||||
cursor: s-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
bottom: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-resizable-e {
|
||||
cursor: e-resize;
|
||||
width: 7px;
|
||||
right: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-w {
|
||||
cursor: w-resize;
|
||||
width: 7px;
|
||||
left: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-se {
|
||||
cursor: se-resize;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
right: 1px;
|
||||
bottom: 1px;
|
||||
}
|
||||
.ui-resizable-sw {
|
||||
cursor: sw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
bottom: -5px;
|
||||
}
|
||||
.ui-resizable-nw {
|
||||
cursor: nw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-resizable-ne {
|
||||
cursor: ne-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-selectable {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-selectable-helper {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
border: 1px dotted black;
|
||||
}
|
||||
.ui-sortable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-accordion .ui-accordion-header {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
margin: 2px 0 0 0;
|
||||
padding: .5em .5em .5em .7em;
|
||||
min-height: 0; /* support: IE7 */
|
||||
font-size: 100%;
|
||||
}
|
||||
.ui-accordion .ui-accordion-icons {
|
||||
padding-left: 2.2em;
|
||||
}
|
||||
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
|
||||
padding-left: 2.2em;
|
||||
}
|
||||
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
|
||||
position: absolute;
|
||||
left: .5em;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.ui-accordion .ui-accordion-content {
|
||||
padding: 1em 2.2em;
|
||||
border-top: 0;
|
||||
|
@ -210,17 +113,78 @@
|
|||
left: 0;
|
||||
cursor: default;
|
||||
}
|
||||
.ui-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
outline: 0;
|
||||
}
|
||||
.ui-menu .ui-menu {
|
||||
position: absolute;
|
||||
}
|
||||
.ui-menu .ui-menu-item {
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
/* support: IE10, see #8844 */
|
||||
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
}
|
||||
.ui-menu .ui-menu-item-wrapper {
|
||||
position: relative;
|
||||
padding: 3px 1em 3px .4em;
|
||||
}
|
||||
.ui-menu .ui-menu-divider {
|
||||
margin: 5px 0;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
.ui-menu .ui-state-focus,
|
||||
.ui-menu .ui-state-active {
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons {
|
||||
position: relative;
|
||||
}
|
||||
.ui-menu-icons .ui-menu-item-wrapper {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: .2em;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
.ui-button {
|
||||
padding: .4em 1em;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
line-height: normal;
|
||||
margin-right: .1em;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
overflow: visible; /* removes extra width in IE */
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
/* Support: IE <= 11 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.ui-button,
|
||||
.ui-button:link,
|
||||
.ui-button:visited,
|
||||
|
@ -228,92 +192,130 @@
|
|||
.ui-button:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* to make room for the icon, a width needs to be set here */
|
||||
.ui-button-icon-only {
|
||||
width: 2.2em;
|
||||
}
|
||||
/* button elements seem to need a little more width */
|
||||
button.ui-button-icon-only {
|
||||
width: 2.4em;
|
||||
}
|
||||
.ui-button-icons-only {
|
||||
width: 3.4em;
|
||||
}
|
||||
button.ui-button-icons-only {
|
||||
width: 3.7em;
|
||||
width: 2em;
|
||||
box-sizing: border-box;
|
||||
text-indent: -9999px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* button text element */
|
||||
.ui-button .ui-button-text {
|
||||
display: block;
|
||||
line-height: normal;
|
||||
}
|
||||
.ui-button-text-only .ui-button-text {
|
||||
padding: .4em 1em;
|
||||
}
|
||||
.ui-button-icon-only .ui-button-text,
|
||||
.ui-button-icons-only .ui-button-text {
|
||||
padding: .4em;
|
||||
text-indent: -9999999px;
|
||||
}
|
||||
.ui-button-text-icon-primary .ui-button-text,
|
||||
.ui-button-text-icons .ui-button-text {
|
||||
padding: .4em 1em .4em 2.1em;
|
||||
}
|
||||
.ui-button-text-icon-secondary .ui-button-text,
|
||||
.ui-button-text-icons .ui-button-text {
|
||||
padding: .4em 2.1em .4em 1em;
|
||||
}
|
||||
.ui-button-text-icons .ui-button-text {
|
||||
padding-left: 2.1em;
|
||||
padding-right: 2.1em;
|
||||
}
|
||||
/* no icon support for input elements, provide padding by default */
|
||||
input.ui-button {
|
||||
padding: .4em 1em;
|
||||
/* no icon support for input elements */
|
||||
input.ui-button.ui-button-icon-only {
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
/* button icon element(s) */
|
||||
.ui-button-icon-only .ui-icon,
|
||||
.ui-button-text-icon-primary .ui-icon,
|
||||
.ui-button-text-icon-secondary .ui-icon,
|
||||
.ui-button-text-icons .ui-icon,
|
||||
.ui-button-icons-only .ui-icon {
|
||||
.ui-button-icon-only .ui-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.ui-button-icon-only .ui-icon {
|
||||
left: 50%;
|
||||
margin-top: -8px;
|
||||
margin-left: -8px;
|
||||
}
|
||||
.ui-button-text-icon-primary .ui-button-icon-primary,
|
||||
.ui-button-text-icons .ui-button-icon-primary,
|
||||
.ui-button-icons-only .ui-button-icon-primary {
|
||||
left: .5em;
|
||||
}
|
||||
.ui-button-text-icon-secondary .ui-button-icon-secondary,
|
||||
.ui-button-text-icons .ui-button-icon-secondary,
|
||||
.ui-button-icons-only .ui-button-icon-secondary {
|
||||
right: .5em;
|
||||
|
||||
.ui-button.ui-icon-notext .ui-icon {
|
||||
padding: 0;
|
||||
width: 2.1em;
|
||||
height: 2.1em;
|
||||
text-indent: -9999px;
|
||||
white-space: nowrap;
|
||||
|
||||
}
|
||||
|
||||
/* button sets */
|
||||
.ui-buttonset {
|
||||
margin-right: 7px;
|
||||
}
|
||||
.ui-buttonset .ui-button {
|
||||
margin-left: 0;
|
||||
margin-right: -.3em;
|
||||
input.ui-button.ui-icon-notext .ui-icon {
|
||||
width: auto;
|
||||
height: auto;
|
||||
text-indent: 0;
|
||||
white-space: normal;
|
||||
padding: .4em 1em;
|
||||
}
|
||||
|
||||
/* workarounds */
|
||||
/* reset extra padding in Firefox, see h5bp.com/l */
|
||||
/* Support: Firefox 5 - 40 */
|
||||
input.ui-button::-moz-focus-inner,
|
||||
button.ui-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ui-controlgroup {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
.ui-controlgroup > .ui-controlgroup-item {
|
||||
float: left;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.ui-controlgroup > .ui-controlgroup-item:focus,
|
||||
.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
|
||||
z-index: 9999;
|
||||
}
|
||||
.ui-controlgroup-vertical > .ui-controlgroup-item {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-item {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.ui-controlgroup .ui-controlgroup-label {
|
||||
padding: .4em 1em;
|
||||
}
|
||||
.ui-controlgroup .ui-controlgroup-label span {
|
||||
font-size: 80%;
|
||||
}
|
||||
.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
|
||||
border-left: none;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
|
||||
border-top: none;
|
||||
}
|
||||
.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
|
||||
border-right: none;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Spinner specific style fixes */
|
||||
.ui-controlgroup-vertical .ui-spinner-input {
|
||||
|
||||
/* Support: IE8 only, Android < 4.4 only */
|
||||
width: 75%;
|
||||
width: calc( 100% - 2.4em );
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
|
||||
border-top-style: solid;
|
||||
}
|
||||
|
||||
.ui-checkboxradio-label .ui-icon-background {
|
||||
box-shadow: inset 1px 1px 1px #ccc;
|
||||
border-radius: .12em;
|
||||
border: none;
|
||||
}
|
||||
.ui-checkboxradio-radio-label .ui-icon-background {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 1em;
|
||||
overflow: visible;
|
||||
border: none;
|
||||
}
|
||||
.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
|
||||
.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
|
||||
background-image: none;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
}
|
||||
.ui-checkboxradio-disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
.ui-datepicker {
|
||||
width: 17em;
|
||||
padding: .2em .2em 0;
|
||||
|
@ -479,8 +481,17 @@ button.ui-button::-moz-focus-inner {
|
|||
border-right-width: 0;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
.ui-dialog {
|
||||
|
||||
/* Icons */
|
||||
.ui-datepicker .ui-icon {
|
||||
display: block;
|
||||
text-indent: -99999px;
|
||||
overflow: hidden;
|
||||
background-repeat: no-repeat;
|
||||
left: .5em;
|
||||
top: .3em;
|
||||
}
|
||||
.ui-dialog {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
@ -529,68 +540,121 @@ button.ui-button::-moz-focus-inner {
|
|||
margin: .5em .4em .5em 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-dialog .ui-resizable-n {
|
||||
height: 2px;
|
||||
top: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-e {
|
||||
width: 2px;
|
||||
right: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-s {
|
||||
height: 2px;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-w {
|
||||
width: 2px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-se,
|
||||
.ui-dialog .ui-resizable-sw,
|
||||
.ui-dialog .ui-resizable-ne,
|
||||
.ui-dialog .ui-resizable-nw {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.ui-dialog .ui-resizable-se {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
right: -5px;
|
||||
bottom: -5px;
|
||||
background-position: 16px 16px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-sw {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-ne {
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-nw {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ui-draggable .ui-dialog-titlebar {
|
||||
cursor: move;
|
||||
}
|
||||
.ui-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
.ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable {
|
||||
position: relative;
|
||||
}
|
||||
.ui-resizable-handle {
|
||||
position: absolute;
|
||||
font-size: 0.1px;
|
||||
display: block;
|
||||
outline: none;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-menu .ui-menu {
|
||||
position: absolute;
|
||||
.ui-resizable-disabled .ui-resizable-handle,
|
||||
.ui-resizable-autohide .ui-resizable-handle {
|
||||
display: none;
|
||||
}
|
||||
.ui-menu .ui-menu-item {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 3px 1em 3px .4em;
|
||||
cursor: pointer;
|
||||
min-height: 0; /* support: IE7 */
|
||||
/* support: IE10, see #8844 */
|
||||
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
.ui-resizable-n {
|
||||
cursor: n-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
top: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-menu .ui-menu-divider {
|
||||
margin: 5px 0;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border-width: 1px 0 0 0;
|
||||
.ui-resizable-s {
|
||||
cursor: s-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
bottom: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-menu .ui-state-focus,
|
||||
.ui-menu .ui-state-active {
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons {
|
||||
position: relative;
|
||||
}
|
||||
.ui-menu-icons .ui-menu-item {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon {
|
||||
position: absolute;
|
||||
.ui-resizable-e {
|
||||
cursor: e-resize;
|
||||
width: 7px;
|
||||
right: -5px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: .2em;
|
||||
margin: auto 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon {
|
||||
left: auto;
|
||||
right: 0;
|
||||
.ui-resizable-w {
|
||||
cursor: w-resize;
|
||||
width: 7px;
|
||||
left: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-se {
|
||||
cursor: se-resize;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
right: 1px;
|
||||
bottom: 1px;
|
||||
}
|
||||
.ui-resizable-sw {
|
||||
cursor: sw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
bottom: -5px;
|
||||
}
|
||||
.ui-resizable-nw {
|
||||
cursor: nw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-resizable-ne {
|
||||
cursor: ne-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-progressbar {
|
||||
height: 2em;
|
||||
|
@ -610,6 +674,15 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-progressbar-indeterminate .ui-progressbar-value {
|
||||
background-image: none;
|
||||
}
|
||||
.ui-selectable {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-selectable-helper {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
border: 1px dotted black;
|
||||
}
|
||||
.ui-selectmenu-menu {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
@ -620,7 +693,6 @@ button.ui-button::-moz-focus-inner {
|
|||
}
|
||||
.ui-selectmenu-menu .ui-menu {
|
||||
overflow: auto;
|
||||
/* Support: IE7 */
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
@ -636,28 +708,20 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-selectmenu-open {
|
||||
display: block;
|
||||
}
|
||||
.ui-selectmenu-button {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-selectmenu-button span.ui-icon {
|
||||
right: 0.5em;
|
||||
left: auto;
|
||||
margin-top: -8px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
.ui-selectmenu-button span.ui-selectmenu-text {
|
||||
text-align: left;
|
||||
padding: 0.4em 2.1em 0.4em 1em;
|
||||
.ui-selectmenu-text {
|
||||
display: block;
|
||||
line-height: 1.4;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.ui-selectmenu-button.ui-button {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
width: 14em;
|
||||
}
|
||||
.ui-selectmenu-icon.ui-icon {
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
}
|
||||
.ui-slider {
|
||||
position: relative;
|
||||
|
@ -724,6 +788,10 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-slider-vertical .ui-slider-range-max {
|
||||
top: 0;
|
||||
}
|
||||
.ui-sortable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-spinner {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
@ -735,14 +803,14 @@ button.ui-button::-moz-focus-inner {
|
|||
border: none;
|
||||
background: none;
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
padding: .222em 0;
|
||||
margin: .2em 0;
|
||||
vertical-align: middle;
|
||||
margin-left: .4em;
|
||||
margin-right: 22px;
|
||||
margin-right: 2em;
|
||||
}
|
||||
.ui-spinner-button {
|
||||
width: 16px;
|
||||
width: 1.6em;
|
||||
height: 50%;
|
||||
font-size: .5em;
|
||||
padding: 0;
|
||||
|
@ -756,16 +824,9 @@ button.ui-button::-moz-focus-inner {
|
|||
}
|
||||
/* more specificity required here to override default borders */
|
||||
.ui-spinner a.ui-spinner-button {
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
border-right: none;
|
||||
}
|
||||
/* vertically center icon */
|
||||
.ui-spinner .ui-icon {
|
||||
position: absolute;
|
||||
margin-top: -8px;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
border-top-style: none;
|
||||
border-bottom-style: none;
|
||||
border-right-style: none;
|
||||
}
|
||||
.ui-spinner-up {
|
||||
top: 0;
|
||||
|
@ -773,12 +834,6 @@ button.ui-button::-moz-focus-inner {
|
|||
.ui-spinner-down {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* TR overrides */
|
||||
.ui-spinner .ui-icon-triangle-1-s {
|
||||
/* need to fix icons sprite */
|
||||
background-position: -65px -16px;
|
||||
}
|
||||
.ui-tabs {
|
||||
position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
||||
padding: .2em;
|
||||
|
@ -825,8 +880,6 @@ button.ui-button::-moz-focus-inner {
|
|||
position: absolute;
|
||||
z-index: 9999;
|
||||
max-width: 300px;
|
||||
-webkit-box-shadow: 0 0 5px #aaa;
|
||||
box-shadow: 0 0 5px #aaa;
|
||||
}
|
||||
body .ui-tooltip {
|
||||
border-width: 2px;
|
5
web/socket/jquery-ui-1.12.1/jquery-ui.structure.min.css
vendored
Normal file
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* jQuery UI CSS Framework 1.11.4
|
||||
* jQuery UI CSS Framework 1.12.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* http://api.jqueryui.com/category/theming/
|
||||
*
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6
|
||||
*/
|
||||
|
||||
|
||||
|
@ -28,6 +28,9 @@
|
|||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
.ui-widget.ui-widget-content {
|
||||
border: 1px solid #c5c5c5;
|
||||
}
|
||||
.ui-widget-content {
|
||||
border: 1px solid #dddddd;
|
||||
background: #ffffff;
|
||||
|
@ -50,7 +53,13 @@
|
|||
----------------------------------*/
|
||||
.ui-state-default,
|
||||
.ui-widget-content .ui-state-default,
|
||||
.ui-widget-header .ui-state-default {
|
||||
.ui-widget-header .ui-state-default,
|
||||
.ui-button,
|
||||
|
||||
/* We use html here because we need a greater specificity to make sure disabled
|
||||
works properly when clicked or hovered */
|
||||
html .ui-button.ui-state-disabled:hover,
|
||||
html .ui-button.ui-state-disabled:active {
|
||||
border: 1px solid #c5c5c5;
|
||||
background: #f6f6f6;
|
||||
font-weight: normal;
|
||||
|
@ -58,7 +67,11 @@
|
|||
}
|
||||
.ui-state-default a,
|
||||
.ui-state-default a:link,
|
||||
.ui-state-default a:visited {
|
||||
.ui-state-default a:visited,
|
||||
a.ui-button,
|
||||
a:link.ui-button,
|
||||
a:visited.ui-button,
|
||||
.ui-button {
|
||||
color: #454545;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -67,7 +80,9 @@
|
|||
.ui-widget-header .ui-state-hover,
|
||||
.ui-state-focus,
|
||||
.ui-widget-content .ui-state-focus,
|
||||
.ui-widget-header .ui-state-focus {
|
||||
.ui-widget-header .ui-state-focus,
|
||||
.ui-button:hover,
|
||||
.ui-button:focus {
|
||||
border: 1px solid #cccccc;
|
||||
background: #ededed;
|
||||
font-weight: normal;
|
||||
|
@ -80,18 +95,32 @@
|
|||
.ui-state-focus a,
|
||||
.ui-state-focus a:hover,
|
||||
.ui-state-focus a:link,
|
||||
.ui-state-focus a:visited {
|
||||
.ui-state-focus a:visited,
|
||||
a.ui-button:hover,
|
||||
a.ui-button:focus {
|
||||
color: #2b2b2b;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-visual-focus {
|
||||
box-shadow: 0 0 3px 1px rgb(94, 158, 214);
|
||||
}
|
||||
.ui-state-active,
|
||||
.ui-widget-content .ui-state-active,
|
||||
.ui-widget-header .ui-state-active {
|
||||
.ui-widget-header .ui-state-active,
|
||||
a.ui-button:active,
|
||||
.ui-button:active,
|
||||
.ui-button.ui-state-active:hover {
|
||||
border: 1px solid #003eff;
|
||||
background: #007fff;
|
||||
font-weight: normal;
|
||||
color: #ffffff;
|
||||
}
|
||||
.ui-icon-background,
|
||||
.ui-state-active .ui-icon-background {
|
||||
border: #003eff;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.ui-state-active a,
|
||||
.ui-state-active a:link,
|
||||
.ui-state-active a:visited {
|
||||
|
@ -108,6 +137,10 @@
|
|||
background: #fffa90;
|
||||
color: #777620;
|
||||
}
|
||||
.ui-state-checked {
|
||||
border: 1px solid #dad55e;
|
||||
background: #fffa90;
|
||||
}
|
||||
.ui-state-highlight a,
|
||||
.ui-widget-content .ui-state-highlight a,
|
||||
.ui-widget-header .ui-state-highlight a {
|
||||
|
@ -168,41 +201,45 @@
|
|||
.ui-widget-header .ui-icon {
|
||||
background-image: url("images/ui-icons_444444_256x240.png");
|
||||
}
|
||||
.ui-state-default .ui-icon {
|
||||
background-image: url("images/ui-icons_777777_256x240.png");
|
||||
}
|
||||
.ui-state-hover .ui-icon,
|
||||
.ui-state-focus .ui-icon {
|
||||
.ui-state-focus .ui-icon,
|
||||
.ui-button:hover .ui-icon,
|
||||
.ui-button:focus .ui-icon {
|
||||
background-image: url("images/ui-icons_555555_256x240.png");
|
||||
}
|
||||
.ui-state-active .ui-icon {
|
||||
.ui-state-active .ui-icon,
|
||||
.ui-button:active .ui-icon {
|
||||
background-image: url("images/ui-icons_ffffff_256x240.png");
|
||||
}
|
||||
.ui-state-highlight .ui-icon {
|
||||
.ui-state-highlight .ui-icon,
|
||||
.ui-button .ui-state-highlight.ui-icon {
|
||||
background-image: url("images/ui-icons_777620_256x240.png");
|
||||
}
|
||||
.ui-state-error .ui-icon,
|
||||
.ui-state-error-text .ui-icon {
|
||||
background-image: url("images/ui-icons_cc0000_256x240.png");
|
||||
}
|
||||
.ui-button .ui-icon {
|
||||
background-image: url("images/ui-icons_777777_256x240.png");
|
||||
}
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-blank { background-position: 16px 16px; }
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-caret-1-n { background-position: 0 0; }
|
||||
.ui-icon-caret-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-caret-1-e { background-position: -32px 0; }
|
||||
.ui-icon-caret-1-se { background-position: -48px 0; }
|
||||
.ui-icon-caret-1-s { background-position: -65px 0; }
|
||||
.ui-icon-caret-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-caret-1-w { background-position: -96px 0; }
|
||||
.ui-icon-caret-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-caret-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-caret-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -65px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
|
@ -212,7 +249,7 @@
|
|||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -65px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
|
@ -224,7 +261,7 @@
|
|||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 1px -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
|
@ -397,14 +434,10 @@
|
|||
/* Overlays */
|
||||
.ui-widget-overlay {
|
||||
background: #aaaaaa;
|
||||
opacity: .3;
|
||||
filter: Alpha(Opacity=30); /* support: IE8 */
|
||||
opacity: .003;
|
||||
filter: Alpha(Opacity=.3); /* support: IE8 */
|
||||
}
|
||||
.ui-widget-shadow {
|
||||
margin: 0px 0 0 0px;
|
||||
padding: 5px;
|
||||
background: #666666;
|
||||
opacity: .3;
|
||||
filter: Alpha(Opacity=30); /* support: IE8 */
|
||||
border-radius: 8px;
|
||||
-webkit-box-shadow: 0px 0px 5px #666666;
|
||||
box-shadow: 0px 0px 5px #666666;
|
||||
}
|
5
web/socket/jquery-ui-1.12.1/jquery-ui.theme.min.css
vendored
Normal file
74
web/socket/jquery-ui-1.12.1/package.json
Normal file
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"name": "jquery-ui",
|
||||
"title": "jQuery UI",
|
||||
"description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.",
|
||||
"version": "1.12.1",
|
||||
"homepage": "http://jqueryui.com",
|
||||
"author": {
|
||||
"name": "jQuery Foundation and other contributors",
|
||||
"url": "https://github.com/jquery/jquery-ui/blob/1.12.1/AUTHORS.txt"
|
||||
},
|
||||
"main": "ui/widget.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Scott González",
|
||||
"email": "scott.gonzalez@gmail.com",
|
||||
"url": "http://scottgonzalez.com"
|
||||
},
|
||||
{
|
||||
"name": "Jörn Zaefferer",
|
||||
"email": "joern.zaefferer@gmail.com",
|
||||
"url": "http://bassistance.de"
|
||||
},
|
||||
{
|
||||
"name": "Mike Sherov",
|
||||
"email": "mike.sherov@gmail.com",
|
||||
"url": "http://mike.sherov.com"
|
||||
},
|
||||
{
|
||||
"name": "TJ VanToll",
|
||||
"email": "tj.vantoll@gmail.com",
|
||||
"url": "http://tjvantoll.com"
|
||||
},
|
||||
{
|
||||
"name": "Felix Nagel",
|
||||
"email": "info@felixnagel.com",
|
||||
"url": "http://www.felixnagel.com"
|
||||
},
|
||||
{
|
||||
"name": "Alex Schmitz",
|
||||
"email": "arschmitz@gmail.com",
|
||||
"url": "https://github.com/arschmitz"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jquery/jquery-ui.git"
|
||||
},
|
||||
"bugs": "https://bugs.jqueryui.com/",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "grunt"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"commitplease": "2.3.0",
|
||||
"grunt": "0.4.5",
|
||||
"grunt-bowercopy": "1.2.4",
|
||||
"grunt-cli": "0.1.13",
|
||||
"grunt-compare-size": "0.4.0",
|
||||
"grunt-contrib-concat": "0.5.1",
|
||||
"grunt-contrib-csslint": "0.5.0",
|
||||
"grunt-contrib-jshint": "0.12.0",
|
||||
"grunt-contrib-qunit": "1.0.1",
|
||||
"grunt-contrib-requirejs": "0.4.4",
|
||||
"grunt-contrib-uglify": "0.11.1",
|
||||
"grunt-git-authors": "3.1.0",
|
||||
"grunt-html": "6.0.0",
|
||||
"grunt-jscs": "2.1.0",
|
||||
"load-grunt-tasks": "3.4.0",
|
||||
"rimraf": "2.5.1",
|
||||
"testswarm": "1.1.0"
|
||||
},
|
||||
"keywords": []
|
||||
}
|
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 4.4 KiB |