diff --git a/.classpath b/.classpath
new file mode 100644
index 00000000..e01fe513
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index b5e6a76d..00000000
--- a/.gitattributes
+++ /dev/null
@@ -1,5 +0,0 @@
-# Github language stats file
-external/* linguist-vendored
-lib/* linguist-vendored
-*.css linguist-vendored
-*.js linguist-vendored
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
index cc2fb2a5..d3a916cb
--- a/.gitignore
+++ b/.gitignore
@@ -1,14 +1,5 @@
-# Configuration and dependencies
+/screenlog.0
/hal.conf
/hal.db*
-/lib/zutil-*
-/recordings/
-
-# Runtime files
-/screenlog.0*
-/OZW_Log.txt
-
-# Build and Ide files
-build
-.gradle
-.idea
\ No newline at end of file
+/build/
+/lib/Zutil.jar
diff --git a/.project b/.project
new file mode 100644
index 00000000..2656b0ff
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+
+
+ hal
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/Hal.iml b/Hal.iml
new file mode 100755
index 00000000..75f455bc
--- /dev/null
+++ b/Hal.iml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
deleted file mode 100644
index c82929e5..00000000
--- a/Jenkinsfile
+++ /dev/null
@@ -1,35 +0,0 @@
-// Jenkinsfile (Pipeline Script)
-node {
- // Configure environment
- env.JAVA_HOME = tool name: 'jdk-11'
- env.REPO_URL = "repo.koc.se/hal.git" //scm.getUserRemoteConfigs()[0].getUrl()
- env.BUILD_NAME = "BUILD-${env.BUILD_ID}"
-
-
- checkout scm
-
- stage('Build') {
- sh './gradlew clean'
- sh './gradlew build'
- }
-
- stage('Test') {
- try {
- sh './gradlew test'
- } finally {
- junit testResults: '**/build/test-results/test/*.xml'
- }
- }
-
- stage('Package') {
- sh './gradlew distZip'
- archiveArtifacts artifacts: 'build/distributions/Hal.zip', fingerprint: true
-
- // Tag artifact
- withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'f8e5f6c6-4adb-4ab2-bb5d-1c8535dff491',
- usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
- sh "git tag ${env.BUILD_NAME}"
- sh "git push 'https://${USERNAME}:${PASSWORD}@${env.REPO_URL}' ${env.BUILD_NAME}"
- }
- }
-}
diff --git a/LICENSE.txt b/LICENSE.txt
old mode 100644
new mode 100755
index 1db896c5..1ee44236
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2016-2025 Daniel Collin, Ziver Koc
+Copyright (c) 2016 Daniel Collin, Ziver Koc
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
deleted file mode 100644
index 5a054d6b..00000000
--- a/README.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Hal
-
-Hal is a home automation hub with sensor statistics with the functionality to
-share that data between friends. It has been developed to be very extensible so future
-Sensors and other input devices can be supported.
-
-Features:
-- **Map**, Set up a house map with sensors and events mapped on a floorplan
-- **Triggers and Actions**, IFTTT type functionality
-- **Power;Challenge**, Sync power or sensor usage between friends to challenge each other to lower the power usage
-- **[Google Assistant Integration](plugins/hal-assistant-google/READNME.md)**
-
-Currently supported devices:
-- **Network Scanner**, IP scanner to detect devices on local network
-- **NUT**, Linux UPS daemon
-- **Tellstick**, Supported devices:
- - NexaSelfLearning
- - Oregon0x1A2D
-- **Raspberry Pi**, GPIO connected sensors
-- **[Zigbee](plugins/hal-zigbee/README.md)**
- - Temperature Sensors
- - Humidity Sensors
- - Pressure Sensors
- - OnnOff Devices
-- **Google Assistant**
-- **MQTT Devices**
-
-Under development (Not ready to be used yet)
-- **Z-Wave**
-
-
-The project is currently in alpha state, and as such things will change and break continuously.
-
-### Screenshots
-
-
-
-
-
-
-
-
-## Installing
-
-To run the Hal server you first need to clone the git repository and then run the
-gradle command to build and run the server:
-
-```
-./gradlew run
-```
-
-Check `hal.conf.example` for available configuration options.
-By default, HAL server will be listening to http://localhost:8080.
-
-## Running the tests
-
-The current test coverage is greatly lacking, but to run the available JUnit
-test-cases run:
-
-```
-./gradlew test
-```
-
-## Architecture
-
-```
- HalAbstractControlerManager
- |
- | HalAbstractController
- | |
- | | HalAbstractDevice
- | | |
- .-----------. .------------. .--------.
- | | | | | |
- | | | | ----> | Device |
- | | | | | |
- | | ----> | Controller | '--------'
- | | | | .--------.
- | | | | | |
- | Manager | | | ----> | Device |
- | | | | | |
- | | '------------' '--------'
- | | .------------. .--------.
- | | | | | |
- | | ----> | Controller | ----> | Device |
- | | | | | |
- '-----------' '------------' '--------'
-
-```
-
-## Authors
-
-* **Daniel Collin**
-* **Ziver Koc**
-
-
-## License
-
-This project is licensed under the MIT License - see the
-[LICENSE.txt](LICENSE.txt) file for details
-
-## Acknowledgments
-
-* Tellstick, for open-sourcing their code
diff --git a/arduino/ArduinoTellstickDuo/archtech.cpp b/arduino/ArduinoTellstickDuo/archtech.cpp
index 491ce88d..74662a3b 100644
--- a/arduino/ArduinoTellstickDuo/archtech.cpp
+++ b/arduino/ArduinoTellstickDuo/archtech.cpp
@@ -59,28 +59,28 @@ bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP) { //start
uint64_t data = 0;
bool dimValuePresent;
uint8_t b1,b2,b3,b4;
-
+
//parse preamp
b1 = *bufStartP;
stepBufferPointer(&bufStartP);
b2 = *bufStartP;
stepBufferPointer(&bufStartP);
- if (!IS_PREAMP(b1, b2)){
+ if(!IS_PREAMP(b1, b2)){
return false;
}
//parse data
-
+
uint16_t dataBitsInBuffer = (calculateBufferPointerDistance(bufStartP, bufEndP)-2) / 4; //each bit is representd by 4 high/low
if (dataBitsInBuffer == 32) {
dimValuePresent = false;
- } else if (dataBitsInBuffer == 36){
+ }else if(dataBitsInBuffer == 36){
dimValuePresent = true;
} else {
return false;
}
-
+
for (uint8_t i = 0; i < dataBitsInBuffer; ++i) {
b1 = *bufStartP; //no of high
stepBufferPointer(&bufStartP);
@@ -103,7 +103,7 @@ bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP) { //start
}
//data parsed - send event over serial
-
+
Serial.print(F("+Wclass:command;protocol:arctech;model:selflearning;data:0x"));
uint8_t hexToSend = (dimValuePresent ? 9 : 8);
for (int8_t i = hexToSend - 1; i >= 0; --i) {
diff --git a/arduino/ArduinoTellstickDuo/rf.cpp b/arduino/ArduinoTellstickDuo/rf.cpp
index c97cc0d7..0d5a31a7 100644
--- a/arduino/ArduinoTellstickDuo/rf.cpp
+++ b/arduino/ArduinoTellstickDuo/rf.cpp
@@ -17,29 +17,29 @@ void parseRadioRXBuffer() {
bool parse = false;
while (bufferReadP != bufferWriteP) { //stop if the read pointer is pointing to where the writing is currently performed
uint8_t sampleCount = *bufferReadP;
-
+
if ( (((uintptr_t)bufferReadP) & 0x1) == 1 ) { //buffer pointer is odd (stores highs)
//Serial.print("high:"); Serial.println(sampleCount);
if (prevValue >= SILENCE_LENGTH) {
startDataP = bufferReadP; //some new data must start here since this is the first "high" after a silent period
}
-
+
//stream data to stream parsers
parseOregonStream(HIGH, sampleCount);
-
+
} else { //buffer pointer is even (stores lows)
//Serial.print("low:"); Serial.println(sampleCount);
if (sampleCount >= SILENCE_LENGTH) { //evaluate if it is time to parse the curernt data
endDataP = bufferReadP; //this is a silient period and must be the end of a data
- if (startDataP != 0){
+ if(startDataP != 0){
parse = true;
break;
}
}
-
+
//stream data to stream parsers
parseOregonStream(LOW, sampleCount);
-
+
}
//step the read pointer one step
@@ -74,11 +74,11 @@ void parseRadioRXBuffer() {
//Let all available parsers parse the data set now.
parseArctechSelfLearning(startDataP, endDataP);
//TODO: add more parsers here
-
+
//reset the data pointers since the data have been parsed at this point
startDataP = 0;
endDataP = 0;
-
+
}; //end radioTask
void sendTCodedData(uint8_t* data, uint8_t T_long, uint8_t* timings, uint8_t repeat, uint8_t pause) {
@@ -88,7 +88,7 @@ void sendTCodedData(uint8_t* data, uint8_t T_long, uint8_t* timings, uint8_t rep
for (int i = 0; i < T_long; ++i) {
uint8_t timeIndex = (data[i / 4] >> (6 - (2 * (i % 4)))) & 0x03;
if (timings[timeIndex] > 0 || i == T_long - 1) {
- if (nextPinState){
+ if(nextPinState){
TX_PIN_HIGH();
}else{
TX_PIN_LOW();
@@ -111,7 +111,7 @@ void sendSCodedData(uint8_t* data, uint8_t pulseCount, uint8_t repeat, uint8_t p
bool nextPinState = HIGH;
for (int i = 0; i < pulseCount; ++i) {
if (data[i] > 0 || i == pulseCount - 1) {
- if (nextPinState){
+ if(nextPinState){
TX_PIN_HIGH();
}else{
TX_PIN_LOW();
diff --git a/arduino/HalMultiSensor/HalConfiguration.h b/arduino/HalMultiSensor/HalConfiguration.h
old mode 100644
new mode 100755
index afab67fa..72ef3529
--- a/arduino/HalMultiSensor/HalConfiguration.h
+++ b/arduino/HalMultiSensor/HalConfiguration.h
@@ -3,28 +3,26 @@
//#define ENABLE_DEBUG // comment out to disable debug
-
-#define TIMER_MILLISECOND 60000 // poling in minutes
+#define TIMER_MILLISECOND 60*1000 // poling in minutes
#define INDICATOR_PIN 13 // diode
-#define TX_PIN 11
-#define DEVICE_BASE_ID 99
+
// POWER CONSUMPTION SENSOR
//#define POWERCON_ENABLED // comment out to disable sensor
#define POWERCON_SENSOR SensorPhotocell()
-#define POWERCON_PROTOCOL ProtocolOregon(TX_PIN, DEVICE_BASE_ID + 0)
+#define POWERCON_PROTOCOL ProtocolOregon(11, 186)
#define POWER_TIMER_MULTIPLIER 1
// TEMPERATURE SENSOR
#define TEMPERATURE_ENABLED // comment out to disable sensor
-#define TEMPERATURE_SENSOR SensorDHT(DHT11, 10)
-#define TEMPERATURE_PROTOCOL ProtocolOregon(TX_PIN, DEVICE_BASE_ID + 1)
+#define TEMPERATURE_SENSOR SensorDHT(DHT22, 10)
+#define TEMPERATURE_PROTOCOL ProtocolOregon(11, 100)
#define TEMPERATURE_TIMER_MULTIPLIER 10
// LIGHT SENSOR
//#define LIGHT_ENABLED // comment out to disable sensor
-#define LIGHT_SENSOR SensorBH1750()
-#define LIGHT_PROTOCOL ProtocolOregon(TX_PIN, DEVICE_BASE_ID + 2)
+#define LIGHT_SENSOR SensorDH1750()
+#define LIGHT_PROTOCOL ?
#define LIGHT_TIMER_MULTIPLIER 10
diff --git a/arduino/HalMultiSensor/HalInclude.h b/arduino/HalMultiSensor/HalInclude.h
old mode 100644
new mode 100755
diff --git a/arduino/HalMultiSensor/HalInterfaces.h b/arduino/HalMultiSensor/HalInterfaces.h
old mode 100644
new mode 100755
diff --git a/arduino/HalMultiSensor/HalMultiSensor.ino b/arduino/HalMultiSensor/HalMultiSensor.ino
old mode 100644
new mode 100755
index 0b9f3b4b..374d3655
--- a/arduino/HalMultiSensor/HalMultiSensor.ino
+++ b/arduino/HalMultiSensor/HalMultiSensor.ino
@@ -10,15 +10,6 @@ the data to a central location.
#include "Interrupt.h"
-#ifndef POWERCON_ENABLED
- #define POWER_TIMER_MULTIPLIER 1
-#endif
-#ifndef TEMPERATURE_ENABLED
- #define TEMPERATURE_TIMER_MULTIPLIER 1
-#endif
-#ifndef LIGHT_ENABLED
- #define LIGHT_TIMER_MULTIPLIER 1
-#endif
#define TIMER_MULTIPLIER_MAX \
POWER_TIMER_MULTIPLIER * TEMPERATURE_TIMER_MULTIPLIER * LIGHT_TIMER_MULTIPLIER
unsigned int timerMultiplier = 0;
@@ -92,7 +83,7 @@ void loop()
// Send power consumption
#ifdef POWERCON_ENABLED
- if (timerMultiplier % POWER_TIMER_MULTIPLIER == 0)
+ if(timerMultiplier % POWER_TIMER_MULTIPLIER == 0)
{
static PowerData powerData;
powerSensor->read(powerData); // not needed, only here for future use
@@ -103,7 +94,7 @@ void loop()
// Handle temperature sensor
#ifdef TEMPERATURE_ENABLED
- if (timerMultiplier % TEMPERATURE_TIMER_MULTIPLIER == 0)
+ if(timerMultiplier % TEMPERATURE_TIMER_MULTIPLIER == 0)
{
static TemperatureData tempData;
tempSensor->read(tempData);
@@ -114,11 +105,11 @@ void loop()
// Handle light sensor
#ifdef LIGHT_ENABLED
- if (timerMultiplier % LIGHT_TIMER_MULTIPLIER == 0)
+ if(timerMultiplier % LIGHT_TIMER_MULTIPLIER == 0)
{
static LightData lightData;
lightSensor->read(lightData);
- DEBUGF("Read LIGHT_SENSOR= lumen:%d", lightData.lumen);
+ DEBUG("Read LIGHT_SENSOR= lumen:%d", lightData.lumen);
lightProtocol->send(lightData);
}
#endif
diff --git a/arduino/HalMultiSensor/HalMultiSensorEnclosure.FCStd b/arduino/HalMultiSensor/HalMultiSensorEnclosure.FCStd
deleted file mode 100644
index 89019798..00000000
Binary files a/arduino/HalMultiSensor/HalMultiSensorEnclosure.FCStd and /dev/null differ
diff --git a/arduino/HalMultiSensor/HalMultiSensorEnclosure_bottom.stl b/arduino/HalMultiSensor/HalMultiSensorEnclosure_bottom.stl
deleted file mode 100644
index 43e2e492..00000000
Binary files a/arduino/HalMultiSensor/HalMultiSensorEnclosure_bottom.stl and /dev/null differ
diff --git a/arduino/HalMultiSensor/HalMultiSensorEnclosure_top.stl b/arduino/HalMultiSensor/HalMultiSensorEnclosure_top.stl
deleted file mode 100644
index 6fe06d5e..00000000
Binary files a/arduino/HalMultiSensor/HalMultiSensorEnclosure_top.stl and /dev/null differ
diff --git a/arduino/HalMultiSensor/Interrupt.cpp b/arduino/HalMultiSensor/Interrupt.cpp
old mode 100644
new mode 100755
index 009af7e7..3351215f
--- a/arduino/HalMultiSensor/Interrupt.cpp
+++ b/arduino/HalMultiSensor/Interrupt.cpp
@@ -1,4 +1,5 @@
#include "Interrupt.h"
+#include
#include
#include
#include
@@ -35,16 +36,14 @@ void Interrupt::sleep()
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
-
- //power_adc_disable();
- //power_spi_disable();
- //power_usart0_disable();
- //power_timer0_disable();
- //power_timer1_disable();
- //power_timer2_disable();
- //power_twi_disable();
- //power_all_disable();
-
+ /*
+ power_adc_disable();
+ power_spi_disable();
+ power_timer0_disable();
+ power_timer1_disable();
+ power_timer2_disable();
+ power_twi_disable();
+ */
while( ! Interrupt::wakeUpNow)
{
sleep_mode(); // here the device is actually put to sleep!!
@@ -53,13 +52,6 @@ void Interrupt::sleep()
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
- //power_adc_enable();
- //power_spi_enable();
- //power_usart0_enable();
- //power_timer0_enable();
- //power_timer1_enable();
- //power_timer2_enable();
- //power_twi_enable();
//power_all_enable(); // during normal running time.
}
@@ -115,7 +107,7 @@ ISR(WDT_vect)
Interrupt::handleWatchDogInterrupt();
}
-void Interrupt::setupWatchDogInterrupt(int32_t milliseconds)
+void Interrupt::setupWatchDogInterrupt(uint16_t milliseconds)
{
wdtTimeLeft = wdtTime = milliseconds;
setupWatchDogInterrupt();
diff --git a/arduino/HalMultiSensor/Interrupt.h b/arduino/HalMultiSensor/Interrupt.h
old mode 100644
new mode 100755
index e9771a94..34094ee5
--- a/arduino/HalMultiSensor/Interrupt.h
+++ b/arduino/HalMultiSensor/Interrupt.h
@@ -1,7 +1,6 @@
#ifndef INTERRUPT_H
#define INTERRUPT_H
-#include
typedef void (*InterruptFunction) ();
@@ -11,7 +10,7 @@ public:
static void wakeUp() { wakeUpNow = true; };
static void sleep();
static void setupPinInterrupt(int pin);
- static void setupWatchDogInterrupt(int32_t milliseconds);
+ static void setupWatchDogInterrupt(unsigned int milliseconds);
//static void setupTimerInterrupt(unsigned int milliseconds);
static void setPinCallback(InterruptFunction callback){ Interrupt::pinCallback = callback;}
diff --git a/arduino/HalMultiSensor/ProtocolNexa.cpp b/arduino/HalMultiSensor/ProtocolNexa.cpp
old mode 100644
new mode 100755
diff --git a/arduino/HalMultiSensor/ProtocolNexa.h b/arduino/HalMultiSensor/ProtocolNexa.h
old mode 100644
new mode 100755
diff --git a/arduino/HalMultiSensor/ProtocolOregon.cpp b/arduino/HalMultiSensor/ProtocolOregon.cpp
old mode 100644
new mode 100755
index 96f04174..42212f91
--- a/arduino/HalMultiSensor/ProtocolOregon.cpp
+++ b/arduino/HalMultiSensor/ProtocolOregon.cpp
@@ -23,13 +23,6 @@ void ProtocolOregon::send(const TemperatureData& data)
send(data.temperature, data.humidity);
}
-void ProtocolOregon::send(const LightData& data)
-{
- send(data.lumen, 0);
-}
-
-
-
void ProtocolOregon::send(float temperature, short humidity)
{
byte buffer[9];
@@ -83,14 +76,14 @@ inline void ProtocolOregon::setId(byte data[], byte id)
*/
inline void ProtocolOregon::setBatteryLevel(byte data[], bool level)
{
- if (!level) data[4] = 0x0C;
+ if(!level) data[4] = 0x0C;
else data[4] = 0x00;
}
inline void ProtocolOregon::setTemperature(byte data[], float temp)
{
// Set temperature sign
- if (temp < 0)
+ if(temp < 0)
{
data[6] = 0x08;
temp *= -1;
@@ -127,9 +120,9 @@ inline void ProtocolOregon::calculateAndSetChecksum(byte data[])
for(byte i = 0; i<8;i++)
{
sum += (data[i]&0xF0) >> 4;
- sum += (data[i]&0x0F);
+ sum += (data[i]&0xF);
}
- data[8] = ((sum - 0x0A) & 0xFF);
+ data[8] = ((sum - 0xa) & 0xFF);
}
diff --git a/arduino/HalMultiSensor/ProtocolOregon.h b/arduino/HalMultiSensor/ProtocolOregon.h
old mode 100644
new mode 100755
index 89f82268..b5311ca6
--- a/arduino/HalMultiSensor/ProtocolOregon.h
+++ b/arduino/HalMultiSensor/ProtocolOregon.h
@@ -5,7 +5,7 @@
#include "HalInterfaces.h"
-class ProtocolOregon : public ProtocolTemperature, public ProtocolPowerConsumption, public ProtocolLight
+class ProtocolOregon : public ProtocolTemperature, public ProtocolPowerConsumption
{
public:
ProtocolOregon(short pin, unsigned char address) : txPin(pin), address(address){};
@@ -13,7 +13,6 @@ public:
virtual void setup();
virtual void send(const TemperatureData& data);
virtual void send(const PowerData& data);
- virtual void send(const LightData& data);
private:
short txPin;
diff --git a/arduino/HalMultiSensor/SensorBH1750.cpp b/arduino/HalMultiSensor/SensorBH1750.cpp
old mode 100644
new mode 100755
index 87a79842..f8461515
--- a/arduino/HalMultiSensor/SensorBH1750.cpp
+++ b/arduino/HalMultiSensor/SensorBH1750.cpp
@@ -51,7 +51,7 @@ based on Christopher Laws, March, 2013 code.
void SensorBH1750::setup() {
Wire.begin();
- //configure(BH1750_ONE_TIME_HIGH_RES_MODE);
+ configure(BH1750_ONE_TIME_HIGH_RES_MODE);
}
@@ -76,18 +76,22 @@ void SensorBH1750::configure(uint8_t mode) {
}
}
-
-void SensorBH1750::read(LightData& data) {
- configure(BH1750_ONE_TIME_HIGH_RES_MODE);
- _delay_ms(200); // Wait for measurement
-
- Wire.beginTransmission(BH1750_I2CADDR);
- Wire.requestFrom(BH1750_I2CADDR, 2);
- uint16_t level = Wire.read();
- level <<= 8;
- level |= Wire.read();
- Wire.endTransmission();
-
- data.lumen = level/1.2; // convert to lux
+void SensorBH1750::read(PowerData& data)
+{
+ data.consumption = pulses;
+ pulses = 0;
+}
+
+void SensorBH1750::read(LightData& data) {
+ uint16_t level;
+
+ Wire.beginTransmission(BH1750_I2CADDR);
+ Wire.requestFrom(BH1750_I2CADDR, 2);
+ level = Wire.read();
+ level <<= 8;
+ level |= Wire.read();
+ Wire.endTransmission();
+
+ data.lumen = level/1.2; // convert to lux
}
diff --git a/arduino/HalMultiSensor/SensorBH1750.h b/arduino/HalMultiSensor/SensorBH1750.h
old mode 100644
new mode 100755
index 7e9dc9df..cb139272
--- a/arduino/HalMultiSensor/SensorBH1750.h
+++ b/arduino/HalMultiSensor/SensorBH1750.h
@@ -5,9 +5,10 @@
#include "HalInterfaces.h"
-class SensorBH1750 : public SensorLight{
+class SensorBH1750 : public SensorPowerConsumption, public SensorLight{
public:
virtual void setup();
+ virtual void read(PowerData& data);
virtual void read(LightData& data);
private:
diff --git a/arduino/HalMultiSensor/SensorDHT.cpp b/arduino/HalMultiSensor/SensorDHT.cpp
old mode 100644
new mode 100755
diff --git a/arduino/HalMultiSensor/SensorDHT.h b/arduino/HalMultiSensor/SensorDHT.h
old mode 100644
new mode 100755
diff --git a/arduino/HalMultiSensor/SensorPhotocell.cpp b/arduino/HalMultiSensor/SensorPhotocell.cpp
old mode 100644
new mode 100755
diff --git a/arduino/HalMultiSensor/SensorPhotocell.h b/arduino/HalMultiSensor/SensorPhotocell.h
old mode 100644
new mode 100755
diff --git a/arduino/PowerTransmitter/BH1750FVI.cpp b/arduino/PowerTransmitter/BH1750FVI.cpp
new file mode 100755
index 00000000..772b21f5
--- /dev/null
+++ b/arduino/PowerTransmitter/BH1750FVI.cpp
@@ -0,0 +1,76 @@
+#include "BH1750FVI.h"
+
+BH1750FVI::BH1750FVI(){ }
+
+void BH1750FVI::begin(void){
+ Wire.begin();
+ I2CWriteTo(Power_On ); //Turn it On
+ pinMode(AddrPin,OUTPUT);
+ digitalWrite(AddrPin,HIGH);
+
+}
+void BH1750FVI::Sleep(void){
+ I2CWriteTo(Power_Down ); //Turn it off , Reset operator won't work in this mode
+}
+void BH1750FVI::Reset(void){
+ I2CWriteTo(Power_On ); //Turn it on again
+ I2CWriteTo(reset ); //Reset
+}
+
+void BH1750FVI::SetAddress(uint8_t add){
+ switch (add){
+ case Device_Address_L:
+ address_value=Device_Address_L;
+ digitalWrite(AddrPin,LOW);
+ state=false;
+ break;
+ case Device_Address_H:
+ address_value=Device_Address_H;
+ digitalWrite(AddrPin,HIGH);
+ state=true;
+ break;
+ }
+}
+
+void BH1750FVI::SetMode(uint8_t MODE){
+ switch(MODE){
+ case Continuous_H_resolution_Mode:
+ break;
+ case Continuous_H_resolution_Mode2:
+ break;
+ case Continuous_L_resolution_Mode:
+ break;
+ case OneTime_H_resolution_Mode:
+ break;
+ case OneTime_H_resolution_Mode2:
+ break;
+ case OneTime_L_resolution_Mode:
+ break;
+ }
+ delay(10);
+ I2CWriteTo(MODE);
+ }
+
+ uint16_t BH1750FVI::GetLightIntensity(void){
+ uint16_t Intensity_value;
+ if(state ==true){
+ Wire.beginTransmission(Device_Address_H);
+ Wire.requestFrom(Device_Address_H, 2);
+ }
+ if(state ==false){
+ Wire.beginTransmission(Device_Address_L);
+ Wire.requestFrom(Device_Address_L, 2);
+ }
+ Intensity_value = Wire.read();
+ Intensity_value <<= 8;
+ Intensity_value |= Wire.read();
+ Wire.endTransmission();
+ Intensity_value=Intensity_value/1.2;
+ return Intensity_value;
+}
+
+void BH1750FVI::I2CWriteTo(uint8_t DataToSend){
+ Wire.beginTransmission(address_value);
+ Wire.write(DataToSend);
+ Wire.endTransmission();
+}
diff --git a/arduino/PowerTransmitter/BH1750FVI.h b/arduino/PowerTransmitter/BH1750FVI.h
new file mode 100755
index 00000000..e3517b6d
--- /dev/null
+++ b/arduino/PowerTransmitter/BH1750FVI.h
@@ -0,0 +1,69 @@
+
+
+/* This library for Digital Light sensor BH1750FVI
+
+ use I2C Communication protocal , SDA,SCL Are required
+
+ to interface with this sensor
+
+ pin configuration :
+
+ VCC >>> 3.3V
+ SDA >>> A4
+ SCL >>> A5
+ ADDR >> A3 "Optional"
+ GND >>> gnd
+
+ written By : Mohannad Rawashdeh
+ www.genotronex.com
+ */
+
+#ifndef BH1750FVI_h
+#define BH1750FVI_h
+
+#include
+#include
+
+#define Device_Address_L 0x23 // Device address when address pin LOW
+#define Device_Address_H 0x5C // Device address when address pin LOW
+//all command here taken from Data sheet OPECODE Table page 5
+#define Power_Down 0x00
+
+#define Power_On 0x01
+
+#define reset 0x07
+
+#define Continuous_H_resolution_Mode 0x10
+
+#define Continuous_H_resolution_Mode2 0x11
+
+#define Continuous_L_resolution_Mode 0x13
+
+#define OneTime_H_resolution_Mode 0x20
+
+#define OneTime_H_resolution_Mode2 0x21
+
+#define OneTime_L_resolution_Mode 0x23//As well as address value
+
+#define AddrPin 17 // Address pin enable
+
+
+class BH1750FVI {
+ public:
+ BH1750FVI();
+ void begin(void);
+ void Sleep(void);
+ void SetMode(uint8_t MODE);
+ void Reset(void);
+ void SetAddress(uint8_t add);
+ uint16_t GetLightIntensity(void);
+
+ private:
+ void I2CWriteTo(uint8_t DataToSend);
+ byte address_value;
+ boolean state;
+};
+#endif
+
+
+
diff --git a/arduino/ThermometerTransmitter/ThermometerTransmitter.ino b/arduino/ThermometerTransmitter/ThermometerTransmitter.ino
new file mode 100755
index 00000000..b159e104
--- /dev/null
+++ b/arduino/ThermometerTransmitter/ThermometerTransmitter.ino
@@ -0,0 +1,289 @@
+/*
+* Protocol: Oregon V2.1
+* Emulating sensor: THGR2228N
+*/
+
+#include
+#include
+
+#define TEMP_SENSOR_PIN 9
+OneWire oneWire(TEMP_SENSOR_PIN);
+DallasTemperature tempSensors(&oneWire);
+
+const byte TX_PIN = 10;
+const byte LED_PIN = 13;
+const unsigned long TIME = 512;
+const unsigned long TWOTIME = TIME*2;
+#define SEND_HIGH() digitalWrite(TX_PIN, HIGH)
+#define SEND_LOW() digitalWrite(TX_PIN, LOW)
+byte OregonMessageBuffer[9];
+unsigned long previousTime = 0;
+unsigned long currentTime = millis();
+
+void setup()
+{
+ Serial.begin(9600);
+
+ pinMode(TX_PIN, OUTPUT);
+ pinMode(LED_PIN, OUTPUT);
+ SEND_LOW();
+ byte ID[] = { 0x1A,0x2D }; //temperature/humidity sensor (THGR2228N)
+ setType(OregonMessageBuffer, ID);
+ setChannel(OregonMessageBuffer, 0x20);
+
+ tempSensors.begin();
+}
+
+
+boolean light = false;
+void loop()
+{
+ currentTime = millis();
+ if(currentTime - previousTime > 5000) {
+ previousTime = currentTime;
+
+ tempSensors.requestTemperatures();
+ float temp = tempSensors.getTempCByIndex(0);
+ Serial.print("temp = ");
+ Serial.println(temp);
+
+ send433(temp,0,0xBB);
+ delay(500);
+ }
+}
+
+void send433(float temperature, byte humidity, byte Identitet)
+{
+ digitalWrite(LED_PIN, HIGH);
+ setId(OregonMessageBuffer, Identitet); //set id of the sensor, BB=187
+ setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high
+ setTemperature(OregonMessageBuffer, temperature); //org setTemperature(OregonMessageBuffer, 55.5);
+ setHumidity(OregonMessageBuffer, humidity);
+ calculateAndSetChecksum(OregonMessageBuffer);
+
+ // Show the Oregon Message
+ for (byte i = 0; i < sizeof(OregonMessageBuffer); ++i) {
+ Serial.print(OregonMessageBuffer[i] >> 4, HEX);
+ Serial.print(OregonMessageBuffer[i] & 0x0F, HEX);
+ }
+ Serial.println();
+
+ // Send the Message over RF
+ sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));
+ // Send a "pause"
+ SEND_LOW();
+ delayMicroseconds(TWOTIME*8);
+ // Send a copie of the first message. The v2.1 protocol send the message two time
+ sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));
+ SEND_LOW();
+ digitalWrite(LED_PIN, LOW);
+}
+
+inline void setId(byte *data, byte ID)
+{
+ data[3] = ID;
+}
+
+void setBatteryLevel(byte *data, byte level)
+{
+ if(!level) data[4] = 0x0C;
+ else data[4] = 0x00;
+}
+
+void setTemperature(byte *data, float temp)
+{
+ // Set temperature sign
+ if(temp < 0)
+ {
+ data[6] = 0x08;
+ temp *= -1;
+ }
+ else
+ {
+ data[6] = 0x00;
+ }
+
+ // Determine decimal and float part
+ int tempInt = (int)temp;
+ int td = (int)(tempInt / 10);
+ int tf = (int)round((float)((float)tempInt/10 - (float)td) * 10);
+
+ int tempFloat = (int)round((float)(temp - (float)tempInt) * 10);
+
+ // Set temperature decimal part
+ data[5] = (td << 4);
+ data[5] |= tf;
+
+ // Set temperature float part
+ data[4] |= (tempFloat << 4);
+}
+
+void setHumidity(byte* data, byte hum)
+{
+ data[7] = (hum/10);
+ data[6] |= (hum - data[7]*10) << 4;
+}
+
+void calculateAndSetChecksum(byte* data)
+{
+ int sum = 0;
+ for(byte i = 0; i<8;i++)
+ {
+ sum += (data[i]&0xF0) >> 4;
+ sum += (data[i]&0xF);
+ }
+ data[8] = ((sum - 0xa) & 0xFF);
+}
+
+
+
+
+//*********************************************************************************************************
+
+
+/**
+ * \brief Send logical "0" over RF
+ * \details azero bit be represented by an off-to-on transition
+ * \ of the RF signal at the middle of a clock period.
+ * \ Remenber, the Oregon v2.1 protocol add an inverted bit first
+ */
+inline void sendZero(void)
+{
+ SEND_HIGH();
+ delayMicroseconds(TIME);
+ SEND_LOW();
+ delayMicroseconds(TWOTIME);
+ SEND_HIGH();
+ delayMicroseconds(TIME);
+}
+
+/**
+ * \brief Send logical "1" over RF
+ * \details a one bit be represented by an on-to-off transition
+ * \ of the RF signal at the middle of a clock period.
+ * \ Remenber, the Oregon v2.1 protocol add an inverted bit first
+ */
+inline void sendOne(void)
+{
+ SEND_LOW();
+ delayMicroseconds(TIME);
+ SEND_HIGH();
+ delayMicroseconds(TWOTIME);
+ SEND_LOW();
+ delayMicroseconds(TIME);
+}
+
+/**
+ * \brief Send a bits quarter (4 bits = MSB from 8 bits value) over RF
+ * \param data Data to send
+ */
+inline void sendQuarterMSB(const byte data)
+{
+ (bitRead(data, 4)) ? sendOne() : sendZero();
+ (bitRead(data, 5)) ? sendOne() : sendZero();
+ (bitRead(data, 6)) ? sendOne() : sendZero();
+ (bitRead(data, 7)) ? sendOne() : sendZero();
+}
+
+/**
+ * \brief Send a bits quarter (4 bits = LSB from 8 bits value) over RF
+ * \param data Data to send
+ */
+inline void sendQuarterLSB(const byte data)
+{
+ (bitRead(data, 0)) ? sendOne() : sendZero();
+ (bitRead(data, 1)) ? sendOne() : sendZero();
+ (bitRead(data, 2)) ? sendOne() : sendZero();
+ (bitRead(data, 3)) ? sendOne() : sendZero();
+}
+
+/******************************************************************/
+/******************************************************************/
+/******************************************************************/
+
+/**
+ * \brief Send a buffer over RF
+ * \param data Data to send
+ * \param size size of data to send
+ */
+void sendData(byte *data, byte size)
+{
+ for(byte i = 0; i < size; ++i)
+ {
+ sendQuarterLSB(data[i]);
+ sendQuarterMSB(data[i]);
+ }
+}
+
+/**
+ * \brief Send an Oregon message
+ * \param data The Oregon message
+ */
+void sendOregon(byte *data, byte size)
+{
+ sendPreamble();
+ //sendSync();
+ sendData(data, size);
+ sendPostamble();
+}
+
+/**
+ * \brief Send preamble
+ * \details The preamble consists of 16 "1" bits
+ */
+inline void sendPreamble(void)
+{
+ byte PREAMBLE[]={
+ 0xFF,0xFF };
+ sendData(PREAMBLE, 2);
+}
+
+/**
+ * \brief Send postamble
+ * \details The postamble consists of 8 "0" bits
+ */
+inline void sendPostamble(void)
+{
+ byte POSTAMBLE[]={
+ 0x00 };
+ sendData(POSTAMBLE, 1);
+}
+
+/**
+ * \brief Send sync nibble
+ * \details The sync is 0xA. It is not use in this version since the sync nibble
+ * \ is include in the Oregon message to send.
+ */
+inline void sendSync(void)
+{
+ sendQuarterLSB(0xA);
+}
+
+/******************************************************************/
+/******************************************************************/
+/******************************************************************/
+
+/**
+ * \brief Set the sensor type
+ * \param data Oregon message
+ * \param type Sensor type
+ */
+inline void setType(byte *data, byte* type)
+{
+ data[0] = type[0];
+ data[1] = type[1];
+}
+
+/**
+ * \brief Set the sensor channel
+ * \param data Oregon message
+ * \param channel Sensor channel (0x10, 0x20, 0x30)
+ */
+inline void setChannel(byte *data, byte channel)
+{
+ data[2] = channel;
+}
+
+
+
+
diff --git a/arduino/lib/BH1750/BH1750FVI.cpp b/arduino/lib/BH1750/BH1750FVI.cpp
new file mode 100755
index 00000000..dcddda16
--- /dev/null
+++ b/arduino/lib/BH1750/BH1750FVI.cpp
@@ -0,0 +1,80 @@
+#include "BH1750FVI.h"
+#include "Arduino.h"
+
+BH1750FVI::BH1750FVI(){
+
+ }
+
+ void BH1750FVI::begin(void){
+ Wire.begin();
+ I2CWriteTo(Power_On ); //Turn it On
+ pinMode(AddrPin,OUTPUT);
+ digitalWrite(AddrPin,HIGH);
+
+ }
+ void BH1750FVI::Sleep(void){
+ I2CWriteTo(Power_Down ); //Turn it off , Reset operator won't work in this mode
+ }
+ void BH1750FVI::Reset(void){
+ I2CWriteTo(Power_On ); //Turn it on again
+ I2CWriteTo(reset ); //Reset
+
+ }
+ void BH1750FVI::SetAddress(uint8_t add){
+ switch (add){
+ case Device_Address_L:
+ address_value=Device_Address_L;
+ digitalWrite(AddrPin,LOW);
+ state=false;
+ break;
+ case Device_Address_H:
+ address_value=Device_Address_H;
+ digitalWrite(AddrPin,HIGH);
+ state=true;
+ break;
+ }
+
+ }
+ void BH1750FVI::SetMode(uint8_t MODE){
+ switch(MODE){
+ case Continuous_H_resolution_Mode:
+ break;
+ case Continuous_H_resolution_Mode2:
+ break;
+ case Continuous_L_resolution_Mode:
+ break;
+ case OneTime_H_resolution_Mode:
+ break;
+ case OneTime_H_resolution_Mode2:
+ break;
+ case OneTime_L_resolution_Mode:
+ break;
+ }
+ delay(10);
+ I2CWriteTo(MODE);
+ }
+
+ uint16_t BH1750FVI::GetLightIntensity(void){
+ uint16_t Intensity_value;
+ if(state ==true){
+ Wire.beginTransmission(Device_Address_H);
+ Wire.requestFrom(Device_Address_H, 2);
+ }
+ if(state ==false){
+ Wire.beginTransmission(Device_Address_L);
+ Wire.requestFrom(Device_Address_L, 2);
+ }
+ Intensity_value = Wire.read();
+ Intensity_value <<= 8;
+ Intensity_value |= Wire.read();
+ Wire.endTransmission();
+ Intensity_value=Intensity_value/1.2;
+ return Intensity_value;
+
+ }
+
+ void BH1750FVI::I2CWriteTo(uint8_t DataToSend){
+ Wire.beginTransmission(address_value);
+ Wire.write(DataToSend);
+ Wire.endTransmission();
+ }
diff --git a/arduino/lib/BH1750/BH1750FVI.h b/arduino/lib/BH1750/BH1750FVI.h
new file mode 100755
index 00000000..eea3fa85
--- /dev/null
+++ b/arduino/lib/BH1750/BH1750FVI.h
@@ -0,0 +1,68 @@
+
+
+/* This library for Digital Light sensor BH1750FVI
+
+ use I2C Communication protocal , SDA,SCL Are required
+
+ to interface with this sensor
+
+ pin configuration :
+
+ VCC >>> 3.3V
+ SDA >>> A4
+ SCL >>> A5
+ ADDR >> A3 "Optional"
+ GND >>> gnd
+
+ written By : Mohannad Rawashdeh
+ www.genotronex.com
+ */
+
+#ifndef BH1750FVI_h
+#define BH1750FVI_h
+
+#include "Arduino.h"
+
+#include "Wire.h"
+
+#define Device_Address_L 0x23 // Device address when address pin LOW
+#define Device_Address_H 0x5C // Device address when address pin LOW
+//all command here taken from Data sheet OPECODE Table page 5
+#define Power_Down 0x00
+
+#define Power_On 0x01
+
+#define reset 0x07
+
+#define Continuous_H_resolution_Mode 0x10
+
+#define Continuous_H_resolution_Mode2 0x11
+
+#define Continuous_L_resolution_Mode 0x13
+
+#define OneTime_H_resolution_Mode 0x20
+
+#define OneTime_H_resolution_Mode2 0x21
+
+#define OneTime_L_resolution_Mode 0x23//As well as address value
+
+#define AddrPin 17 // Address pin enable
+ class BH1750FVI {
+ public:
+ BH1750FVI();
+ void begin(void);
+ void Sleep(void);
+ void SetMode(uint8_t MODE);
+ void Reset(void);
+ void SetAddress(uint8_t add);
+ uint16_t GetLightIntensity(void);
+
+ private:
+ void I2CWriteTo(uint8_t DataToSend);
+ byte address_value;
+ boolean state;
+ };
+ #endif
+
+
+
diff --git a/arduino/lib/BH1750/Examples/BH1750_LCD/BH1750_LCD.ino b/arduino/lib/BH1750/Examples/BH1750_LCD/BH1750_LCD.ino
new file mode 100755
index 00000000..ca5fd9d7
--- /dev/null
+++ b/arduino/lib/BH1750/Examples/BH1750_LCD/BH1750_LCD.ino
@@ -0,0 +1,60 @@
+ /*
+ This is a simple code to test BH1750FVI Light senosr
+ communicate using I2C Protocol
+ this library enable 2 slave device address
+ Main address 0x23
+ secondary address 0x5C
+ connect this sensor as following :
+ VCC >>> 3.3V
+ SDA >>> A4
+ SCL >>> A5
+ addr >> A3
+ Gnd >>>Gnd
+
+ Written By : Mohannad Rawashdeh
+
+ */
+
+ // First define the library :
+ #include // Sensor Library
+ #include // I2C Library
+ #include
+
+ LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
+ uint16_t Light_Intensity=0;
+ // Call the function
+
+ BH1750FVI LightSensor;
+
+
+void setup() {
+ // put your setup code here, to run once:
+ Serial.begin(9600);
+ lcd.begin(16, 2);
+
+ // call begin Function so turn the sensor On .
+ LightSensor.begin();
+ LightSensor.SetAddress(Device_Address_H); //Address 0x5C
+ LightSensor.SetMode(Continuous_H_resolution_Mode);
+ lcd.setCursor(0, 0);
+ lcd.print("BH1750 Sensor");
+ lcd.setCursor(1, 1);
+ lcd.print("Please wait...");
+ delay(3000);
+ lcd.clear();
+
+}
+
+ void loop() {
+ // put your main code here, to run repeatedly:
+ lcd.clear();
+ lcd.setCursor(0, 0);
+ lcd.print(" Intensity = ");
+ lcd.setCursor(5, 1);
+ Light_Intensity = LightSensor.GetLightIntensity();
+ lcd.print(Light_Intensity);
+ lcd.print(" Lux");
+ delay(2000);
+
+
+}
diff --git a/arduino/lib/BH1750/Examples/BH1750_Led/BH1750_Led.ino b/arduino/lib/BH1750/Examples/BH1750_Led/BH1750_Led.ino
new file mode 100755
index 00000000..49015e31
--- /dev/null
+++ b/arduino/lib/BH1750/Examples/BH1750_Led/BH1750_Led.ino
@@ -0,0 +1,74 @@
+/*
+ This is a simple code to test BH1750FVI Light senosr
+ communicate using I2C Protocol
+ this library enable 2 slave device address
+ Main address 0x23
+ secondary address 0x5C
+ connect this sensor as following :
+ VCC >>> 3.3V
+ SDA >>> A4
+ SCL >>> A5
+ addr >> A3
+ Gnd >>>Gnd
+
+ Written By : Mohannad Rawashdeh
+
+ */
+
+ // First define the library :
+ #include // Sensor Library
+ #include // I2C Library
+
+ uint16_t Light_Intensity=0;
+ // Call the function
+ #define LedPin 9 // led connecting to pin D9
+ BH1750FVI LightSensor;
+
+ int SensorValue =0;
+void setup() {
+ // put your setup code here, to run once:
+ Serial.begin(9600);
+ // call begin Function so turn the sensor On .
+ LightSensor.begin();
+ /*
+ Set the address for this sensor
+ you can use 2 different address
+ Device_Address_H "0x5C"
+ Device_Address_L "0x23"
+ you must connect Addr pin to A3 .
+ */
+ LightSensor.SetAddress(Device_Address_H); //Address 0x5C
+ // To adjust the slave on other address , uncomment this line
+ // lightMeter.SetAddress(Device_Address_L); //Address 0x5C
+ //-----------------------------------------------
+ /*
+ set the Working Mode for this sensor
+ Select the following Mode:
+ Continuous_H_resolution_Mode
+ Continuous_H_resolution_Mode2
+ Continuous_L_resolution_Mode
+ OneTime_H_resolution_Mode
+ OneTime_H_resolution_Mode2
+ OneTime_L_resolution_Mode
+
+ The data sheet recommanded To use Continuous_H_resolution_Mode
+ */
+ LightSensor.SetMode(Continuous_H_resolution_Mode);
+ pinMode(9,OUTPUT) // Connect LED With 100ohm resistor
+ // to pin D9
+
+
+}
+
+void loop() {
+ // put your main code here, to run repeatedly:
+ // call GetLightIntensity() Function , so the sensor read
+ //the Intensity Value and send it
+ Light_Intensity=LightSensor.GetLightIntensity();
+ delay(50);
+
+ SensorValue=map(Light_Intensity,0,2000,255,0);
+ SensorValue=constrain(SensorValue,255,0);
+ digitalWrite(LedPin,SensorValue);
+ // ready to another reading .
+}
diff --git a/arduino/lib/BH1750/Examples/BH1750_serial/BH1750_serial.ino b/arduino/lib/BH1750/Examples/BH1750_serial/BH1750_serial.ino
new file mode 100755
index 00000000..d4753151
--- /dev/null
+++ b/arduino/lib/BH1750/Examples/BH1750_serial/BH1750_serial.ino
@@ -0,0 +1,68 @@
+
+/*
+ This is a simple code to test BH1750FVI Light senosr
+ communicate using I2C Protocol
+ this library enable 2 slave device address
+ Main address 0x23
+ secondary address 0x5C
+ connect this sensor as following :
+ VCC >>> 3.3V
+ SDA >>> A4
+ SCL >>> A5
+ addr >> A3
+ Gnd >>>Gnd
+
+ Written By : Mohannad Rawashdeh
+
+ */
+
+ // First define the library :
+
+#include
+#include
+
+
+BH1750FVI LightSensor;
+
+
+void setup() { // put your setup code here, to run once:
+ Serial.begin(9600);
+ LightSensor.begin();
+ /*
+ Set the address for this sensor
+ you can use 2 different address
+ Device_Address_H "0x5C"
+ Device_Address_L "0x23"
+ you must connect Addr pin to A3 .
+ */
+ LightSensor.SetAddress(Device_Address_H);//Address 0x5C
+ // To adjust the slave on other address , uncomment this line
+ // lightMeter.SetAddress(Device_Address_L); //Address 0x5C
+ //-----------------------------------------------
+ /*
+ set the Working Mode for this sensor
+ Select the following Mode:
+ Continuous_H_resolution_Mode
+ Continuous_H_resolution_Mode2
+ Continuous_L_resolution_Mode
+ OneTime_H_resolution_Mode
+ OneTime_H_resolution_Mode2
+ OneTime_L_resolution_Mode
+
+ The data sheet recommanded To use Continuous_H_resolution_Mode
+ */
+
+ LightSensor.SetMode(Continuous_H_resolution_Mode);
+
+ Serial.println("Running...");
+}
+
+
+void loop() {
+ // put your main code here, to run repeatedly:
+ uint16_t lux = LightSensor.GetLightIntensity();// Get Lux value
+ Serial.print("Light: ");
+ Serial.print(lux);
+ Serial.println(" lux");
+ delay(1000);
+}
diff --git a/arduino/lib/BH1750/keywords.txt b/arduino/lib/BH1750/keywords.txt
new file mode 100755
index 00000000..feeee116
--- /dev/null
+++ b/arduino/lib/BH1750/keywords.txt
@@ -0,0 +1,24 @@
+#######################################
+# Syntax Coloring Map For BH1750FVI
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+ KEYWORD1
+BH1750FVI KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+
+KEYWORD2
+begin KEYWORD2
+Sleep KEYWORD2SetMode KEYWORD2Reset KEYWORD2GetLightIntensity KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
diff --git a/arduino/lib/DallasTemperature/DallasTemperature.cpp b/arduino/lib/DallasTemperature/DallasTemperature.cpp
new file mode 100755
index 00000000..8d0a9722
--- /dev/null
+++ b/arduino/lib/DallasTemperature/DallasTemperature.cpp
@@ -0,0 +1,738 @@
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// Version 3.7.2 modified on Dec 6, 2011 to support Arduino 1.0
+// See Includes...
+// Modified by Jordan Hochenbaum
+
+#include "DallasTemperature.h"
+
+#if ARDUINO >= 100
+ #include "Arduino.h"
+#else
+extern "C" {
+ #include "WConstants.h"
+}
+#endif
+
+DallasTemperature::DallasTemperature(OneWire* _oneWire)
+ #if REQUIRESALARMS
+ : _AlarmHandler(&defaultAlarmHandler)
+ #endif
+{
+ _wire = _oneWire;
+ devices = 0;
+ parasite = false;
+ bitResolution = 9;
+ waitForConversion = true;
+ checkForConversion = true;
+}
+
+// initialise the bus
+void DallasTemperature::begin(void)
+{
+ DeviceAddress deviceAddress;
+
+ _wire->reset_search();
+ devices = 0; // Reset the number of devices when we enumerate wire devices
+
+ while (_wire->search(deviceAddress))
+ {
+ if (validAddress(deviceAddress))
+ {
+ if (!parasite && readPowerSupply(deviceAddress)) parasite = true;
+
+ ScratchPad scratchPad;
+
+ readScratchPad(deviceAddress, scratchPad);
+
+ bitResolution = max(bitResolution, getResolution(deviceAddress));
+
+ devices++;
+ }
+ }
+}
+
+// returns the number of devices found on the bus
+uint8_t DallasTemperature::getDeviceCount(void)
+{
+ return devices;
+}
+
+// returns true if address is valid
+bool DallasTemperature::validAddress(uint8_t* deviceAddress)
+{
+ return (_wire->crc8(deviceAddress, 7) == deviceAddress[7]);
+}
+
+// finds an address at a given index on the bus
+// returns true if the device was found
+bool DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index)
+{
+ uint8_t depth = 0;
+
+ _wire->reset_search();
+
+ while (depth <= index && _wire->search(deviceAddress))
+ {
+ if (depth == index && validAddress(deviceAddress)) return true;
+ depth++;
+ }
+
+ return false;
+}
+
+// attempt to determine if the device at the given address is connected to the bus
+bool DallasTemperature::isConnected(uint8_t* deviceAddress)
+{
+ ScratchPad scratchPad;
+ return isConnected(deviceAddress, scratchPad);
+}
+
+// attempt to determine if the device at the given address is connected to the bus
+// also allows for updating the read scratchpad
+bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad)
+{
+ readScratchPad(deviceAddress, scratchPad);
+ return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]);
+}
+
+// read device's scratch pad
+void DallasTemperature::readScratchPad(uint8_t* deviceAddress, uint8_t* scratchPad)
+{
+ // send the command
+ _wire->reset();
+ _wire->select(deviceAddress);
+ _wire->write(READSCRATCH);
+
+ // TODO => collect all comments & use simple loop
+ // byte 0: temperature LSB
+ // byte 1: temperature MSB
+ // byte 2: high alarm temp
+ // byte 3: low alarm temp
+ // byte 4: DS18S20: store for crc
+ // DS18B20 & DS1822: configuration register
+ // byte 5: internal use & crc
+ // byte 6: DS18S20: COUNT_REMAIN
+ // DS18B20 & DS1822: store for crc
+ // byte 7: DS18S20: COUNT_PER_C
+ // DS18B20 & DS1822: store for crc
+ // byte 8: SCRATCHPAD_CRC
+ //
+ // for(int i=0; i<9; i++)
+ // {
+ // scratchPad[i] = _wire->read();
+ // }
+
+
+ // read the response
+
+ // byte 0: temperature LSB
+ scratchPad[TEMP_LSB] = _wire->read();
+
+ // byte 1: temperature MSB
+ scratchPad[TEMP_MSB] = _wire->read();
+
+ // byte 2: high alarm temp
+ scratchPad[HIGH_ALARM_TEMP] = _wire->read();
+
+ // byte 3: low alarm temp
+ scratchPad[LOW_ALARM_TEMP] = _wire->read();
+
+ // byte 4:
+ // DS18S20: store for crc
+ // DS18B20 & DS1822: configuration register
+ scratchPad[CONFIGURATION] = _wire->read();
+
+ // byte 5:
+ // internal use & crc
+ scratchPad[INTERNAL_BYTE] = _wire->read();
+
+ // byte 6:
+ // DS18S20: COUNT_REMAIN
+ // DS18B20 & DS1822: store for crc
+ scratchPad[COUNT_REMAIN] = _wire->read();
+
+ // byte 7:
+ // DS18S20: COUNT_PER_C
+ // DS18B20 & DS1822: store for crc
+ scratchPad[COUNT_PER_C] = _wire->read();
+
+ // byte 8:
+ // SCTRACHPAD_CRC
+ scratchPad[SCRATCHPAD_CRC] = _wire->read();
+
+ _wire->reset();
+}
+
+// writes device's scratch pad
+void DallasTemperature::writeScratchPad(uint8_t* deviceAddress, const uint8_t* scratchPad)
+{
+ _wire->reset();
+ _wire->select(deviceAddress);
+ _wire->write(WRITESCRATCH);
+ _wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp
+ _wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp
+ // DS18S20 does not use the configuration register
+ if (deviceAddress[0] != DS18S20MODEL) _wire->write(scratchPad[CONFIGURATION]); // configuration
+ _wire->reset();
+ // save the newly written values to eeprom
+ _wire->write(COPYSCRATCH, parasite);
+ if (parasite) delay(10); // 10ms delay
+ _wire->reset();
+}
+
+// reads the device's power requirements
+bool DallasTemperature::readPowerSupply(uint8_t* deviceAddress)
+{
+ bool ret = false;
+ _wire->reset();
+ _wire->select(deviceAddress);
+ _wire->write(READPOWERSUPPLY);
+ if (_wire->read_bit() == 0) ret = true;
+ _wire->reset();
+ return ret;
+}
+
+
+// set resolution of all devices to 9, 10, 11, or 12 bits
+// if new resolution is out of range, it is constrained.
+void DallasTemperature::setResolution(uint8_t newResolution)
+{
+ bitResolution = constrain(newResolution, 9, 12);
+ DeviceAddress deviceAddress;
+ for (int i=0; ireset();
+ _wire->skip();
+ _wire->write(STARTCONVO, parasite);
+
+ // ASYNC mode?
+ if (!waitForConversion) return;
+ blockTillConversionComplete(&bitResolution, 0);
+
+ return;
+}
+
+// sends command for one device to perform a temperature by address
+// returns FALSE if device is disconnected
+// returns TRUE otherwise
+bool DallasTemperature::requestTemperaturesByAddress(uint8_t* deviceAddress)
+{
+
+ _wire->reset();
+ _wire->select(deviceAddress);
+ _wire->write(STARTCONVO, parasite);
+
+ // check device
+ ScratchPad scratchPad;
+ if (!isConnected(deviceAddress, scratchPad)) return false;
+
+
+ // ASYNC mode?
+ if (!waitForConversion) return true;
+ uint8_t bitResolution = getResolution(deviceAddress);
+ blockTillConversionComplete(&bitResolution, deviceAddress);
+
+ return true;
+}
+
+
+void DallasTemperature::blockTillConversionComplete(uint8_t* bitResolution, uint8_t* deviceAddress)
+{
+ if(deviceAddress != 0 && checkForConversion && !parasite)
+ {
+ // Continue to check if the IC has responded with a temperature
+ // NB: Could cause issues with multiple devices (one device may respond faster)
+ unsigned long start = millis();
+ while(!isConversionAvailable(0) && ((millis() - start) < 750));
+ }
+
+ // Wait a fix number of cycles till conversion is complete (based on IC datasheet)
+ switch (*bitResolution)
+ {
+ case 9:
+ delay(94);
+ break;
+ case 10:
+ delay(188);
+ break;
+ case 11:
+ delay(375);
+ break;
+ case 12:
+ default:
+ delay(750);
+ break;
+ }
+
+}
+
+// sends command for one device to perform a temp conversion by index
+bool DallasTemperature::requestTemperaturesByIndex(uint8_t deviceIndex)
+{
+ DeviceAddress deviceAddress;
+ getAddress(deviceAddress, deviceIndex);
+ return requestTemperaturesByAddress(deviceAddress);
+}
+
+// Fetch temperature for device index
+float DallasTemperature::getTempCByIndex(uint8_t deviceIndex)
+{
+ DeviceAddress deviceAddress;
+ getAddress(deviceAddress, deviceIndex);
+ return getTempC((uint8_t*)deviceAddress);
+}
+
+// Fetch temperature for device index
+float DallasTemperature::getTempFByIndex(uint8_t deviceIndex)
+{
+ return toFahrenheit(getTempCByIndex(deviceIndex));
+}
+
+// reads scratchpad and returns the temperature in degrees C
+float DallasTemperature::calculateTemperature(uint8_t* deviceAddress, uint8_t* scratchPad)
+{
+ int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB];
+
+ switch (deviceAddress[0])
+ {
+ case DS18B20MODEL:
+ case DS1822MODEL:
+ switch (scratchPad[CONFIGURATION])
+ {
+ case TEMP_12_BIT:
+ return (float)rawTemperature * 0.0625;
+ break;
+ case TEMP_11_BIT:
+ return (float)(rawTemperature >> 1) * 0.125;
+ break;
+ case TEMP_10_BIT:
+ return (float)(rawTemperature >> 2) * 0.25;
+ break;
+ case TEMP_9_BIT:
+ return (float)(rawTemperature >> 3) * 0.5;
+ break;
+ }
+ break;
+ case DS18S20MODEL:
+ /*
+
+ Resolutions greater than 9 bits can be calculated using the data from
+ the temperature, COUNT REMAIN and COUNT PER �C registers in the
+ scratchpad. Note that the COUNT PER �C register is hard-wired to 16
+ (10h). After reading the scratchpad, the TEMP_READ value is obtained
+ by truncating the 0.5�C bit (bit 0) from the temperature data. The
+ extended resolution temperature can then be calculated using the
+ following equation:
+
+ COUNT_PER_C - COUNT_REMAIN
+ TEMPERATURE = TEMP_READ - 0.25 + --------------------------
+ COUNT_PER_C
+ */
+
+ // Good spot. Thanks Nic Johns for your contribution
+ return (float)(rawTemperature >> 1) - 0.25 +((float)(scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) / (float)scratchPad[COUNT_PER_C] );
+ break;
+ }
+}
+
+// returns temperature in degrees C or DEVICE_DISCONNECTED if the
+// device's scratch pad cannot be read successfully.
+// the numeric value of DEVICE_DISCONNECTED is defined in
+// DallasTemperature.h. It is a large negative number outside the
+// operating range of the device
+float DallasTemperature::getTempC(uint8_t* deviceAddress)
+{
+ // TODO: Multiple devices (up to 64) on the same bus may take
+ // some time to negotiate a response
+ // What happens in case of collision?
+
+ ScratchPad scratchPad;
+ if (isConnected(deviceAddress, scratchPad)) return calculateTemperature(deviceAddress, scratchPad);
+ return DEVICE_DISCONNECTED;
+}
+
+// returns temperature in degrees F
+// TODO: - when getTempC returns DEVICE_DISCONNECTED
+// -127 gets converted to -196.6 F
+float DallasTemperature::getTempF(uint8_t* deviceAddress)
+{
+ return toFahrenheit(getTempC(deviceAddress));
+}
+
+// returns true if the bus requires parasite power
+bool DallasTemperature::isParasitePowerMode(void)
+{
+ return parasite;
+}
+
+#if REQUIRESALARMS
+
+/*
+
+ALARMS:
+
+TH and TL Register Format
+
+BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
+ S 2^6 2^5 2^4 2^3 2^2 2^1 2^0
+
+Only bits 11 through 4 of the temperature register are used
+in the TH and TL comparison since TH and TL are 8-bit
+registers. If the measured temperature is lower than or equal
+to TL or higher than or equal to TH, an alarm condition exists
+and an alarm flag is set inside the DS18B20. This flag is
+updated after every temperature measurement; therefore, if the
+alarm condition goes away, the flag will be turned off after
+the next temperature conversion.
+
+*/
+
+// sets the high alarm temperature for a device in degrees celsius
+// accepts a float, but the alarm resolution will ignore anything
+// after a decimal point. valid range is -55C - 125C
+void DallasTemperature::setHighAlarmTemp(uint8_t* deviceAddress, char celsius)
+{
+ // make sure the alarm temperature is within the device's range
+ if (celsius > 125) celsius = 125;
+ else if (celsius < -55) celsius = -55;
+
+ ScratchPad scratchPad;
+ if (isConnected(deviceAddress, scratchPad))
+ {
+ scratchPad[HIGH_ALARM_TEMP] = (uint8_t)celsius;
+ writeScratchPad(deviceAddress, scratchPad);
+ }
+}
+
+// sets the low alarm temperature for a device in degreed celsius
+// accepts a float, but the alarm resolution will ignore anything
+// after a decimal point. valid range is -55C - 125C
+void DallasTemperature::setLowAlarmTemp(uint8_t* deviceAddress, char celsius)
+{
+ // make sure the alarm temperature is within the device's range
+ if (celsius > 125) celsius = 125;
+ else if (celsius < -55) celsius = -55;
+
+ ScratchPad scratchPad;
+ if (isConnected(deviceAddress, scratchPad))
+ {
+ scratchPad[LOW_ALARM_TEMP] = (uint8_t)celsius;
+ writeScratchPad(deviceAddress, scratchPad);
+ }
+}
+
+// returns a char with the current high alarm temperature or
+// DEVICE_DISCONNECTED for an address
+char DallasTemperature::getHighAlarmTemp(uint8_t* deviceAddress)
+{
+ ScratchPad scratchPad;
+ if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[HIGH_ALARM_TEMP];
+ return DEVICE_DISCONNECTED;
+}
+
+// returns a char with the current low alarm temperature or
+// DEVICE_DISCONNECTED for an address
+char DallasTemperature::getLowAlarmTemp(uint8_t* deviceAddress)
+{
+ ScratchPad scratchPad;
+ if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[LOW_ALARM_TEMP];
+ return DEVICE_DISCONNECTED;
+}
+
+// resets internal variables used for the alarm search
+void DallasTemperature::resetAlarmSearch()
+{
+ alarmSearchJunction = -1;
+ alarmSearchExhausted = 0;
+ for(uint8_t i = 0; i < 7; i++)
+ alarmSearchAddress[i] = 0;
+}
+
+// This is a modified version of the OneWire::search method.
+//
+// Also added the OneWire search fix documented here:
+// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295
+//
+// Perform an alarm search. If this function returns a '1' then it has
+// enumerated the next device and you may retrieve the ROM from the
+// OneWire::address variable. If there are no devices, no further
+// devices, or something horrible happens in the middle of the
+// enumeration then a 0 is returned. If a new device is found then
+// its address is copied to newAddr. Use
+// DallasTemperature::resetAlarmSearch() to start over.
+bool DallasTemperature::alarmSearch(uint8_t* newAddr)
+{
+ uint8_t i;
+ char lastJunction = -1;
+ uint8_t done = 1;
+
+ if (alarmSearchExhausted) return false;
+ if (!_wire->reset()) return false;
+
+ // send the alarm search command
+ _wire->write(0xEC, 0);
+
+ for(i = 0; i < 64; i++)
+ {
+ uint8_t a = _wire->read_bit( );
+ uint8_t nota = _wire->read_bit( );
+ uint8_t ibyte = i / 8;
+ uint8_t ibit = 1 << (i & 7);
+
+ // I don't think this should happen, this means nothing responded, but maybe if
+ // something vanishes during the search it will come up.
+ if (a && nota) return false;
+
+ if (!a && !nota)
+ {
+ if (i == alarmSearchJunction)
+ {
+ // this is our time to decide differently, we went zero last time, go one.
+ a = 1;
+ alarmSearchJunction = lastJunction;
+ }
+ else if (i < alarmSearchJunction)
+ {
+ // take whatever we took last time, look in address
+ if (alarmSearchAddress[ibyte] & ibit) a = 1;
+ else
+ {
+ // Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s
+ a = 0;
+ done = 0;
+ lastJunction = i;
+ }
+ }
+ else
+ {
+ // we are blazing new tree, take the 0
+ a = 0;
+ alarmSearchJunction = i;
+ done = 0;
+ }
+ // OneWire search fix
+ // See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295
+ }
+
+ if (a) alarmSearchAddress[ibyte] |= ibit;
+ else alarmSearchAddress[ibyte] &= ~ibit;
+
+ _wire->write_bit(a);
+ }
+
+ if (done) alarmSearchExhausted = 1;
+ for (i = 0; i < 8; i++) newAddr[i] = alarmSearchAddress[i];
+ return true;
+}
+
+// returns true if device address has an alarm condition
+// TODO: can this be done with only TEMP_MSB REGISTER (faster)
+// if ((char) scratchPad[TEMP_MSB] <= (char) scratchPad[LOW_ALARM_TEMP]) return true;
+// if ((char) scratchPad[TEMP_MSB] >= (char) scratchPad[HIGH_ALARM_TEMP]) return true;
+bool DallasTemperature::hasAlarm(uint8_t* deviceAddress)
+{
+ ScratchPad scratchPad;
+ if (isConnected(deviceAddress, scratchPad))
+ {
+ float temp = calculateTemperature(deviceAddress, scratchPad);
+
+ // check low alarm
+ if ((char)temp <= (char)scratchPad[LOW_ALARM_TEMP]) return true;
+
+ // check high alarm
+ if ((char)temp >= (char)scratchPad[HIGH_ALARM_TEMP]) return true;
+ }
+
+ // no alarm
+ return false;
+}
+
+// returns true if any device is reporting an alarm condition on the bus
+bool DallasTemperature::hasAlarm(void)
+{
+ DeviceAddress deviceAddress;
+ resetAlarmSearch();
+ return alarmSearch(deviceAddress);
+}
+
+// runs the alarm handler for all devices returned by alarmSearch()
+void DallasTemperature::processAlarms(void)
+{
+ resetAlarmSearch();
+ DeviceAddress alarmAddr;
+
+ while (alarmSearch(alarmAddr))
+ {
+ if (validAddress(alarmAddr))
+ _AlarmHandler(alarmAddr);
+ }
+}
+
+// sets the alarm handler
+void DallasTemperature::setAlarmHandler(AlarmHandler *handler)
+{
+ _AlarmHandler = handler;
+}
+
+// The default alarm handler
+void DallasTemperature::defaultAlarmHandler(uint8_t* deviceAddress)
+{
+}
+
+#endif
+
+// Convert float celsius to fahrenheit
+float DallasTemperature::toFahrenheit(float celsius)
+{
+ return (celsius * 1.8) + 32;
+}
+
+// Convert float fahrenheit to celsius
+float DallasTemperature::toCelsius(float fahrenheit)
+{
+ return (fahrenheit - 32) / 1.8;
+}
+
+#if REQUIRESNEW
+
+// MnetCS - Allocates memory for DallasTemperature. Allows us to instance a new object
+void* DallasTemperature::operator new(unsigned int size) // Implicit NSS obj size
+{
+ void * p; // void pointer
+ p = malloc(size); // Allocate memory
+ memset((DallasTemperature*)p,0,size); // Initalise memory
+
+ //!!! CANT EXPLICITLY CALL CONSTRUCTOR - workaround by using an init() methodR - workaround by using an init() method
+ return (DallasTemperature*) p; // Cast blank region to NSS pointer
+}
+
+// MnetCS 2009 - Unallocates the memory used by this instance
+void DallasTemperature::operator delete(void* p)
+{
+ DallasTemperature* pNss = (DallasTemperature*) p; // Cast to NSS pointer
+ pNss->~DallasTemperature(); // Destruct the object
+
+ free(p); // Free the memory
+}
+
+#endif
diff --git a/arduino/lib/DallasTemperature/DallasTemperature.h b/arduino/lib/DallasTemperature/DallasTemperature.h
new file mode 100755
index 00000000..d71fb981
--- /dev/null
+++ b/arduino/lib/DallasTemperature/DallasTemperature.h
@@ -0,0 +1,242 @@
+#ifndef DallasTemperature_h
+#define DallasTemperature_h
+
+#define DALLASTEMPLIBVERSION "3.7.2"
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// set to true to include code for new and delete operators
+#ifndef REQUIRESNEW
+#define REQUIRESNEW false
+#endif
+
+// set to true to include code implementing alarm search functions
+#ifndef REQUIRESALARMS
+#define REQUIRESALARMS true
+#endif
+
+#include
+#include
+
+// Model IDs
+#define DS18S20MODEL 0x10
+#define DS18B20MODEL 0x28
+#define DS1822MODEL 0x22
+
+// OneWire commands
+#define STARTCONVO 0x44 // Tells device to take a temperature reading and put it on the scratchpad
+#define COPYSCRATCH 0x48 // Copy EEPROM
+#define READSCRATCH 0xBE // Read EEPROM
+#define WRITESCRATCH 0x4E // Write to EEPROM
+#define RECALLSCRATCH 0xB8 // Reload from last known
+#define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power
+#define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition
+
+// Scratchpad locations
+#define TEMP_LSB 0
+#define TEMP_MSB 1
+#define HIGH_ALARM_TEMP 2
+#define LOW_ALARM_TEMP 3
+#define CONFIGURATION 4
+#define INTERNAL_BYTE 5
+#define COUNT_REMAIN 6
+#define COUNT_PER_C 7
+#define SCRATCHPAD_CRC 8
+
+// Device resolution
+#define TEMP_9_BIT 0x1F // 9 bit
+#define TEMP_10_BIT 0x3F // 10 bit
+#define TEMP_11_BIT 0x5F // 11 bit
+#define TEMP_12_BIT 0x7F // 12 bit
+
+// Error Codes
+#define DEVICE_DISCONNECTED -127
+
+typedef uint8_t DeviceAddress[8];
+
+class DallasTemperature
+{
+ public:
+
+ DallasTemperature(OneWire*);
+
+ // initalise bus
+ void begin(void);
+
+ // returns the number of devices found on the bus
+ uint8_t getDeviceCount(void);
+
+ // Is a conversion complete on the wire?
+ bool isConversionComplete(void);
+
+ // returns true if address is valid
+ bool validAddress(uint8_t*);
+
+ // finds an address at a given index on the bus
+ bool getAddress(uint8_t*, const uint8_t);
+
+ // attempt to determine if the device at the given address is connected to the bus
+ bool isConnected(uint8_t*);
+
+ // attempt to determine if the device at the given address is connected to the bus
+ // also allows for updating the read scratchpad
+ bool isConnected(uint8_t*, uint8_t*);
+
+ // read device's scratchpad
+ void readScratchPad(uint8_t*, uint8_t*);
+
+ // write device's scratchpad
+ void writeScratchPad(uint8_t*, const uint8_t*);
+
+ // read device's power requirements
+ bool readPowerSupply(uint8_t*);
+
+ // get global resolution
+ uint8_t getResolution();
+
+ // set global resolution to 9, 10, 11, or 12 bits
+ void setResolution(uint8_t);
+
+ // returns the device resolution, 9-12
+ uint8_t getResolution(uint8_t*);
+
+ // set resolution of a device to 9, 10, 11, or 12 bits
+ bool setResolution(uint8_t*, uint8_t);
+
+ // sets/gets the waitForConversion flag
+ void setWaitForConversion(bool);
+ bool getWaitForConversion(void);
+
+ // sets/gets the checkForConversion flag
+ void setCheckForConversion(bool);
+ bool getCheckForConversion(void);
+
+ // sends command for all devices on the bus to perform a temperature conversion
+ void requestTemperatures(void);
+
+ // sends command for one device to perform a temperature conversion by address
+ bool requestTemperaturesByAddress(uint8_t*);
+
+ // sends command for one device to perform a temperature conversion by index
+ bool requestTemperaturesByIndex(uint8_t);
+
+ // returns temperature in degrees C
+ float getTempC(uint8_t*);
+
+ // returns temperature in degrees F
+ float getTempF(uint8_t*);
+
+ // Get temperature for device index (slow)
+ float getTempCByIndex(uint8_t);
+
+ // Get temperature for device index (slow)
+ float getTempFByIndex(uint8_t);
+
+ // returns true if the bus requires parasite power
+ bool isParasitePowerMode(void);
+
+ bool isConversionAvailable(uint8_t*);
+
+ #if REQUIRESALARMS
+
+ typedef void AlarmHandler(uint8_t*);
+
+ // sets the high alarm temperature for a device
+ // accepts a char. valid range is -55C - 125C
+ void setHighAlarmTemp(uint8_t*, const char);
+
+ // sets the low alarm temperature for a device
+ // accepts a char. valid range is -55C - 125C
+ void setLowAlarmTemp(uint8_t*, const char);
+
+ // returns a signed char with the current high alarm temperature for a device
+ // in the range -55C - 125C
+ char getHighAlarmTemp(uint8_t*);
+
+ // returns a signed char with the current low alarm temperature for a device
+ // in the range -55C - 125C
+ char getLowAlarmTemp(uint8_t*);
+
+ // resets internal variables used for the alarm search
+ void resetAlarmSearch(void);
+
+ // search the wire for devices with active alarms
+ bool alarmSearch(uint8_t*);
+
+ // returns true if ia specific device has an alarm
+ bool hasAlarm(uint8_t*);
+
+ // returns true if any device is reporting an alarm on the bus
+ bool hasAlarm(void);
+
+ // runs the alarm handler for all devices returned by alarmSearch()
+ void processAlarms(void);
+
+ // sets the alarm handler
+ void setAlarmHandler(AlarmHandler *);
+
+ // The default alarm handler
+ static void defaultAlarmHandler(uint8_t*);
+
+ #endif
+
+ // convert from celcius to farenheit
+ static float toFahrenheit(const float);
+
+ // convert from farenheit to celsius
+ static float toCelsius(const float);
+
+ #if REQUIRESNEW
+
+ // initalize memory area
+ void* operator new (unsigned int);
+
+ // delete memory reference
+ void operator delete(void*);
+
+ #endif
+
+ private:
+ typedef uint8_t ScratchPad[9];
+
+ // parasite power on or off
+ bool parasite;
+
+ // used to determine the delay amount needed to allow for the
+ // temperature conversion to take place
+ uint8_t bitResolution;
+
+ // used to requestTemperature with or without delay
+ bool waitForConversion;
+
+ // used to requestTemperature to dynamically check if a conversion is complete
+ bool checkForConversion;
+
+ // count of devices on the bus
+ uint8_t devices;
+
+ // Take a pointer to one wire instance
+ OneWire* _wire;
+
+ // reads scratchpad and returns the temperature in degrees C
+ float calculateTemperature(uint8_t*, uint8_t*);
+
+ void blockTillConversionComplete(uint8_t*,uint8_t*);
+
+ #if REQUIRESALARMS
+
+ // required for alarmSearch
+ uint8_t alarmSearchAddress[8];
+ char alarmSearchJunction;
+ uint8_t alarmSearchExhausted;
+
+ // the alarm handler function pointer
+ AlarmHandler *_AlarmHandler;
+
+ #endif
+
+};
+#endif
diff --git a/arduino/lib/DallasTemperature/Multiple/Multiple.ino b/arduino/lib/DallasTemperature/Multiple/Multiple.ino
new file mode 100755
index 00000000..14536a87
--- /dev/null
+++ b/arduino/lib/DallasTemperature/Multiple/Multiple.ino
@@ -0,0 +1,152 @@
+#include
+#include
+
+// Data wire is plugged into port 2 on the Arduino
+#define ONE_WIRE_BUS 2
+#define TEMPERATURE_PRECISION 9
+
+// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
+OneWire oneWire(ONE_WIRE_BUS);
+
+// Pass our oneWire reference to Dallas Temperature.
+DallasTemperature sensors(&oneWire);
+
+// arrays to hold device addresses
+DeviceAddress insideThermometer, outsideThermometer, middleThermometer;
+
+void setup(void)
+{
+ // start serial port
+ Serial.begin(9600);
+ Serial.println("Dallas Temperature IC Control Library Demo");
+
+ // Start up the library
+ sensors.begin();
+
+ // locate devices on the bus
+ Serial.print("Locating devices...");
+ Serial.print("Found ");
+ Serial.print(sensors.getDeviceCount(), DEC);
+ Serial.println(" devices.");
+
+ // report parasite power requirements
+ Serial.print("Parasite power is: ");
+ if (sensors.isParasitePowerMode()) Serial.println("ON");
+ else Serial.println("OFF");
+
+ // assign address manually. the addresses below will beed to be changed
+ // to valid device addresses on your bus. device address can be retrieved
+ // by using either oneWire.search(deviceAddress) or individually via
+ // sensors.getAddress(deviceAddress, index)
+ //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
+ //outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };
+
+ // search for devices on the bus and assign based on an index. ideally,
+ // you would do this to initially discover addresses on the bus and then
+ // use those addresses and manually assign them (see above) once you know
+ // the devices on your bus (and assuming they don't change).
+ //
+ // method 1: by index
+ if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
+ if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
+ if (!sensors.getAddress(middleThermometer, 2)) Serial.println("Unable to find address for Device 2");
+
+ // method 2: search()
+ // search() looks for the next device. Returns 1 if a new address has been
+ // returned. A zero might mean that the bus is shorted, there are no devices,
+ // or you have already retrieved all of them. It might be a good idea to
+ // check the CRC to make sure you didn't get garbage. The order is
+ // deterministic. You will always get the same devices in the same order
+ //
+ // Must be called before search()
+ //oneWire.reset_search();
+ // assigns the first address found to insideThermometer
+ //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
+ // assigns the seconds address found to outsideThermometer
+ //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");
+
+ // show the addresses we found on the bus
+ Serial.print("Device 0 Address: ");
+ printAddress(insideThermometer);
+ Serial.println();
+
+ Serial.print("Device 1 Address: ");
+ printAddress(outsideThermometer);
+ Serial.println();
+
+ Serial.print("Device 2 Address: ");
+ printAddress(middleThermometer);
+ Serial.println();
+
+ // set the resolution to 9 bit
+ sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
+ sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
+ sensors.setResolution(middleThermometer, TEMPERATURE_PRECISION);
+
+ Serial.print("Device 0 Resolution: ");
+ Serial.print(sensors.getResolution(insideThermometer), DEC);
+ Serial.println();
+
+ Serial.print("Device 1 Resolution: ");
+ Serial.print(sensors.getResolution(outsideThermometer), DEC);
+ Serial.println();
+
+ Serial.print("Device 2 Resolution: ");
+ Serial.print(sensors.getResolution(middleThermometer), DEC);
+ Serial.println();
+}
+
+// function to print a device address
+void printAddress(DeviceAddress deviceAddress)
+{
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ // zero pad the address if necessary
+ if (deviceAddress[i] < 16) Serial.print("0");
+ Serial.print(deviceAddress[i], HEX);
+ }
+}
+
+// function to print the temperature for a device
+void printTemperature(DeviceAddress deviceAddress)
+{
+ float tempC = sensors.getTempC(deviceAddress);
+ Serial.print("Temp C: ");
+ Serial.print(tempC);
+ Serial.print(" Temp F: ");
+ Serial.print(DallasTemperature::toFahrenheit(tempC));
+}
+
+// function to print a device's resolution
+void printResolution(DeviceAddress deviceAddress)
+{
+ Serial.print("Resolution: ");
+ Serial.print(sensors.getResolution(deviceAddress));
+ Serial.println();
+}
+
+// main function to print information about a device
+void printData(DeviceAddress deviceAddress)
+{
+ Serial.print("Device Address: ");
+ printAddress(deviceAddress);
+ Serial.print(" ");
+ printTemperature(deviceAddress);
+ Serial.println();
+}
+
+void loop(void)
+{
+ // call sensors.requestTemperatures() to issue a global temperature
+ // request to all devices on the bus
+ Serial.print("Requesting temperatures...");
+ sensors.requestTemperatures();
+ Serial.println("DONE");
+
+ // print the device information
+ printData(insideThermometer);
+ printData(outsideThermometer);
+ printData(middleThermometer);
+ delay(1000);
+}
+
diff --git a/arduino/lib/DallasTemperature/README.TXT b/arduino/lib/DallasTemperature/README.TXT
new file mode 100755
index 00000000..764bdd73
--- /dev/null
+++ b/arduino/lib/DallasTemperature/README.TXT
@@ -0,0 +1,53 @@
+Arduino Library for Dallas Temperature ICs
+==========================================
+
+Usage
+-----
+
+This library supports the following devices:
+ DS18B20
+ DS18S20 - Please note there appears to be an issue with this series.
+ DS1822
+
+You will need a pull-up resistor of about 5 KOhm between the 1-Wire data line
+and your 5V power. If you are using the DS18B20, ground pins 1 and 3. The
+centre pin is the data line '1-wire'.
+
+We have included a "REQUIRESNEW" and "REQUIRESALARMS" definition. If you
+want to slim down the code feel free to use either of these by including
+#define REQUIRESNEW or #define REQUIRESALARMS a the top of DallasTemperature.h
+
+Credits
+-------
+
+The OneWire code has been derived from
+http://www.arduino.cc/playground/Learning/OneWire.
+Miles Burton originally developed this library.
+Tim Newsome added support for multiple sensors on
+the same bus.
+Guil Barros [gfbarros@bappos.com] added getTempByAddress (v3.5)
+Rob Tillaart [rob.tillaart@gmail.com] added async modus (v3.7.0)
+
+
+Website
+-------
+
+You can find the latest version of the library at
+http://milesburton.com/index.php?title=Dallas_Temperature_Control_Library
+
+License
+-------
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/arduino/lib/DallasTemperature/change.txt b/arduino/lib/DallasTemperature/change.txt
new file mode 100755
index 00000000..42564ca1
--- /dev/null
+++ b/arduino/lib/DallasTemperature/change.txt
@@ -0,0 +1,85 @@
+
+This file contains the change history of the Dallas Temperature Control Library.
+
+VERSION 3.7.2 BETA
+===================
+DATE: 6 DEC 2011
+
+- Jordan Hochenbaum [jhochenbaum@gmail.com] updated library for compatibility with Arduino 1.0.
+
+VERSION 3.7.0 BETA
+===================
+DATE: 11 JAN 2011
+
+- Rob Tillaart [rob.tillaart@gmail.com] added async modus (v3.7.0)
+ The library is backwards compatible with version 3.6.0
+
+ MAJOR: async modus
+ ------------------
+- Added - private bool waitForConversion.
+This boolean is default set to true in the Constructor to keep the library backwards compatible. If this flag is true calls to requestTemperatures(), requestTemperaturesByAddress() et al, will be blocking with the appropiate time specified (in datasheet) for the resolution used. If the flag is set to false, requestTemperatures() et al, will return immediately after the conversion command is send over the 1-wire interface. The programmer is responsible to wait long enough before reading the temperature values. This enables the application to do other things while waiting for a new reading, like calculations, update LCD, read/write other IO lines etc. See examples.
+
+- Added - void setWaitForConversion(bool);
+To set the flag to true or false, depending on the modus needed.
+
+- Added - bool getWaitForConversion(void);
+To get the current value of the flag.
+
+- Changed - void requestTemperatures(void);
+Added a test (false == waitForConversion) to return immediately after the conversion command instead of waiting until the conversion is ready.
+
+- Changed - bool requestTemperaturesByAddress(uint8_t*);
+Added a test (false == waitForConversion) to return immediately after the conversion command instead of waiting until the conversion is ready.
+
+
+ MINOR version number
+ --------------------
+- Added - #define DALLASTEMPLIBVERSION "3.7.0"
+To indicate the version number in .h file
+
+
+ MINOR internal var bitResolution
+ ----------------------------
+- Changed - private int conversionDelay - is renamed to - private int bitResolution
+As this variable holds the resolution. The delay for the conversion is derived from it.
+
+- Changed - uint8_t getResolution(uint8_t* deviceAddress);
+If the device is not connected, it returns 0, otherwise it returns the resolution of the device.
+
+- Changed - bool setResolution(uint8_t* deviceAddress, uint8_t newResolution);
+If the device is not connected, it returns FALSE (fail), otherwise it returns TRUE (succes).
+
+- Added - uint8_t getResolution();
+Returns bitResolution.
+
+- Added - void setResolution(uint8_t newResolution)
+Sets the internal variable bitResolution, and all devices to this value
+
+
+ MINOR check connected state
+ ----------------------------
+- Changed - bool requestTemperaturesByIndex(deviceIndex)
+Changed return type from void to bool. The function returns false if the device identified with [deviceIndex] is not found on the bus and true otherwise.
+
+- Changed - bool requestTemperaturesByAddress(deviceAddress)
+Changed return type from void to bool. The function returns false if the device identified with [deviceAddress] is not found on the bus and true otherwise.
+Added code to handle the DS18S20 which has a 9 bit resolution separately.
+Changed code so the blocking delay matches the bitResolution set in the device with deviceAddress.
+
+- Changed - bool requestTemperaturesByIndex(uint8_t deviceIndex)
+Changed return type from void to bool. The function returns false if the device identified with [deviceIndex] is not found on the bus and true otherwise.
+
+
+
+VERSION 3.6.0
+==============
+DATE: 2010-10-10
+
+- no detailed change history known except:
+
+- The OneWire code has been derived from
+http://www.arduino.cc/playground/Learning/OneWire.
+- Miles Burton originally developed this library.
+- Tim Newsome added support for multiple sensors on
+the same bus.
+- Guil Barros [gfbarros@bappos.com] added getTempByAddress (v3.5)
diff --git a/arduino/lib/DallasTemperature/examples/Multiple/Multiple.ino b/arduino/lib/DallasTemperature/examples/Multiple/Multiple.ino
new file mode 100755
index 00000000..245381db
--- /dev/null
+++ b/arduino/lib/DallasTemperature/examples/Multiple/Multiple.ino
@@ -0,0 +1,140 @@
+#include
+#include
+
+// Data wire is plugged into port 2 on the Arduino
+#define ONE_WIRE_BUS 2
+#define TEMPERATURE_PRECISION 12
+
+// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
+OneWire oneWire(ONE_WIRE_BUS);
+
+// Pass our oneWire reference to Dallas Temperature.
+DallasTemperature sensors(&oneWire);
+
+// arrays to hold device addresses
+DeviceAddress insideThermometer, outsideThermometer;
+
+void setup(void)
+{
+ // start serial port
+ Serial.begin(9600);
+ Serial.println("Dallas Temperature IC Control Library Demo");
+
+ // Start up the library
+ sensors.begin();
+
+ // locate devices on the bus
+ Serial.print("Locating devices...");
+ Serial.print("Found ");
+ Serial.print(sensors.getDeviceCount(), DEC);
+ Serial.println(" devices.");
+
+ // report parasite power requirements
+ Serial.print("Parasite power is: ");
+ if (sensors.isParasitePowerMode()) Serial.println("ON");
+ else Serial.println("OFF");
+
+ // assign address manually. the addresses below will beed to be changed
+ // to valid device addresses on your bus. device address can be retrieved
+ // by using either oneWire.search(deviceAddress) or individually via
+ // sensors.getAddress(deviceAddress, index)
+ //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
+ //outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };
+
+ // search for devices on the bus and assign based on an index. ideally,
+ // you would do this to initially discover addresses on the bus and then
+ // use those addresses and manually assign them (see above) once you know
+ // the devices on your bus (and assuming they don't change).
+ //
+ // method 1: by index
+ if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
+ if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
+
+ // method 2: search()
+ // search() looks for the next device. Returns 1 if a new address has been
+ // returned. A zero might mean that the bus is shorted, there are no devices,
+ // or you have already retrieved all of them. It might be a good idea to
+ // check the CRC to make sure you didn't get garbage. The order is
+ // deterministic. You will always get the same devices in the same order
+ //
+ // Must be called before search()
+ //oneWire.reset_search();
+ // assigns the first address found to insideThermometer
+ //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
+ // assigns the seconds address found to outsideThermometer
+ //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");
+
+ // show the addresses we found on the bus
+ Serial.print("Device 0 Address: ");
+ printAddress(insideThermometer);
+ Serial.println();
+
+ Serial.print("Device 1 Address: ");
+ printAddress(outsideThermometer);
+ Serial.println();
+
+ // set the resolution
+ sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
+ sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
+
+ Serial.print("Device 0 Resolution: ");
+ Serial.print(sensors.getResolution(insideThermometer), DEC);
+ Serial.println();
+
+ Serial.print("Device 1 Resolution: ");
+ Serial.print(sensors.getResolution(outsideThermometer), DEC);
+ Serial.println();
+}
+
+// function to print a device address
+void printAddress(DeviceAddress deviceAddress)
+{
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ // zero pad the address if necessary
+ if (deviceAddress[i] < 16) Serial.print("0");
+ Serial.print(deviceAddress[i], HEX);
+ }
+}
+
+// function to print the temperature for a device
+void printTemperature(DeviceAddress deviceAddress)
+{
+ float tempC = sensors.getTempC(deviceAddress);
+ Serial.print("Temp C: ");
+ Serial.print(tempC);
+ Serial.print(" Temp F: ");
+ Serial.print(DallasTemperature::toFahrenheit(tempC));
+}
+
+// function to print a device's resolution
+void printResolution(DeviceAddress deviceAddress)
+{
+ Serial.print("Resolution: ");
+ Serial.print(sensors.getResolution(deviceAddress));
+ Serial.println();
+}
+
+// main function to print information about a device
+void printData(DeviceAddress deviceAddress)
+{
+ Serial.print("Device Address: ");
+ printAddress(deviceAddress);
+ Serial.print(" ");
+ printTemperature(deviceAddress);
+ Serial.println();
+}
+
+void loop(void)
+{
+ // call sensors.requestTemperatures() to issue a global temperature
+ // request to all devices on the bus
+ Serial.print("Requesting temperatures...");
+ sensors.requestTemperatures();
+ Serial.println("DONE");
+
+ // print the device information
+ printData(insideThermometer);
+ printData(outsideThermometer);
+}
+
diff --git a/arduino/lib/DallasTemperature/examples/Simple/Simple.ino b/arduino/lib/DallasTemperature/examples/Simple/Simple.ino
new file mode 100755
index 00000000..e4383bfb
--- /dev/null
+++ b/arduino/lib/DallasTemperature/examples/Simple/Simple.ino
@@ -0,0 +1,33 @@
+#include
+#include
+
+// Data wire is plugged into port 2 on the Arduino
+#define ONE_WIRE_BUS 2
+
+// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
+OneWire oneWire(ONE_WIRE_BUS);
+
+// Pass our oneWire reference to Dallas Temperature.
+DallasTemperature sensors(&oneWire);
+
+void setup(void)
+{
+ // start serial port
+ Serial.begin(9600);
+ Serial.println("Dallas Temperature IC Control Library Demo");
+
+ // Start up the library
+ sensors.begin();
+}
+
+void loop(void)
+{
+ // call sensors.requestTemperatures() to issue a global temperature
+ // request to all devices on the bus
+ Serial.print("Requesting temperatures...");
+ sensors.requestTemperatures(); // Send the command to get temperatures
+ Serial.println("DONE");
+
+ Serial.print("Temperature for the device 1 (index 0) is: ");
+ Serial.println(sensors.getTempCByIndex(0));
+}
diff --git a/arduino/lib/DallasTemperature/examples/Single/Single.ino b/arduino/lib/DallasTemperature/examples/Single/Single.ino
new file mode 100755
index 00000000..784eb7ab
--- /dev/null
+++ b/arduino/lib/DallasTemperature/examples/Single/Single.ino
@@ -0,0 +1,109 @@
+#include
+#include
+
+// Data wire is plugged into port 2 on the Arduino
+#define ONE_WIRE_BUS 2
+
+// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
+OneWire oneWire(ONE_WIRE_BUS);
+
+// Pass our oneWire reference to Dallas Temperature.
+DallasTemperature sensors(&oneWire);
+
+// arrays to hold device address
+DeviceAddress insideThermometer;
+
+void setup(void)
+{
+ // start serial port
+ Serial.begin(9600);
+ Serial.println("Dallas Temperature IC Control Library Demo");
+
+ // locate devices on the bus
+ Serial.print("Locating devices...");
+ sensors.begin();
+ Serial.print("Found ");
+ Serial.print(sensors.getDeviceCount(), DEC);
+ Serial.println(" devices.");
+
+ // report parasite power requirements
+ Serial.print("Parasite power is: ");
+ if (sensors.isParasitePowerMode()) Serial.println("ON");
+ else Serial.println("OFF");
+
+ // assign address manually. the addresses below will beed to be changed
+ // to valid device addresses on your bus. device address can be retrieved
+ // by using either oneWire.search(deviceAddress) or individually via
+ // sensors.getAddress(deviceAddress, index)
+ //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
+
+ // Method 1:
+ // search for devices on the bus and assign based on an index. ideally,
+ // you would do this to initially discover addresses on the bus and then
+ // use those addresses and manually assign them (see above) once you know
+ // the devices on your bus (and assuming they don't change).
+ if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
+
+ // method 2: search()
+ // search() looks for the next device. Returns 1 if a new address has been
+ // returned. A zero might mean that the bus is shorted, there are no devices,
+ // or you have already retrieved all of them. It might be a good idea to
+ // check the CRC to make sure you didn't get garbage. The order is
+ // deterministic. You will always get the same devices in the same order
+ //
+ // Must be called before search()
+ //oneWire.reset_search();
+ // assigns the first address found to insideThermometer
+ //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
+
+ // show the addresses we found on the bus
+ Serial.print("Device 0 Address: ");
+ printAddress(insideThermometer);
+ Serial.println();
+
+ // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
+ sensors.setResolution(insideThermometer, 9);
+
+ Serial.print("Device 0 Resolution: ");
+ Serial.print(sensors.getResolution(insideThermometer), DEC);
+ Serial.println();
+}
+
+// function to print the temperature for a device
+void printTemperature(DeviceAddress deviceAddress)
+{
+ // method 1 - slower
+ //Serial.print("Temp C: ");
+ //Serial.print(sensors.getTempC(deviceAddress));
+ //Serial.print(" Temp F: ");
+ //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit
+
+ // method 2 - faster
+ float tempC = sensors.getTempC(deviceAddress);
+ Serial.print("Temp C: ");
+ Serial.print(tempC);
+ Serial.print(" Temp F: ");
+ Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
+}
+
+void loop(void)
+{
+ // call sensors.requestTemperatures() to issue a global temperature
+ // request to all devices on the bus
+ Serial.print("Requesting temperatures...");
+ sensors.requestTemperatures(); // Send the command to get temperatures
+ Serial.println("DONE");
+
+ // It responds almost immediately. Let's print out the data
+ printTemperature(insideThermometer); // Use a simple function to print out the data
+}
+
+// function to print a device address
+void printAddress(DeviceAddress deviceAddress)
+{
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ if (deviceAddress[i] < 16) Serial.print("0");
+ Serial.print(deviceAddress[i], HEX);
+ }
+}
diff --git a/arduino/lib/DallasTemperature/examples/Tester/Tester.ino b/arduino/lib/DallasTemperature/examples/Tester/Tester.ino
new file mode 100755
index 00000000..4f75839a
--- /dev/null
+++ b/arduino/lib/DallasTemperature/examples/Tester/Tester.ino
@@ -0,0 +1,124 @@
+#include
+#include
+
+// Data wire is plugged into port 2 on the Arduino
+#define ONE_WIRE_BUS 2
+#define TEMPERATURE_PRECISION 9
+
+// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
+OneWire oneWire(ONE_WIRE_BUS);
+
+// Pass our oneWire reference to Dallas Temperature.
+DallasTemperature sensors(&oneWire);
+
+int numberOfDevices; // Number of temperature devices found
+
+DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
+
+void setup(void)
+{
+ // start serial port
+ Serial.begin(9600);
+ Serial.println("Dallas Temperature IC Control Library Demo");
+
+ // Start up the library
+ sensors.begin();
+
+ // Grab a count of devices on the wire
+ numberOfDevices = sensors.getDeviceCount();
+
+ // locate devices on the bus
+ Serial.print("Locating devices...");
+
+ Serial.print("Found ");
+ Serial.print(numberOfDevices, DEC);
+ Serial.println(" devices.");
+
+ // report parasite power requirements
+ Serial.print("Parasite power is: ");
+ if (sensors.isParasitePowerMode()) Serial.println("ON");
+ else Serial.println("OFF");
+
+ // Loop through each device, print out address
+ for(int i=0;i
+
+OneWire ds(2); // Connect your 1-wire device to pin 2
+
+void setup(void) {
+ Serial.begin(9600);
+ discoverOneWireDevices();
+}
+
+void discoverOneWireDevices(void) {
+ byte i;
+ byte present = 0;
+ byte data[12];
+ byte addr[8];
+
+ Serial.print("Looking for 1-Wire devices...\n\r");
+ while(ds.search(addr)) {
+ Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
+ for( i = 0; i < 8; i++) {
+ Serial.print("0x");
+ if (addr[i] < 16) {
+ Serial.print('0');
+ }
+ Serial.print(addr[i], HEX);
+ if (i < 7) {
+ Serial.print(", ");
+ }
+ }
+ if ( OneWire::crc8( addr, 7) != addr[7]) {
+ Serial.print("CRC is not valid!\n");
+ return;
+ }
+ }
+ Serial.print("\n\r\n\rThat's it.\r\n");
+ ds.reset_search();
+ return;
+}
+
+void loop(void) {
+ // nothing to see here
+}
+
+
diff --git a/arduino/lib/DallasTemperature/keywords.txt b/arduino/lib/DallasTemperature/keywords.txt
new file mode 100755
index 00000000..0212d443
--- /dev/null
+++ b/arduino/lib/DallasTemperature/keywords.txt
@@ -0,0 +1,54 @@
+#######################################
+# Syntax Coloring Map For Ultrasound
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+DallasTemperature KEYWORD1
+OneWire KEYWORD1
+AlarmHandler KEYWORD1
+DeviceAddress KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+setResolution KEYWORD2
+getResolution KEYWORD2
+getTempC KEYWORD2
+toFahrenheit KEYWORD2
+getTempF KEYWORD2
+getTempCByIndex KEYWORD2
+getTempFByIndex KEYWORD2
+setWaitForConversion KEYWORD2
+getWaitForConversion KEYWORD2
+requestTemperatures KEYWORD2
+requestTemperaturesByAddress KEYWORD2
+requestTemperaturesByIndex KEYWORD2
+isParasitePowerMode KEYWORD2
+begin KEYWORD2
+getDeviceCount KEYWORD2
+getAddress KEYWORD2
+validAddress KEYWORD2
+isConnected KEYWORD2
+readScratchPad KEYWORD2
+writeScratchPad KEYWORD2
+readPowerSupply KEYWORD2
+setHighAlarmTemp KEYWORD2
+setLowAlarmTemp KEYWORD2
+getHighAlarmTemp KEYWORD2
+getLowAlarmTemp KEYWORD2
+resetAlarmSearch KEYWORD2
+alarmSearch KEYWORD2
+hasAlarm KEYWORD2
+toCelsius KEYWORD2
+processAlarmss KEYWORD2
+setAlarmHandlers KEYWORD2
+defaultAlarmHandler KEYWORD2
+calculateTemperature KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index d3876ef0..00000000
--- a/build.gradle
+++ /dev/null
@@ -1,126 +0,0 @@
-plugins {
- id 'java'
- id 'application'
-}
-
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2025 Ziver Koc
- *
- * 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.
- */
-
-// ------------------------------------
-// Hal common configuration
-// ------------------------------------
-
-allprojects {
- repositories {
- mavenLocal()
- mavenCentral()
- }
-}
-
-subprojects {
- apply plugin: 'java-library'
-
- dependencies {
- //implementation 'se.koc:zutil:1.0.314'
- implementation 'se.koc:zutil:1.0.0-SNAPSHOT'
-
- testImplementation 'junit:junit:4.12'
- testImplementation 'org.hamcrest:hamcrest-core:2.2'
- }
-
- sourceSets {
- main {
- java {
- srcDirs 'src'
- }
- // We do not want the resource folder to be included in the jar file
- //resources {
- // srcDir 'resource'
- //}
- }
- test {
- java {
- srcDirs 'test'
- }
- }
- }
-
- tasks.withType(JavaCompile) {
- options.compilerArgs << "-Xlint:deprecation"
- //options.compilerArgs << "-Xlint:unchecked"
- }
-}
-
-// ------------------------------------
-// Hal general configuration
-// ------------------------------------
-
-dependencies {
- project.subprojects.each { subProject ->
- runtimeOnly subProject
- }
-}
-
-distributions {
- main {
- contents {
- // from root project
- from 'hal.conf.example'
- from 'logging.properties'
- from 'run.sh'
-
- // from subprojects
- project.subprojects.each { subProject ->
- into('bin') {
- from "${subProject.projectDir}/resources/bin"
- }
- into('web') {
- from "${subProject.projectDir}/resources/web"
- }
- into('resources') {
- from ("${subProject.projectDir}/resources") {
- exclude 'bin'
- exclude 'web'
- }
- }
- }
- }
- }
-}
-
-distTar.enabled = false
-distZip.enabled = false
-assemble.dependsOn(installDist)
-
-project.gradle.startParameter.taskNames.each { taskName ->
- if (taskName == 'distZip') {
- distZip.enabled = true
- }
-}
-
-application {
- mainClass = 'se.hal.HalServer'
-}
-
-startScripts.enabled = false
diff --git a/build.xml b/build.xml
new file mode 100755
index 00000000..f27aa573
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/external/Z-Stick_Gen5_Drivers.zip b/external/Z-Stick_Gen5_Drivers.zip
deleted file mode 100644
index c5b3356e..00000000
Binary files a/external/Z-Stick_Gen5_Drivers.zip and /dev/null differ
diff --git a/external/marytts-5.1.2/LICENSE.txt b/external/marytts-5.1.2/LICENSE.txt
new file mode 100755
index 00000000..01dc74eb
--- /dev/null
+++ b/external/marytts-5.1.2/LICENSE.txt
@@ -0,0 +1,74 @@
+MARY Software User Agreement
+11 April 2011
+
+MARY is licensed under the following terms.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see .
+
+
+
+
+Applicable Licenses
+
+MARY is built upon a number of other open source technologies and products.
+Here is a list of those products with links to their licenses.
+
+hts_engine: the HMM-based speech synthesis code in MARY TTS is based on HTS, ported to Java by DFKI. The original HTS can be obtained from
+http://hts-engine.sourceforge.net/ -- it is released under the New and
+Simplified BSD License.
+
+freetts: MARY uses code from FreeTTS (http://freetts.sf.net) for various
+processing modules and as the source of one method for waveform synthesis.
+FreeTTS is licensed under the (BSD-style) FreeTTS license, see
+doc/licenses/freetts-license.txt.
+
+JTok: The JTok tokenizer from http://heartofgold.dfki.de is distributed
+under the GNU Lesser General Public License, see http://www.gnu.org or
+doc/licenses/LGPL.txt.
+
+jsresources.jar: A few utility classes from http://www.jsresources.org
+are distributed under the terms of the jsresources license, see
+doc/licenses/jsresources-license.txt.
+
+log4j: MARY uses log4j (http://logging.apache.org/log4j) as a logging
+mechanism. log4j is distributed under the Apache Software License, see
+http://www.apache.org or doc/licenses/apache-software-license.txt
+
+JUnit: For unit testing of the java source, mary uses JUnit
+(http://junit.org). JUnit is licensed under the Common Public License, see
+http://junit.org or doc/licenses/CPL.txt.
+
+java-diff: A java diff implementation from http://www.incava.org/projects/java-diff for input-output-comparisons in the
+Mary Expert Interface. java-diff is licensed under the GNU Lesser General
+Public License, see http://www.gnu.org or doc/licenses/LGPL.txt.
+
+fast-md5: A fast md5 checksum implementation from http://www.twmacinta.com/myjava/fast_md5.php
+used for computing checksums after downloading voices. fast-md5 is licensed under
+the GNU Lesser General Public License, see http://www.gnu.org or doc/licenses/LGPL.txt.
+
+JavaOpenAIR: MARY can optionally be used as an OpenAIR component,
+building on the JavaOpenAIR reference implementation from
+http://www.mindmakers.org, which is licensed under the
+(BSD-style) JavaOpenAIR license, see doc/licenses/JavaOpenAIR-license.txt
+(files concerned: JavaOpenAIR.jar)
+
+mwdumper: A tool for extracting sets of pages from a MediaWiki dump file.
+mwdumper is MIT-style like licensed, see http://www.mediawiki.org/wiki/Mwdumper
+and for the license http://en.wikipedia.org/wiki/MIT_License.
+(files concerned: mwdumper-2008-04-13.jar)
+
+
+sgt: The Scientific Graphics Toolkit (sgt) is provided by the NOAA/PMEL/EPIC group (see http://www.epic.noaa.gov/java/sgt/) under the BSD-style EPIC license, see doc/licenses/epic-license.txt.
+
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS
+AND CONDITIONS PRIOR TO USE OF THIS CONTENT.
diff --git a/external/marytts-5.1.2/bin/marytts-client b/external/marytts-5.1.2/bin/marytts-client
new file mode 100755
index 00000000..f20b9315
--- /dev/null
+++ b/external/marytts-5.1.2/bin/marytts-client
@@ -0,0 +1,10 @@
+#!/bin/bash
+##########################################################################
+# MARY TTS client
+##########################################################################
+
+# Set the Mary base installation directory in an environment variable:
+BINDIR="`dirname "$0"`"
+export MARY_BASE="`(cd "$BINDIR"/.. ; pwd)`"
+
+java -showversion -ea -Dserver.host=localhost -Dserver.port=59125 -jar "$MARY_BASE/lib/marytts-client-5.1.2-jar-with-dependencies.jar"
diff --git a/external/marytts-5.1.2/bin/marytts-client.bat b/external/marytts-5.1.2/bin/marytts-client.bat
new file mode 100755
index 00000000..4a231d9f
--- /dev/null
+++ b/external/marytts-5.1.2/bin/marytts-client.bat
@@ -0,0 +1,10 @@
+@echo off
+set BINDIR=%~dp0
+call :RESOLVE "%BINDIR%\.." MARY_BASE
+
+java -showversion -ea -Dserver.host=localhost -Dserver.port=59125 -jar "%MARY_BASE%\lib\marytts-client-5.1.2-jar-with-dependencies.jar"
+goto :EOF
+
+:RESOLVE
+set %2=%~f1
+goto :EOF
diff --git a/external/marytts-5.1.2/bin/marytts-component-installer b/external/marytts-5.1.2/bin/marytts-component-installer
new file mode 100755
index 00000000..44cea75d
--- /dev/null
+++ b/external/marytts-5.1.2/bin/marytts-component-installer
@@ -0,0 +1,5 @@
+#!/bin/sh
+BINDIR="`dirname "$0"`"
+export MARY_BASE="`(cd "$BINDIR"/.. ; pwd)`"
+java -showversion -ea -Dmary.base="$MARY_BASE" $* -cp "$MARY_BASE/lib/*" marytts.tools.install.InstallerGUI
+
diff --git a/external/marytts-5.1.2/bin/marytts-component-installer.bat b/external/marytts-5.1.2/bin/marytts-component-installer.bat
new file mode 100755
index 00000000..8f4ff657
--- /dev/null
+++ b/external/marytts-5.1.2/bin/marytts-component-installer.bat
@@ -0,0 +1,9 @@
+@echo off
+set BINDIR=%~dp0
+call :RESOLVE "%BINDIR%\.." MARY_BASE
+java -showversion -ea -Dmary.base="%MARY_BASE%" -cp ".;%MARY_BASE%\lib\*" marytts.tools.install.InstallerGUI
+goto :EOF
+
+:RESOLVE
+set %2=%~f1
+goto :EOF
diff --git a/external/marytts-5.1.2/bin/marytts-server b/external/marytts-5.1.2/bin/marytts-server
new file mode 100755
index 00000000..be3c0939
--- /dev/null
+++ b/external/marytts-5.1.2/bin/marytts-server
@@ -0,0 +1,11 @@
+#!/bin/bash
+##########################################################################
+# MARY TTS server
+##########################################################################
+
+# Set the Mary base installation directory in an environment variable:
+BINDIR="`dirname "$0"`"
+export MARY_BASE="`(cd "$BINDIR"/.. ; pwd)`"
+
+
+java -showversion -ea -Xms40m -Xmx1g -cp "$MARY_BASE/lib/*" -Dmary.base="$MARY_BASE" $* marytts.server.Mary
diff --git a/external/marytts-5.1.2/bin/marytts-server.bat b/external/marytts-5.1.2/bin/marytts-server.bat
new file mode 100755
index 00000000..f3cc2dad
--- /dev/null
+++ b/external/marytts-5.1.2/bin/marytts-server.bat
@@ -0,0 +1,14 @@
+@echo off
+
+rem Set the Mary base installation directory in an environment variable:
+set BINDIR=%~dp0
+
+call :RESOLVE "%BINDIR%\.." MARY_BASE
+
+set CLASSPATH=".;%MARY_BASE%\lib\*"
+java -showversion -ea -Xms40m -Xmx1g -cp %CLASSPATH% "-Dmary.base=%MARY_BASE%" marytts.server.Mary
+goto :EOF
+
+:RESOLVE
+set %2=%~f1
+goto :EOF
diff --git a/external/marytts-5.1.2/doc/examples/client/MaryClient.py b/external/marytts-5.1.2/doc/examples/client/MaryClient.py
new file mode 100755
index 00000000..46569873
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/MaryClient.py
@@ -0,0 +1,367 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import socket, sys, types, getopt
+
+
+languageNames = {'de':'German',
+ 'en':'English',
+ 'en_US':'US English',
+ 'tib':'Tibetan'}
+
+class MaryClient:
+ specificationVersion = "0.1"
+
+ """Python implementation of a MARY TTS client"""
+ def __init__( self, host="cling.dfki.uni-sb.de", port=59125, profile=False, quiet=False ):
+ self.host = host
+ self.port = port
+ self.profile = profile
+ self.quiet = quiet
+ self.allVoices = None # array of Voice objects
+ self.voicesByLocaleMap = {} # Map locale strings to arrays of Voice objects
+ self.allDataTypes = None # array of DataType objects
+ self.inputDataTypes = None # array of DataType objects
+ self.outputDataTypes = None # array of DataType objects
+ self.serverExampleTexts = {}
+ self.voiceExampleTexts = {}
+ self.serverVersionInfo = u''
+
+ if not self.quiet:
+ sys.stderr.write( "MARY TTS Python Client %s\n" % ( self.specificationVersion ) )
+ try:
+ info = self.getServerVersionInfo()
+ except:
+ sys.stderr.write( "Problem connecting to mary server at %s:%i\n" % ( self.host, self.port ) )
+ raise
+ sys.stderr.write( "Connected to %s:%i, " % ( self.host, self.port ) )
+ sys.stderr.write( info )
+ sys.stderr.write( '\n' )
+
+ def __getServerInfo( self, request="", marySocket=None ):
+ """Get answer to request from mary server. Returns a list of unicode strings,
+ each representing a line without the line break.
+ """
+ closeSocket = False
+ if marySocket is None:
+ closeSocket = True
+ marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ marySocket.connect( ( self.host, self.port ) )
+ assert isinstance(marySocket, socket.SocketType)
+ maryFile = marySocket.makefile( 'rwb', 1 ) # read-write, line-buffered
+ maryFile.write( unicode( request+"\n" ).encode( 'utf-8' ) )
+ result = []
+ while True:
+ got = unicode( maryFile.readline().strip(), 'utf-8' )
+ # read until end of file or an empty line is read:
+ if not got: break
+ result.append(got)
+ if closeSocket:
+ marySocket.close()
+ return result
+
+ def getServerVersionInfo( self ):
+ "Get version info from server. Returns a unicode string"
+ if self.serverVersionInfo == u'':
+ # need to get it from server
+ self.serverVersionInfo = u'\n'.join(self.__getServerInfo("MARY VERSION"))
+ return self.serverVersionInfo
+
+ def getAllDataTypes(self, locale=None):
+ """Obtain a list of all data types known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of DataType objects
+ """
+ if self.allDataTypes is None:
+ self.__fillDataTypes()
+ assert self.allDataTypes is not None and len( self.allDataTypes ) > 0
+ if locale is None:
+ return self.allDataTypes
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ return [d for d in self.allDataTypes if d.locale is None or d.locale == locale]
+
+ def getInputDataTypes(self,locale=None):
+ """Obtain a list of input data types known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an arry of DataType objects
+ """
+ if self.inputDataTypes is None:
+ self.__fillDataTypes()
+ assert self.inputDataTypes is not None and len( self.inputDataTypes ) > 0
+ if locale is None:
+ return self.inputDataTypes
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ return [d for d in self.inputDataTypes if d.locale is None or d.locale == locale]
+
+ def getOutputDataTypes(self, locale=None):
+ """Obtain a list of output data types known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an arry of DataType objects
+ """
+ if self.outputDataTypes is None:
+ self.__fillDataTypes()
+ assert self.outputDataTypes is not None and len( self.outputDataTypes ) > 0
+ if locale is None:
+ return self.outputDataTypes
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ return [d for d in self.outputDataTypes if d.locale is None or d.locale == locale]
+
+
+ def __fillDataTypes( self ):
+ self.allDataTypes = []
+ self.inputDataTypes = []
+ self.outputDataTypes = []
+ marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ marySocket.connect( ( self.host, self.port ) )
+ # Expect a variable number of lines of the kind
+ # RAWMARYXML INPUT OUTPUT
+ # TEXT_DE LOCALE=de INPUT
+ # AUDIO OUTPUT
+ typeStrings = self.__getServerInfo( "MARY LIST DATATYPES", marySocket )
+ if not typeStrings or len(typeStrings) == 0:
+ raise IOError( "Could not get list of data types from Mary server" )
+ marySocket.close()
+ for typeString in typeStrings:
+ parts = typeString.split()
+ if len( parts ) == 0:
+ continue
+ name = parts[0]
+ isInputType = False
+ isOutputType = False
+ locale = None
+ for part in parts[1:]:
+ if part[:7] == "LOCALE=":
+ locale = part[7:]
+ elif part == "INPUT":
+ isInputType = True
+ elif part == "OUTPUT":
+ isOutputType = True
+ dt = DataType( name, locale, isInputType, isOutputType )
+ self.allDataTypes.append( dt )
+ if dt.isInputType:
+ self.inputDataTypes.append( dt )
+ if dt.isOutputType:
+ self.outputDataTypes.append( dt )
+
+ def getVoices( self, locale=None ):
+ """Obtain a list of voices known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of Voice objects
+ """
+ if self.allVoices is None:
+ self.__fillVoices()
+ assert self.allVoices is not None and len( self.allVoices ) > 0
+ if locale is None:
+ return self.allVoices
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ if self.voicesByLocaleMap.has_key(locale):
+ return self.voicesByLocaleMap[locale]
+ else:
+ raise Exception("No voices for locale '%s'" % (locale))
+
+ def __fillVoices( self ):
+ self.allVoices = []
+ self.voicesByLocaleMap = {}
+ marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ marySocket.connect( ( self.host, self.port ) )
+ # Expect a variable number of lines of the kind
+ # de7 de female
+ # us2 en male
+ # dfki-stadium-emo de male limited
+ voiceStrings = self.__getServerInfo( "MARY LIST VOICES", marySocket )
+ if not voiceStrings or len(voiceStrings) == 0:
+ raise IOError( "Could not get list of voices from Mary server" )
+ marySocket.close()
+ for voiceString in voiceStrings:
+ parts = voiceString.split()
+ if len( parts ) < 3:
+ continue
+ name = parts[0]
+ locale = parts[1]
+ gender = parts[2]
+ domain = None
+ if len( parts ) > 3:
+ domain = parts[3]
+ voice = Voice( name, locale, gender, domain )
+ self.allVoices.append( voice )
+ localeVoices = None
+ if self.voicesByLocaleMap.has_key( locale ):
+ localeVoices = self.voicesByLocaleMap[locale]
+ else:
+ localeVoices = []
+ self.voicesByLocaleMap[locale] = localeVoices
+ localeVoices.append( voice )
+
+ def getGeneralDomainVoices( self, locale=None ):
+ """Obtain a list of general domain voices known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of Voice objects
+ """
+ return [v for v in self.getVoices( locale ) if not v.isLimitedDomain]
+
+ def getLimitedDomainVoices( self, locale=None ):
+ """Obtain a list of limited domain voices known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of Voice objects
+ """
+ return [v for v in self.getVoices( locale ) if v.isLimitedDomain]
+
+ def getAvailableLanguages(self):
+ """ Check available voices and return a list of tuples (abbrev, name)
+ representing the available languages -- e.g. [('en', 'English'),('de', 'German')].
+ """
+ if self.allVoices is None:
+ self.__fillVoices()
+ assert self.allVoices is not None and len( self.allVoices ) > 0
+ languages = []
+ for l in self.voicesByLocaleMap.keys():
+ if languageNames.has_key(l):
+ languages.append((l,languageNames[l]))
+ else:
+ languages.append((l, l))
+ return languages
+
+ def getServerExampleText( self, dataType ):
+ """Request an example text for a given data type from the server.
+ dataType the string representation of the data type,
+ e.g. "RAWMARYXML". This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities."""
+ if not self.serverExampleTexts.has_key( dataType ):
+ exampleTexts = self.__getServerInfo( "MARY EXAMPLETEXT %s" % ( dataType ) )
+ if not exampleTexts or len(exampleTexts) == 0:
+ raise IOError( "Could not get example text for type '%s' from Mary server" % (dataType))
+ exampleText = u'\n'.join(exampleTexts)
+ self.serverExampleTexts[dataType] = exampleText
+ return self.serverExampleTexts[dataType]
+
+ def process( self, input, inputType, outputType, audioType=None, defaultVoiceName=None, output=sys.stdout ):
+ assert type( input ) in types.StringTypes
+ assert type( inputType ) in types.StringTypes
+ assert type( outputType ) in types.StringTypes
+ assert audioType is None or type( audioType ) in types.StringTypes
+ assert defaultVoiceName is None or type( defaultVoiceName ) in types.StringTypes
+ assert callable( getattr( output, 'write' ) )
+ if type( input ) != types.UnicodeType:
+ input = unicode( input, 'utf-8' )
+ maryInfoSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ maryInfoSocket.connect( ( self.host, self.port ) )
+ assert type( maryInfoSocket ) is socket.SocketType
+ maryInfo = maryInfoSocket.makefile( 'rwb', 1 ) # read-write, line-buffered
+ maryInfo.write( unicode( "MARY IN=%s OUT=%s" % ( inputType, outputType ), 'utf-8' ) )
+ if audioType:
+ maryInfo.write( unicode( " AUDIO=%s" % ( audioType ), 'utf-8' ) )
+ if defaultVoiceName:
+ maryInfo.write( unicode( " VOICE=%s" % ( defaultVoiceName ), 'utf-8' ) )
+ maryInfo.write( "\r\n" )
+ # Receive a request ID:
+ id = maryInfo.readline()
+ maryDataSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ maryDataSocket.connect( ( self.host, self.port ) )
+ assert type( maryDataSocket ) is socket.SocketType
+ maryDataSocket.sendall( id ) # includes newline
+ maryDataSocket.sendall( input.encode( 'utf-8' ) )
+ maryDataSocket.shutdown( 1 ) # shutdown writing
+ # Set mary info socket to non-blocking, so we only read somthing
+ # if there is something to read:
+ maryInfoSocket.setblocking( 0 )
+ while True:
+ try:
+ err = maryInfoSocket.recv( 8192 )
+ if err: sys.stderr.write( err )
+ except:
+ pass
+ got = maryDataSocket.recv( 8192 )
+ if not got: break
+ output.write( got )
+ maryInfoSocket.setblocking( 1 )
+ while True:
+ err = maryInfoSocket.recv( 8192 )
+ if not err: break
+ sys.stderr.write( err )
+
+
+
+################ data representation classes ##################
+
+class DataType:
+ def __init__( self, name, locale=None, isInputType=False, isOutputType=False ):
+ self.name = name
+ self.locale = locale
+ self.isInputType = isInputType
+ self.isOutputType = isOutputType
+
+ def isTextType( self ):
+ return self.name != "AUDIO"
+
+class Voice:
+
+ def __init__( self, name, locale, gender, domain="general" ):
+ self.name = name
+ self.locale = locale
+ self.gender = gender
+ self.domain = domain
+ if not domain or domain == "general":
+ self.isLimitedDomain = False
+ else:
+ self.isLimitedDomain = True
+
+ def __str__(self):
+ if languageNames.has_key(self.locale):
+ langName = languageNames[self.locale]
+ else:
+ langName = self.locale
+ if self.isLimitedDomain:
+ return "%s (%s, %s %s)" % (self.name, self.domain, langName, self.gender)
+ else:
+ return "%s (%s %s)" % (self.name, langName, self.gender)
+
+##################### Main #########################
+
+if __name__ == '__main__':
+
+ serverHost = "cling.dfki.uni-sb.de"
+ serverPort = 59125
+ inputType = "TEXT"
+ outputType = "AUDIO"
+ audioType = "WAVE"
+ defaultVoice = None
+ inputEncoding = 'utf-8'
+ ( options, rest ) = getopt.getopt( sys.argv[1:], '', \
+ ['server.host=', 'server.port=', 'input.type=', 'output.type=', \
+ 'audio.type=', 'voice.default=', 'input.encoding='] )
+ for ( option, value ) in options:
+ if option == '--server.host': serverHost = value
+ elif option == '--server.port': serverPort = int( value )
+ elif option == '--input.type': inputType = value
+ elif option == '--output.type': outputType = value
+ elif option == '--audio.type': audioType = value
+ elif option == '--voice.default': defaultVoice = value
+ elif option == '--input.encoding': inputEncoding = value
+ if len( rest )>0: # have input file
+ inputFile = file( rest[0] )
+ else:
+ inputFile = sys.stdin
+ input = unicode( ''.join( inputFile.readlines() ), inputEncoding )
+ if len( rest )>1: # also have output file
+ outputFile = file( rest[1] )
+ else:
+ outputFile = sys.stdout
+
+ maryClient = MaryClient( serverHost, serverPort )
+ maryClient.process( input, inputType, outputType, audioType, defaultVoice, outputFile )
diff --git a/external/marytts-5.1.2/doc/examples/client/MaryClientUser.java b/external/marytts-5.1.2/doc/examples/client/MaryClientUser.java
new file mode 100755
index 00000000..a416ab3a
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/MaryClientUser.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright 2000-2006 DFKI GmbH.
+ * All Rights Reserved. Use is subject to license terms.
+ *
+ * Permission is hereby granted, free of charge, to use and distribute
+ * this software and its documentation without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of this work, and to
+ * permit persons to whom this work is furnished to do so, subject to
+ * the following conditions:
+ *
+ * 1. The code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Any modifications must be clearly marked as such.
+ * 3. Original authors' names are not deleted.
+ * 4. The authors' names are not used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+ * CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+import marytts.client.MaryClient;
+import marytts.util.data.audio.AudioPlayer;
+import marytts.util.http.Address;
+
+import javax.sound.sampled.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.UnknownHostException;
+
+/**
+ * A demo class illustrating how to use the MaryClient class.
+ * This will connect to a MARY server, version 4.x.
+ * It requires maryclient.jar from MARY 4.0.
+ * This works transparently with MARY servers in both http and socket server mode.
+ *
+ * Compile this as follows:
+ * javac -cp maryclient.jar MaryClientUser.java
+ *
+ * And run as:
+ * java -cp .:maryclient.jar MaryClientUser
+ *
+ * @author marc
+ *
+ */
+
+public class MaryClientUser {
+
+ public static void main(String[] args)
+ throws IOException, UnknownHostException, UnsupportedAudioFileException,
+ InterruptedException
+ {
+ String serverHost = System.getProperty("server.host", "cling.dfki.uni-sb.de");
+ int serverPort = Integer.getInteger("server.port", 59125).intValue();
+ MaryClient mary = MaryClient.getMaryClient(new Address(serverHost, serverPort));
+ String text = "Willkommen in der Welt der Sprachsynthese!";
+ // If the given locale is not supported by the server, it returns
+ // an ambigous exception: "Problem processing the data."
+ String locale = "de"; // or US English (en-US), Telugu (te), Turkish (tr), ...
+ String inputType = "TEXT";
+ String outputType = "AUDIO";
+ String audioType = "WAVE";
+ String defaultVoiceName = null;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ mary.process(text, inputType, outputType, locale, audioType, defaultVoiceName, baos);
+ // The byte array constitutes a full wave file, including the headers.
+ // And now, play the audio data:
+ AudioInputStream ais = AudioSystem.getAudioInputStream(
+ new ByteArrayInputStream(baos.toByteArray()));
+ LineListener lineListener = new LineListener() {
+ public void update(LineEvent event) {
+ if (event.getType() == LineEvent.Type.START) {
+ System.err.println("Audio started playing.");
+ } else if (event.getType() == LineEvent.Type.STOP) {
+ System.err.println("Audio stopped playing.");
+ } else if (event.getType() == LineEvent.Type.OPEN) {
+ System.err.println("Audio line opened.");
+ } else if (event.getType() == LineEvent.Type.CLOSE) {
+ System.err.println("Audio line closed.");
+ }
+ }
+ };
+
+ AudioPlayer ap = new AudioPlayer(ais, lineListener);
+ ap.start();
+ }
+}
diff --git a/external/marytts-5.1.2/doc/examples/client/c++/Makefile b/external/marytts-5.1.2/doc/examples/client/c++/Makefile
new file mode 100755
index 00000000..a609beda
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/c++/Makefile
@@ -0,0 +1,45 @@
+##########################################################################
+# Copyright (C) 2000-2006 DFKI GmbH.
+# All rights reserved. Use is subject to license terms.
+#
+# Permission is hereby granted, free of charge, to use and distribute
+# this software and its documentation without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of this work, and to
+# permit persons to whom this work is furnished to do so, subject to
+# the following conditions:
+#
+# 1. The code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+# 2. Any modifications must be clearly marked as such.
+# 3. Original authors' names are not deleted.
+# 4. The authors' names are not used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+##########################################################################
+
+CC=g++
+CFLAGS=-Wall -w -O3 -g
+ICUDIR=/usr/local/icu
+ICULIBS=-Wl,-R,$(ICUDIR)/lib -L$(ICUDIR)/lib -licuuc -licui18n -ldl
+
+all: MaryDemo
+
+MaryDemo: MaryClient.o MaryDemo.o
+ $(CC) $(CFLAGS) *.o -o MaryDemo $(LIBS)
+
+%.o: %.cc
+ $(CC) $(CFLAGS) $(RFLAGS) -o $@ -c $<
+
+clean:
+ rm -rf *.o ./MaryDemo
+
diff --git a/external/marytts-5.1.2/doc/examples/client/c++/MaryClient.cc b/external/marytts-5.1.2/doc/examples/client/c++/MaryClient.cc
new file mode 100755
index 00000000..7e920d95
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/c++/MaryClient.cc
@@ -0,0 +1,277 @@
+/**
+ * Copyright 2000-2006 DFKI GmbH.
+ * All Rights Reserved. Use is subject to license terms.
+ *
+ * Permission is hereby granted, free of charge, to use and distribute
+ * this software and its documentation without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of this work, and to
+ * permit persons to whom this work is furnished to do so, subject to
+ * the following conditions:
+ *
+ * 1. The code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Any modifications must be clearly marked as such.
+ * 3. Original authors' names are not deleted.
+ * 4. The authors' names are not used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+ * CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include
+#include
+#include
+#include
+
+#include "MaryClient.h"
+
+using namespace std;
+
+/**
+ * A C++ implementation of a simple client to the MARY TTS system.
+ * result: an empty string serving as the container for the output.
+ * It will return text or audio data; text data will be encoded as UTF-8.
+ * inputText: the UTF-8 encoded text (or XML document) to send as a request
+ * maryInFormat: the input type of the data in inputText, e.g. TEXT
+ * maryOutFormat: the output type to produce, e.g. MBROLA, AUDIO
+ * locale: the language of the input, e.g. EN-US, DE
+ * audioType: for AUDIO output, the type of audio data to produce,
+ * e.g. WAVE or MP3.
+ * voice: the voice to be used, e.g. cmu-slt-hsmm, bits3.
+ * effects: the list of effects to be generated.
+ * return value: 0 on success, negative on failure.
+ */
+int
+MaryClient::maryQuery( int server_port,
+ string server_host,
+ string& result,
+ string inputText,
+ string maryInFormat,
+ string maryOutFormat,
+ string locale,
+ string audioType,
+ string voice,
+ string effects ) {
+
+ // prepare the request
+ string query = "MARY";
+ query += " IN=" + maryInFormat;
+ query += " OUT=" + maryOutFormat;
+ query += " LOCALE=" + locale; // remove this line, if using an older version than MARY 4.0
+ query += " AUDIO=" + audioType;
+ query += " VOICE=" + voice;
+ if (effects != "") {
+ query += " EFFECTS=" + effects;
+ }
+ query += "\012\015";
+
+ //cout << "Constructed query: " << query << endl;
+
+ // declare connection stuff
+ struct sockaddr_in maryServer;
+ struct sockaddr_in maryClient;
+ struct hostent* hostInfo;
+
+ // declare variables
+ int maryInfoSocket;
+ int maryDataSocket;
+
+ // set configuration parameters
+
+ // get host information
+ hostInfo = gethostbyname (server_host.c_str());
+
+ if (hostInfo == NULL)
+ {
+ return -2;
+ }
+
+
+ // create a tcp connection to the mary server
+ maryInfoSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryInfoSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryInfoSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryInfoSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+ // send request to the Mary server
+ if (send (maryInfoSocket, query.c_str (), query.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // receive the request id
+ char id [32] = "";
+
+ if (recv (maryInfoSocket, id, 32, 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Read id: " << id << endl;
+
+ // create a tcp connection to the mary server
+ maryDataSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryDataSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryDataSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryDataSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+
+ // send the request id to the Mary server
+ if (send (maryDataSocket, id, strlen (id), 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Sending request: " << inputText << endl;
+
+ // send the query to the Mary server
+ if (send (maryDataSocket, inputText.c_str (), inputText.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+ if (send (maryDataSocket, "\012\015", 2, 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // shutdown data socket
+ shutdown (maryDataSocket, 1);
+
+
+ //cout << "Reading result" << endl;
+
+ unsigned int total_bytes = 0;
+ int recv_bytes = 0;
+ char data [1024] = "";
+
+ result [0] = '\0';
+
+ // receive the request result
+ do
+ {
+ data [0] = '\0';
+
+ recv_bytes = recv (maryDataSocket, data, 1024, 0);
+
+ if (recv_bytes == -1)
+ {
+ return -2;
+ }
+ else if (recv_bytes > 0)
+ {
+ //cout << "("</libwsock32.a
+#include
+#else
+#include
+#endif
+
+#include
+#include
+#include
+
+#include "MaryClient.h"
+
+using namespace std;
+
+/**
+ * A C++ implementation of a simple client to the MARY TTS system.
+ * result: an empty string serving as the container for the output.
+ * It will return text or audio data; text data will be encoded as UTF-8.
+ * inputText: the UTF-8 encoded text (or XML document) to send as a request
+ * maryInFormat: the input type of the data in inputText, e.g. TEXT
+ * maryOutFormat: the output type to produce, e.g. MBROLA, AUDIO
+ * locale: the language of the input, e.g. EN-US, DE
+ * audioType: for AUDIO output, the type of audio data to produce,
+ * e.g. WAVE or MP3.
+ * voice: the voice to be used, e.g. cmu-slt-hsmm, bits3.
+ * effects: the list of effects to be generated.
+ * return value: 0 on success, negative on failure.
+ */
+int
+MaryClient::maryQuery( int server_port,
+ string server_host,
+ string& result,
+ string inputText,
+ string maryInFormat,
+ string maryOutFormat,
+ string locale,
+ string audioType,
+ string voice,
+ string effects ) {
+
+ // prepare the request
+ string query = "MARY";
+ query += " IN=" + maryInFormat;
+ query += " OUT=" + maryOutFormat;
+ query += " LOCALE=" + locale; // remove this line, if using an older version than MARY 4.0
+ query += " AUDIO=" + audioType;
+ query += " VOICE=" + voice;
+ if (effects != "") {
+ query += " EFFECTS=" + effects;
+ }
+ query += "\012\015";
+
+ //cout << "Constructed query: " << query << endl;
+
+ // declare connection stuff
+ struct sockaddr_in maryServer;
+ struct sockaddr_in maryClient;
+ struct hostent* hostInfo;
+
+ // declare variables
+ int maryInfoSocket;
+ int maryDataSocket;
+
+ // set configuration parameters
+
+ // get host information
+ hostInfo = gethostbyname (server_host.c_str());
+
+ if (hostInfo == NULL)
+ {
+ return -2;
+ }
+
+
+ // create a tcp connection to the mary server
+ maryInfoSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryInfoSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryInfoSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryInfoSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+ // send request to the Mary server
+ if (send (maryInfoSocket, query.c_str (), query.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // receive the request id
+ char id [32] = "";
+
+ if (recv (maryInfoSocket, id, 32, 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Read id: " << id << endl;
+
+ // create a tcp connection to the mary server
+ maryDataSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryDataSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryDataSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryDataSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+
+ // send the request id to the Mary server
+ if (send (maryDataSocket, id, strlen (id), 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Sending request: " << inputText << endl;
+
+ // send the query to the Mary server
+ if (send (maryDataSocket, inputText.c_str (), inputText.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+ if (send (maryDataSocket, "\012\015", 2, 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // shutdown data socket
+ shutdown (maryDataSocket, 1);
+
+
+ //cout << "Reading result" << endl;
+
+ unsigned int total_bytes = 0;
+ int recv_bytes = 0;
+ char data [1024] = "";
+
+ result [0] = '\0';
+
+ // receive the request result
+ do
+ {
+ data [0] = '\0';
+
+ recv_bytes = recv (maryDataSocket, data, 1024, 0);
+
+ if (recv_bytes == -1)
+ {
+ return -2;
+ }
+ else if (recv_bytes > 0)
+ {
+ //cout << "("<
+#include
+#include
+
+#include "MaryClient.h"
+
+using namespace std;
+
+/**
+ * Demonstration code for using the MaryClient.
+ + Call this as:
+ * ./MaryDemo
+ * or
+ * ./MaryDemo > output.wav
+ */
+int main() {
+ int server_port = 59125;
+ string server_host = "localhost";
+ string inputText = "Welcome to the world of speech synthesis!";
+ string maryInFormat = "TEXT";
+ string maryOutFormat = "AUDIO";
+ //string maryOutFormat = "REALISED_DURATIONS";
+ string locale = "en-US";
+ string audioType = "WAV_FILE";
+ string voice = "cmu-slt-hsmm";
+ string effects;
+// effects += "Volume(amount:5.0;)+";
+// effects += "TractScaler(amount:1.5;)+";
+// effects += "F0Scale(f0Scale:2.0;)+";
+// effects += "F0Add(f0Add:50.0;)+";
+// effects += "Rate(durScale:1.5;)+";
+// effects += "Robot(amount:100.0;)+";
+// effects += "Whisper(amount:100.0;)+";
+// effects += "Stadium(amount:100.0)+";
+// effects += "Chorus(delay1:466;amp1:0.54;delay2:600;amp2:-0.10;delay3:250;amp3:0.30)+";
+// effects += "FIRFilter(type:3;fc1:500.0;fc2:2000.0)+";
+// effects += "JetPilot";
+ string result;
+
+ MaryClient maryClient;
+ maryClient.maryQuery( server_port, server_host, result, inputText, maryInFormat, maryOutFormat, locale, audioType, voice, effects);
+
+ if (maryOutFormat == "AUDIO") {
+ // write result into a file
+ const char *filename = "output.wav";
+ ofstream file( filename );
+ file << result;
+
+ // play output
+ //system("play output.wav");
+ } else {
+ cout << "RESULT: " << endl << result << endl;
+ }
+
+ return 0;
+}
+
diff --git a/external/marytts-5.1.2/doc/examples/client/c++/README.txt b/external/marytts-5.1.2/doc/examples/client/c++/README.txt
new file mode 100755
index 00000000..e38af989
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/c++/README.txt
@@ -0,0 +1,4 @@
+Start MARY as a socket server:
+
+maryserver -Dserver=socket
+(or change entry 'server' in conf/marybase.config)
diff --git a/external/marytts-5.1.2/doc/examples/client/maryclient-http.py b/external/marytts-5.1.2/doc/examples/client/maryclient-http.py
new file mode 100755
index 00000000..cf9782e8
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/maryclient-http.py
@@ -0,0 +1,185 @@
+#!/usr/bin/env python
+import httplib, urllib
+
+# A basic mary client in Python,
+# kindly donated to the MARY TTS project
+# by Hugh Sasse. Thanks Hugh!
+
+# A very basic Python class for accessing
+# the MARY TTS system using the modern
+# HTTP server.
+# Warning, this is probably ghastly Python,
+# most of my time of late has been with
+# other languages, so I'm not up to date
+# with all the stylistic conventions of
+# modern Python.
+# This does seem to work OK though.
+
+class maryclient:
+ """A basic handler for MARY-TTS HTTP clients
+
+ At present, there is no checking for
+ allowed voices, locales, and so on.
+ Most of the useful parameters can be
+ accessed by get_ and set_ methods.
+ Relying on winsound, this is Windows
+ specific.
+ """
+ def __init__(self):
+ """Set up useful defaults (for
+ people in England, anyway)"""
+ self.host = "127.0.0.1"
+ self.port = 59125
+ self.input_type = "TEXT"
+ self.output_type = "AUDIO"
+ self.audio = "WAVE_FILE"
+ self.locale = "en_GB"
+ self.voice = "dfki-prudence-hsmm"
+
+ def set_host(self, a_host):
+ """Set the host for the TTS server."""
+ self.host = a_host
+
+ def get_host(self):
+ """Get the host for the TTS server."""
+ self.host
+
+ def set_port(self, a_port):
+ """Set the port for the TTS server."""
+ self.port = a_port
+
+ def get_port(self):
+ """Get the port for the TTS server."""
+ self.port
+
+ def set_input_type(self, type):
+ """Set the type of input being
+ supplied to the TTS server
+ (such as 'TEXT')."""
+ self.input_type = type
+
+ def get_input_type(self):
+ """Get the type of input being
+ supplied to the TTS server
+ (such as 'TEXT')."""
+ self.input_type
+
+ def set_output_type(self, type):
+ """Set the type of input being
+ supplied to the TTS server
+ (such as 'AUDIO')."""
+ self.output_type = type
+
+ def get_output_type(self):
+ """Get the type of input being
+ supplied to the TTS server
+ (such as "AUDIO")."""
+ self.output_type
+
+ def set_locale(self, a_locale):
+ """Set the locale
+ (such as "en_GB")."""
+ self.locale = a_locale
+
+ def get_locale(self):
+ """Get the locale
+ (such as "en_GB")."""
+ self.locale
+
+ def set_audio(self, audio_type):
+ """Set the audio type for playback
+ (such as "WAVE_FILE")."""
+ self.audio = audio_type
+
+ def get_audio(self):
+ """Get the audio type for playback
+ (such as "WAVE_FILE")."""
+ self.audio
+
+ def set_voice(self, a_voice):
+ """Set the voice to speak with
+ (such as "dfki-prudence-hsmm")."""
+ self.voice = a_voice
+
+ def get_voice(self):
+ """Get the voice to speak with
+ (such as "dfki-prudence-hsmm")."""
+ self.voice
+
+ def generate(self, message):
+ """Given a message in message,
+ return a response in the appropriate
+ format."""
+ raw_params = {"INPUT_TEXT": message,
+ "INPUT_TYPE": self.input_type,
+ "OUTPUT_TYPE": self.output_type,
+ "LOCALE": self.locale,
+ "AUDIO": self.audio,
+ "VOICE": self.voice,
+ }
+ params = urllib.urlencode(raw_params)
+ headers = {}
+
+ # Open connection to self.host, self.port.
+ conn = httplib.HTTPConnection(self.host, self.port)
+
+ # conn.set_debuglevel(5)
+
+ conn.request("POST", "/process", params, headers)
+ response = conn.getresponse()
+ if response.status != 200:
+ print response.getheaders()
+ raise RuntimeError("{0}: {1}".format(response.status,
+ response.reason))
+ return response.read()
+
+# If this is invoked as a program, just give
+# a greeting to show it is working.
+# The platform specific code is moved to this
+# part so that this file may be imported without
+# bringing platform specific code in.
+if __name__ == "__main__":
+
+ # For handling command line arguments:
+ import sys
+ import platform
+
+ # check we are on Windows:
+ system = platform.system().lower()
+ if (system == "windows"):
+
+ import winsound
+
+ class Player:
+ def __init__(self):
+ pass
+
+ def play(self, a_sound):
+ winsound.PlaySound(a_sound, winsound.SND_MEMORY)
+
+ #if ("cygwin" in system):
+ else:
+ # Not sure how to do audio on cygwin,
+ # portably for python. So have a sound
+ # player class that doesn't play sounds.
+ # A null object, if you like.
+ class Player:
+ def __init__(self):
+ pass
+
+ def play(self, a_sound):
+ print("Here I would play a sound if I knew how")
+ pass
+
+ # Probably want to parse arguments to
+ # set the voice, etc., here
+
+ client = maryclient()
+ client.set_audio("WAVE_FILE") # for example
+
+ player = Player()
+ the_sound = client.generate("hello from Mary Text to Speech, with Python.")
+ if client.output_type == "AUDIO":
+ player.play(the_sound)
+
+# vi:set sw=4 et:
diff --git a/external/marytts-5.1.2/doc/examples/client/maryclient.cgi b/external/marytts-5.1.2/doc/examples/client/maryclient.cgi
new file mode 100755
index 00000000..876a846e
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/maryclient.cgi
@@ -0,0 +1,177 @@
+#!/usr/bin/perl -T
+# -*- Mode: Perl -*-
+# MARY Text-to-Speech System
+# CGI Script implementing a simple mary client,
+# can be used for web pages.
+##########################################################################
+# Copyright (C) 2000-2006 DFKI GmbH.
+# All rights reserved. Use is subject to license terms.
+#
+# Permission is hereby granted, free of charge, to use and distribute
+# this software and its documentation without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of this work, and to
+# permit persons to whom this work is furnished to do so, subject to
+# the following conditions:
+#
+# 1. The code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+# 2. Any modifications must be clearly marked as such.
+# 3. Original authors' names are not deleted.
+# 4. The authors' names are not used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+##########################################################################
+# Author: Marc Schroeder
+
+use strict;
+use IO::Socket;
+use CGI;
+
+# variables getting their values from form:
+my ($inputtext, $in, $out, $audiotype, $voice);
+
+# little helpers:
+my ($var, $tmp);
+
+# contacting the mary server:
+my ($host, $port, $maryInfoSocket, $maryDataSocket, $id);
+
+# helping with audio output:
+my ($save_to_disk, $audiosubtype, $filename);
+
+
+my $cgi = new CGI;
+my @param = $cgi->param();
+$inputtext = $cgi->param('inputtext');
+$in = $cgi->param('in');
+$out = $cgi->param('out');
+$audiotype = $cgi->param('audiotype');
+$save_to_disk = $cgi->param('save_to_disk');
+$voice = $cgi->param('voice');
+
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
+$year += 1900;
+printf STDERR "[%04i-%02i-%02i %02i:%02i:%02i] ", $year, $mon, $mday, $hour, $min, $sec;
+print STDERR "Request from ",$cgi->remote_user(),"@",$cgi->remote_host(),": \n";
+print STDERR " in=",$in;
+print STDERR " out=",$out;
+print STDERR " audiotype=",$audiotype;
+print STDERR " voice=",$voice;
+print STDERR " save_to_disk=",$save_to_disk,"\n";
+print STDERR " inputtext: ";
+print STDERR $inputtext,"\n";
+
+
+# Limit inputtext length to 5000 bytes:
+if (length $inputtext > 5000) {
+ $inputtext = substr $inputtext, 0, 5000;
+}
+
+
+# set audio subtype
+if ($out eq "AUDIO") {
+ if ($audiotype eq "AU") {
+ $audiosubtype = "basic";
+ $filename = "mary.au";
+ } elsif ($audiotype eq "AIFF") {
+ $audiosubtype = "x-aiff";
+ $filename = "mary.aiff";
+ } elsif ($audiotype eq "WAVE") {
+ $audiosubtype = "x-wav";
+ $filename = "mary.wav";
+ } elsif ($audiotype eq "MP3") {
+ $audiosubtype = "mp3";
+ $filename = "mary.mp3";
+ } else {
+ $audiosubtype = "x-wav";
+ $filename = "mary.wav";
+ }
+}
+
+# announce data type on stdout
+if ($save_to_disk) {
+ print "Content-Type: application/octet-stream";
+} else {
+ print "Content-Type: audio/$audiosubtype";
+}
+print "\nContent-Disposition: filename=\"$filename\"\n\n";
+
+# contact mary server
+$host = "cling.dfki.uni-sb.de";
+$port = 59125;
+
+# create a tcp connection to the specified host and port
+$maryInfoSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+
+# avoid buffering when writing to server:
+$maryInfoSocket->autoflush(1); # so output gets there right away
+
+########## Write input to server: ##########
+# formulate the request:
+print $maryInfoSocket "MARY IN=$in OUT=$out AUDIO=$audiotype";
+if ($voice && $voice ne 'v') { print $maryInfoSocket " VOICE=$voice"; }
+print $maryInfoSocket " LOG=\"REMOTE_HOST=$ENV{'REMOTE_HOST'}",
+ ", REMOTE_ADDR=$ENV{'REMOTE_ADDR'}\"";
+print $maryInfoSocket "\015\012";
+
+# receive a request ID:
+$id = <$maryInfoSocket>;
+
+# open second socket for the data:
+$maryDataSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+# identify with request number:
+print $maryDataSocket $id; # $id contains a newline character
+
+# copy $inputtext to mary data socket
+print $maryDataSocket $inputtext;
+
+# mark end-of-request:
+print $maryDataSocket "\015\012"; # that is a \n, actually
+$maryDataSocket->shutdown(1); # we have stopped writing data
+
+########## Read output from server: ##########
+# copy the data socket to standard output
+if ($out ne "AUDIO") { # text output
+ my $line;
+ while (defined ($line = <$maryDataSocket>)) {
+ print STDOUT $line;
+ }
+} else { # audio data output
+ my $nr; # number of bytes read
+ my $buf; # buffer to read into
+ my $outnr; # number of bytes written
+ while($nr = read($maryDataSocket, $buf, 8192)) {
+ # (read returns no. of bytes read, 0 at eof)
+ print STDOUT $buf
+ or die "Write error on stdout";
+ } # while read something from socket
+} # audio output
+
+### Read complaints from server:
+my $line;
+while (defined ($line = <$maryInfoSocket>)) {
+ print STDERR $line;
+}
+
+
+
+
+
+
+
diff --git a/external/marytts-5.1.2/doc/examples/client/maryclient.pl b/external/marytts-5.1.2/doc/examples/client/maryclient.pl
new file mode 100755
index 00000000..8b3f5f80
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/maryclient.pl
@@ -0,0 +1,136 @@
+#!/usr/bin/env perl
+#
+# MARY Text-to-Speech System
+# Minimal Socket client (for demonstration)
+##########################################################################
+# Copyright (C) 2000-2006 DFKI GmbH.
+# All rights reserved. Use is subject to license terms.
+#
+# Permission is hereby granted, free of charge, to use and distribute
+# this software and its documentation without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of this work, and to
+# permit persons to whom this work is furnished to do so, subject to
+# the following conditions:
+#
+# 1. The code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+# 2. Any modifications must be clearly marked as such.
+# 3. Original authors' names are not deleted.
+# 4. The authors' names are not used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+##########################################################################
+# Author: Marc Schroeder
+# This is a minimal version of a socket client for the mary TtS system.
+# It is intended to be used as a model for writing socket clients for
+# particular applications. All input verification, command line options,
+# and other luxury have been omitted.
+#
+# Usage:
+# maryclient.pl infile.txt > outfile.wav
+#
+# Input/output formats and other options must be set in the perl code directly.
+# See also Protocol.html for a description of the Protocol.
+#
+
+use strict;
+use IO::Socket;
+
+############################
+# Package-global variables #
+############################
+# global settings:
+my $maryInfoSocket; # handle to socket server
+my $maryDataSocket; # handle to socket server
+my $host; # string containing host address
+my $port; # socket port on which we listen
+my ($in, $out, $audiotype); # requested input / output format
+my $voice; # default voice
+my $id; # request ID
+
+######################################################################
+################################ main ################################
+######################################################################
+
+STDOUT->autoflush(1);
+
+$host = "cling.dfki.uni-sb.de";
+$port = 59125;
+$in = "TEXT_DE";
+$out = "AUDIO";
+$audiotype = "MP3";
+#$audiotype = "WAVE";
+#$voice = "male";
+$voice = "de3";
+
+# create a tcp connection to the specified host and port
+$maryInfoSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+
+# avoid buffering when writing to server:
+$maryInfoSocket->autoflush(1); # so output gets there right away
+
+########## Write input to server: ##########
+# formulate the request:
+print $maryInfoSocket "MARY IN=$in OUT=$out AUDIO=$audiotype";
+if ($voice) { print $maryInfoSocket " VOICE=$voice"; }
+print $maryInfoSocket "\015\012";
+
+# receive a request ID:
+$id = <$maryInfoSocket>;
+chomp $id; chomp $id;
+
+# open second socket for the data:
+$maryDataSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+# identify with request number:
+print $maryDataSocket $id, "\015\012";
+
+# copy standard input and/or files given on the command line to the socket
+while (defined (my $line = <>)) {
+ print $maryDataSocket $line;
+}
+# mark end-of-request:
+print $maryDataSocket "\015\012"; # that is a \n, actually
+shutdown($maryDataSocket, 1); # we have stopped writing data
+
+########## Read output from server: ##########
+# copy the data socket to standard output
+if ($out ne "AUDIO") { # text output
+ my $line;
+ while (defined ($line = <$maryDataSocket>)) {
+ print STDOUT $line;
+ }
+} else { # audio data output
+ my $nr; # number of bytes read
+ my $buf; # buffer to read into
+ my $outnr; # number of bytes written
+ while($nr = read($maryDataSocket, $buf, 100000)) {
+ # (read returns no. of bytes read, 0 at eof)
+ print STDOUT $buf
+ or die "Write error on stdout";
+ } # while read something from socket
+} # audio output
+
+### Read complaints from server:
+my $line;
+while (defined ($line = <$maryInfoSocket>)) {
+ print STDERR $line;
+}
+
+
+
diff --git a/external/marytts-5.1.2/doc/examples/client/maryclient.rb b/external/marytts-5.1.2/doc/examples/client/maryclient.rb
new file mode 100755
index 00000000..c4156cbb
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/maryclient.rb
@@ -0,0 +1,261 @@
+#!/usr/bin/env ruby
+#
+# A basic mary client in Ruby,
+# kindly donated to the MARY TTS project
+# by Hugh Sasse. Thanks Hugh!
+
+
+# Ruby client for the MARY TTS HTTP server.
+# This is for Windows only, and relies on
+# the Win32-Sound gem to access the audio.
+#
+#
+
+require 'rubygems'
+require 'net/http'
+require 'uri'
+
+# A fairly minimal client class for the
+# MARY TTS system. This uses the modern
+# HTTP interface to access the server.
+# At present, this doesn't wrap the methods
+# which provide documentation or lists of
+# voices or features.
+class MaryClient
+ attr_accessor :host, :port
+ attr_accessor :input_type, :output_type
+ attr_accessor :locale, :audio, :voice
+
+ # Set up the defaults for the MARY TTS
+ # server, which is assumed to be running
+ # on the local host, with British voices
+ # installed. These may be modified with
+ # the appropriate methods.
+ # host = 127.0.0.1)
+ # port = 59125
+ # input_type = "TEXT"
+ # output_type = "AUDIO"
+ # audio = "WAVE_FILE"
+ # locale = "en_GB"
+ # voice = "dfki-prudence-hsmm"
+ def initialize
+ @host = "127.0.0.1" # The local machine
+ @port = 59125
+ @input_type = "TEXT"
+ @output_type = "AUDIO"
+ @locale = "en_GB"
+ @audio = "WAVE_FILE"
+ @voice = "dfki-prudence-hsmm"
+ end
+
+ # Process a text message, which with a
+ # new client, will return the audio.
+ # This is so that platform dependent parts
+ # are kept separate.
+ def generate(message)
+ raw_params = {"INPUT_TEXT" => message,
+ "INPUT_TYPE" => @input_type,
+ "OUTPUT_TYPE" => @output_type,
+ "LOCALE" => @locale,
+ "AUDIO" => @audio,
+ "VOICE" => @voice,
+ }
+ res = Net::HTTP.post_form(URI.parse("http://#{@host}:#{@port}/process"), raw_params)
+ res.value # Throw an exception on failure
+ #puts res.body
+ return res.body
+ end
+end
+
+
+# If this invoked as a program with no
+# argumens, just give a greeting to show
+# that it is working. If arguments are
+# supplied, process options to work out
+# what to do with the arguments.
+if __FILE__ == $0
+
+ # These files are only loaded when this is
+ # invoked as a program.
+ require 'rbconfig'
+ require 'getoptlong'
+
+ # PLATFORM SPECIFIC CODE.
+ # Needs more work [!]
+ case Config::CONFIG['host_os']
+ when /darwin/i
+ raise NotImplementedError.new("Don't know how to play audio on a Mac")
+ when /linux/i
+ raise NotImplementedError.new("Far too many ways to play audio on Linux, you'll need to choose something")
+ when /sunos|solaris/i
+ raise NotImplementedError.new("Have not played audio on Suns for too long to implement this.")
+ when /java/i
+ raise NotImplementedError.new("Don't know how to play audio from Java ")
+ when /win32|cygwin|mingw32/i
+ # The various things that can use the Win32
+ # sound gem
+ require 'win32/sound'
+ # Create a player class that will play the
+ # sound that the Mary TTS system returns
+ class Player
+
+ # Play the audio passed in.
+ # Possibly this should receive the audio
+ # type so we can check that we can play it,
+ # but at the moment that is the
+ # responsibility of the user.
+ def self.play(sound)
+ Win32::Sound.play(sound, Win32::Sound::MEMORY)
+ end
+ end
+ else
+ raise NotImplementedError.new("Haven't thought how to support this OS yet")
+ end
+
+
+ client = nil
+ split = ""
+
+ if ARGV.size.zero?
+ client = MaryClient.new()
+ sound = client.generate("Hello from Mary Text to Speech with Ruby.")
+ Player.play(sound)
+ else
+ args_mode = :words
+ stdout_mode = :absorb
+ opts = GetoptLong::new(
+ ["--audio", "-a", GetoptLong::REQUIRED_ARGUMENT],
+ ["--echo", "-e", GetoptLong::NO_ARGUMENT],
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
+ ["--host", "-H", GetoptLong::REQUIRED_ARGUMENT],
+ ["--input-type", "-i", GetoptLong::REQUIRED_ARGUMENT],
+ ["--locale", "-l", GetoptLong::REQUIRED_ARGUMENT],
+ ["--read", "-r", GetoptLong::NO_ARGUMENT],
+
+ ["--split", "-s", GetoptLong::REQUIRED_ARGUMENT],
+ ["--output-type", "-o", GetoptLong::REQUIRED_ARGUMENT],
+ ["--port", "-P", GetoptLong::REQUIRED_ARGUMENT],
+ ["--tee", "-t", GetoptLong::NO_ARGUMENT],
+ ["--voice", "-v", GetoptLong::REQUIRED_ARGUMENT]
+ )
+
+ opts.each do |opt, arg|
+ unless ["--help", "-h"].include?(opt)
+ # skip if we are only getting help
+ client ||= MaryClient.new()
+ end
+ case opt
+ when "--help", "-h"
+ puts <<-EOHELP
+Usage: #{$0} [options] [arguments]
+--audio -a
+ Audio format. Defualt: WAVE_FILE
+--echo -e
+ Act as an echo command and send output
+ arguments to the synthesizer only (not
+ to standard output.
+ Turns off --read|-r
+--help -h
+ Print this help, then exit.
+--host -H
+ The host which is the server.
+ Default: 127.0.0.1
+--input-type -i
+ The type of the input supplied to the
+ TTS system. Default: TEXT
+--locale -l
+ The locale of the input. Default: en_GB
+--output-type -o
+ The output type from the TTS system.
+ Default: AUDIO
+--port -P
+ The port for the TTS server
+ Default: 59125
+--read -r
+ Read the files passed as arguments.
+ Turns off --echo|-e
+--split -s (lines|paragraphs)
+ When reading files, split the input
+ into lines or paragraphs. Paragraphs
+ mean reading up to the next double
+ newline. Note, the argument is literally
+ "lines" or "paragraphs" (or some
+ abbreviation of those) without the
+ quotes.
+ Default is paragraphs.
+--tee -t
+ Act as tee: send the output to the TTS
+ system, and to standard output.
+--voice -v
+ The voice to use.
+ Default: dfki-prudence-hsmm
+ EOHELP
+ exit(0)
+ when "--audio", "-a"
+ client.audio = arg
+ when "--echo", "-e"
+ args_mode = :words
+ when "--host", "-H"
+ client.host = arg
+ when "--input-type", "-i"
+ client.input_type = arg
+ when "--locale", "-l"
+ client.locale = arg
+ when "--output-type", "-o"
+ client.output_type = arg
+ when "--port", "-P"
+ client.port = arg.to_i
+ when "--read", "-r"
+ args_mode = :files
+ when "--split", "-s"
+ case arg
+ when /^p/i
+ split = ""
+ when /^l/i
+ split = $/
+ end
+ when "--tee", "-t"
+ stdout_mode = :emit
+ when "--voice", "-v"
+ client.voice = arg
+ end
+ end
+
+ client ||= MaryClient.new()
+ case args_mode
+ when :words
+ input_text = ARGV.join(" ")
+ unless input_text =~ /\A\s*\Z/m
+ sound = client.generate(input_text)
+ if client.output_type == "AUDIO"
+ Player.play(sound)
+ end
+ end
+ if stdout_mode == :emit
+ puts input_text
+ end
+ when :files
+ # Slurp in paragraphs so sentences
+ # don't get broken in stupid places.
+ $/ = split # paragraph mode
+ ARGF.each do |paragraph|
+ begin
+ unless paragraph =~ /\A\s*\Z/m
+ sound = client.generate(paragraph)
+ if client.output_type == "AUDIO"
+ # and client.audio == "WAVE_FILE"
+ Player.play(sound)
+ end
+ end
+ rescue Exception => e
+ puts "got error #{e} while trying to say #{paragraph.inspect}"
+ raise
+ end
+ if stdout_mode == :emit
+ puts paragraph
+ end # end if
+ end # end ARGF.each
+ end # end case
+ end # if ARGV.size.zero?
+end
+
diff --git a/external/marytts-5.1.2/doc/examples/client/maryclient.tcl b/external/marytts-5.1.2/doc/examples/client/maryclient.tcl
new file mode 100755
index 00000000..3a358235
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/maryclient.tcl
@@ -0,0 +1,705 @@
+# Tcl/Tk MARY TTS client.
+
+# This has been tested on Windows, and because
+# of the use of sound there will be portability
+# issues. However, there should be enough here
+# for a reasonable start at a client, for any
+# platform that supports Tcl/Tk. The platform
+# specific code has, as far as possible, been
+# isolated in the part of the code that detects
+# whether this is being run as a program.
+
+# Notes:
+# More work will need to be done with this,
+# in order to make the code clean. It should
+# probably be wrapped in a package, to solve
+# any namespace issues. There are a lot of
+# global variables. It seems that some of
+# these are necessary for the menus to work.
+# Handling of temporary files could be improved.
+
+# TODO:
+# Create modifier sliders, for the effects.
+# Extend the query proc to make use of them.
+# Turn the Help menu into something more useful.
+# Debug the actions for the Edit menu.
+# Provide a means of getting example inputs
+# from the server.
+# Provide a means of re-loading all the
+# dynamically collected information when the
+# server is changed from the menu. This means
+# that we need to delete the existing menu
+# entries in order to add them correctly.
+# How do we ensure temporary files are removed
+# in the event of a problem? if {catch {}} ...?
+# Maybe leaving them around is diagnostic info?
+# Make that an option?
+# Add error handling code for network and disk
+# failures likely to beset such clients.
+# Add sensible defaults for things the user must
+# always set at startup, but these will be
+# platform spacific. Always default to Audio
+# output for example, or is it possible that
+# people have no voices installed?
+
+
+# This is a GUI, so:
+package require Tk
+
+# We are communicating with the Mary server
+# with HTTP.
+package require http
+
+# Use the local machine in preference to the
+# one in Germany.
+set mary_tts_default_host "127.0.0.1"
+set mary_tts_default_port 59125
+
+# Actual host and port, and global old
+# copies to allow revert on cancel in the
+# dialogues. Apparently upvar #0 is the
+# norm for that sort of thing [Tcl Wiki]
+set mary_tts_host $mary_tts_default_host
+set old_mary_tts_host $mary_tts_host
+set mary_tts_port $mary_tts_default_port
+set old_mary_tts_port $mary_tts_port
+
+# Informational URLs
+set informational_urls [ list \
+version datatypes voices \
+audioformats audioeffects ]
+
+#######
+
+# Obtain a static page from the server, i.e.
+# no parameters are needed to get it.
+proc get_page { relative_url } {
+ global mary_tts_host mary_tts_port
+ set url http://$mary_tts_host:$mary_tts_port/$relative_url
+ set result [::http::geturl $url]
+ return [::http::data $result]
+}
+
+proc list_of_lines {str} {
+ return [ split $str "\n" ]
+}
+
+
+# We will need to collect this information
+# when we have the server and port chosen.
+proc get_audioeffects {} {
+ return [list_of_lines [get_page audioeffects] ]
+}
+
+proc get_audioformats {} {
+ return [list_of_lines [get_page audioformats] ]
+}
+
+proc get_datatypes {} {
+ return [ list_of_lines [get_page datatypes] ]
+}
+
+
+proc get_voices {} {
+ return [list_of_lines [get_page voices] ]
+}
+
+# Handling post queries.
+
+# Submit the query to the server, using the
+# http POST method.
+proc make_query {url encoded_params} {
+ set http [::http::geturl $url -query $encoded_params]
+ set result [::http::data $http]
+ return $result
+}
+
+# Get the text from the input text area
+proc get_input_text {} {
+ return [.io.inp.input_area get 1.0 end]
+}
+
+# Get the text from the output text area
+proc get_output_text {} {
+ return [.io.out.output_area get 1.0 end]
+}
+
+# Collect the audio data from the server.
+proc collect_audio_data {text_to_process} {
+ global mary_tts_host mary_tts_port
+ global inputtype outputtype locales
+ global audioformat voice
+ set url "http://$mary_tts_host:$mary_tts_port/process"
+ # ::http::formatQuery converts a list of
+ # key value pairs into the correct format
+ # for http POST.
+ set params [::http::formatQuery INPUT_TEXT $text_to_process INPUT_TYPE $inputtype OUTPUT_TYPE $outputtype LOCALE $locales($voice) AUDIO $audioformat VOICE $voice ]
+ set result [make_query $url $params]
+ return $result
+}
+
+# Pushes the query to the server and gets
+# the results back, displaying or playing
+# them.
+proc generate_output {text_to_process} {
+ global outputtype
+ set result [collect_audio_data $text_to_process]
+ if {$outputtype eq "AUDIO"} {
+ # call the platform dependent implementation.
+ play $result
+ } else {
+ clear_output
+ add_message $result
+ }
+ # Return the result so we can save it if
+ # the user requires it.
+ return $result
+}
+
+
+# These next procs are for handling the
+# lists of data one gets back from the server
+# which possibly have several words per line,
+# separated by spaces.
+
+# If the first word of each listed line is
+# significant, extract the list of first words.
+proc collect_first_words_of_phrase_list {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ set word [ lindex [split $data " "] 0 ]
+ lappend words $word
+ }
+ return $words
+}
+
+
+# If the second word of each listed line is
+# significant, extract the list of second words.
+proc collect_second_words_of_phrase_list {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ set word [ lindex [split $data " "] 1 ]
+ lappend words $word
+ }
+ return $words
+}
+
+
+# The list of datatypes must be separated into
+# input data types and output data types so that
+# interactions with the server make sense.
+# This handles the inputs.
+proc collect_first_words_of_input_types {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ if {[ string match -nocase "*input*" $data ]} {
+ set word [ lindex [split $data " "] 0 ]
+ lappend words $word
+ }
+ }
+ return $words
+}
+
+
+# The list of datatypes must be separated into
+# input data types and output data types so that
+# interactions with the server make sense.
+# This handles the outputs.
+proc collect_first_words_of_output_types {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ if {[string match -nocase "*output*" $data]} {
+ set word [ lindex [split $data " "] 0 ]
+ lappend words $word
+ }
+ }
+ return $words
+}
+
+# setup all the variables to hold voices,
+# audio options, etc., based on what the
+# server can do.
+proc setup_globals {} {
+ global audioeffects audioformats voices
+ global inputtypes outputtypes audioformat voice
+ global inputtype outputtype locales
+
+ set audioeffects [get_audioeffects]
+ set audioformats [get_audioformats]
+ set audioformat [lindex $audioformats 0 ]
+ set datatypes_data [get_datatypes]
+ set inputtypes [collect_first_words_of_input_types $datatypes_data]
+ set inputtype [lindex $inputtypes 0]
+ set outputtypes [collect_first_words_of_output_types $datatypes_data]
+ set outputtype [lindex $outputtypes 0]
+ set voices_data [get_voices]
+ set voices [collect_first_words_of_phrase_list $voices_data]
+ set locales_list [collect_second_words_of_phrase_list $voices_data ]
+ for {set i 0} {$i < [llength $voices]} {incr i} {
+ set locales([lindex $voices $i]) [lindex $locales_list $i]
+ }
+ set voice [lindex $voices 0]
+}
+
+# A general procedure for filling in the
+# elements of a listbox from a list.
+# At present this is unused, but it could
+# be useful later. [It took a while to
+# figure out so I'm not ready to kill it
+# with YAGNI.]
+proc add_listbox_items {a_var a_widget} {
+ upvar $a_var var
+ foreach item $var {
+ $a_widget insert end $item
+ }
+}
+
+# Create the menubuttons along the top.
+# Usual File, Edit and Help menus plus
+# those to set attributes.
+proc create_menubuttons {} {
+ set buttons [ list file File edit Edit \
+ server "Server" \
+ inputtype "Input type" outputtype "Output type" \
+ voice Voice \
+ audioformat "Audio format" \
+ textstyle "Text style" help Help ]
+
+ set count 1
+ foreach { menu_tag string_tag} $buttons {
+ menubutton .menus.$menu_tag -text $string_tag \
+ -menu .menus.${menu_tag}.menu -underline 0 -font ClientFont
+ menu .menus.${menu_tag}.menu -tearoff true
+ grid .menus.$menu_tag -in .menus -row 1 -column $count -sticky w
+ incr count
+ }
+}
+
+# Get the contents of a text file for reading
+# or loading into a text widget, etc.
+proc text_file_contents {what_for} {
+ set a_file [tk_getOpenFile -title $what_for ]
+ set the_text ""
+
+ if {$a_file != ""} {
+ set a_stream [open $a_file r ]
+ set the_text [read $a_stream]
+ close $a_stream
+ }
+
+ return $the_text
+}
+
+
+# Save the_text to a text file specified
+# by the user, for the given reason (what_for).
+# At the moment there is no error handling
+# for this (disk full, write protected, etc).
+proc save_text_file {the_text what_for} {
+ set a_file [tk_getSaveFile -title $what_for -parent .]
+ if {$a_file != ""} {
+ set a_stream [open $a_file w ]
+ puts $a_stream $the_text
+ close $a_stream
+ }
+}
+
+# Save the_data to a binary file specified
+# by the user, for the given reason (what_for),
+# a text string.
+# At the moment there is no error handling
+# for this (disk full, write protected, etc).
+proc save_binary_file {the_data what_for} {
+ set a_file [tk_getSaveFile -title $what_for -parent .]
+ if {$a_file != ""} {
+ set a_stream [open $a_file w ]
+ fconfigure $a_stream -translation binary
+ puts -nonewline $a_stream $the_data
+ close $a_stream
+ }
+}
+
+# Create the menu for File operations
+proc create_menu_file {} {
+ set fmenu .menus.file.menu
+ $fmenu add command -label "New" \
+ -font ClientFont -command {
+ .io.inp.input_area delete 1.0 end
+ }
+ # Replace the contents of the input text
+ # widget by the data from the open file.
+ # YAGNI, but is there any reason
+ # to allow inserting a file, rather than
+ # replacing the text with file contents?
+ #
+ $fmenu add command -label "Open" \
+ -font ClientFont -command {
+ set the_text [text_file_contents "File to load"]
+ if {$the_text != ""} {
+ .io.inp.input_area delete 1.0 end
+ .io.inp.input_area insert end $the_text
+ }
+ }
+
+ $fmenu add command -label "Read" \
+ -font ClientFont -command {
+ generate_output [text_file_contents "File to read"]
+ }
+ # How to make these disabled for now?
+ $fmenu add command -label "Save Input" \
+ -font ClientFont -command {
+ set the_text [get_input_text]
+ save_text_file $the_text "Save Input"
+ }
+ $fmenu add command -label "Save Output" \
+ -font ClientFont -command {
+ set the_text [get_output_text]
+ save_text_file $the_text "Save Output"
+ }
+}
+
+# Create the menu for edit operations
+proc create_menu_edit {} {
+ set emenu .menus.edit.menu
+ $emenu add command -label "Select All from Input Area" \
+ -font ClientFont -command {
+ # This code says copy the selection as well.
+ # May be wrong for some platforms, but is
+ # it more useful?
+ .io.inp.input_area tag add sel 1.0 end
+ event generate .io.inp.input_area <>
+}
+ $emenu add command -label "Select All from Output Area" \
+ -font ClientFont -command {
+ # This code says copy the selection as well.
+ # May be wrong for some platforms, but is
+ # it more useful?
+ .io.out.output_area tag add sel 1.0 end
+ event generate .io.out.output_area <>
+}
+ $emenu add command -label "Copy from Input Area" \
+ -font ClientFont -command {
+ # this appears not to work. FIXME
+ event generate .io.inp.input_area <>
+ }
+ $emenu add command -label "Copy from Output Area" \
+ -font ClientFont -command {
+ # this appears not to work. FIXME
+ event generate .io.out.output_area <>
+ }
+ $emenu add command -label "Paste into Input Area" \
+ -font ClientFont -command {
+ # this appears not to work. FIXME
+ event generate .io.inp.input_area <>
+ }
+ $emenu add command \
+ -font ClientFont -label "Insert example text into Input Area"\
+ -command {
+ }
+ # Add specific editing commands here later.
+ # For example, we would like to be able to
+ # add whole tags to the XML based formats,
+ # wrap matching tags around selected text.
+ # Also we need to find out what happens with
+ # copy cut and paste, given that X Windows
+ # is different from MS Windows.
+ # Allow example text to be inserted.
+ # However, my thinking is that this should not
+ # overwrite as it is in the Java application,
+ # because this rubs out edits when switching
+ # voices, and this can be annoying when
+ # exploring the system.
+}
+
+# Set the server properties, mostly just
+# host and port. Maybe later protocol will
+# be possible for https connections?
+proc create_menu_server {} {
+ set smenu .menus.server.menu
+ $smenu add command -label "host" -font ClientFont -command {
+ create_entry_dialog "MARY TTS server name" "hostname/IP Address" mary_tts_host
+ }
+ $smenu add command -label "port" -font ClientFont -command {
+ create_entry_dialog "MARY TTS server port" "pott number" mary_tts_port
+ }
+}
+
+# setup the fonts for the various areas on the dipslay.
+proc setup_font {family size} {
+ foreach win {.io .controls .entry.dialogue } {
+ font configure ClientFont -family $family -size $size
+ }
+}
+
+# Create the menu for changing the text size.
+proc create_menu_textstyle {} {
+ set tmenu .menus.textstyle.menu
+
+ $tmenu add cascade -label "Courier" -underline 0 -menu \
+ $tmenu.courier -font ClientFont
+ $tmenu add cascade -label "Times" -underline 0 -menu \
+ $tmenu.times -font ClientFont
+ $tmenu add cascade -label "Helvetica" -underline 0 -menu \
+ $tmenu.helvetica -font ClientFont
+ foreach {name family} [list $tmenu.courier Courier \
+ $tmenu.times Times $tmenu.helvetica Helvetica ] {
+ set m1 [menu $name]
+ foreach pts {6 7 8 9 10 12 14 16 18 20 24 28 32 36} {
+ $m1 add command -label "$pts" -font ClientFont\
+ -command [list setup_font $family $pts ]
+ }
+ }
+}
+
+
+
+# Create the menu for Help
+proc create_menu_help {} {
+ # This is all pretty much "wet paint"
+ # Is there enough to merit separate menus?
+ set hmenu .menus.help.menu
+ $hmenu add command -label "Introduction" -font ClientFont\
+ -command {
+ tk_messageBox -message "This is a basic Tcl/Tk
+client for the MARY TTS system. Most of the options
+are reached through the menus on the top. Some
+facilities are presently lacking.
+
+Most of the interface should be self-explanatory.
+In the File menu, Read will read a given file aloud
+(or at least take it as input for the present
+form of processing), whereas Open will load it
+into the input area. Save input and Save output
+refer to the contents of the text windows. The
+save button next to the play button will save
+the output to a file; this is assumed to be a
+text file, unless the output is audio, in which
+case it is a binary file.
+
+The Edit menu has cut and paste facilities,
+but these don't seem to work reliably. The
+default key bindings for text areas should
+be useable.
+
+You will need to set the input and output types
+and the audio format before pressing play.
+Code does not yet exist to figure out sensible
+defaults for your platform.
+
+This does not have support for the effects, yet.
+
+Contributions from developers welcome." -type ok
+ }
+ $hmenu add command -label "About" -command {} -font ClientFont
+}
+
+# We need to create menus for the available
+# voices and audio formats, etc.
+# When we have the data for these menus from
+# the server, create them by using the global
+# lists of information.
+proc create_radio_menu_from_list {what} {
+ global $what
+ set plural "${what}s"
+ upvar 1 $plural var
+ foreach item $var {
+ .menus.${what}.menu add radiobutton -label $item -variable $what \
+ -value $item -font ClientFont
+ }
+}
+
+proc reset_entry_and_var {a_variable} {
+ upvar #0 $a_variable var
+ upvar #0 old_$a_variable old_var
+ set var $old_var
+ destroy .entry_dialogue
+}
+# Create the toplevel for choosing a host
+# or port, something taken from an entry.
+proc create_entry_dialog {a_message a_label a_variable} {
+ upvar #0 $a_variable var
+ upvar #0 old_$a_variable old_var
+ toplevel .entry_dialogue
+ label .entry_dialogue.the_message -text $a_message \
+ -font ClientFont
+ label .entry_dialogue.the_label -text $a_label -font ClientFont
+ entry .entry_dialogue.the_entry -textvariable $a_variable \
+ -font ClientFont
+ button .entry_dialogue.ok -text "OK" -font ClientFont -command {
+ destroy .entry_dialogue
+ }
+ button .entry_dialogue.cancel -text "Cancel" -font ClientFont \
+ -command "reset_entry_and_var $a_variable"
+
+ grid .entry_dialogue.the_message -row 1 -column 1
+ grid .entry_dialogue.the_label -row 2 -column 1
+ grid .entry_dialogue.the_entry -row 2 -column 2
+ grid .entry_dialogue.ok -row 3 -column 1
+ grid .entry_dialogue.cancel -row 3 -column 2
+}
+
+# Add a message to the end of the output
+# text widget.
+proc add_message {a_message} {
+ .io.out.output_area configure -state normal
+ .io.out.output_area insert end $a_message
+ .io.out.output_area configure -state disabled
+}
+
+
+# Clear the text in the output text widget.
+proc clear_output {} {
+ .io.out.output_area configure -state normal
+ .io.out.output_area delete 1.0 end
+ .io.out.output_area configure -state disabled
+}
+
+# Sound generation is platform dependent.
+# This provides an "abstract" function to
+# be overridden by the platform dependent
+# code. In this case it alerts the user
+# in the output window that nothing is going
+# to happen.
+proc play {sound} {
+ add_message \
+ "play sound not implemented on this platform apparently"
+}
+
+# Graphical stuff.
+
+# In order to be able to scale the font, define a font.
+font create ClientFont -family [font actual TkDefaultFont -family] \
+ -size [font actual TkDefaultFont -size]
+
+frame .menus
+create_menubuttons
+create_menu_file
+create_menu_edit
+create_menu_server
+create_menu_textstyle
+create_menu_help
+# Fill in the other menus at runtime.
+
+# .io communicates text with the user,
+# through an input and output window.
+frame .io
+frame .io.inp
+frame .io.out
+# .controls will hold the play button and
+# the effects controls.
+frame .controls
+
+# Draw the controls in .io
+label .io.inp.input_label -text "Input Area" -font ClientFont
+text .io.inp.input_area -height 10 -width 40 \
+-xscrollcommand ".io.inp.input_x set" \
+-yscrollcommand ".io.inp.input_y set" -font ClientFont
+scrollbar .io.inp.input_x -orient horizontal \
+-command ".io.inp.input_area xview"
+scrollbar .io.inp.input_y -orient vertical \
+-command ".io.inp.input_area yview"
+
+label .io.out.output_label -text "Output Area" -font ClientFont
+text .io.out.output_area -height 10 -width 40 -state disabled \
+-xscrollcommand ".io.out.output_x set" \
+-yscrollcommand ".io.out.output_y set" -font ClientFont
+scrollbar .io.out.output_x -orient horizontal \
+-command ".io.out.output_area xview"
+scrollbar .io.out.output_y -orient vertical \
+-command ".io.out.output_area yview"
+
+grid .io.inp -in .io -row 1 -column 1
+grid .io.out -in .io -row 1 -column 2
+grid .io.inp.input_label -in .io.inp -row 1 -column 1
+grid .io.inp.input_area -in .io.inp -row 2 -column 1
+grid .io.inp.input_y -in .io.inp -row 2 -column 2 -sticky ns
+grid .io.inp.input_x -in .io.inp -row 3 -column 1 -sticky ew
+
+grid .io.out.output_label -in .io.out -row 1 -column 1
+grid .io.out.output_area -in .io.out -row 2 -column 1
+grid .io.out.output_y -in .io.out -row 2 -column 2 -sticky ns
+grid .io.out.output_x -in .io.out -row 3 -column 1 -sticky ew
+
+button .controls.play -text "play" -font ClientFont -command {
+ generate_output [get_input_text]
+}
+grid .controls.play -in .controls -row 1 -column 1
+
+button .controls.save -text "save" -font ClientFont -command {
+ global outputtype
+ set input_text [get_input_text]
+ if { $outputtype eq "AUDIO" } {
+ save_binary_file [collect_audio_data $input_text ] "Save audio file"
+ } else {
+ save_text_file [collect_audio_data $input_text ] "Save output to file"
+ }
+}
+
+grid .controls.save -in .controls -row 1 -column 2
+
+pack .menus .io .controls -in . -side top
+
+
+
+# Detect whether this is the main program
+# This test was taken from the Tcl Wiki, and
+# seems to work OK.
+
+if {[info exists argv0] && [file tail [info script]] eq [file tail $argv0]} {
+
+ # Try to find the temporary files directory.
+ catch { set tmpdir "/tmp" }
+ catch { set tmpdir $::env(TRASH_FOLDER) }
+ catch { set tmpdir $::env(TMP) }
+ catch { set tmpdir $::env(TEMP) }
+ # This needs better handling of
+ # possible alternatives
+ # This is needed for Windows sound only.
+
+ # Do the platform dependent things.
+ if {$tcl_platform(platform) eq "windows"} {
+ package require twapi
+
+ proc play {sound} {
+ global tmpdir
+ # Write sound to a temporary file
+ set sndfile [file join $tmpdir "MARYTTS_sound.[pid].wav" ]
+ set stream [open $sndfile w]
+ # Make sure the file is binary:
+ fconfigure $stream -translation binary
+ puts -nonewline $stream $sound
+ close $stream
+ # Play the file.
+ ::twapi::play_sound $sndfile
+ # Remove the file.
+ file delete $sndfile
+ }
+ }
+ # Put other platforms here.
+
+ # Setup the globals with reference to the
+ # server, which is assumed to be working.
+ # Since we have options to alter this with
+ # menu items, there probably needs to be
+ # some way to reload all this. But we need
+ # to know how to delete the existing menu
+ # entries to do that.
+ setup_globals
+ create_radio_menu_from_list inputtype
+ create_radio_menu_from_list outputtype
+ create_radio_menu_from_list voice
+ create_radio_menu_from_list audioformat
+
+ # Note, at the moment voices holds locales,
+ # gender, and voice type
+
+ # At the moment this is just diagnostic:
+ ## add_message [ join $voices "\n" ]
+ # it tells us we have a basically working
+ # system and the list of voices has been
+ # picked up and manipulated correctly.
+ # So it is commented out now.
+}
+
+
diff --git a/external/marytts-5.1.2/doc/examples/client/texttospeechdemo.html b/external/marytts-5.1.2/doc/examples/client/texttospeechdemo.html
new file mode 100755
index 00000000..e788cf50
--- /dev/null
+++ b/external/marytts-5.1.2/doc/examples/client/texttospeechdemo.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/hal-core/resources/web/api/openapi.json b/hal-core/resources/web/api/openapi.json
deleted file mode 100644
index a3dbf042..00000000
--- a/hal-core/resources/web/api/openapi.json
+++ /dev/null
@@ -1,313 +0,0 @@
-{
- "components": {
- "schemas": {
- "alertClass": {
- "type": "object",
- "properties": {
- "id": {"type": "integer"},
- "level": {"type": "string"},
- "ttl": {"type": "integer"},
- "title": {"type": "string"},
- "description": {"type": "string"}
- }
- },
-
- "eventClass": {
- "type": "object",
- "properties": {
- "data": {
- "type": "object",
- "$ref": "#/components/schemas/dataClass"
- },
- "dataType": {"type": "string"},
- "name": {"type": "string"},
- "id": {"type": "integer"},
- "map": {
- "type": "object",
- "$ref": "#/components/schemas/mapClass"
- },
- "user": {"type": "string"},
- "config": {
- "type": "object",
- "$ref": "#/components/schemas/configClass"
- },
- "configType": {"type": "string"}
- }
- },
-
- "roomClass": {
- "type": "object",
- "properties": {
- "id": {"type": "integer"},
- "name": {"type": "string"},
- "map": {
- "type": "object",
- "$ref": "#/components/schemas/mapClass"
- }
- }
- },
-
- "sensorClass": {
- "type": "object",
- "properties": {
- "data": {
- "type": "object",
- "$ref": "#/components/schemas/dataClass"
- },
- "name": {"type": "string"},
- "id": {"type": "integer"},
- "map": {
- "type": "object",
- "$ref": "#/components/schemas/mapClass"
- },
- "user": {"type": "string"},
- "config": {
- "type": "object",
- "$ref": "#/components/schemas/configClass"
- },
- "aggregate": {
- "type": "object",
- "properties": {
- "data": {
- "type": "array",
- "items": {
- "type": "number"
- }
- },
- "timestamps": {
- "type": "array",
- "items": {
- "type": "integer"
- }
- }
- }
- }
- }
- },
-
- "configClass": {
- "type": "object",
- "properties": {
- }
- },
-
- "dataClass": {
- "type": "object",
- "properties": {
- "valueStr": {"type": "string"},
- "value": {"type": "number"},
- "timestamp": {"type": "integer"}
- }
- },
-
- "mapClass": {
- "type": "object",
- "properties": {
- "x": {"type": "number"},
- "y": {"type": "number"},
- "width": {"type": "number"},
- "height": {"type": "number"}
- }
- },
- }
- },
-
- "servers": [
- {
- "description": "Hal Server",
- "url": "/api"
- }
- ],
-
- "openapi": "3.0.1",
-
- "paths": {
- "/alert": {
- "get": {
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "type": "object",
- "$ref": "#/components/schemas/alertClass"
- }
- }
- }
- }
- }
- },
- "parameters": [
- {
- "schema": {
- "type": "string",
- "enum": [
- "poll",
- "peek",
- "dismiss"
- ]
- },
- "in": "query",
- "name": "action",
- "required": true
- },
- {
- "schema": {
- "type": "integer"
- },
- "in": "query",
- "name": "id",
- "required": false
- }
- ]
- }
- },
-
- "/event": {
- "get": {
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "type": "object",
- "$ref": "#/components/schemas/eventClass"
- }
- }
- }
- }
- }
- },
- "parameters": [
- {
- "schema": {
- "type": "integer"
- },
- "in": "query",
- "name": "id",
- "required": false
- },
- {
- "schema": {
- "type": "string"
- },
- "in": "query",
- "name": "configType",
- "required": false
- },
- {
- "schema": {
- "type": "string"
- },
- "in": "query",
- "name": "dataType",
- "required": false
- }
- ]
- }
- },
-
- "/room": {
- "get": {
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "type": "object",
- "$ref": "#/components/schemas/roomClass"
- }
- }
- }
- }
- }
- },
- "parameters": [
- {
- "schema": {
- "type": "integer"
- },
- "in": "query",
- "name": "id",
- "required": false
- }
- ]
- }
- },
-
- "/sensor": {
- "get": {
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "type": "object",
- "$ref": "#/components/schemas/sensorClass"
- }
- }
- }
- }
- }
- },
- "parameters": [
- {
- "schema": {
- "type": "integer"
- },
- "in": "query",
- "name": "id",
- "required": false
- },
- {
- "schema": {
- "type": "string"
- },
- "in": "query",
- "name": "configType",
- "required": false
- },
- {
- "schema": {
- "type": "string"
- },
- "in": "query",
- "name": "dataType",
- "required": false
- },
- {
- "schema": {
- "type": "string",
- "enum": [
- "min",
- "hour",
- "day",
- "week"
- ]
- },
- "in": "query",
- "name": "aggregation",
- "required": false
- }
- ]
- }
- }
- },
- "info": {
- "description": "This API allows developers and external tools to interface to Hal data and trigger different actions.",
- "title": "Hal REST API",
- "version": ""
- }
-}
\ No newline at end of file
diff --git a/hal-core/resources/web/css/hal.css b/hal-core/resources/web/css/hal.css
deleted file mode 100644
index 030b1863..00000000
--- a/hal-core/resources/web/css/hal.css
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Base structure
- */
-
-/* Move down content because we have a fixed navbar that is 50px tall */
-body {
- padding-top: 50px;
-}
-
-
-/*
- * Global add-ons
- */
-
-.sub-header {
- padding-bottom: 10px;
- border-bottom: 1px solid #eee;
-}
-
-/*
- * Top navigation
- * Hide default border to remove 1px line.
- */
-.navbar-fixed-top {
- border: 0;
-}
-
-/*
- * Sidebar
- */
-
-/* Hide for mobile, show later */
-.sidebar {
- display: none;
-}
-@media (min-width: 768px) {
- .sidebar {
- position: fixed;
- top: 51px;
- bottom: 0;
- left: 0;
- z-index: 1000;
- display: block;
- padding: 20px;
- overflow-x: hidden;
- overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
- background-color: #f5f5f5;
- border-right: 1px solid #eee;
- }
-}
-
-/* Sidebar navigation */
-.nav-sidebar {
- margin-right: -21px; /* 20px padding + 1px border */
- margin-bottom: 20px;
- margin-left: -20px;
-}
-.nav-sidebar > li > a {
- padding-right: 20px;
- padding-left: 20px;
-}
-.nav-sidebar > .active > a,
-.nav-sidebar > .active > a:hover,
-.nav-sidebar > .active > a:focus {
- color: #fff;
- background-color: #428bca;
-}
-
-
-/*
- * Main content
- */
-
-.main {
- padding: 20px;
-}
-@media (min-width: 768px) {
- .main {
- padding-right: 40px;
- padding-left: 40px;
- }
-}
-.main .page-header {
- margin-top: 0;
-}
-
-.vertical-space {
- height: 70px;
-}
-.text-vert-middle {
- vertical-align: middle !important;
-}
-
-.table-borderless tbody tr td {
- border: none;
-}
-
-.drop-shadow {
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12)
-}
-
-.disabled {
- background-color: lightgray;
- opacity: .6;
-}
-
-/*
- * Placeholder dashboard ideas
- */
-
-.placeholders {
- margin-bottom: 150px;
- text-align: center;
-}
-.placeholders h4 {
- margin-bottom: 0;
-}
-.placeholder {
- margin-bottom: 20px;
-}
-.placeholder img {
- display: inline-block;
- border-radius: 50%;
-}
-
-
-/*
- * c3.js charts overrides
- */
-.c3 line, .c3 path {
- stroke: #ccc;
-}
-.c3-line {
- stroke-width: 2px;
-}
-
-
-.anim-spin {
- animation: spin 2s infinite linear;
-}
-@keyframes spin {
- 0% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(359deg);
- }
-}
-
-/*
- * Animations
- */
-
-.pulse-border {
- animation: pulse 2s infinite;
-}
-
-@keyframes pulse {
- 0% {
- stroke-width: 3;
- opacity: 1;
- }
-
- 10% {
- stroke-width: 5;
- opacity: 0.2;
- }
- 15% {
- stroke-width: 5;
- opacity: 0.2;
- }
-
- 50% {
- stroke-width: 3;
- opacity: 1;
- }
-
- 100% {
- stroke-width: 3;
- opacity: 1;
- }
-}
-
-/*
- * Switch checkbox CSS, originally from:
- * https://community.tadabase.io/t/convert-checkbox-to-toggle-switch/2566
- */
-
-input[type="checkbox"].switch {
- /* Backgrpund properties */
- appearance: none;
- background-color: #e1e1e1; /* unchecked background color */
- border-radius: 72px;
- border-style: none;
- flex-shrink: 0;
- position: relative;
- cursor: pointer;
- margin: 0 !important;
- width: 40px !important;
- height: 20px !important;
- border: 1px solid #ccc;
-}
-input[type="checkbox"].switch,
-input[type="checkbox"].switch::after {
- transition: all 100ms ease-out;
-}
-input[type="checkbox"].switch::after {
- /* Ball properties */
- background-color: #fff; /* Color of ball */
- border-radius: 50%;
- content: "";
- height: 15px !important;
- width: 15px !important;
- left: 3px !important;
- top: 2px !important;
- position: absolute;
-}
-/* Properties for a checked state */
-input[type="checkbox"].switch:checked {
- background-color: #d9534f; /* Color of background */
-}
-input[type="checkbox"].switch:checked::after {
- background-color: #fff; /* Color of ball */
- left: 20px !important;
-}
-
-/*
- * Slider styling
- */
-
-input[type="range"] {
- accent-color: #d9534f;
-}
diff --git a/hal-core/resources/web/css/lib/bootstrap-switch.min.css b/hal-core/resources/web/css/lib/bootstrap-switch.min.css
deleted file mode 100644
index 77006595..00000000
--- a/hal-core/resources/web/css/lib/bootstrap-switch.min.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.
- *
- * @version v3.3.4
- * @homepage https://bttstrp.github.io/bootstrap-switch
- * @author Mattia Larentis (http://larentis.eu)
- * @license Apache-2.0
- */
-
-.bootstrap-switch{display:inline-block;direction:ltr;cursor:pointer;border-radius:4px;border:1px solid #ccc;position:relative;text-align:left;overflow:hidden;line-height:8px;z-index:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.bootstrap-switch .bootstrap-switch-container{display:inline-block;top:0;border-radius:4px;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on,.bootstrap-switch .bootstrap-switch-label{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;cursor:pointer;display:table-cell;vertical-align:middle;padding:6px 12px;font-size:14px;line-height:20px}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on{text-align:center;z-index:1}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary{color:#fff;background:#337ab7}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info{color:#fff;background:#5bc0de}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success{color:#fff;background:#5cb85c}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning{background:#f0ad4e;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger{color:#fff;background:#d9534f}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default{color:#000;background:#eee}.bootstrap-switch .bootstrap-switch-label{text-align:center;margin-top:-1px;margin-bottom:-1px;z-index:100;color:#333;background:#fff}.bootstrap-switch span::before{content:"\200b"}.bootstrap-switch .bootstrap-switch-handle-on{border-bottom-left-radius:3px;border-top-left-radius:3px}.bootstrap-switch .bootstrap-switch-handle-off{border-bottom-right-radius:3px;border-top-right-radius:3px}.bootstrap-switch input[type=radio],.bootstrap-switch input[type=checkbox]{position:absolute!important;top:0;left:0;margin:0;z-index:-1;opacity:0;filter:alpha(opacity=0);visibility:hidden}.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label{padding:1px 5px;font-size:12px;line-height:1.5}.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label{padding:5px 10px;font-size:12px;line-height:1.5}.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label{padding:6px 16px;font-size:18px;line-height:1.3333333}.bootstrap-switch.bootstrap-switch-disabled,.bootstrap-switch.bootstrap-switch-indeterminate,.bootstrap-switch.bootstrap-switch-readonly{cursor:default!important}.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label{opacity:.5;filter:alpha(opacity=50);cursor:default!important}.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container{-webkit-transition:margin-left .5s;-o-transition:margin-left .5s;transition:margin-left .5s}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on{border-radius:0 3px 3px 0}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off{border-radius:3px 0 0 3px}.bootstrap-switch.bootstrap-switch-focused{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label{border-bottom-right-radius:3px;border-top-right-radius:3px}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label{border-bottom-left-radius:3px;border-top-left-radius:3px}
\ No newline at end of file
diff --git a/hal-core/resources/web/css/lib/bootstrap.min.css b/hal-core/resources/web/css/lib/bootstrap.min.css
deleted file mode 100644
index 2b8fc88d..00000000
--- a/hal-core/resources/web/css/lib/bootstrap.min.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/*!
- * Bootstrap v3.3.7 (http://getbootstrap.com)
- * Copyright 2011-2016 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../../fonts/glyphicons-halflings-regular.eot);src:url(../../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
-/*# sourceMappingURL=bootstrap.min.css.map */
\ No newline at end of file
diff --git a/hal-core/resources/web/css/lib/c3.css b/hal-core/resources/web/css/lib/c3.css
deleted file mode 100644
index fda42427..00000000
--- a/hal-core/resources/web/css/lib/c3.css
+++ /dev/null
@@ -1,167 +0,0 @@
-/*-- Chart --*/
-.c3 svg {
- font: 10px sans-serif;
- -webkit-tap-highlight-color: transparent; }
-
-.c3 path, .c3 line {
- fill: none;
- stroke: #000; }
-
-.c3 text {
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none; }
-
-.c3-legend-item-tile,
-.c3-xgrid-focus,
-.c3-ygrid,
-.c3-event-rect,
-.c3-bars path {
- shape-rendering: crispEdges; }
-
-.c3-chart-arc path {
- stroke: #fff; }
-
-.c3-chart-arc text {
- fill: #fff;
- font-size: 13px; }
-
-/*-- Axis --*/
-/*-- Grid --*/
-.c3-grid line {
- stroke: #aaa; }
-
-.c3-grid text {
- fill: #aaa; }
-
-.c3-xgrid, .c3-ygrid {
- stroke-dasharray: 3 3; }
-
-/*-- Text on Chart --*/
-.c3-text.c3-empty {
- fill: #808080;
- font-size: 2em; }
-
-/*-- Line --*/
-.c3-line {
- stroke-width: 1px; }
-
-/*-- Point --*/
-.c3-circle._expanded_ {
- stroke-width: 1px;
- stroke: white; }
-
-.c3-selected-circle {
- fill: white;
- stroke-width: 2px; }
-
-/*-- Bar --*/
-.c3-bar {
- stroke-width: 0; }
-
-.c3-bar._expanded_ {
- fill-opacity: 0.75; }
-
-/*-- Focus --*/
-.c3-target.c3-focused {
- opacity: 1; }
-
-.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {
- stroke-width: 2px; }
-
-.c3-target.c3-defocused {
- opacity: 0.3 !important; }
-
-/*-- Region --*/
-.c3-region {
- fill: steelblue;
- fill-opacity: .1; }
-
-/*-- Brush --*/
-.c3-brush .extent {
- fill-opacity: .1; }
-
-/*-- Select - Drag --*/
-/*-- Legend --*/
-.c3-legend-item {
- font-size: 12px; }
-
-.c3-legend-item-hidden {
- opacity: 0.15; }
-
-.c3-legend-background {
- opacity: 0.75;
- fill: white;
- stroke: lightgray;
- stroke-width: 1; }
-
-/*-- Title --*/
-.c3-title {
- font: 14px sans-serif; }
-
-/*-- Tooltip --*/
-.c3-tooltip-container {
- z-index: 10; }
-
-.c3-tooltip {
- border-collapse: collapse;
- border-spacing: 0;
- background-color: #fff;
- empty-cells: show;
- -webkit-box-shadow: 7px 7px 12px -9px #777777;
- -moz-box-shadow: 7px 7px 12px -9px #777777;
- box-shadow: 7px 7px 12px -9px #777777;
- opacity: 0.9; }
-
-.c3-tooltip tr {
- border: 1px solid #CCC; }
-
-.c3-tooltip th {
- background-color: #aaa;
- font-size: 14px;
- padding: 2px 5px;
- text-align: left;
- color: #FFF; }
-
-.c3-tooltip td {
- font-size: 13px;
- padding: 3px 6px;
- background-color: #fff;
- border-left: 1px dotted #999; }
-
-.c3-tooltip td > span {
- display: inline-block;
- width: 10px;
- height: 10px;
- margin-right: 6px; }
-
-.c3-tooltip td.value {
- text-align: right; }
-
-/*-- Area --*/
-.c3-area {
- stroke-width: 0;
- opacity: 0.2; }
-
-/*-- Arc --*/
-.c3-chart-arcs-title {
- dominant-baseline: middle;
- font-size: 1.3em; }
-
-.c3-chart-arcs .c3-chart-arcs-background {
- fill: #e0e0e0;
- stroke: none; }
-
-.c3-chart-arcs .c3-chart-arcs-gauge-unit {
- fill: #000;
- font-size: 16px; }
-
-.c3-chart-arcs .c3-chart-arcs-gauge-max {
- fill: #777; }
-
-.c3-chart-arcs .c3-chart-arcs-gauge-min {
- fill: #777; }
-
-.c3-chart-arc .c3-gauge-value {
- fill: #000;
- /* font-size: 28px !important;*/ }
diff --git a/hal-core/resources/web/css/lib/c3.min.css b/hal-core/resources/web/css/lib/c3.min.css
deleted file mode 100644
index 1e20d5b1..00000000
--- a/hal-core/resources/web/css/lib/c3.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:gray;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #CCC}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#FFF}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max,.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000}
\ No newline at end of file
diff --git a/hal-core/resources/web/css/lib/jquery.filer.css b/hal-core/resources/web/css/lib/jquery.filer.css
deleted file mode 100644
index ead852a6..00000000
--- a/hal-core/resources/web/css/lib/jquery.filer.css
+++ /dev/null
@@ -1,438 +0,0 @@
-/*!
- * CSS jQuery.filer
- * Copyright (c) 2015 CreativeDream
- * Version: 1.0.5 (19-Nov-2015)
-*/
-/*@import url('../assets/fonts/jquery.filer-icons/jquery-filer.css');*/
-
-/*-------------------------
- Basic configurations
--------------------------*/
-.jFiler * {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-}
-
-.jFiler {
- font-family: sans-serif;
- font-size: 14px;
- color: #494949;
-}
-
-/* Helpers */
-.jFiler ul.list-inline li {
- display: inline-block;
- padding-right: 5px;
- padding-left: 5px;
-}
-
-.jFiler .pull-left {
- float: left;
-}
-
-.jFiler .pull-right {
- float: right;
-}
-
-/* File Icons */
-span.jFiler-icon-file {
- position: relative;
- width: 57px;
- height: 70px;
- display: inline-block;
- line-height: 70px;
- text-align: center;
- border-radius: 3px;
- color: #fff;
- font-family: sans-serif;
- font-size: 13px;
- font-weight: bold;
- overflow: hidden;
- box-shadow: 42px -55px 0 0 #A4A7AC inset;
-}
-
-span.jFiler-icon-file:after {
- position: absolute;
- top: -1px;
- right: -1px;
- display: inline-block;
- content: '';
- border-style: solid;
- border-width: 16px 0 0 16px;
- border-color: transparent transparent transparent #DADDE1;
-}
-
-span.jFiler-icon-file i[class*="icon-jfi-"] {
- font-size: 24px;
-}
-
-span.jFiler-icon-file.f-image {
- box-shadow: 42px -55px 0 0 #e15955 inset;
-}
-
-span.jFiler-icon-file.f-image:after {
- border-left-color: #c6393f;
-}
-
-span.jFiler-icon-file.f-video {
- box-shadow: 42px -55px 0 0 #4183d7 inset;
-}
-
-span.jFiler-icon-file.f-video:after {
- border-left-color: #446cb3;
-}
-
-span.jFiler-icon-file.f-audio {
- box-shadow: 42px -55px 0 0 #5bab6e inset;
-}
-
-span.jFiler-icon-file.f-audio:after {
- border-left-color: #448353;
-}
-
-
-/* Progress Bar */
-.jFiler-jProgressBar {
- height: 8px;
- background: #f1f1f1;
- margin-top: 3px;
- margin-bottom: 0;
- overflow: hidden;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
-}
-
-.jFiler-jProgressBar .bar {
- float: left;
- width: 0;
- height: 100%;
- font-size: 12px;
- color: #ffffff;
- text-align: center;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- background-color: #50A1E9;
- box-sizing: border-box;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- -webkit-transition: width 0.3s ease;
- -moz-transition: width 0.3s ease;
- -o-transition: width 0.3s ease;
- transition: width 0.3s ease;
-}
-
-.jFiler-jProgressBar .bar.dark {
- background-color: #555;
-}
-
-.jFiler-jProgressBar .bar.blue {
- background-color: #428bca;
-}
-
-.jFiler-jProgressBar .bar.green {
- background-color: #5cb85c;
-}
-
-.jFiler-jProgressBar .bar.orange {
- background-color: #f7a923;
-}
-
-.jFiler-jProgressBar .bar.red {
- background-color: #d9534f;
-}
-
-/* Thumbs */
-.jFiler-row:after,
-.jFiler-item:after {
- display: table;
- line-height: 0;
- content: "";
- clear: both;
-}
-
-.jFiler-items ul {
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-/*-------------------------
- Default Theme
--------------------------*/
-.jFiler-theme-default .jFiler-input {
- position: relative;
- display: block;
- width: 400px;
- height: 35px;
- margin: 0 0 15px 0;
- background: #fefefe;
- border: 1px solid #cecece;
- font-size: 12px;
- font-family: sans-serif;
- color: #888;
- border-radius: 4px;
- cursor: pointer;
- overflow: hidden;
- -webkit-box-shadow: rgba(0,0,0,.25) 0 4px 5px -5px inset;
- -moz-box-shadow: rgba(0,0,0,.25) 0 4px 5px -5px inset;
- box-shadow: rgba(0,0,0,.25) 0 4px 5px -5px inset;
-}
-
-.jFiler-theme-default .jFiler-input.focused {
- outline: none;
- -webkit-box-shadow: 0 0 7px rgba(0,0,0,0.1);
- -moz-box-shadow: 0 0 7px rgba(0,0,0,0.1);
- box-shadow: 0 0 7px rgba(0,0,0,0.1);
-}
-
-.jFiler-theme-default .jFiler.dragged .jFiler-input {
- border: 1px dashed #aaaaaa;
- background: #f9f9f9;
-}
-
-.jFiler-theme-default .jFiler.dragged .jFiler-input:hover {
- background: #FFF8D0;
-}
-
-.jFiler-theme-default .jFiler.dragged .jFiler-input * {
- pointer-events: none;
-}
-
-.jFiler-theme-default .jFiler.dragged .jFiler-input .jFiler-input-caption {
- width: 100%;
- text-align: center;
-}
-
-.jFiler-theme-default .jFiler.dragged .jFiler-input .jFiler-input-button {
- display: none;
-}
-
-.jFiler-theme-default .jFiler-input-caption {
- display: block;
- float: left;
- height: 100%;
- padding-top: 8px;
- padding-left: 10px;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-
-.jFiler-theme-default .jFiler-input-button {
- display: block;
- float: right;
- height: 100%;
- padding-top: 8px;
- padding-left: 15px;
- padding-right: 15px;
- border-left: 1px solid #ccc;
- color: #666666;
- text-align: center;
- background-color: #fefefe;
- background-image: -webkit-gradient(linear,0 0,0 100%,from(#fefefe),to(#f1f1f1));
- background-image: -webkit-linear-gradient(top,#fefefe,#f1f1f1);
- background-image: -o-linear-gradient(top,#fefefe,#f1f1f1);
- background-image: linear-gradient(to bottom,#fefefe,#f1f1f1);
- background-image: -moz-linear-gradient(top,#fefefe,#f1f1f1);
- -webkit-transition: all .1s ease-out;
- -moz-transition: all .1s ease-out;
- -o-transition: all .1s ease-out;
- transition: all .1s ease-out;
-}
-
-.jFiler-theme-default .jFiler-input-button:hover {
- -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.07);
- -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.07);
- box-shadow: inset 0 0 10px rgba(0,0,0,0.07);
-}
-
-.jFiler-theme-default .jFiler-input-button:active {
- background-image: -webkit-gradient(linear,0 0,0 100%,from(#f1f1f1),to(#fefefe));
- background-image: -webkit-linear-gradient(top,#f1f1f1,#fefefe);
- background-image: -o-linear-gradient(top,#f1f1f1,#fefefe);
- background-image: linear-gradient(to bottom,#f1f1f1,#fefefe);
- background-image: -moz-linear-gradient(top,#f1f1f1,#fefefe);
-}
-
-/*-------------------------
- Thumbnails
--------------------------*/
-.jFiler-items-default .jFiler-items {
-
-}
-
-.jFiler-items-default .jFiler-item {
- position: relative;
- padding: 16px;
- margin-bottom: 16px;
- background: #f7f7f7;
- color: #4d4d4c;
-}
-
-
-.jFiler-items-default .jFiler-item .jFiler-item-icon {
- font-size: 32px;
- color: #f5871f;
-
- margin-right: 15px;
- margin-top: -3px;
-}
-
-.jFiler-items-default .jFiler-item .jFiler-item-title {
- font-weight: bold;
-}
-
-.jFiler-items-default .jFiler-item .jFiler-item-others {
- font-size: 12px;
- color: #777;
- margin-left: -5px;
- margin-right: -5px;
-}
-
-.jFiler-items-default .jFiler-item .jFiler-item-others span {
- padding-left: 5px;
- padding-right: 5px;
-}
-
-.jFiler-items-default .jFiler-item-assets {
- position: absolute;
- display: block;
- right: 16px;
- top: 50%;
- margin-top: -10px;
-}
-
-.jFiler-items-default .jFiler-item-assets a {
- padding: 8px 9px 8px 12px;
- cursor: pointer;
- background: #fafafa;
- color: #777;
- border-radius: 4px;
- border: 1px solid #e3e3e3
-}
-
-.jFiler-items-default .jFiler-item-assets .jFiler-item-trash-action:hover,
-.jFiler-items-default .jFiler-item-assets .jFiler-item-trash-action:active {
- color: #d9534f;
-}
-
-.jFiler-items-default .jFiler-item-assets .jFiler-item-trash-action:active {
- background: transparent;
-}
-
-/* Thumbnails: Grid */
-.jFiler-items-grid .jFiler-item {
- float: left;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container {
- position: relative;
- margin: 0 20px 30px 0;
- padding: 10px;
- border: 1px solid #e1e1e1;
- border-radius: 3px;
- background: #fff;
- -webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.06);
- -moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.06);
- box-shadow: 0px 0px 3px rgba(0,0,0,0.06);
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-thumb {
- position: relative;
- width: 160px;
- height: 115px;
- min-height: 115px;
- border: 1px solid #e1e1e1;
- overflow: hidden;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-thumb .jFiler-item-thumb-image {
- width: 100%;
- height: 100%;
- text-align: center;
-}
-
-.jFiler-item .jFiler-item-container .jFiler-item-thumb img {
- max-width: none;
- max-height: 100%;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-thumb span.jFiler-icon-file {
- margin-top: 20px;
-}
-
-.jFiler-items-grid .jFiler-item-thumb-image.fi-loading {
- background: url('data:image/gif;base64,R0lGODlhIwAjAMQAAP////f39+/v7+bm5t7e3tbW1s7OzsXFxb29vbW1ta2traWlpZycnJSUlIyMjISEhHt7e3Nzc2tra2NjY1paWlJSUkpKSkJCQjo6OjExMSkpKRkZGRAQEAAAAP///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFBAAeACwAAAAAIwAjAAAF5CAgjmRpnmiqrmzrvnAsz3Rto4Fwm4EYLIweQHcTKAiAQOPRI0QKRcYiEGA4qI8K9HZoGAIOSOBgCdIGBeLCMUgoBJSJjsBAxAiKRSFAQBCVBwMKGRsNQi8DBwsJhyQVGxMKjTCJk0kPjDI5AlQqBAcICFstBQqmmScFGh0dHBaWKAIEBQQDKQEKDxEQCTMBA5Y/o5oDoZYCHB1PMgIHCQacwCPACRStDTEDBrYABQg5wAgGIg4YYjQCogEGB3wI3J2+oD0G42PfN2Pc7D2JRDb/+In4t8MHwYIIEypcyLChQ4YhAAAh+QQFBAAeACwIAAgAEwATAAAFlqAnjiKSjAFJBscgLos4NIQ6JggAKLHXSDWbp6CoLRgeg0ShGwkIKQ9iITggPJFHaqA4eAYIRK0a9SwK0spl0TQkvEIJJnIlCdDCRk4lEJIGBgcHRn4jBBkciROFKgkNDg51jCJBJJU2ARocD4xNAQsGCBMcGz2FAxwZKQwVDYVwEhwOI02MAxsceJMeOgwaJ7skCX0jIQAh+QQFBAAeACwAAAAAAQABAAAFA6AXAgAh+QQFBAAeACwAAAAAAQABAAAFA6AXAgAh+QQFBAAeACwJAAcAEgAVAAAFjqAnjmJAnihgHChqCACAJKMyoMHBeggSJ40baoC4zTwFB6IlOiwLhkCDMUIYUAUSgiA4RCZLAXPkoDQOsfFosVNjDYaBQiRmWjaaDMTdXDAYbWMJQnwiGBoOBEwmIwVeGhhzKAJ+BBsXIgoSVCcEAxkbAw8enEwAARkaYqluAqliChlLY64aQrNjAT2MKCEAIfkEBQQAHgAsBwAIABQAFAAABZqgJ45jUQBkqorGgQqIsKqteCjyTLbAsBg6UoBA8CgSIoGhGGQNAoXG4zAaNBcPxalJQhS4KwGhUCQgRYHZQGKxVBpgD8CQUCiAYEQTpZpcGFYrBgw5HgkEBg4XFHoqFx10CwMZFCIIDwl8IwscFAQXGR4NGQo6BBocRRUYHgIWGEwqBxoPHgEWoYYXVCsBCTIBqzkHaVwHvCshACH5BAUEAB4ALAAAAAABAAEAAAUDoBcCACH5BAUEAB4ALAcACAAVABQAAAWaoCeOpDECZKqKgRcY7bqanoHI6+EKSIHjCJ2oMPidCgIPQbHwGUkIBoLwJAEM1OpqQBgkC0yjwBGRRBQokfdXOASzo0MjqTrQUwQIpwM/QSYJKQoaHRUKHgtQSgwTEUIeDRcPSRQcHgiBFREiB1IkdAkaEgMUGAILFoE4AxkaRRIVLRIURTIGGQ0iExWcEzQyBzGwI05PV78rIQAh+QQFBAAeACwAAAAAAQABAAAFA6AXAgAh+QQFBAAeACwHAAgAFAAUAAAFlaAnjmRBnmgqCip6kEGbDnJqvmJAsLVIDwgEoTc6JAy0k05VSIoKiSgipgoIaIFKZ8tBVBeNBgORkEwkDt6sYECSBosUwJRybDiqxuOgTmTwCAUKIwAHAwMJDw10CxUNMRIaBQcIAmhPCgYjVAcZDx4REx5lOCoWGCIPER4Bqi0FFwwiEBIxBg9DKpqpEVS5PQUFACohACH5BAUEAB4ALAAAAAABAAEAAAUDoBcCACH5BAUEAB4ALAcACAAUABQAAAWRoCeOpEGeaCoGKmqOQlvKXgId4usR6DA+HA6kQDsxMB0Nr0hSTHxFAgJxIABogpiEI9rgVAiF2ICARCANVovAjsESKoKaNGBkMqrEojA/WDYSHgMIJAVZBwsKSwoSCyIOFx4FJg4LVwQHRCgVDQIOEAEHDi9XJwISFAIADA4iDJ1xEwoiDa2SDFA0rCO5NGwtIQAh+QQFBAAeACwAAAAAAQABAAAFA6AXAgAh+QQFBAAeACwHAAgAEwAUAAAFj6AnisNonqeBLWg7GpwmtAENcc8s6ifyGKJMp1DyIFqNjecxUEiKLpGi4slATcBW4hkdDQ6HbHd048TELtah8XCwxqjAsXXdKSyWuuiAILwmGBBABzUiBDUFCQglCBAJIgsTBAQFAQpzAwZ1BREsCwweBQt+Lg8QNQpvCAqFJwMQc6mGjy6kHrI7cB4DeiIhACH5BAUEAB4ALAAAAAABAAEAAAUDoBcCACH5BAUEAB4ALAcABwASABUAAAWXoCeOI0GQaBpUl5CSRZV4QrYN71hoWBBkGpdISAI4No2BhoNLHRijy8YQmQwOpJMC2BAgIh5fgJZKSDYWYg4FWZMMhkLT7XHYeAW6wrBgLGZ0KQZjgR4IEhFqJIAeBQ8UDQUCeSNzIwcNCCIJDwMDJwgGawSZAQgzBAiWIwELDSIHmh6xOQyiAKciV4oeAHO0IwB0ArweIQAh+QQFBAAeACwAAAAAAQABAAAFA6AXAgAh+QQFBAAeACwHAAcAEAAVAAAFjKAnjuMwkKgnjFJVosSEeMGVrcc1j8TlehVMIIDh7EaMzMKDuTE4k4DHsCiIKJnCI0LYcE6ehMWyPDxGgshyZL5MUqID6uCAowsEwsouWlTGFAR8HgUJCglHgyNWigF0dXYzBAwPCoJgcAUKBnELAgKYcAObHgdyfIYiBQcAdgIJjAanrq0AsoojQyghACH5BAUEAB4ALAAAAAABAAEAAAUDoBcCACH5BAUEAB4ALAcACAAUABQAAAWYoCeKwQhF5aiqA3SIlDVW7yoOlCRKlVhtNZtHYUkIKBfPYoNaFRADUUTWeAwyGYHHAFmIDhIJImBorBIFB6cDSZUnEGEA08k0UiPDQrsSTB58HgEDhEIqAHgIERESVoY2BAcIBwaPlh5Rl04KCnhnKwMJDFCelgMIBAAeT3hBNqoeAggFIgiaX7ZblZoBB5lbqoG3wzbCKyEAIfkEBQQAHgAsBwAHABUAEwAABZygJ46jIJBoSjZPqa6GGEmBZ0zx60Gt90QiSSb3QkgOHskkkMj0UAOkyCEhLBiey2X0SIwMLKRVAPAEHggCY8N5egiKB6OGAmwtC1UhQScFIgt9JAKCKQUICQkxBw2NCycqBhsdlBgBAwUGBgRlKgMPExMSgSSdKmQvBAgIOqwoAgeKkDopBgMiMbOutCgGSLe8IlIeSKbBI1LAKCEAIfkEBQQAHgAsAAAAAAEAAQAABQOgFwIAIfkEBQQAHgAsAAAAAAEAAQAABQOgFwIAIfkECQQAHgAsAAAAACMAIwAABbWgJ45kaZ5oqq5s675wLM90baPBvS6MTgoKgqjxEBEihZuAsRAxHKJHJXk7NAwBB8RzsPRqBYFo4RgkFALKxMhAxAiKBdXtAXgah4Eis2nIBgcLCSgVGxMKNYAoD4MzAgI5KgQHCAhULQUKmgmRJgUaIhwWLwIEBQQDKQEKDxEQCXYxnSUBcjapKAIcHUg+JgkUHRx+YB6zIw4YEMc2QiMBzDB0HgbGvifR19rb3N3e3+Dh4ikhADs=') no-repeat center;
- width: 100%;
- height: 100%;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-info {
- position: absolute;
- bottom: -10%;
- left: 0;
- width: 100%;
- color: #fff;
- padding: 6px 10px;
- background: -moz-linear-gradient(bottom,rgba(0,0,0,1) 0,rgba(0,0,0,0) 100%);
- background: -webkit-linear-gradient(bottom,rgba(0,0,0,1) 0,rgba(0,0,0,0) 100%);
- background: -o-linear-gradient(bottom,rgba(0,0,0,1) 0,rgba(0,0,0,0) 100%);
- background: -ms-linear-gradient(bottom,rgba(0,0,0,1) 0,rgba(0,0,0,0) 100%);
- background: linear-gradient(to top,rgba(0,0,0,1) 0,rgba(0,0,0,0) 100%);
- z-index: 9;
- opacity: 0;
- filter: alpha(opacity(0));
- -webkit-transition: all 0.12s;
- -moz-transition: all 0.12s;
- transition: all 0.12s;
-}
-
-.jFiler-items-grid .jFiler-no-thumbnail.jFiler-item .jFiler-item-container .jFiler-item-info {
- background: rgba(0,0,0,0.55);
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-thumb:hover .jFiler-item-info {
- bottom: 0;
- opacity: 1;
- filter: aplpha(opacity(100));
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-info .jFiler-item-title {
- display: block;
- font-weight: bold;
- word-break: break-all;
- line-height: 1;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-info .jFiler-item-others {
- display: inline-block;
- font-size: 10px;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-assets {
- margin-top: 10px;
- color: #999;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-assets .text-success {
- color: #3C763D
-}
-
-.jFiler-items-grid .jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-assets .text-error {
- color: #A94442
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-assets .jFiler-jProgressBar {
- width: 120px;
- margin-left: -5px;
-}
-
-.jFiler-items-grid .jFiler-item .jFiler-item-container .jFiler-item-assets .jFiler-item-others {
- font-size: 12px;
-}
-
-.jFiler-items-grid .jFiler-item-trash-action:hover {
- cursor: pointer;
- color: #d9534f;
-}
\ No newline at end of file
diff --git a/hal-core/resources/web/css/lib/svg.select.css b/hal-core/resources/web/css/lib/svg.select.css
deleted file mode 100644
index 18888ab3..00000000
--- a/hal-core/resources/web/css/lib/svg.select.css
+++ /dev/null
@@ -1,44 +0,0 @@
-.svg_select_points_lt{
- cursor: nw-resize;
-}
-.svg_select_points_rt{
- cursor: ne-resize;
-}
-.svg_select_points_rb{
- cursor: se-resize;
-}
-.svg_select_points_lb{
- cursor: sw-resize;
-}
-.svg_select_points_t{
- cursor: n-resize;
-}
-.svg_select_points_r{
- cursor: e-resize;
-}
-.svg_select_points_b{
- cursor: s-resize;
-}
-.svg_select_points_l{
- cursor: w-resize;
-}
-
-.svg_select_points_rot{
- stroke-width:1;
- stroke:black;
- fill: #F9FFED;
-}
-
-.svg_select_points_point{
- cursor: move;
-}
-
-.svg_select_boundingRect{
- stroke-width:1;
- fill:gray;
- stroke-dasharray:10 10;
- stroke:black;
- stroke-opacity:0.8;
- fill-opacity:0.1;
- pointer-events:none; /* This ons is needed if you want to deselect or drag the shape*/
-}
\ No newline at end of file
diff --git a/hal-core/resources/web/css/lib/svg.select.min.css b/hal-core/resources/web/css/lib/svg.select.min.css
deleted file mode 100644
index d8345130..00000000
--- a/hal-core/resources/web/css/lib/svg.select.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.svg_select_points_lt{cursor:nw-resize}.svg_select_points_rt{cursor:ne-resize}.svg_select_points_rb{cursor:se-resize}.svg_select_points_lb{cursor:sw-resize}.svg_select_points_t{cursor:n-resize}.svg_select_points_r{cursor:e-resize}.svg_select_points_b{cursor:s-resize}.svg_select_points_l{cursor:w-resize}.svg_select_points_rot{stroke-width:1;stroke:#000;fill:#f9ffed}.svg_select_points_point{cursor:move}.svg_select_boundingRect{stroke-width:1;fill:gray;stroke-dasharray:10 10;stroke:#000;stroke-opacity:.8;fill-opacity:.1;pointer-events:none}
\ No newline at end of file
diff --git a/hal-core/resources/web/favicon.ico b/hal-core/resources/web/favicon.ico
deleted file mode 100644
index e9d61583..00000000
Binary files a/hal-core/resources/web/favicon.ico and /dev/null differ
diff --git a/hal-core/resources/web/img/favicon.svg b/hal-core/resources/web/img/favicon.svg
deleted file mode 100644
index bb6996a5..00000000
--- a/hal-core/resources/web/img/favicon.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/hal-core/resources/web/img/lightbulb_off.svg b/hal-core/resources/web/img/lightbulb_off.svg
deleted file mode 100644
index fcd6bad5..00000000
--- a/hal-core/resources/web/img/lightbulb_off.svg
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/hal-core/resources/web/img/temperature.svg b/hal-core/resources/web/img/temperature.svg
deleted file mode 100644
index 68a0864d..00000000
--- a/hal-core/resources/web/img/temperature.svg
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/hal-core/resources/web/js/hal.js b/hal-core/resources/web/js/hal.js
deleted file mode 100644
index e731b2e7..00000000
--- a/hal-core/resources/web/js/hal.js
+++ /dev/null
@@ -1,214 +0,0 @@
-// --------------------------------------------------------
-// Autostart
-// --------------------------------------------------------
-
-"use strict";
-
-$(function(){
- $(".toggle-switch").bootstrapSwitch({inverse: true, size: "mini"});
-
- $(".timestamp").relTimestamp();
-});
-
-// --------------------------------------------------------
-// JQuery helper functions
-// --------------------------------------------------------
-
-// $.attr() # returns all attributes of an element
-(function(old) {
- $.fn.attr = function() {
- if(arguments.length === 0) {
- if(this.length === 0) {
- return null;
- }
-
- let obj = {};
- $.each(this[0].attributes, function() {
- if(this.specified) {
- obj[this.name] = this.value;
- }
- });
- return obj;
- }
-
- return old.apply(this, arguments);
- };
-})($.fn.attr);
-
-// --------------------------------------------------------
-// Timestamps
-// --------------------------------------------------------
-
-// Converts all timestamps to human readable time and date
-$.fn.relTimestamp = function() {
- return this.each(function() {
- let timestamp = parseInt($(this).text());
-
- $(this).text(getRelTimestamp(timestamp));
- return this;
- });
-};
-
-// Converts all timestamps to human readable time and date
-function getRelTimestamp(timestamp) {
- if (timestamp == null)
- return "";
-
- let timestampNow = Date.now();
- let timeDiff = timestampNow - timestamp;
-
- if(timeDiff < 10 * 60 * 1000) // less than 10 min
- return moment(timestamp).fromNow();
- else if(timeDiff < 24 * 60 * 60 * 1000) // less than 24 hours
- return moment(timestamp).fromNow() + " ("+moment(timestamp).format("HH:mm")+")";
- else
- return moment(timestamp).format("YYYY-MM-DD HH:mm");
-}
-
-// --------------------------------------------------------
-// Chart functions
-// --------------------------------------------------------
-
-function createChart(elementId, url, updateTime=-1){
- let tickConf = {count: 20};
- if (updateTime < 60*60*1000)
- tickConf['format'] = '%H:%M';
- else if (updateTime < 24*60*60*1000)
- tickConf['format'] = '%Y-%m-%d %H:%M';
- else
- tickConf['format'] = '%Y-%m-%d';
-
-
- var chart = c3.generate({
- bindto: elementId,
- data: {json: []}, // set empty data, data will be loaded later
- axis : {
- x : {
- type : 'timeseries',
- label: 'Timestamp',
- tick: tickConf,
- },
- y: {
- label: 'Power (kWh)',
- min: 0,
- },
- y2: {
- show: true,
- label: 'Temperature (C)',
- min: 0,
- }
- },
- grid: {
- y: {show: true}
- },
- point: {
- show: false
- }
- });
-
- updateChart(chart, url, updateTime);
- $(window).focus(function(e) {
- updateChart(chart, url);
- });
-}
-function updateChart(chart, url, updateTime=-1){
- console.log('Updating chart: ' + chart.element.id);
-
- $.getJSON(url, function(json) {
- chart.load(getChartData(json));
- });
-
- if (updateTime > 0) {
- setTimeout(function() {
- updateChart(chart, url, updateTime);
- }, updateTime);
- }
-}
-function getChartData(json){
- let dataXaxis = {};
- let dataYaxis = {};
- let data = [];
- let labels = [];
-
- json.forEach(function(sensor, i) {
- var index = 'data' + i;
- labels[index] = sensor.user + ': ' + sensor.name;
- dataXaxis[index] = 'data' + i + 'x';
- data.push([index + 'x'].concat(sensor.aggregate.timestamps));
- data.push([index].concat(sensor.aggregate.data));
-
- if (sensor.type == 'PowerConsumptionSensorData')
- dataYaxis[index] = 'y';
- else //if (sensor.type == "TemperatureSensorData")
- dataYaxis[index] = 'y2';
- });
-
- return {
- xs: dataXaxis,
- columns: data,
- names: labels,
- type: 'spline',
- axes: dataYaxis,
- unload: true,
- };
-}
-
-// --------------------------------------------------------
-// Dynamic forms
-// --------------------------------------------------------
-
-var dynamicConf = {};
-
-function initDynamicModalForm(modalId, formTemplateId = null, templateID = null){
- // read in all configurations into global variable (to skip naming issues)
- if (formTemplateId != null) {
- dynamicConf[formTemplateId] = [];
- $("#" + templateID + " div").each(function(){
- dynamicConf[formTemplateId][$(this).prop("id")] = $(this).html();
- });
-
- // Update dynamic inputs
- $("#" + modalId + " select[name=type]").change(function(){
- $("#" + modalId + " #" + formTemplateId).html(dynamicConf[formTemplateId][$(this).val()]);
- });
- }
-
- // click event
- $("#" + modalId).on('show.bs.modal', function (event) {
- let button = $(event.relatedTarget);
- let modal = $(this);
-
- modal.find(" input, select").val('').change(); // Reset all inputs
-
- // Set dynamic form data
- $.each(button.attr(), function(fieldName, value) {
- if(fieldName.startsWith("data-")) {
- fieldName = fieldName.substring(5); // remove prefix data-
-
- // Case-insensitive search
- var input = modal.find("input, select").filter(function() {
- if (this.name.toLowerCase() == fieldName) {
- if (this.type == "hidden" && modal.find("input[type=checkbox][name=" + fieldName + "]").length > 0)
- return false; // Workaround for the default(false) boolean input
- return true;
- }
- return false;
- });
-
- if (input.length > 0) {
- if (input.prop("type") == "checkbox") { // special handling for checkboxes
- input.prop("value", "true");
- input.prop("checked", value == "true");
-
- if (modal.find("input[type=hidden][name=" + fieldName + "]") == null) {
- // Add default false value as a unchecked checkbox is not included in the post
- input.parent().prepend("");
- }
- } else {
- input.val(value).change();
- }
- }
- }
- });
- });
-}
\ No newline at end of file
diff --git a/hal-core/resources/web/js/hal_alert.js b/hal-core/resources/web/js/hal_alert.js
deleted file mode 100644
index e2e9baa7..00000000
--- a/hal-core/resources/web/js/hal_alert.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// --------------------------------------------------------
-// Autostart
-// --------------------------------------------------------
-
-"use strict";
-
-var alertDivId = "alert-container"
-var alertTemplate = {
- ERROR: `
-
-
-
-
-
-
`,
- WARNING: `
-
-
-
-
-
-
`,
- SUCCESS: `
-
-
-
-
-
-
`,
- INFO: `
-
-
-
-
-
-
`
-}
-
-$(function(){
- updateAlerts();
-
- setInterval(function() {
- updateAlerts();
- }, 3000); // 3 sec
-});
-
-function updateAlerts() {
- fetch('/api/alert?action=poll')
- .then(response => response.json())
- .then(data => {
- data.forEach(alert => {
- var alertElement = $("#alert-id-" + alert.id);
-
- if (alertElement.length <= 0) {
- alertElement = $(alertTemplate[alert.level]);
- $("#" + alertDivId).append(alertElement);
-
- alertElement.attr("id", "alert-id-" + alert.id);
- alertElement.data("alert-id", alert.id);
- alertElement.find(".close").click(dismissEvent);
- }
-
- alertElement.find(".alert-title").html(alert.title);
- alertElement.find(".alert-description").html(alert.description);
- alertElement.find(".timestamp").relTimestamp();
- });
- });
-}
-
-function dismissEvent(e) {
- dismissAlert($(e.target).parent().parent().data("alert-id"));
-}
-function dismissAlert(id) {
- fetch('/api/alert?action=dismiss&id=' + id)
- .then(response => response.json())
- .then(data => {
- });
-}
\ No newline at end of file
diff --git a/hal-core/resources/web/js/hal_map.js b/hal-core/resources/web/js/hal_map.js
deleted file mode 100644
index d05f22a4..00000000
--- a/hal-core/resources/web/js/hal_map.js
+++ /dev/null
@@ -1,306 +0,0 @@
-"use strict";
-
-var svg;
-var data = {
- rooms: [],
- sensors: [],
- events: []
-};
-var editModeEnabled = false;
-
-$(function(){
- // ------------------------------------------
- // Setup map
- // ------------------------------------------
-
- svg = SVG('map');
-
- // Initialize events
-
- $("#button-edit").click(function() {
- editMode(true);
- });
- $("#button-save").click(function() {
- saveMap();
- editMode(false);
- fetchData(drawMap);
- });
- $("#button-cancel").click(function() {
- editMode(false);
- fetchData(drawMap);
- });
-
- // Initialize background image uploader
-
- $("#button-bg-edit").click(function() {
- // Reset modal
- $('#bg-file-input').parent().show();
- if ($("#file_input").prop("jFiler") != null)
- $("#file_input").prop("jFiler").reset();
- $('#bg-file-progress').parent().hide();
- $('#bgUploadModal').modal('show');
- });
- $('#bg-file-input').filer({
- limit: 1,
- extensions: ['jpg','png','svg','gif'],
- maxSize: 3, // in MB
- uploadFile: {
- url: "",
- type: 'POST',
- enctype: 'multipart/form-data',
- beforeSend: function(){
- $('#bg-file-input').parent().hide();
- $('#bg-file-progress').parent().show();
- },
- success: function(data, el){
- $('#bgUploadModal').modal('hide');
- drawMap();
- },
- error: function(el){
- $("#bg-file-progress").addClass("progress-bar-danger");
- },
- onProgress: function(t){
- $("#bg-file-progress").css("width", t + "%");
- },
- }
- });
-
- // ------------------------------------------
- // Start draw loop
- // ------------------------------------------
-
- fetchData(drawMap);
-
- setInterval(function() {
- if (editModeEnabled == false) {
- fetchData(drawMap);
- }
- }, 3000); // 3 sec
- //}, 10000); // 10 sec
-
-});
-
-// ----------------------------------------------
-// Events
-// ----------------------------------------------
-
-function editMode(enable){
- if (editModeEnabled == enable) {
- return;
- }
-
- editModeEnabled = enable;
-
- if (editModeEnabled) {
- $('.edit-mode').show();
- $('.view-mode').hide();
- $('#map').css('border-color', '#6eb16e');
-
- svg.select('.draggable').draggable(true);
- //svg.select('.resizable').on('click', selectEvent, false);
- svg.select('.resizable').selectize({
- points: ['rt', 'lb', 'rb'], // Add selection points on the corners
- rotationPoint: false
- }).resize()
- } else {
- $('.edit-mode').hide();
- $('.view-mode').show();
- $('#map').css('border-color', '');
-
- svg.select('.draggable').draggable(false);
- svg.select('resizable').selectize(false);
- }
-}
-
-function beforeDragEvent(e) {
- if (editModeEnabled == false) {
- e.preventDefault(); // Prevent drag
- }
-}
-
-function selectEvent(e) {
- if (editModeEnabled == true) {
- e.target.selectize({
- points: ['rt', 'lb', 'rb'], // Add selection points on the corners
- rotationPoint: false
- }).resize();
- }
-}
-
-// --------------------------------------
-// Draw
-// --------------------------------------
-
-function drawMap() {
- // Reset map
- svg.clear();
-
- // Background
-
- if (svg.select(".bg-image").length() <= 0) {
- var bgImage = svg.image("?bgimage").addClass("bg-image")
- .x(0)
- .y(0)
- .width("100%")
- .height("100%");
- }
-
- // Rooms
-
- if (data.rooms != null) {
- $.each(data.rooms, function(i, room) {
- svg.select("#room-" + room.id).remove();
-
- var group = svg.group();
-
- group.text(room.name).move(5, 5).fill('#999');
- var rect = group.rect(room.map.width, room.map.height);
- setAlertStyle(rect, (room.alert == null ? null : room.alert.level));
- rect.addClass("resizable");
-
- group.addClass("room")
- .attr("id", "room-" + room.id)
- .attr("room-id", room.id)
- .x(room.map.x)
- .y(room.map.y)
- .addClass("draggable");
- });
- }
-
- // Sensors
-
- if (data.sensors != null) {
- $.each(data.sensors, function(i, sensor) {
- svg.select("#sensor-" + sensor.id).remove();
-
- var group = svg.group();
- group.element('title').words(sensor.name);
-
- group.text(sensor.data.valueStr).move(45, 15).fill('#999');
- group.image("/img/temperature.svg").size(50, 50);
-
- group.addClass("sensor")
- .attr("id", "sensor-" + sensor.id)
- .attr("sensor-id", sensor.id)
- .x(sensor.map.x)
- .y(sensor.map.y)
- .addClass("draggable");
- });
- }
-
- // Events
-
- if (data.events != null) {
- $.each(data.events, function(i, event) {
- svg.select("#event-" + event.id).remove();
-
- var group = svg.group();
- group.element('title').words(event.name);
-
- var img = "/img/lightbulb_off.svg";
- if (event.data.valueStr == "ON")
- img = "/img/lightbulb_on.svg";
- group.image(img).size(50, 50);
-
- group.addClass("event")
- .attr("id", "event-" + event.id)
- .attr("event-id", event.id)
- .x(event.map.x)
- .y(event.map.y)
- .addClass("draggable");
- });
- }
-}
-
-// ----------------------------------------------
-// Load and Store data
-// ----------------------------------------------
-
-async function fetchData(callback) {
- await fetch('/api/room')
- .then(response => response.json())
- .then(json => {
- data.rooms = json;
- })
-
- await fetch('/api/sensor')
- .then(response => response.json())
- .then(json => {
- data.sensors = json;
- })
-
- await fetch('/api/event')
- .then(response => response.json())
- .then(json => {
- data.events = json;
- })
-
- callback();
-}
-
-function saveMap(){
- svg.select(".room").each(function(){
- saveDevice(this, "room", "room-id");
- });
- svg.select(".sensor").each(function(){
- saveDevice(this, "sensor", "sensor-id");
- });
- svg.select(".event").each(function(){
- saveDevice(this, "event", "event-id");
- });
-}
-function saveDevice(element, type, id) {
- var data = {
- action: "save",
- id: element.attr(id),
- type: type,
- x: element.x(),
- y: element.y()
- };
-
- var resizable = element.select(".resizable");
- if (resizable.length() > 0) {
- data.width = resizable.get(0).width();
- data.height = resizable.get(0).height();
- }
-
- $.ajax({
- async: false,
- dataType: "json",
- url: "/api/map?",
- data: data
- });
-}
-
-// ----------------------------------------------
-// Colors
-// ----------------------------------------------
-
-function setAlertStyle(target, level=null) {
- target.addClass("pulse-border");
- target.fill('none');
-
- switch(level) {
- case "ERROR":
- target.stroke({opacity: 1, color: '#f00'});
- break;
- case "WARNING":
- target.stroke({opacity: 1, color: '#ffa500'});
- break;
- case "SUCCESS":
- target.stroke({opacity: 1, color: '#90EE90'});
- break;
- case "INFO":
- target.stroke({opacity: 1, color: '#87CEFA'});
- break;
-
- default:
- target.removeClass("pulse-border");
- target.stroke({
- color: '#000',
- opacity: 0.6,
- width: 3
- });;
- break;
- }
-}
\ No newline at end of file
diff --git a/hal-core/resources/web/js/lib/bootstrap-colorpicker.LICENSE b/hal-core/resources/web/js/lib/bootstrap-colorpicker.LICENSE
deleted file mode 100644
index bc6fc511..00000000
--- a/hal-core/resources/web/js/lib/bootstrap-colorpicker.LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Javi Aguilar
-
-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.
diff --git a/hal-core/resources/web/js/lib/bootstrap-colorpicker.LICENSE.txt b/hal-core/resources/web/js/lib/bootstrap-colorpicker.LICENSE.txt
deleted file mode 100644
index bc6fc511..00000000
--- a/hal-core/resources/web/js/lib/bootstrap-colorpicker.LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Javi Aguilar
-
-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.
diff --git a/hal-core/resources/web/js/lib/bootstrap-colorpicker.js b/hal-core/resources/web/js/lib/bootstrap-colorpicker.js
deleted file mode 100644
index e2fd15da..00000000
--- a/hal-core/resources/web/js/lib/bootstrap-colorpicker.js
+++ /dev/null
@@ -1,6252 +0,0 @@
-/*!
- * Bootstrap Colorpicker - Bootstrap Colorpicker is a modular color picker plugin for Bootstrap 4.
- * @package bootstrap-colorpicker
- * @version v3.2.0
- * @license MIT
- * @link https://itsjavi.com/bootstrap-colorpicker/
- * @link https://github.com/itsjavi/bootstrap-colorpicker.git
- */
-(function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory(require("jquery"));
- else if(typeof define === 'function' && define.amd)
- define("bootstrap-colorpicker", ["jquery"], factory);
- else if(typeof exports === 'object')
- exports["bootstrap-colorpicker"] = factory(require("jquery"));
- else
- root["bootstrap-colorpicker"] = factory(root["jQuery"]);
-})(window, function(__WEBPACK_EXTERNAL_MODULE__0__) {
-return /******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-/******/
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-/******/
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId]) {
-/******/ return installedModules[moduleId].exports;
-/******/ }
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ i: moduleId,
-/******/ l: false,
-/******/ exports: {}
-/******/ };
-/******/
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/ // Flag the module as loaded
-/******/ module.l = true;
-/******/
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-/******/
-/******/
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-/******/
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-/******/
-/******/ // define getter function for harmony exports
-/******/ __webpack_require__.d = function(exports, name, getter) {
-/******/ if(!__webpack_require__.o(exports, name)) {
-/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
-/******/ }
-/******/ };
-/******/
-/******/ // define __esModule on exports
-/******/ __webpack_require__.r = function(exports) {
-/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ }
-/******/ Object.defineProperty(exports, '__esModule', { value: true });
-/******/ };
-/******/
-/******/ // create a fake namespace object
-/******/ // mode & 1: value is a module id, require it
-/******/ // mode & 2: merge all properties of value into the ns
-/******/ // mode & 4: return value when already ns object
-/******/ // mode & 8|1: behave like require
-/******/ __webpack_require__.t = function(value, mode) {
-/******/ if(mode & 1) value = __webpack_require__(value);
-/******/ if(mode & 8) return value;
-/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
-/******/ var ns = Object.create(null);
-/******/ __webpack_require__.r(ns);
-/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
-/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
-/******/ return ns;
-/******/ };
-/******/
-/******/ // getDefaultExport function for compatibility with non-harmony modules
-/******/ __webpack_require__.n = function(module) {
-/******/ var getter = module && module.__esModule ?
-/******/ function getDefault() { return module['default']; } :
-/******/ function getModuleExports() { return module; };
-/******/ __webpack_require__.d(getter, 'a', getter);
-/******/ return getter;
-/******/ };
-/******/
-/******/ // Object.prototype.hasOwnProperty.call
-/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-/******/
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "";
-/******/
-/******/
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(__webpack_require__.s = 7);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ (function(module, exports) {
-
-module.exports = __WEBPACK_EXTERNAL_MODULE__0__;
-
-/***/ }),
-/* 1 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _jquery = __webpack_require__(0);
-
-var _jquery2 = _interopRequireDefault(_jquery);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-/**
- * Colorpicker extension class.
- */
-var Extension = function () {
- /**
- * @param {Colorpicker} colorpicker
- * @param {Object} options
- */
- function Extension(colorpicker) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- _classCallCheck(this, Extension);
-
- /**
- * The colorpicker instance
- * @type {Colorpicker}
- */
- this.colorpicker = colorpicker;
- /**
- * Extension options
- *
- * @type {Object}
- */
- this.options = options;
-
- if (!(this.colorpicker.element && this.colorpicker.element.length)) {
- throw new Error('Extension: this.colorpicker.element is not valid');
- }
-
- this.colorpicker.element.on('colorpickerCreate.colorpicker-ext', _jquery2.default.proxy(this.onCreate, this));
- this.colorpicker.element.on('colorpickerDestroy.colorpicker-ext', _jquery2.default.proxy(this.onDestroy, this));
- this.colorpicker.element.on('colorpickerUpdate.colorpicker-ext', _jquery2.default.proxy(this.onUpdate, this));
- this.colorpicker.element.on('colorpickerChange.colorpicker-ext', _jquery2.default.proxy(this.onChange, this));
- this.colorpicker.element.on('colorpickerInvalid.colorpicker-ext', _jquery2.default.proxy(this.onInvalid, this));
- this.colorpicker.element.on('colorpickerShow.colorpicker-ext', _jquery2.default.proxy(this.onShow, this));
- this.colorpicker.element.on('colorpickerHide.colorpicker-ext', _jquery2.default.proxy(this.onHide, this));
- this.colorpicker.element.on('colorpickerEnable.colorpicker-ext', _jquery2.default.proxy(this.onEnable, this));
- this.colorpicker.element.on('colorpickerDisable.colorpicker-ext', _jquery2.default.proxy(this.onDisable, this));
- }
-
- /**
- * Function called every time a new color needs to be created.
- * Return false to skip this resolver and continue with other extensions' ones
- * or return anything else to consider the color resolved.
- *
- * @param {ColorItem|String|*} color
- * @param {boolean} realColor if true, the color should resolve into a real (not named) color code
- * @return {ColorItem|String|*}
- */
-
-
- _createClass(Extension, [{
- key: 'resolveColor',
- value: function resolveColor(color) {
- var realColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
-
- return false;
- }
-
- /**
- * Method called after the colorpicker is created
- *
- * @listens Colorpicker#colorpickerCreate
- * @param {Event} event
- */
-
- }, {
- key: 'onCreate',
- value: function onCreate(event) {}
- // to be extended
-
-
- /**
- * Method called after the colorpicker is destroyed
- *
- * @listens Colorpicker#colorpickerDestroy
- * @param {Event} event
- */
-
- }, {
- key: 'onDestroy',
- value: function onDestroy(event) {
- this.colorpicker.element.off('.colorpicker-ext');
- }
-
- /**
- * Method called after the colorpicker is updated
- *
- * @listens Colorpicker#colorpickerUpdate
- * @param {Event} event
- */
-
- }, {
- key: 'onUpdate',
- value: function onUpdate(event) {}
- // to be extended
-
-
- /**
- * Method called after the colorpicker color is changed
- *
- * @listens Colorpicker#colorpickerChange
- * @param {Event} event
- */
-
- }, {
- key: 'onChange',
- value: function onChange(event) {}
- // to be extended
-
-
- /**
- * Method called when the colorpicker color is invalid
- *
- * @listens Colorpicker#colorpickerInvalid
- * @param {Event} event
- */
-
- }, {
- key: 'onInvalid',
- value: function onInvalid(event) {}
- // to be extended
-
-
- /**
- * Method called after the colorpicker is hidden
- *
- * @listens Colorpicker#colorpickerHide
- * @param {Event} event
- */
-
- }, {
- key: 'onHide',
- value: function onHide(event) {}
- // to be extended
-
-
- /**
- * Method called after the colorpicker is shown
- *
- * @listens Colorpicker#colorpickerShow
- * @param {Event} event
- */
-
- }, {
- key: 'onShow',
- value: function onShow(event) {}
- // to be extended
-
-
- /**
- * Method called after the colorpicker is disabled
- *
- * @listens Colorpicker#colorpickerDisable
- * @param {Event} event
- */
-
- }, {
- key: 'onDisable',
- value: function onDisable(event) {}
- // to be extended
-
-
- /**
- * Method called after the colorpicker is enabled
- *
- * @listens Colorpicker#colorpickerEnable
- * @param {Event} event
- */
-
- }, {
- key: 'onEnable',
- value: function onEnable(event) {
- // to be extended
- }
- }]);
-
- return Extension;
-}();
-
-exports.default = Extension;
-module.exports = exports.default;
-
-/***/ }),
-/* 2 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.ColorItem = exports.HSVAColor = undefined;
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
- * Color manipulation class, specific for Bootstrap Colorpicker
- */
-
-
-var _color = __webpack_require__(16);
-
-var _color2 = _interopRequireDefault(_color);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-/**
- * HSVA color data class, containing the hue, saturation, value and alpha
- * information.
- */
-var HSVAColor = function () {
- /**
- * @param {number|int} h
- * @param {number|int} s
- * @param {number|int} v
- * @param {number|int} a
- */
- function HSVAColor(h, s, v, a) {
- _classCallCheck(this, HSVAColor);
-
- this.h = isNaN(h) ? 0 : h;
- this.s = isNaN(s) ? 0 : s;
- this.v = isNaN(v) ? 0 : v;
- this.a = isNaN(h) ? 1 : a;
- }
-
- _createClass(HSVAColor, [{
- key: 'toString',
- value: function toString() {
- return this.h + ', ' + this.s + '%, ' + this.v + '%, ' + this.a;
- }
- }]);
-
- return HSVAColor;
-}();
-
-/**
- * HSVA color manipulation
- */
-
-
-var ColorItem = function () {
- _createClass(ColorItem, [{
- key: 'api',
-
-
- /**
- * Applies a method of the QixColor API and returns a new Color object or
- * the return value of the method call.
- *
- * If no argument is provided, the internal QixColor object is returned.
- *
- * @param {String} fn QixColor function name
- * @param args QixColor function arguments
- * @example let darkerColor = color.api('darken', 0.25);
- * @example let luminosity = color.api('luminosity');
- * @example color = color.api('negate');
- * @example let qColor = color.api().negate();
- * @returns {ColorItem|QixColor|*}
- */
- value: function api(fn) {
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- args[_key - 1] = arguments[_key];
- }
-
- if (arguments.length === 0) {
- return this._color;
- }
-
- var result = this._color[fn].apply(this._color, args);
-
- if (!(result instanceof _color2.default)) {
- // return result of the method call
- return result;
- }
-
- return new ColorItem(result, this.format);
- }
-
- /**
- * Returns the original ColorItem constructor data,
- * plus a 'valid' flag to know if it's valid or not.
- *
- * @returns {{color: *, format: String, valid: boolean}}
- */
-
- }, {
- key: 'original',
- get: function get() {
- return this._original;
- }
-
- /**
- * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data
- * @param {String|null} format Color model to convert to by default. Supported: 'rgb', 'hsl', 'hex'.
- */
-
- }], [{
- key: 'HSVAColor',
-
-
- /**
- * Returns the HSVAColor class
- *
- * @static
- * @example let colorData = new ColorItem.HSVAColor(360, 100, 100, 1);
- * @returns {HSVAColor}
- */
- get: function get() {
- return HSVAColor;
- }
- }]);
-
- function ColorItem() {
- var color = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
- var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
-
- _classCallCheck(this, ColorItem);
-
- this.replace(color, format);
- }
-
- /**
- * Replaces the internal QixColor object with a new one.
- * This also replaces the internal original color data.
- *
- * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data to be parsed (if needed)
- * @param {String|null} format Color model to convert to by default. Supported: 'rgb', 'hsl', 'hex'.
- * @example color.replace('rgb(255,0,0)', 'hsl');
- * @example color.replace(hsvaColorData);
- */
-
-
- _createClass(ColorItem, [{
- key: 'replace',
- value: function replace(color) {
- var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
-
- format = ColorItem.sanitizeFormat(format);
-
- /**
- * @type {{color: *, format: String}}
- * @private
- */
- this._original = {
- color: color,
- format: format,
- valid: true
- };
- /**
- * @type {QixColor}
- * @private
- */
- this._color = ColorItem.parse(color);
-
- if (this._color === null) {
- this._color = (0, _color2.default)();
- this._original.valid = false;
- return;
- }
-
- /**
- * @type {*|string}
- * @private
- */
- this._format = format ? format : ColorItem.isHex(color) ? 'hex' : this._color.model;
- }
-
- /**
- * Parses the color returning a Qix Color object or null if cannot be
- * parsed.
- *
- * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data
- * @example let qColor = ColorItem.parse('rgb(255,0,0)');
- * @static
- * @returns {QixColor|null}
- */
-
- }, {
- key: 'isValid',
-
-
- /**
- * Returns true if the color is valid, false if not.
- *
- * @returns {boolean}
- */
- value: function isValid() {
- return this._original.valid === true;
- }
-
- /**
- * Hue value from 0 to 360
- *
- * @returns {int}
- */
-
- }, {
- key: 'setHueRatio',
-
-
- /**
- * Sets the hue ratio, where 1.0 is 0, 0.5 is 180 and 0.0 is 360.
- *
- * @ignore
- * @param {number} h Ratio from 1.0 to 0.0
- */
- value: function setHueRatio(h) {
- this.hue = (1 - h) * 360;
- }
-
- /**
- * Sets the saturation value
- *
- * @param {int} value Integer from 0 to 100
- */
-
- }, {
- key: 'setSaturationRatio',
-
-
- /**
- * Sets the saturation ratio, where 1.0 is 100 and 0.0 is 0.
- *
- * @ignore
- * @param {number} s Ratio from 0.0 to 1.0
- */
- value: function setSaturationRatio(s) {
- this.saturation = s * 100;
- }
-
- /**
- * Sets the 'value' channel value
- *
- * @param {int} value Integer from 0 to 100
- */
-
- }, {
- key: 'setValueRatio',
-
-
- /**
- * Sets the value ratio, where 1.0 is 0 and 0.0 is 100.
- *
- * @ignore
- * @param {number} v Ratio from 1.0 to 0.0
- */
- value: function setValueRatio(v) {
- this.value = (1 - v) * 100;
- }
-
- /**
- * Sets the alpha value. It will be rounded to 2 decimals.
- *
- * @param {int} value Float from 0.0 to 1.0
- */
-
- }, {
- key: 'setAlphaRatio',
-
-
- /**
- * Sets the alpha ratio, where 1.0 is 0.0 and 0.0 is 1.0.
- *
- * @ignore
- * @param {number} a Ratio from 1.0 to 0.0
- */
- value: function setAlphaRatio(a) {
- this.alpha = 1 - a;
- }
-
- /**
- * Sets the default color format
- *
- * @param {String} value Supported: 'rgb', 'hsl', 'hex'
- */
-
- }, {
- key: 'isDesaturated',
-
-
- /**
- * Returns true if the saturation value is zero, false otherwise
- *
- * @returns {boolean}
- */
- value: function isDesaturated() {
- return this.saturation === 0;
- }
-
- /**
- * Returns true if the alpha value is zero, false otherwise
- *
- * @returns {boolean}
- */
-
- }, {
- key: 'isTransparent',
- value: function isTransparent() {
- return this.alpha === 0;
- }
-
- /**
- * Returns true if the alpha value is numeric and less than 1, false otherwise
- *
- * @returns {boolean}
- */
-
- }, {
- key: 'hasTransparency',
- value: function hasTransparency() {
- return this.hasAlpha() && this.alpha < 1;
- }
-
- /**
- * Returns true if the alpha value is numeric, false otherwise
- *
- * @returns {boolean}
- */
-
- }, {
- key: 'hasAlpha',
- value: function hasAlpha() {
- return !isNaN(this.alpha);
- }
-
- /**
- * Returns a new HSVAColor object, based on the current color
- *
- * @returns {HSVAColor}
- */
-
- }, {
- key: 'toObject',
- value: function toObject() {
- return new HSVAColor(this.hue, this.saturation, this.value, this.alpha);
- }
-
- /**
- * Alias of toObject()
- *
- * @returns {HSVAColor}
- */
-
- }, {
- key: 'toHsva',
- value: function toHsva() {
- return this.toObject();
- }
-
- /**
- * Returns a new HSVAColor object with the ratio values (from 0.0 to 1.0),
- * based on the current color.
- *
- * @ignore
- * @returns {HSVAColor}
- */
-
- }, {
- key: 'toHsvaRatio',
- value: function toHsvaRatio() {
- return new HSVAColor(this.hue / 360, this.saturation / 100, this.value / 100, this.alpha);
- }
-
- /**
- * Converts the current color to its string representation,
- * using the internal format of this instance.
- *
- * @returns {String}
- */
-
- }, {
- key: 'toString',
- value: function toString() {
- return this.string();
- }
-
- /**
- * Converts the current color to its string representation,
- * using the given format.
- *
- * @param {String|null} format Format to convert to. If empty or null, the internal format will be used.
- * @returns {String}
- */
-
- }, {
- key: 'string',
- value: function string() {
- var format = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
-
- format = ColorItem.sanitizeFormat(format ? format : this.format);
-
- if (!format) {
- return this._color.round().string();
- }
-
- if (this._color[format] === undefined) {
- throw new Error('Unsupported color format: \'' + format + '\'');
- }
-
- var str = this._color[format]();
-
- return str.round ? str.round().string() : str;
- }
-
- /**
- * Returns true if the given color values equals this one, false otherwise.
- * The format is not compared.
- * If any of the colors is invalid, the result will be false.
- *
- * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data
- *
- * @returns {boolean}
- */
-
- }, {
- key: 'equals',
- value: function equals(color) {
- color = color instanceof ColorItem ? color : new ColorItem(color);
-
- if (!color.isValid() || !this.isValid()) {
- return false;
- }
-
- return this.hue === color.hue && this.saturation === color.saturation && this.value === color.value && this.alpha === color.alpha;
- }
-
- /**
- * Creates a copy of this instance
- *
- * @returns {ColorItem}
- */
-
- }, {
- key: 'getClone',
- value: function getClone() {
- return new ColorItem(this._color, this.format);
- }
-
- /**
- * Creates a copy of this instance, only copying the hue value,
- * and setting the others to its max value.
- *
- * @returns {ColorItem}
- */
-
- }, {
- key: 'getCloneHueOnly',
- value: function getCloneHueOnly() {
- return new ColorItem([this.hue, 100, 100, 1], this.format);
- }
-
- /**
- * Creates a copy of this instance setting the alpha to the max.
- *
- * @returns {ColorItem}
- */
-
- }, {
- key: 'getCloneOpaque',
- value: function getCloneOpaque() {
- return new ColorItem(this._color.alpha(1), this.format);
- }
-
- /**
- * Converts the color to a RGB string
- *
- * @returns {String}
- */
-
- }, {
- key: 'toRgbString',
- value: function toRgbString() {
- return this.string('rgb');
- }
-
- /**
- * Converts the color to a Hexadecimal string
- *
- * @returns {String}
- */
-
- }, {
- key: 'toHexString',
- value: function toHexString() {
- return this.string('hex');
- }
-
- /**
- * Converts the color to a HSL string
- *
- * @returns {String}
- */
-
- }, {
- key: 'toHslString',
- value: function toHslString() {
- return this.string('hsl');
- }
-
- /**
- * Returns true if the color is dark, false otherwhise.
- * This is useful to decide a text color.
- *
- * @returns {boolean}
- */
-
- }, {
- key: 'isDark',
- value: function isDark() {
- return this._color.isDark();
- }
-
- /**
- * Returns true if the color is light, false otherwhise.
- * This is useful to decide a text color.
- *
- * @returns {boolean}
- */
-
- }, {
- key: 'isLight',
- value: function isLight() {
- return this._color.isLight();
- }
-
- /**
- * Generates a list of colors using the given hue-based formula or the given array of hue values.
- * Hue formulas can be extended using ColorItem.colorFormulas static property.
- *
- * @param {String|Number[]} formula Examples: 'complementary', 'triad', 'tetrad', 'splitcomplement', [180, 270]
- * @example let colors = color.generate('triad');
- * @example let colors = color.generate([45, 80, 112, 200]);
- * @returns {ColorItem[]}
- */
-
- }, {
- key: 'generate',
- value: function generate(formula) {
- var hues = [];
-
- if (Array.isArray(formula)) {
- hues = formula;
- } else if (!ColorItem.colorFormulas.hasOwnProperty(formula)) {
- throw new Error('No color formula found with the name \'' + formula + '\'.');
- } else {
- hues = ColorItem.colorFormulas[formula];
- }
-
- var colors = [],
- mainColor = this._color,
- format = this.format;
-
- hues.forEach(function (hue) {
- var levels = [hue ? (mainColor.hue() + hue) % 360 : mainColor.hue(), mainColor.saturationv(), mainColor.value(), mainColor.alpha()];
-
- colors.push(new ColorItem(levels, format));
- });
-
- return colors;
- }
- }, {
- key: 'hue',
- get: function get() {
- return this._color.hue();
- }
-
- /**
- * Saturation value from 0 to 100
- *
- * @returns {int}
- */
- ,
-
-
- /**
- * Sets the hue value
- *
- * @param {int} value Integer from 0 to 360
- */
- set: function set(value) {
- this._color = this._color.hue(value);
- }
- }, {
- key: 'saturation',
- get: function get() {
- return this._color.saturationv();
- }
-
- /**
- * Value channel value from 0 to 100
- *
- * @returns {int}
- */
- ,
- set: function set(value) {
- this._color = this._color.saturationv(value);
- }
- }, {
- key: 'value',
- get: function get() {
- return this._color.value();
- }
-
- /**
- * Alpha value from 0.0 to 1.0
- *
- * @returns {number}
- */
- ,
- set: function set(value) {
- this._color = this._color.value(value);
- }
- }, {
- key: 'alpha',
- get: function get() {
- var a = this._color.alpha();
-
- return isNaN(a) ? 1 : a;
- }
-
- /**
- * Default color format to convert to when calling toString() or string()
- *
- * @returns {String} 'rgb', 'hsl', 'hex' or ''
- */
- ,
- set: function set(value) {
- // 2 decimals max
- this._color = this._color.alpha(Math.round(value * 100) / 100);
- }
- }, {
- key: 'format',
- get: function get() {
- return this._format ? this._format : this._color.model;
- },
- set: function set(value) {
- this._format = ColorItem.sanitizeFormat(value);
- }
- }], [{
- key: 'parse',
- value: function parse(color) {
- if (color instanceof _color2.default) {
- return color;
- }
-
- if (color instanceof ColorItem) {
- return color._color;
- }
-
- var format = null;
-
- if (color instanceof HSVAColor) {
- color = [color.h, color.s, color.v, isNaN(color.a) ? 1 : color.a];
- } else {
- color = ColorItem.sanitizeString(color);
- }
-
- if (color === null) {
- return null;
- }
-
- if (Array.isArray(color)) {
- format = 'hsv';
- }
-
- try {
- return (0, _color2.default)(color, format);
- } catch (e) {
- return null;
- }
- }
-
- /**
- * Sanitizes a color string, adding missing hash to hexadecimal colors
- * and converting 'transparent' to a color code.
- *
- * @param {String|*} str Color string
- * @example let colorStr = ColorItem.sanitizeString('ffaa00');
- * @static
- * @returns {String|*}
- */
-
- }, {
- key: 'sanitizeString',
- value: function sanitizeString(str) {
- if (!(typeof str === 'string' || str instanceof String)) {
- return str;
- }
-
- if (str.match(/^[0-9a-f]{2,}$/i)) {
- return '#' + str;
- }
-
- if (str.toLowerCase() === 'transparent') {
- return '#FFFFFF00';
- }
-
- return str;
- }
-
- /**
- * Detects if a value is a string and a color in hexadecimal format (in any variant).
- *
- * @param {String} str
- * @example ColorItem.isHex('rgba(0,0,0)'); // false
- * @example ColorItem.isHex('ffaa00'); // true
- * @example ColorItem.isHex('#ffaa00'); // true
- * @static
- * @returns {boolean}
- */
-
- }, {
- key: 'isHex',
- value: function isHex(str) {
- if (!(typeof str === 'string' || str instanceof String)) {
- return false;
- }
-
- return !!str.match(/^#?[0-9a-f]{2,}$/i);
- }
-
- /**
- * Sanitizes a color format to one supported by web browsers.
- * Returns an empty string of the format can't be recognised.
- *
- * @param {String|*} format
- * @example ColorItem.sanitizeFormat('rgba'); // 'rgb'
- * @example ColorItem.isHex('hex8'); // 'hex'
- * @example ColorItem.isHex('invalid'); // ''
- * @static
- * @returns {String} 'rgb', 'hsl', 'hex' or ''.
- */
-
- }, {
- key: 'sanitizeFormat',
- value: function sanitizeFormat(format) {
- switch (format) {
- case 'hex':
- case 'hex3':
- case 'hex4':
- case 'hex6':
- case 'hex8':
- return 'hex';
- case 'rgb':
- case 'rgba':
- case 'keyword':
- case 'name':
- return 'rgb';
- case 'hsl':
- case 'hsla':
- case 'hsv':
- case 'hsva':
- case 'hwb': // HWB this is supported by Qix Color, but not by browsers
- case 'hwba':
- return 'hsl';
- default:
- return '';
- }
- }
- }]);
-
- return ColorItem;
-}();
-
-/**
- * List of hue-based color formulas used by ColorItem.prototype.generate()
- *
- * @static
- * @type {{complementary: number[], triad: number[], tetrad: number[], splitcomplement: number[]}}
- */
-
-
-ColorItem.colorFormulas = {
- complementary: [180],
- triad: [0, 120, 240],
- tetrad: [0, 90, 180, 270],
- splitcomplement: [0, 72, 216]
-};
-
-exports.default = ColorItem;
-exports.HSVAColor = HSVAColor;
-exports.ColorItem = ColorItem;
-
-/***/ }),
-/* 3 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-/**
- * @module
- */
-
-// adjust these values accordingly to the sass vars
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-var sassVars = {
- 'bar_size_short': 16,
- 'base_margin': 6,
- 'columns': 6
-};
-
-var sliderSize = sassVars.bar_size_short * sassVars.columns + sassVars.base_margin * (sassVars.columns - 1);
-
-/**
- * Colorpicker default options
- */
-exports.default = {
- /**
- * Custom class to be added to the `.colorpicker-element` element
- *
- * @type {String|null}
- * @default null
- */
- customClass: null,
- /**
- * Sets a initial color, ignoring the one from the element/input value or the data-color attribute.
- *
- * @type {(String|ColorItem|boolean)}
- * @default false
- */
- color: false,
- /**
- * Fallback color to use when the given color is invalid.
- * If false, the latest valid color will be used as a fallback.
- *
- * @type {String|ColorItem|boolean}
- * @default false
- */
- fallbackColor: false,
- /**
- * Forces an specific color format. If 'auto', it will be automatically detected the first time only,
- * but if null it will be always recalculated.
- *
- * Note that the ending 'a' of the format meaning "alpha" has currently no effect, meaning that rgb is the same as
- * rgba excepting if the alpha channel is disabled (see useAlpha).
- *
- * @type {('rgb'|'hex'|'hsl'|'auto'|null)}
- * @default 'auto'
- */
- format: 'auto',
- /**
- * Horizontal mode layout.
- *
- * If true, the hue and alpha channel bars will be rendered horizontally, above the saturation selector.
- *
- * @type {boolean}
- * @default false
- */
- horizontal: false,
- /**
- * Forces to show the colorpicker as an inline element.
- *
- * Note that if there is no container specified, the inline element
- * will be added to the body, so you may want to set the container option.
- *
- * @type {boolean}
- * @default false
- */
- inline: false,
- /**
- * Container where the colorpicker is appended to in the DOM.
- *
- * If is a string (CSS selector), the colorpicker will be placed inside this container.
- * If true, the `.colorpicker-element` element itself will be used as the container.
- * If false, the document body is used as the container, unless it is a popover (in this case it is appended to the
- * popover body instead).
- *
- * @type {String|boolean}
- * @default false
- */
- container: false,
- /**
- * Bootstrap Popover options.
- * The trigger, content and html options are always ignored.
- *
- * @type {boolean}
- * @default Object
- */
- popover: {
- animation: true,
- placement: 'bottom',
- fallbackPlacement: 'flip'
- },
- /**
- * If true, loads the 'debugger' extension automatically, which logs the events in the console
- * @type {boolean}
- * @default false
- */
- debug: false,
- /**
- * Child CSS selector for the colorpicker input.
- *
- * @type {String}
- * @default 'input'
- */
- input: 'input',
- /**
- * Child CSS selector for the colorpicker addon.
- * If it exists, the child element background will be changed on color change.
- *
- * @type {String}
- * @default '.colorpicker-trigger, .colorpicker-input-addon'
- */
- addon: '.colorpicker-input-addon',
- /**
- * If true, the input content will be replaced always with a valid color,
- * if false, the invalid color will be left in the input,
- * while the internal color object will still resolve into a valid one.
- *
- * @type {boolean}
- * @default true
- */
- autoInputFallback: true,
- /**
- * If true a hash will be prepended to hexadecimal colors.
- * If false, the hash will be removed.
- * This only affects the input values in hexadecimal format.
- *
- * @type {boolean}
- * @default true
- */
- useHashPrefix: true,
- /**
- * If true, the alpha channel bar will be displayed no matter what.
- *
- * If false, it will be always hidden and alpha channel will be disabled also programmatically, meaning that
- * the selected or typed color will be always opaque.
- *
- * If null, the alpha channel will be automatically disabled/enabled depending if the initial color format supports
- * alpha or not.
- *
- * @type {boolean}
- * @default true
- */
- useAlpha: true,
- /**
- * Colorpicker widget template
- * @type {String}
- * @example
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */
- template: '
\n
\n
\n
\n \n \n
\n
',
- /**
- *
- * Associative object with the extension class name and its config.
- * Colorpicker comes with many bundled extensions: debugger, palette, preview and swatches (a superset of palette).
- *
- * @type {Object[]}
- * @example
- * extensions: [
- * {
- * name: 'swatches'
- * options: {
- * colors: {
- * 'primary': '#337ab7',
- * 'success': '#5cb85c',
- * 'info': '#5bc0de',
- * 'warning': '#f0ad4e',
- * 'danger': '#d9534f'
- * },
- * namesAsValues: true
- * }
- * }
- * ]
- */
- extensions: [{
- name: 'preview',
- options: {
- showText: true
- }
- }],
- /**
- * Vertical sliders configuration
- * @type {Object}
- */
- sliders: {
- saturation: {
- selector: '.colorpicker-saturation',
- maxLeft: sliderSize,
- maxTop: sliderSize,
- callLeft: 'setSaturationRatio',
- callTop: 'setValueRatio'
- },
- hue: {
- selector: '.colorpicker-hue',
- maxLeft: 0,
- maxTop: sliderSize,
- callLeft: false,
- callTop: 'setHueRatio'
- },
- alpha: {
- selector: '.colorpicker-alpha',
- childSelector: '.colorpicker-alpha-color',
- maxLeft: 0,
- maxTop: sliderSize,
- callLeft: false,
- callTop: 'setAlphaRatio'
- }
- },
- /**
- * Horizontal sliders configuration
- * @type {Object}
- */
- slidersHorz: {
- saturation: {
- selector: '.colorpicker-saturation',
- maxLeft: sliderSize,
- maxTop: sliderSize,
- callLeft: 'setSaturationRatio',
- callTop: 'setValueRatio'
- },
- hue: {
- selector: '.colorpicker-hue',
- maxLeft: sliderSize,
- maxTop: 0,
- callLeft: 'setHueRatio',
- callTop: false
- },
- alpha: {
- selector: '.colorpicker-alpha',
- childSelector: '.colorpicker-alpha-color',
- maxLeft: sliderSize,
- maxTop: 0,
- callLeft: 'setAlphaRatio',
- callTop: false
- }
- }
-};
-module.exports = exports.default;
-
-/***/ }),
-/* 4 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _Extension2 = __webpack_require__(1);
-
-var _Extension3 = _interopRequireDefault(_Extension2);
-
-var _jquery = __webpack_require__(0);
-
-var _jquery2 = _interopRequireDefault(_jquery);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var defaults = {
- /**
- * Key-value pairs defining a color alias and its CSS color representation.
- *
- * They can also be just an array of values. In that case, no special names are used, only the real colors.
- *
- * @type {Object|Array}
- * @default null
- * @example
- * {
- * 'black': '#000000',
- * 'white': '#ffffff',
- * 'red': '#FF0000',
- * 'default': '#777777',
- * 'primary': '#337ab7',
- * 'success': '#5cb85c',
- * 'info': '#5bc0de',
- * 'warning': '#f0ad4e',
- * 'danger': '#d9534f'
- * }
- *
- * @example ['#f0ad4e', '#337ab7', '#5cb85c']
- */
- colors: null,
- /**
- * If true, when a color swatch is selected the name (alias) will be used as input value,
- * otherwise the swatch real color value will be used.
- *
- * @type {boolean}
- * @default true
- */
- namesAsValues: true
-};
-
-/**
- * Palette extension
- * @ignore
- */
-
-var Palette = function (_Extension) {
- _inherits(Palette, _Extension);
-
- _createClass(Palette, [{
- key: 'colors',
-
-
- /**
- * @returns {Object|Array}
- */
- get: function get() {
- return this.options.colors;
- }
- }]);
-
- function Palette(colorpicker) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- _classCallCheck(this, Palette);
-
- var _this = _possibleConstructorReturn(this, (Palette.__proto__ || Object.getPrototypeOf(Palette)).call(this, colorpicker, _jquery2.default.extend(true, {}, defaults, options)));
-
- if (!Array.isArray(_this.options.colors) && _typeof(_this.options.colors) !== 'object') {
- _this.options.colors = null;
- }
- return _this;
- }
-
- /**
- * @returns {int}
- */
-
-
- _createClass(Palette, [{
- key: 'getLength',
- value: function getLength() {
- if (!this.options.colors) {
- return 0;
- }
-
- if (Array.isArray(this.options.colors)) {
- return this.options.colors.length;
- }
-
- if (_typeof(this.options.colors) === 'object') {
- return Object.keys(this.options.colors).length;
- }
-
- return 0;
- }
- }, {
- key: 'resolveColor',
- value: function resolveColor(color) {
- var realColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
-
- if (this.getLength() <= 0) {
- return false;
- }
-
- // Array of colors
- if (Array.isArray(this.options.colors)) {
- if (this.options.colors.indexOf(color) >= 0) {
- return color;
- }
- if (this.options.colors.indexOf(color.toUpperCase()) >= 0) {
- return color.toUpperCase();
- }
- if (this.options.colors.indexOf(color.toLowerCase()) >= 0) {
- return color.toLowerCase();
- }
- return false;
- }
-
- if (_typeof(this.options.colors) !== 'object') {
- return false;
- }
-
- // Map of objects
- if (!this.options.namesAsValues || realColor) {
- return this.getValue(color, false);
- }
- return this.getName(color, this.getName('#' + color));
- }
-
- /**
- * Given a color value, returns the corresponding color name or defaultValue.
- *
- * @param {String} value
- * @param {*} defaultValue
- * @returns {*}
- */
-
- }, {
- key: 'getName',
- value: function getName(value) {
- var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
-
- if (!(typeof value === 'string') || !this.options.colors) {
- return defaultValue;
- }
- for (var name in this.options.colors) {
- if (!this.options.colors.hasOwnProperty(name)) {
- continue;
- }
- if (this.options.colors[name].toLowerCase() === value.toLowerCase()) {
- return name;
- }
- }
- return defaultValue;
- }
-
- /**
- * Given a color name, returns the corresponding color value or defaultValue.
- *
- * @param {String} name
- * @param {*} defaultValue
- * @returns {*}
- */
-
- }, {
- key: 'getValue',
- value: function getValue(name) {
- var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
-
- if (!(typeof name === 'string') || !this.options.colors) {
- return defaultValue;
- }
- if (this.options.colors.hasOwnProperty(name)) {
- return this.options.colors[name];
- }
- return defaultValue;
- }
- }]);
-
- return Palette;
-}(_Extension3.default);
-
-exports.default = Palette;
-module.exports = exports.default;
-
-/***/ }),
-/* 5 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-module.exports = {
- "aliceblue": [240, 248, 255],
- "antiquewhite": [250, 235, 215],
- "aqua": [0, 255, 255],
- "aquamarine": [127, 255, 212],
- "azure": [240, 255, 255],
- "beige": [245, 245, 220],
- "bisque": [255, 228, 196],
- "black": [0, 0, 0],
- "blanchedalmond": [255, 235, 205],
- "blue": [0, 0, 255],
- "blueviolet": [138, 43, 226],
- "brown": [165, 42, 42],
- "burlywood": [222, 184, 135],
- "cadetblue": [95, 158, 160],
- "chartreuse": [127, 255, 0],
- "chocolate": [210, 105, 30],
- "coral": [255, 127, 80],
- "cornflowerblue": [100, 149, 237],
- "cornsilk": [255, 248, 220],
- "crimson": [220, 20, 60],
- "cyan": [0, 255, 255],
- "darkblue": [0, 0, 139],
- "darkcyan": [0, 139, 139],
- "darkgoldenrod": [184, 134, 11],
- "darkgray": [169, 169, 169],
- "darkgreen": [0, 100, 0],
- "darkgrey": [169, 169, 169],
- "darkkhaki": [189, 183, 107],
- "darkmagenta": [139, 0, 139],
- "darkolivegreen": [85, 107, 47],
- "darkorange": [255, 140, 0],
- "darkorchid": [153, 50, 204],
- "darkred": [139, 0, 0],
- "darksalmon": [233, 150, 122],
- "darkseagreen": [143, 188, 143],
- "darkslateblue": [72, 61, 139],
- "darkslategray": [47, 79, 79],
- "darkslategrey": [47, 79, 79],
- "darkturquoise": [0, 206, 209],
- "darkviolet": [148, 0, 211],
- "deeppink": [255, 20, 147],
- "deepskyblue": [0, 191, 255],
- "dimgray": [105, 105, 105],
- "dimgrey": [105, 105, 105],
- "dodgerblue": [30, 144, 255],
- "firebrick": [178, 34, 34],
- "floralwhite": [255, 250, 240],
- "forestgreen": [34, 139, 34],
- "fuchsia": [255, 0, 255],
- "gainsboro": [220, 220, 220],
- "ghostwhite": [248, 248, 255],
- "gold": [255, 215, 0],
- "goldenrod": [218, 165, 32],
- "gray": [128, 128, 128],
- "green": [0, 128, 0],
- "greenyellow": [173, 255, 47],
- "grey": [128, 128, 128],
- "honeydew": [240, 255, 240],
- "hotpink": [255, 105, 180],
- "indianred": [205, 92, 92],
- "indigo": [75, 0, 130],
- "ivory": [255, 255, 240],
- "khaki": [240, 230, 140],
- "lavender": [230, 230, 250],
- "lavenderblush": [255, 240, 245],
- "lawngreen": [124, 252, 0],
- "lemonchiffon": [255, 250, 205],
- "lightblue": [173, 216, 230],
- "lightcoral": [240, 128, 128],
- "lightcyan": [224, 255, 255],
- "lightgoldenrodyellow": [250, 250, 210],
- "lightgray": [211, 211, 211],
- "lightgreen": [144, 238, 144],
- "lightgrey": [211, 211, 211],
- "lightpink": [255, 182, 193],
- "lightsalmon": [255, 160, 122],
- "lightseagreen": [32, 178, 170],
- "lightskyblue": [135, 206, 250],
- "lightslategray": [119, 136, 153],
- "lightslategrey": [119, 136, 153],
- "lightsteelblue": [176, 196, 222],
- "lightyellow": [255, 255, 224],
- "lime": [0, 255, 0],
- "limegreen": [50, 205, 50],
- "linen": [250, 240, 230],
- "magenta": [255, 0, 255],
- "maroon": [128, 0, 0],
- "mediumaquamarine": [102, 205, 170],
- "mediumblue": [0, 0, 205],
- "mediumorchid": [186, 85, 211],
- "mediumpurple": [147, 112, 219],
- "mediumseagreen": [60, 179, 113],
- "mediumslateblue": [123, 104, 238],
- "mediumspringgreen": [0, 250, 154],
- "mediumturquoise": [72, 209, 204],
- "mediumvioletred": [199, 21, 133],
- "midnightblue": [25, 25, 112],
- "mintcream": [245, 255, 250],
- "mistyrose": [255, 228, 225],
- "moccasin": [255, 228, 181],
- "navajowhite": [255, 222, 173],
- "navy": [0, 0, 128],
- "oldlace": [253, 245, 230],
- "olive": [128, 128, 0],
- "olivedrab": [107, 142, 35],
- "orange": [255, 165, 0],
- "orangered": [255, 69, 0],
- "orchid": [218, 112, 214],
- "palegoldenrod": [238, 232, 170],
- "palegreen": [152, 251, 152],
- "paleturquoise": [175, 238, 238],
- "palevioletred": [219, 112, 147],
- "papayawhip": [255, 239, 213],
- "peachpuff": [255, 218, 185],
- "peru": [205, 133, 63],
- "pink": [255, 192, 203],
- "plum": [221, 160, 221],
- "powderblue": [176, 224, 230],
- "purple": [128, 0, 128],
- "rebeccapurple": [102, 51, 153],
- "red": [255, 0, 0],
- "rosybrown": [188, 143, 143],
- "royalblue": [65, 105, 225],
- "saddlebrown": [139, 69, 19],
- "salmon": [250, 128, 114],
- "sandybrown": [244, 164, 96],
- "seagreen": [46, 139, 87],
- "seashell": [255, 245, 238],
- "sienna": [160, 82, 45],
- "silver": [192, 192, 192],
- "skyblue": [135, 206, 235],
- "slateblue": [106, 90, 205],
- "slategray": [112, 128, 144],
- "slategrey": [112, 128, 144],
- "snow": [255, 250, 250],
- "springgreen": [0, 255, 127],
- "steelblue": [70, 130, 180],
- "tan": [210, 180, 140],
- "teal": [0, 128, 128],
- "thistle": [216, 191, 216],
- "tomato": [255, 99, 71],
- "turquoise": [64, 224, 208],
- "violet": [238, 130, 238],
- "wheat": [245, 222, 179],
- "white": [255, 255, 255],
- "whitesmoke": [245, 245, 245],
- "yellow": [255, 255, 0],
- "yellowgreen": [154, 205, 50]
-};
-
-
-/***/ }),
-/* 6 */
-/***/ (function(module, exports, __webpack_require__) {
-
-/* MIT license */
-var cssKeywords = __webpack_require__(5);
-
-// NOTE: conversions should only return primitive values (i.e. arrays, or
-// values that give correct `typeof` results).
-// do not use box values types (i.e. Number(), String(), etc.)
-
-var reverseKeywords = {};
-for (var key in cssKeywords) {
- if (cssKeywords.hasOwnProperty(key)) {
- reverseKeywords[cssKeywords[key]] = key;
- }
-}
-
-var convert = module.exports = {
- rgb: {channels: 3, labels: 'rgb'},
- hsl: {channels: 3, labels: 'hsl'},
- hsv: {channels: 3, labels: 'hsv'},
- hwb: {channels: 3, labels: 'hwb'},
- cmyk: {channels: 4, labels: 'cmyk'},
- xyz: {channels: 3, labels: 'xyz'},
- lab: {channels: 3, labels: 'lab'},
- lch: {channels: 3, labels: 'lch'},
- hex: {channels: 1, labels: ['hex']},
- keyword: {channels: 1, labels: ['keyword']},
- ansi16: {channels: 1, labels: ['ansi16']},
- ansi256: {channels: 1, labels: ['ansi256']},
- hcg: {channels: 3, labels: ['h', 'c', 'g']},
- apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
- gray: {channels: 1, labels: ['gray']}
-};
-
-// hide .channels and .labels properties
-for (var model in convert) {
- if (convert.hasOwnProperty(model)) {
- if (!('channels' in convert[model])) {
- throw new Error('missing channels property: ' + model);
- }
-
- if (!('labels' in convert[model])) {
- throw new Error('missing channel labels property: ' + model);
- }
-
- if (convert[model].labels.length !== convert[model].channels) {
- throw new Error('channel and label counts mismatch: ' + model);
- }
-
- var channels = convert[model].channels;
- var labels = convert[model].labels;
- delete convert[model].channels;
- delete convert[model].labels;
- Object.defineProperty(convert[model], 'channels', {value: channels});
- Object.defineProperty(convert[model], 'labels', {value: labels});
- }
-}
-
-convert.rgb.hsl = function (rgb) {
- var r = rgb[0] / 255;
- var g = rgb[1] / 255;
- var b = rgb[2] / 255;
- var min = Math.min(r, g, b);
- var max = Math.max(r, g, b);
- var delta = max - min;
- var h;
- var s;
- var l;
-
- if (max === min) {
- h = 0;
- } else if (r === max) {
- h = (g - b) / delta;
- } else if (g === max) {
- h = 2 + (b - r) / delta;
- } else if (b === max) {
- h = 4 + (r - g) / delta;
- }
-
- h = Math.min(h * 60, 360);
-
- if (h < 0) {
- h += 360;
- }
-
- l = (min + max) / 2;
-
- if (max === min) {
- s = 0;
- } else if (l <= 0.5) {
- s = delta / (max + min);
- } else {
- s = delta / (2 - max - min);
- }
-
- return [h, s * 100, l * 100];
-};
-
-convert.rgb.hsv = function (rgb) {
- var rdif;
- var gdif;
- var bdif;
- var h;
- var s;
-
- var r = rgb[0] / 255;
- var g = rgb[1] / 255;
- var b = rgb[2] / 255;
- var v = Math.max(r, g, b);
- var diff = v - Math.min(r, g, b);
- var diffc = function (c) {
- return (v - c) / 6 / diff + 1 / 2;
- };
-
- if (diff === 0) {
- h = s = 0;
- } else {
- s = diff / v;
- rdif = diffc(r);
- gdif = diffc(g);
- bdif = diffc(b);
-
- if (r === v) {
- h = bdif - gdif;
- } else if (g === v) {
- h = (1 / 3) + rdif - bdif;
- } else if (b === v) {
- h = (2 / 3) + gdif - rdif;
- }
- if (h < 0) {
- h += 1;
- } else if (h > 1) {
- h -= 1;
- }
- }
-
- return [
- h * 360,
- s * 100,
- v * 100
- ];
-};
-
-convert.rgb.hwb = function (rgb) {
- var r = rgb[0];
- var g = rgb[1];
- var b = rgb[2];
- var h = convert.rgb.hsl(rgb)[0];
- var w = 1 / 255 * Math.min(r, Math.min(g, b));
-
- b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
-
- return [h, w * 100, b * 100];
-};
-
-convert.rgb.cmyk = function (rgb) {
- var r = rgb[0] / 255;
- var g = rgb[1] / 255;
- var b = rgb[2] / 255;
- var c;
- var m;
- var y;
- var k;
-
- k = Math.min(1 - r, 1 - g, 1 - b);
- c = (1 - r - k) / (1 - k) || 0;
- m = (1 - g - k) / (1 - k) || 0;
- y = (1 - b - k) / (1 - k) || 0;
-
- return [c * 100, m * 100, y * 100, k * 100];
-};
-
-/**
- * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
- * */
-function comparativeDistance(x, y) {
- return (
- Math.pow(x[0] - y[0], 2) +
- Math.pow(x[1] - y[1], 2) +
- Math.pow(x[2] - y[2], 2)
- );
-}
-
-convert.rgb.keyword = function (rgb) {
- var reversed = reverseKeywords[rgb];
- if (reversed) {
- return reversed;
- }
-
- var currentClosestDistance = Infinity;
- var currentClosestKeyword;
-
- for (var keyword in cssKeywords) {
- if (cssKeywords.hasOwnProperty(keyword)) {
- var value = cssKeywords[keyword];
-
- // Compute comparative distance
- var distance = comparativeDistance(rgb, value);
-
- // Check if its less, if so set as closest
- if (distance < currentClosestDistance) {
- currentClosestDistance = distance;
- currentClosestKeyword = keyword;
- }
- }
- }
-
- return currentClosestKeyword;
-};
-
-convert.keyword.rgb = function (keyword) {
- return cssKeywords[keyword];
-};
-
-convert.rgb.xyz = function (rgb) {
- var r = rgb[0] / 255;
- var g = rgb[1] / 255;
- var b = rgb[2] / 255;
-
- // assume sRGB
- r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
- g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
- b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
-
- var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
- var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
- var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
-
- return [x * 100, y * 100, z * 100];
-};
-
-convert.rgb.lab = function (rgb) {
- var xyz = convert.rgb.xyz(rgb);
- var x = xyz[0];
- var y = xyz[1];
- var z = xyz[2];
- var l;
- var a;
- var b;
-
- x /= 95.047;
- y /= 100;
- z /= 108.883;
-
- x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
- y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
- z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
-
- l = (116 * y) - 16;
- a = 500 * (x - y);
- b = 200 * (y - z);
-
- return [l, a, b];
-};
-
-convert.hsl.rgb = function (hsl) {
- var h = hsl[0] / 360;
- var s = hsl[1] / 100;
- var l = hsl[2] / 100;
- var t1;
- var t2;
- var t3;
- var rgb;
- var val;
-
- if (s === 0) {
- val = l * 255;
- return [val, val, val];
- }
-
- if (l < 0.5) {
- t2 = l * (1 + s);
- } else {
- t2 = l + s - l * s;
- }
-
- t1 = 2 * l - t2;
-
- rgb = [0, 0, 0];
- for (var i = 0; i < 3; i++) {
- t3 = h + 1 / 3 * -(i - 1);
- if (t3 < 0) {
- t3++;
- }
- if (t3 > 1) {
- t3--;
- }
-
- if (6 * t3 < 1) {
- val = t1 + (t2 - t1) * 6 * t3;
- } else if (2 * t3 < 1) {
- val = t2;
- } else if (3 * t3 < 2) {
- val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
- } else {
- val = t1;
- }
-
- rgb[i] = val * 255;
- }
-
- return rgb;
-};
-
-convert.hsl.hsv = function (hsl) {
- var h = hsl[0];
- var s = hsl[1] / 100;
- var l = hsl[2] / 100;
- var smin = s;
- var lmin = Math.max(l, 0.01);
- var sv;
- var v;
-
- l *= 2;
- s *= (l <= 1) ? l : 2 - l;
- smin *= lmin <= 1 ? lmin : 2 - lmin;
- v = (l + s) / 2;
- sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
-
- return [h, sv * 100, v * 100];
-};
-
-convert.hsv.rgb = function (hsv) {
- var h = hsv[0] / 60;
- var s = hsv[1] / 100;
- var v = hsv[2] / 100;
- var hi = Math.floor(h) % 6;
-
- var f = h - Math.floor(h);
- var p = 255 * v * (1 - s);
- var q = 255 * v * (1 - (s * f));
- var t = 255 * v * (1 - (s * (1 - f)));
- v *= 255;
-
- switch (hi) {
- case 0:
- return [v, t, p];
- case 1:
- return [q, v, p];
- case 2:
- return [p, v, t];
- case 3:
- return [p, q, v];
- case 4:
- return [t, p, v];
- case 5:
- return [v, p, q];
- }
-};
-
-convert.hsv.hsl = function (hsv) {
- var h = hsv[0];
- var s = hsv[1] / 100;
- var v = hsv[2] / 100;
- var vmin = Math.max(v, 0.01);
- var lmin;
- var sl;
- var l;
-
- l = (2 - s) * v;
- lmin = (2 - s) * vmin;
- sl = s * vmin;
- sl /= (lmin <= 1) ? lmin : 2 - lmin;
- sl = sl || 0;
- l /= 2;
-
- return [h, sl * 100, l * 100];
-};
-
-// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
-convert.hwb.rgb = function (hwb) {
- var h = hwb[0] / 360;
- var wh = hwb[1] / 100;
- var bl = hwb[2] / 100;
- var ratio = wh + bl;
- var i;
- var v;
- var f;
- var n;
-
- // wh + bl cant be > 1
- if (ratio > 1) {
- wh /= ratio;
- bl /= ratio;
- }
-
- i = Math.floor(6 * h);
- v = 1 - bl;
- f = 6 * h - i;
-
- if ((i & 0x01) !== 0) {
- f = 1 - f;
- }
-
- n = wh + f * (v - wh); // linear interpolation
-
- var r;
- var g;
- var b;
- switch (i) {
- default:
- case 6:
- case 0: r = v; g = n; b = wh; break;
- case 1: r = n; g = v; b = wh; break;
- case 2: r = wh; g = v; b = n; break;
- case 3: r = wh; g = n; b = v; break;
- case 4: r = n; g = wh; b = v; break;
- case 5: r = v; g = wh; b = n; break;
- }
-
- return [r * 255, g * 255, b * 255];
-};
-
-convert.cmyk.rgb = function (cmyk) {
- var c = cmyk[0] / 100;
- var m = cmyk[1] / 100;
- var y = cmyk[2] / 100;
- var k = cmyk[3] / 100;
- var r;
- var g;
- var b;
-
- r = 1 - Math.min(1, c * (1 - k) + k);
- g = 1 - Math.min(1, m * (1 - k) + k);
- b = 1 - Math.min(1, y * (1 - k) + k);
-
- return [r * 255, g * 255, b * 255];
-};
-
-convert.xyz.rgb = function (xyz) {
- var x = xyz[0] / 100;
- var y = xyz[1] / 100;
- var z = xyz[2] / 100;
- var r;
- var g;
- var b;
-
- r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
- g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
- b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
-
- // assume sRGB
- r = r > 0.0031308
- ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
- : r * 12.92;
-
- g = g > 0.0031308
- ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
- : g * 12.92;
-
- b = b > 0.0031308
- ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
- : b * 12.92;
-
- r = Math.min(Math.max(0, r), 1);
- g = Math.min(Math.max(0, g), 1);
- b = Math.min(Math.max(0, b), 1);
-
- return [r * 255, g * 255, b * 255];
-};
-
-convert.xyz.lab = function (xyz) {
- var x = xyz[0];
- var y = xyz[1];
- var z = xyz[2];
- var l;
- var a;
- var b;
-
- x /= 95.047;
- y /= 100;
- z /= 108.883;
-
- x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
- y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
- z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
-
- l = (116 * y) - 16;
- a = 500 * (x - y);
- b = 200 * (y - z);
-
- return [l, a, b];
-};
-
-convert.lab.xyz = function (lab) {
- var l = lab[0];
- var a = lab[1];
- var b = lab[2];
- var x;
- var y;
- var z;
-
- y = (l + 16) / 116;
- x = a / 500 + y;
- z = y - b / 200;
-
- var y2 = Math.pow(y, 3);
- var x2 = Math.pow(x, 3);
- var z2 = Math.pow(z, 3);
- y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
- x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
- z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
-
- x *= 95.047;
- y *= 100;
- z *= 108.883;
-
- return [x, y, z];
-};
-
-convert.lab.lch = function (lab) {
- var l = lab[0];
- var a = lab[1];
- var b = lab[2];
- var hr;
- var h;
- var c;
-
- hr = Math.atan2(b, a);
- h = hr * 360 / 2 / Math.PI;
-
- if (h < 0) {
- h += 360;
- }
-
- c = Math.sqrt(a * a + b * b);
-
- return [l, c, h];
-};
-
-convert.lch.lab = function (lch) {
- var l = lch[0];
- var c = lch[1];
- var h = lch[2];
- var a;
- var b;
- var hr;
-
- hr = h / 360 * 2 * Math.PI;
- a = c * Math.cos(hr);
- b = c * Math.sin(hr);
-
- return [l, a, b];
-};
-
-convert.rgb.ansi16 = function (args) {
- var r = args[0];
- var g = args[1];
- var b = args[2];
- var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization
-
- value = Math.round(value / 50);
-
- if (value === 0) {
- return 30;
- }
-
- var ansi = 30
- + ((Math.round(b / 255) << 2)
- | (Math.round(g / 255) << 1)
- | Math.round(r / 255));
-
- if (value === 2) {
- ansi += 60;
- }
-
- return ansi;
-};
-
-convert.hsv.ansi16 = function (args) {
- // optimization here; we already know the value and don't need to get
- // it converted for us.
- return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
-};
-
-convert.rgb.ansi256 = function (args) {
- var r = args[0];
- var g = args[1];
- var b = args[2];
-
- // we use the extended greyscale palette here, with the exception of
- // black and white. normal palette only has 4 greyscale shades.
- if (r === g && g === b) {
- if (r < 8) {
- return 16;
- }
-
- if (r > 248) {
- return 231;
- }
-
- return Math.round(((r - 8) / 247) * 24) + 232;
- }
-
- var ansi = 16
- + (36 * Math.round(r / 255 * 5))
- + (6 * Math.round(g / 255 * 5))
- + Math.round(b / 255 * 5);
-
- return ansi;
-};
-
-convert.ansi16.rgb = function (args) {
- var color = args % 10;
-
- // handle greyscale
- if (color === 0 || color === 7) {
- if (args > 50) {
- color += 3.5;
- }
-
- color = color / 10.5 * 255;
-
- return [color, color, color];
- }
-
- var mult = (~~(args > 50) + 1) * 0.5;
- var r = ((color & 1) * mult) * 255;
- var g = (((color >> 1) & 1) * mult) * 255;
- var b = (((color >> 2) & 1) * mult) * 255;
-
- return [r, g, b];
-};
-
-convert.ansi256.rgb = function (args) {
- // handle greyscale
- if (args >= 232) {
- var c = (args - 232) * 10 + 8;
- return [c, c, c];
- }
-
- args -= 16;
-
- var rem;
- var r = Math.floor(args / 36) / 5 * 255;
- var g = Math.floor((rem = args % 36) / 6) / 5 * 255;
- var b = (rem % 6) / 5 * 255;
-
- return [r, g, b];
-};
-
-convert.rgb.hex = function (args) {
- var integer = ((Math.round(args[0]) & 0xFF) << 16)
- + ((Math.round(args[1]) & 0xFF) << 8)
- + (Math.round(args[2]) & 0xFF);
-
- var string = integer.toString(16).toUpperCase();
- return '000000'.substring(string.length) + string;
-};
-
-convert.hex.rgb = function (args) {
- var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
- if (!match) {
- return [0, 0, 0];
- }
-
- var colorString = match[0];
-
- if (match[0].length === 3) {
- colorString = colorString.split('').map(function (char) {
- return char + char;
- }).join('');
- }
-
- var integer = parseInt(colorString, 16);
- var r = (integer >> 16) & 0xFF;
- var g = (integer >> 8) & 0xFF;
- var b = integer & 0xFF;
-
- return [r, g, b];
-};
-
-convert.rgb.hcg = function (rgb) {
- var r = rgb[0] / 255;
- var g = rgb[1] / 255;
- var b = rgb[2] / 255;
- var max = Math.max(Math.max(r, g), b);
- var min = Math.min(Math.min(r, g), b);
- var chroma = (max - min);
- var grayscale;
- var hue;
-
- if (chroma < 1) {
- grayscale = min / (1 - chroma);
- } else {
- grayscale = 0;
- }
-
- if (chroma <= 0) {
- hue = 0;
- } else
- if (max === r) {
- hue = ((g - b) / chroma) % 6;
- } else
- if (max === g) {
- hue = 2 + (b - r) / chroma;
- } else {
- hue = 4 + (r - g) / chroma + 4;
- }
-
- hue /= 6;
- hue %= 1;
-
- return [hue * 360, chroma * 100, grayscale * 100];
-};
-
-convert.hsl.hcg = function (hsl) {
- var s = hsl[1] / 100;
- var l = hsl[2] / 100;
- var c = 1;
- var f = 0;
-
- if (l < 0.5) {
- c = 2.0 * s * l;
- } else {
- c = 2.0 * s * (1.0 - l);
- }
-
- if (c < 1.0) {
- f = (l - 0.5 * c) / (1.0 - c);
- }
-
- return [hsl[0], c * 100, f * 100];
-};
-
-convert.hsv.hcg = function (hsv) {
- var s = hsv[1] / 100;
- var v = hsv[2] / 100;
-
- var c = s * v;
- var f = 0;
-
- if (c < 1.0) {
- f = (v - c) / (1 - c);
- }
-
- return [hsv[0], c * 100, f * 100];
-};
-
-convert.hcg.rgb = function (hcg) {
- var h = hcg[0] / 360;
- var c = hcg[1] / 100;
- var g = hcg[2] / 100;
-
- if (c === 0.0) {
- return [g * 255, g * 255, g * 255];
- }
-
- var pure = [0, 0, 0];
- var hi = (h % 1) * 6;
- var v = hi % 1;
- var w = 1 - v;
- var mg = 0;
-
- switch (Math.floor(hi)) {
- case 0:
- pure[0] = 1; pure[1] = v; pure[2] = 0; break;
- case 1:
- pure[0] = w; pure[1] = 1; pure[2] = 0; break;
- case 2:
- pure[0] = 0; pure[1] = 1; pure[2] = v; break;
- case 3:
- pure[0] = 0; pure[1] = w; pure[2] = 1; break;
- case 4:
- pure[0] = v; pure[1] = 0; pure[2] = 1; break;
- default:
- pure[0] = 1; pure[1] = 0; pure[2] = w;
- }
-
- mg = (1.0 - c) * g;
-
- return [
- (c * pure[0] + mg) * 255,
- (c * pure[1] + mg) * 255,
- (c * pure[2] + mg) * 255
- ];
-};
-
-convert.hcg.hsv = function (hcg) {
- var c = hcg[1] / 100;
- var g = hcg[2] / 100;
-
- var v = c + g * (1.0 - c);
- var f = 0;
-
- if (v > 0.0) {
- f = c / v;
- }
-
- return [hcg[0], f * 100, v * 100];
-};
-
-convert.hcg.hsl = function (hcg) {
- var c = hcg[1] / 100;
- var g = hcg[2] / 100;
-
- var l = g * (1.0 - c) + 0.5 * c;
- var s = 0;
-
- if (l > 0.0 && l < 0.5) {
- s = c / (2 * l);
- } else
- if (l >= 0.5 && l < 1.0) {
- s = c / (2 * (1 - l));
- }
-
- return [hcg[0], s * 100, l * 100];
-};
-
-convert.hcg.hwb = function (hcg) {
- var c = hcg[1] / 100;
- var g = hcg[2] / 100;
- var v = c + g * (1.0 - c);
- return [hcg[0], (v - c) * 100, (1 - v) * 100];
-};
-
-convert.hwb.hcg = function (hwb) {
- var w = hwb[1] / 100;
- var b = hwb[2] / 100;
- var v = 1 - b;
- var c = v - w;
- var g = 0;
-
- if (c < 1) {
- g = (v - c) / (1 - c);
- }
-
- return [hwb[0], c * 100, g * 100];
-};
-
-convert.apple.rgb = function (apple) {
- return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
-};
-
-convert.rgb.apple = function (rgb) {
- return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
-};
-
-convert.gray.rgb = function (args) {
- return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
-};
-
-convert.gray.hsl = convert.gray.hsv = function (args) {
- return [0, 0, args[0]];
-};
-
-convert.gray.hwb = function (gray) {
- return [0, 100, gray[0]];
-};
-
-convert.gray.cmyk = function (gray) {
- return [0, 0, 0, gray[0]];
-};
-
-convert.gray.lab = function (gray) {
- return [gray[0], 0, 0];
-};
-
-convert.gray.hex = function (gray) {
- var val = Math.round(gray[0] / 100 * 255) & 0xFF;
- var integer = (val << 16) + (val << 8) + val;
-
- var string = integer.toString(16).toUpperCase();
- return '000000'.substring(string.length) + string;
-};
-
-convert.rgb.gray = function (rgb) {
- var val = (rgb[0] + rgb[1] + rgb[2]) / 3;
- return [val / 255 * 100];
-};
-
-
-/***/ }),
-/* 7 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
-
-var _Colorpicker = __webpack_require__(8);
-
-var _Colorpicker2 = _interopRequireDefault(_Colorpicker);
-
-var _jquery = __webpack_require__(0);
-
-var _jquery2 = _interopRequireDefault(_jquery);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-var plugin = 'colorpicker';
-
-_jquery2.default[plugin] = _Colorpicker2.default;
-
-// Colorpicker jQuery Plugin API
-_jquery2.default.fn[plugin] = function (option) {
- var fnArgs = Array.prototype.slice.call(arguments, 1),
- isSingleElement = this.length === 1,
- returnValue = null;
-
- var $elements = this.each(function () {
- var $this = (0, _jquery2.default)(this),
- inst = $this.data(plugin),
- options = (typeof option === 'undefined' ? 'undefined' : _typeof(option)) === 'object' ? option : {};
-
- // Create instance if does not exist
- if (!inst) {
- inst = new _Colorpicker2.default(this, options);
- $this.data(plugin, inst);
- }
-
- if (!isSingleElement) {
- return;
- }
-
- returnValue = $this;
-
- if (typeof option === 'string') {
- if (option === 'colorpicker') {
- // Return colorpicker instance: e.g. .colorpicker('colorpicker')
- returnValue = inst;
- } else if (_jquery2.default.isFunction(inst[option])) {
- // Return method call return value: e.g. .colorpicker('isEnabled')
- returnValue = inst[option].apply(inst, fnArgs);
- } else {
- // Return property value: e.g. .colorpicker('element')
- returnValue = inst[option];
- }
- }
- });
-
- return isSingleElement ? returnValue : $elements;
-};
-
-_jquery2.default.fn[plugin].constructor = _Colorpicker2.default;
-
-/***/ }),
-/* 8 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _Extension = __webpack_require__(1);
-
-var _Extension2 = _interopRequireDefault(_Extension);
-
-var _options = __webpack_require__(3);
-
-var _options2 = _interopRequireDefault(_options);
-
-var _extensions = __webpack_require__(9);
-
-var _extensions2 = _interopRequireDefault(_extensions);
-
-var _jquery = __webpack_require__(0);
-
-var _jquery2 = _interopRequireDefault(_jquery);
-
-var _SliderHandler = __webpack_require__(13);
-
-var _SliderHandler2 = _interopRequireDefault(_SliderHandler);
-
-var _PopupHandler = __webpack_require__(14);
-
-var _PopupHandler2 = _interopRequireDefault(_PopupHandler);
-
-var _InputHandler = __webpack_require__(15);
-
-var _InputHandler2 = _interopRequireDefault(_InputHandler);
-
-var _ColorHandler = __webpack_require__(22);
-
-var _ColorHandler2 = _interopRequireDefault(_ColorHandler);
-
-var _PickerHandler = __webpack_require__(23);
-
-var _PickerHandler2 = _interopRequireDefault(_PickerHandler);
-
-var _AddonHandler = __webpack_require__(24);
-
-var _AddonHandler2 = _interopRequireDefault(_AddonHandler);
-
-var _ColorItem = __webpack_require__(2);
-
-var _ColorItem2 = _interopRequireDefault(_ColorItem);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var colorPickerIdCounter = 0;
-
-var root = typeof self !== 'undefined' ? self : undefined; // window
-
-/**
- * Colorpicker widget class
- */
-
-var Colorpicker = function () {
- _createClass(Colorpicker, [{
- key: 'color',
-
-
- /**
- * Internal color object
- *
- * @type {Color|null}
- */
- get: function get() {
- return this.colorHandler.color;
- }
-
- /**
- * Internal color format
- *
- * @type {String|null}
- */
-
- }, {
- key: 'format',
- get: function get() {
- return this.colorHandler.format;
- }
-
- /**
- * Getter of the picker element
- *
- * @returns {jQuery|HTMLElement}
- */
-
- }, {
- key: 'picker',
- get: function get() {
- return this.pickerHandler.picker;
- }
-
- /**
- * @fires Colorpicker#colorpickerCreate
- * @param {Object|String} element
- * @param {Object} options
- * @constructor
- */
-
- }], [{
- key: 'Color',
-
- /**
- * Color class
- *
- * @static
- * @type {Color}
- */
- get: function get() {
- return _ColorItem2.default;
- }
-
- /**
- * Extension class
- *
- * @static
- * @type {Extension}
- */
-
- }, {
- key: 'Extension',
- get: function get() {
- return _Extension2.default;
- }
- }]);
-
- function Colorpicker(element, options) {
- _classCallCheck(this, Colorpicker);
-
- colorPickerIdCounter += 1;
- /**
- * The colorpicker instance number
- * @type {number}
- */
- this.id = colorPickerIdCounter;
-
- /**
- * Latest colorpicker event
- *
- * @type {{name: String, e: *}}
- */
- this.lastEvent = {
- alias: null,
- e: null
- };
-
- /**
- * The element that the colorpicker is bound to
- *
- * @type {*|jQuery}
- */
- this.element = (0, _jquery2.default)(element).addClass('colorpicker-element').attr('data-colorpicker-id', this.id);
-
- /**
- * @type {defaults}
- */
- this.options = _jquery2.default.extend(true, {}, _options2.default, options, this.element.data());
-
- /**
- * @type {boolean}
- * @private
- */
- this.disabled = false;
-
- /**
- * Extensions added to this instance
- *
- * @type {Extension[]}
- */
- this.extensions = [];
-
- /**
- * The element where the
- * @type {*|jQuery}
- */
- this.container = this.options.container === true || this.options.container !== true && this.options.inline === true ? this.element : this.options.container;
-
- this.container = this.container !== false ? (0, _jquery2.default)(this.container) : false;
-
- /**
- * @type {InputHandler}
- */
- this.inputHandler = new _InputHandler2.default(this);
- /**
- * @type {ColorHandler}
- */
- this.colorHandler = new _ColorHandler2.default(this);
- /**
- * @type {SliderHandler}
- */
- this.sliderHandler = new _SliderHandler2.default(this);
- /**
- * @type {PopupHandler}
- */
- this.popupHandler = new _PopupHandler2.default(this, root);
- /**
- * @type {PickerHandler}
- */
- this.pickerHandler = new _PickerHandler2.default(this);
- /**
- * @type {AddonHandler}
- */
- this.addonHandler = new _AddonHandler2.default(this);
-
- this.init();
-
- // Emit a create event
- (0, _jquery2.default)(_jquery2.default.proxy(function () {
- /**
- * (Colorpicker) When the Colorpicker instance has been created and the DOM is ready.
- *
- * @event Colorpicker#colorpickerCreate
- */
- this.trigger('colorpickerCreate');
- }, this));
- }
-
- /**
- * Initializes the plugin
- * @private
- */
-
-
- _createClass(Colorpicker, [{
- key: 'init',
- value: function init() {
- // Init addon
- this.addonHandler.bind();
-
- // Init input
- this.inputHandler.bind();
-
- // Init extensions (before initializing the color)
- this.initExtensions();
-
- // Init color
- this.colorHandler.bind();
-
- // Init picker
- this.pickerHandler.bind();
-
- // Init sliders and popup
- this.sliderHandler.bind();
- this.popupHandler.bind();
-
- // Inject into the DOM (this may make it visible)
- this.pickerHandler.attach();
-
- // Update all components
- this.update();
-
- if (this.inputHandler.isDisabled()) {
- this.disable();
- }
- }
-
- /**
- * Initializes the plugin extensions
- * @private
- */
-
- }, {
- key: 'initExtensions',
- value: function initExtensions() {
- var _this = this;
-
- if (!Array.isArray(this.options.extensions)) {
- this.options.extensions = [];
- }
-
- if (this.options.debug) {
- this.options.extensions.push({ name: 'debugger' });
- }
-
- // Register and instantiate extensions
- this.options.extensions.forEach(function (ext) {
- _this.registerExtension(Colorpicker.extensions[ext.name.toLowerCase()], ext.options || {});
- });
- }
-
- /**
- * Creates and registers the given extension
- *
- * @param {Extension} ExtensionClass The extension class to instantiate
- * @param {Object} [config] Extension configuration
- * @returns {Extension}
- */
-
- }, {
- key: 'registerExtension',
- value: function registerExtension(ExtensionClass) {
- var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var ext = new ExtensionClass(this, config);
-
- this.extensions.push(ext);
- return ext;
- }
-
- /**
- * Destroys the current instance
- *
- * @fires Colorpicker#colorpickerDestroy
- */
-
- }, {
- key: 'destroy',
- value: function destroy() {
- var color = this.color;
-
- this.sliderHandler.unbind();
- this.inputHandler.unbind();
- this.popupHandler.unbind();
- this.colorHandler.unbind();
- this.addonHandler.unbind();
- this.pickerHandler.unbind();
-
- this.element.removeClass('colorpicker-element').removeData('colorpicker', 'color').off('.colorpicker');
-
- /**
- * (Colorpicker) When the instance is destroyed with all events unbound.
- *
- * @event Colorpicker#colorpickerDestroy
- */
- this.trigger('colorpickerDestroy', color);
- }
-
- /**
- * Shows the colorpicker widget if hidden.
- * If the colorpicker is disabled this call will be ignored.
- *
- * @fires Colorpicker#colorpickerShow
- * @param {Event} [e]
- */
-
- }, {
- key: 'show',
- value: function show(e) {
- this.popupHandler.show(e);
- }
-
- /**
- * Hides the colorpicker widget.
- *
- * @fires Colorpicker#colorpickerHide
- * @param {Event} [e]
- */
-
- }, {
- key: 'hide',
- value: function hide(e) {
- this.popupHandler.hide(e);
- }
-
- /**
- * Toggles the colorpicker between visible and hidden.
- *
- * @fires Colorpicker#colorpickerShow
- * @fires Colorpicker#colorpickerHide
- * @param {Event} [e]
- */
-
- }, {
- key: 'toggle',
- value: function toggle(e) {
- this.popupHandler.toggle(e);
- }
-
- /**
- * Returns the current color value as string
- *
- * @param {String|*} [defaultValue]
- * @returns {String|*}
- */
-
- }, {
- key: 'getValue',
- value: function getValue() {
- var defaultValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
-
- var val = this.colorHandler.color;
-
- val = val instanceof _ColorItem2.default ? val : defaultValue;
-
- if (val instanceof _ColorItem2.default) {
- return val.string(this.format);
- }
-
- return val;
- }
-
- /**
- * Sets the color manually
- *
- * @fires Colorpicker#colorpickerChange
- * @param {String|Color} val
- */
-
- }, {
- key: 'setValue',
- value: function setValue(val) {
- if (this.isDisabled()) {
- return;
- }
- var ch = this.colorHandler;
-
- if (ch.hasColor() && !!val && ch.color.equals(val) || !ch.hasColor() && !val) {
- // same color or still empty
- return;
- }
-
- ch.color = val ? ch.createColor(val, this.options.autoInputFallback) : null;
-
- /**
- * (Colorpicker) When the color is set programmatically with setValue().
- *
- * @event Colorpicker#colorpickerChange
- */
- this.trigger('colorpickerChange', ch.color, val);
-
- // force update if color has changed to empty
- this.update();
- }
-
- /**
- * Updates the UI and the input color according to the internal color.
- *
- * @fires Colorpicker#colorpickerUpdate
- */
-
- }, {
- key: 'update',
- value: function update() {
- if (this.colorHandler.hasColor()) {
- this.inputHandler.update();
- } else {
- this.colorHandler.assureColor();
- }
-
- this.addonHandler.update();
- this.pickerHandler.update();
-
- /**
- * (Colorpicker) Fired when the widget is updated.
- *
- * @event Colorpicker#colorpickerUpdate
- */
- this.trigger('colorpickerUpdate');
- }
-
- /**
- * Enables the widget and the input if any
- *
- * @fires Colorpicker#colorpickerEnable
- * @returns {boolean}
- */
-
- }, {
- key: 'enable',
- value: function enable() {
- this.inputHandler.enable();
- this.disabled = false;
- this.picker.removeClass('colorpicker-disabled');
-
- /**
- * (Colorpicker) When the widget has been enabled.
- *
- * @event Colorpicker#colorpickerEnable
- */
- this.trigger('colorpickerEnable');
- return true;
- }
-
- /**
- * Disables the widget and the input if any
- *
- * @fires Colorpicker#colorpickerDisable
- * @returns {boolean}
- */
-
- }, {
- key: 'disable',
- value: function disable() {
- this.inputHandler.disable();
- this.disabled = true;
- this.picker.addClass('colorpicker-disabled');
-
- /**
- * (Colorpicker) When the widget has been disabled.
- *
- * @event Colorpicker#colorpickerDisable
- */
- this.trigger('colorpickerDisable');
- return true;
- }
-
- /**
- * Returns true if this instance is enabled
- * @returns {boolean}
- */
-
- }, {
- key: 'isEnabled',
- value: function isEnabled() {
- return !this.isDisabled();
- }
-
- /**
- * Returns true if this instance is disabled
- * @returns {boolean}
- */
-
- }, {
- key: 'isDisabled',
- value: function isDisabled() {
- return this.disabled === true;
- }
-
- /**
- * Triggers a Colorpicker event.
- *
- * @param eventName
- * @param color
- * @param value
- */
-
- }, {
- key: 'trigger',
- value: function trigger(eventName) {
- var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
- var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
-
- this.element.trigger({
- type: eventName,
- colorpicker: this,
- color: color ? color : this.color,
- value: value ? value : this.getValue()
- });
- }
- }]);
-
- return Colorpicker;
-}();
-
-/**
- * Colorpicker extension classes, indexed by extension name
- *
- * @static
- * @type {Object} a map between the extension name and its class
- */
-
-
-Colorpicker.extensions = _extensions2.default;
-
-exports.default = Colorpicker;
-module.exports = exports.default;
-
-/***/ }),
-/* 9 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.Palette = exports.Swatches = exports.Preview = exports.Debugger = undefined;
-
-var _Debugger = __webpack_require__(10);
-
-var _Debugger2 = _interopRequireDefault(_Debugger);
-
-var _Preview = __webpack_require__(11);
-
-var _Preview2 = _interopRequireDefault(_Preview);
-
-var _Swatches = __webpack_require__(12);
-
-var _Swatches2 = _interopRequireDefault(_Swatches);
-
-var _Palette = __webpack_require__(4);
-
-var _Palette2 = _interopRequireDefault(_Palette);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-exports.Debugger = _Debugger2.default;
-exports.Preview = _Preview2.default;
-exports.Swatches = _Swatches2.default;
-exports.Palette = _Palette2.default;
-exports.default = {
- 'debugger': _Debugger2.default,
- 'preview': _Preview2.default,
- 'swatches': _Swatches2.default,
- 'palette': _Palette2.default
-};
-
-/***/ }),
-/* 10 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
-
-var _Extension2 = __webpack_require__(1);
-
-var _Extension3 = _interopRequireDefault(_Extension2);
-
-var _jquery = __webpack_require__(0);
-
-var _jquery2 = _interopRequireDefault(_jquery);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Debugger extension class
- * @alias DebuggerExtension
- * @ignore
- */
-var Debugger = function (_Extension) {
- _inherits(Debugger, _Extension);
-
- function Debugger(colorpicker) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- _classCallCheck(this, Debugger);
-
- /**
- * @type {number}
- */
- var _this = _possibleConstructorReturn(this, (Debugger.__proto__ || Object.getPrototypeOf(Debugger)).call(this, colorpicker, options));
-
- _this.eventCounter = 0;
- if (_this.colorpicker.inputHandler.hasInput()) {
- _this.colorpicker.inputHandler.input.on('change.colorpicker-ext', _jquery2.default.proxy(_this.onChangeInput, _this));
- }
- return _this;
- }
-
- /**
- * @fires DebuggerExtension#colorpickerDebug
- * @param {string} eventName
- * @param {*} args
- */
-
-
- _createClass(Debugger, [{
- key: 'log',
- value: function log(eventName) {
- var _console;
-
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- args[_key - 1] = arguments[_key];
- }
-
- this.eventCounter += 1;
-
- var logMessage = '#' + this.eventCounter + ': Colorpicker#' + this.colorpicker.id + ' [' + eventName + ']';
-
- (_console = console).debug.apply(_console, [logMessage].concat(args));
-
- /**
- * Whenever the debugger logs an event, this other event is emitted.
- *
- * @event DebuggerExtension#colorpickerDebug
- * @type {object} The event object
- * @property {Colorpicker} colorpicker The Colorpicker instance
- * @property {ColorItem} color The color instance
- * @property {{debugger: DebuggerExtension, eventName: String, logArgs: Array, logMessage: String}} debug
- * The debug info
- */
- this.colorpicker.element.trigger({
- type: 'colorpickerDebug',
- colorpicker: this.colorpicker,
- color: this.color,
- value: null,
- debug: {
- debugger: this,
- eventName: eventName,
- logArgs: args,
- logMessage: logMessage
- }
- });
- }
- }, {
- key: 'resolveColor',
- value: function resolveColor(color) {
- var realColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
-
- this.log('resolveColor()', color, realColor);
- return false;
- }
- }, {
- key: 'onCreate',
- value: function onCreate(event) {
- this.log('colorpickerCreate');
- return _get(Debugger.prototype.__proto__ || Object.getPrototypeOf(Debugger.prototype), 'onCreate', this).call(this, event);
- }
- }, {
- key: 'onDestroy',
- value: function onDestroy(event) {
- this.log('colorpickerDestroy');
- this.eventCounter = 0;
-
- if (this.colorpicker.inputHandler.hasInput()) {
- this.colorpicker.inputHandler.input.off('.colorpicker-ext');
- }
-
- return _get(Debugger.prototype.__proto__ || Object.getPrototypeOf(Debugger.prototype), 'onDestroy', this).call(this, event);
- }
- }, {
- key: 'onUpdate',
- value: function onUpdate(event) {
- this.log('colorpickerUpdate');
- }
-
- /**
- * @listens Colorpicker#change
- * @param {Event} event
- */
-
- }, {
- key: 'onChangeInput',
- value: function onChangeInput(event) {
- this.log('input:change.colorpicker', event.value, event.color);
- }
- }, {
- key: 'onChange',
- value: function onChange(event) {
- this.log('colorpickerChange', event.value, event.color);
- }
- }, {
- key: 'onInvalid',
- value: function onInvalid(event) {
- this.log('colorpickerInvalid', event.value, event.color);
- }
- }, {
- key: 'onHide',
- value: function onHide(event) {
- this.log('colorpickerHide');
- this.eventCounter = 0;
- }
- }, {
- key: 'onShow',
- value: function onShow(event) {
- this.log('colorpickerShow');
- }
- }, {
- key: 'onDisable',
- value: function onDisable(event) {
- this.log('colorpickerDisable');
- }
- }, {
- key: 'onEnable',
- value: function onEnable(event) {
- this.log('colorpickerEnable');
- }
- }]);
-
- return Debugger;
-}(_Extension3.default);
-
-exports.default = Debugger;
-module.exports = exports.default;
-
-/***/ }),
-/* 11 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
-
-var _Extension2 = __webpack_require__(1);
-
-var _Extension3 = _interopRequireDefault(_Extension2);
-
-var _jquery = __webpack_require__(0);
-
-var _jquery2 = _interopRequireDefault(_jquery);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Color preview extension
- * @ignore
- */
-var Preview = function (_Extension) {
- _inherits(Preview, _Extension);
-
- function Preview(colorpicker) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- _classCallCheck(this, Preview);
-
- var _this = _possibleConstructorReturn(this, (Preview.__proto__ || Object.getPrototypeOf(Preview)).call(this, colorpicker, _jquery2.default.extend(true, {}, {
- template: '
',showText:true,format:colorpicker.format},options)));_this.element=(0,_jquery2.default)(_this.options.template);_this.elementInner=_this.element.find("div");return _this}_createClass(Preview,[{key:"onCreate",value:function onCreate(event){_get(Preview.prototype.__proto__||Object.getPrototypeOf(Preview.prototype),"onCreate",this).call(this,event);this.colorpicker.picker.append(this.element)}},{key:"onUpdate",value:function onUpdate(event){_get(Preview.prototype.__proto__||Object.getPrototypeOf(Preview.prototype),"onUpdate",this).call(this,event);if(!event.color){this.elementInner.css("backgroundColor",null).css("color",null).html("");return}this.elementInner.css("backgroundColor",event.color.toRgbString());if(this.options.showText){this.elementInner.html(event.color.string(this.options.format||this.colorpicker.format));if(event.color.isDark()&&event.color.alpha>.5){this.elementInner.css("color","white")}else{this.elementInner.css("color","black")}}}}]);return Preview}(_Extension3.default);exports.default=Preview;module.exports=exports.default},function(module,exports,__webpack_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i\n \n ',swatchTemplate:''};var Swatches=function(_Palette){_inherits(Swatches,_Palette);function Swatches(colorpicker){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};_classCallCheck(this,Swatches);var _this=_possibleConstructorReturn(this,(Swatches.__proto__||Object.getPrototypeOf(Swatches)).call(this,colorpicker,_jquery2.default.extend(true,{},defaults,options)));_this.element=null;return _this}_createClass(Swatches,[{key:"isEnabled",value:function isEnabled(){return this.getLength()>0}},{key:"onCreate",value:function onCreate(event){_get(Swatches.prototype.__proto__||Object.getPrototypeOf(Swatches.prototype),"onCreate",this).call(this,event);if(!this.isEnabled()){return}this.element=(0,_jquery2.default)(this.options.barTemplate);this.load();this.colorpicker.picker.append(this.element)}},{key:"load",value:function load(){var _this2=this;var colorpicker=this.colorpicker,swatchContainer=this.element.find(".colorpicker-swatches--inner"),isAliased=this.options.namesAsValues===true&&!Array.isArray(this.colors);swatchContainer.empty();_jquery2.default.each(this.colors,function(name,value){var $swatch=(0,_jquery2.default)(_this2.options.swatchTemplate).attr("data-name",name).attr("data-value",value).attr("title",isAliased?name+": "+value:value).on("mousedown.colorpicker touchstart.colorpicker",function(e){var $sw=(0,_jquery2.default)(this);colorpicker.setValue(isAliased?$sw.attr("data-name"):$sw.attr("data-value"))});$swatch.find(".colorpicker-swatch--inner").css("background-color",value);swatchContainer.append($swatch)});swatchContainer.append((0,_jquery2.default)(''))}}]);return Swatches}(_Palette3.default);exports.default=Swatches;module.exports=exports.default},function(module,exports,__webpack_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i0}},{key:"onClickingInside",value:function onClickingInside(e){this.clicking=this.isClickingInside(e)}},{key:"createPopover",value:function createPopover(){var cp=this.colorpicker;this.popoverTarget=this.hasAddon?this.addon:this.input;cp.picker.addClass("colorpicker-bs-popover-content");this.popoverTarget.popover(_jquery2.default.extend(true,{},_options2.default.popover,cp.options.popover,{trigger:"manual",content:cp.picker,html:true}));this.popoverTip=(0,_jquery2.default)(this.popoverTarget.popover("getTipElement").data("bs.popover").tip);this.popoverTip.addClass("colorpicker-bs-popover");this.popoverTarget.on("shown.bs.popover",_jquery2.default.proxy(this.fireShow,this));this.popoverTarget.on("hidden.bs.popover",_jquery2.default.proxy(this.fireHide,this))}},{key:"reposition",value:function reposition(e){if(this.popoverTarget&&this.isVisible()){this.popoverTarget.popover("update")}}},{key:"toggle",value:function toggle(e){if(this.isVisible()){this.hide(e)}else{this.show(e)}}},{key:"show",value:function show(e){if(this.isVisible()||this.showing||this.hidding){return}this.showing=true;this.hidding=false;this.clicking=false;var cp=this.colorpicker;cp.lastEvent.alias="show";cp.lastEvent.e=e;if(e&&(!this.hasInput||this.input.attr("type")==="color")&&e&&e.preventDefault){e.stopPropagation();e.preventDefault()}if(this.isPopover){(0,_jquery2.default)(this.root).on("resize.colorpicker",_jquery2.default.proxy(this.reposition,this))}cp.picker.addClass("colorpicker-visible").removeClass("colorpicker-hidden");if(this.popoverTarget){this.popoverTarget.popover("show")}else{this.fireShow()}}},{key:"fireShow",value:function fireShow(){this.hidding=false;this.showing=false;if(this.isPopover){(0,_jquery2.default)(this.root.document).on("mousedown.colorpicker touchstart.colorpicker",_jquery2.default.proxy(this.hide,this));(0,_jquery2.default)(this.root.document).on("mousedown.colorpicker touchstart.colorpicker",_jquery2.default.proxy(this.onClickingInside,this))}this.colorpicker.trigger("colorpickerShow")}},{key:"hide",value:function hide(e){if(this.isHidden()||this.showing||this.hidding){return}var cp=this.colorpicker,clicking=this.clicking||this.isClickingInside(e);this.hidding=true;this.showing=false;this.clicking=false;cp.lastEvent.alias="hide";cp.lastEvent.e=e;if(clicking){this.hidding=false;return}if(this.popoverTarget){this.popoverTarget.popover("hide")}else{this.fireHide()}}},{key:"fireHide",value:function fireHide(){this.hidding=false;this.showing=false;var cp=this.colorpicker;cp.picker.addClass("colorpicker-hidden").removeClass("colorpicker-visible");(0,_jquery2.default)(this.root).off("resize.colorpicker",_jquery2.default.proxy(this.reposition,this));(0,_jquery2.default)(this.root.document).off("mousedown.colorpicker touchstart.colorpicker",_jquery2.default.proxy(this.hide,this));(0,_jquery2.default)(this.root.document).off("mousedown.colorpicker touchstart.colorpicker",_jquery2.default.proxy(this.onClickingInside,this));cp.trigger("colorpickerHide")}},{key:"focus",value:function focus(){if(this.hasAddon){return this.addon.focus()}if(this.hasInput){return this.input.focus()}return false}},{key:"isVisible",value:function isVisible(){return this.colorpicker.picker.hasClass("colorpicker-visible")&&!this.colorpicker.picker.hasClass("colorpicker-hidden")}},{key:"isHidden",value:function isHidden(){return this.colorpicker.picker.hasClass("colorpicker-hidden")&&!this.colorpicker.picker.hasClass("colorpicker-visible")}},{key:"input",get:function get(){return this.colorpicker.inputHandler.input}},{key:"hasInput",get:function get(){return this.colorpicker.inputHandler.hasInput()}},{key:"addon",get:function get(){return this.colorpicker.addonHandler.addon}},{key:"hasAddon",get:function get(){return this.colorpicker.addonHandler.hasAddon()}},{key:"isPopover",get:function get(){return!this.colorpicker.options.inline&&!!this.popoverTip}}]);return PopupHandler}();exports.default=PopupHandler;module.exports=exports.default},function(module,exports,__webpack_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i0&&arguments[0]!==undefined?arguments[0]:null;val=val?val:this.colorpicker.colorHandler.getColorString();if(!val){return""}val=this.colorpicker.colorHandler.resolveColorDelegate(val,false);if(this.colorpicker.options.useHashPrefix===false){val=val.replace(/^#/g,"")}return val}},{key:"hasInput",value:function hasInput(){return this.input!==false}},{key:"isEnabled",value:function isEnabled(){return this.hasInput()&&!this.isDisabled()}},{key:"isDisabled",value:function isDisabled(){return this.hasInput()&&this.input.prop("disabled")===true}},{key:"disable",value:function disable(){if(this.hasInput()){this.input.prop("disabled",true)}}},{key:"enable",value:function enable(){if(this.hasInput()){this.input.prop("disabled",false)}}},{key:"update",value:function update(){if(!this.hasInput()){return}if(this.colorpicker.options.autoInputFallback===false&&this.colorpicker.colorHandler.isInvalidColor()){return}this.setValue(this.getFormattedColor())}},{key:"onchange",value:function onchange(e){this.colorpicker.lastEvent.alias="input.change";this.colorpicker.lastEvent.e=e;var val=this.getValue();if(val!==e.value){this.colorpicker.setValue(val)}}},{key:"onkeyup",value:function onkeyup(e){this.colorpicker.lastEvent.alias="input.keyup";this.colorpicker.lastEvent.e=e;var val=this.getValue();if(val!==e.value){this.colorpicker.setValue(val)}}}]);return InputHandler}();exports.default=InputHandler;module.exports=exports.default},function(module,exports,__webpack_require__){"use strict";var colorString=__webpack_require__(17);var convert=__webpack_require__(20);var _slice=[].slice;var skippedModels=["keyword","gray","hex"];var hashedModelKeys={};Object.keys(convert).forEach(function(model){hashedModelKeys[_slice.call(convert[model].labels).sort().join("")]=model});var limiters={};function Color(obj,model){if(!(this instanceof Color)){return new Color(obj,model)}if(model&&model in skippedModels){model=null}if(model&&!(model in convert)){throw new Error("Unknown model: "+model)}var i;var channels;if(obj==null){this.model="rgb";this.color=[0,0,0];this.valpha=1}else if(obj instanceof Color){this.model=obj.model;this.color=obj.color.slice();this.valpha=obj.valpha}else if(typeof obj==="string"){var result=colorString.get(obj);if(result===null){throw new Error("Unable to parse color from string: "+obj)}this.model=result.model;channels=convert[this.model].channels;this.color=result.value.slice(0,channels);this.valpha=typeof result.value[channels]==="number"?result.value[channels]:1}else if(obj.length){this.model=model||"rgb";channels=convert[this.model].channels;var newArr=_slice.call(obj,0,channels);this.color=zeroArray(newArr,channels);this.valpha=typeof obj[channels]==="number"?obj[channels]:1}else if(typeof obj==="number"){obj&=16777215;this.model="rgb";this.color=[obj>>16&255,obj>>8&255,obj&255];this.valpha=1}else{this.valpha=1;var keys=Object.keys(obj);if("alpha"in obj){keys.splice(keys.indexOf("alpha"),1);this.valpha=typeof obj.alpha==="number"?obj.alpha:0}var hashedKeys=keys.sort().join("");if(!(hashedKeys in hashedModelKeys)){throw new Error("Unable to parse color from object: "+JSON.stringify(obj))}this.model=hashedModelKeys[hashedKeys];var labels=convert[this.model].labels;var color=[];for(i=0;ilum2){return(lum1+.05)/(lum2+.05)}return(lum2+.05)/(lum1+.05)},level:function(color2){var contrastRatio=this.contrast(color2);if(contrastRatio>=7.1){return"AAA"}return contrastRatio>=4.5?"AA":""},isDark:function(){var rgb=this.rgb().color;var yiq=(rgb[0]*299+rgb[1]*587+rgb[2]*114)/1e3;return yiq<128},isLight:function(){return!this.isDark()},negate:function(){var rgb=this.rgb();for(var i=0;i<3;i++){rgb.color[i]=255-rgb.color[i]}return rgb},lighten:function(ratio){var hsl=this.hsl();hsl.color[2]+=hsl.color[2]*ratio;return hsl},darken:function(ratio){var hsl=this.hsl();hsl.color[2]-=hsl.color[2]*ratio;return hsl},saturate:function(ratio){var hsl=this.hsl();hsl.color[1]+=hsl.color[1]*ratio;return hsl},desaturate:function(ratio){var hsl=this.hsl();hsl.color[1]-=hsl.color[1]*ratio;return hsl},whiten:function(ratio){var hwb=this.hwb();hwb.color[1]+=hwb.color[1]*ratio;return hwb},blacken:function(ratio){var hwb=this.hwb();hwb.color[2]+=hwb.color[2]*ratio;return hwb},grayscale:function(){var rgb=this.rgb().color;var val=rgb[0]*.3+rgb[1]*.59+rgb[2]*.11;return Color.rgb(val,val,val)},fade:function(ratio){return this.alpha(this.valpha-this.valpha*ratio)},opaquer:function(ratio){return this.alpha(this.valpha+this.valpha*ratio)},rotate:function(degrees){var hsl=this.hsl();var hue=hsl.color[0];hue=(hue+degrees)%360;hue=hue<0?360+hue:hue;hsl.color[0]=hue;return hsl},mix:function(mixinColor,weight){if(!mixinColor||!mixinColor.rgb){throw new Error('Argument to "mix" was not a Color instance, but rather an instance of '+typeof mixinColor)}var color1=mixinColor.rgb();var color2=this.rgb();var p=weight===undefined?.5:weight;var w=2*p-1;var a=color1.alpha()-color2.alpha();var w1=((w*a===-1?w:(w+a)/(1+w*a))+1)/2;var w2=1-w1;return Color.rgb(w1*color1.red()+w2*color2.red(),w1*color1.green()+w2*color2.green(),w1*color1.blue()+w2*color2.blue(),color1.alpha()*p+color2.alpha()*(1-p))}};Object.keys(convert).forEach(function(model){if(skippedModels.indexOf(model)!==-1){return}var channels=convert[model].channels;Color.prototype[model]=function(){if(this.model===model){return new Color(this)}if(arguments.length){return new Color(arguments,model)}var newAlpha=typeof arguments[channels]==="number"?channels:this.valpha;return new Color(assertArray(convert[this.model][model].raw(this.color)).concat(newAlpha),model)};Color[model]=function(color){if(typeof color==="number"){color=zeroArray(_slice.call(arguments),channels)}return new Color(color,model)}});function roundTo(num,places){return Number(num.toFixed(places))}function roundToPlace(places){return function(num){return roundTo(num,places)}}function getset(model,channel,modifier){model=Array.isArray(model)?model:[model];model.forEach(function(m){(limiters[m]||(limiters[m]=[]))[channel]=modifier});model=model[0];return function(val){var result;if(arguments.length){if(modifier){val=modifier(val)}result=this[model]();result.color[channel]=val;return result}result=this[model]().color[channel];if(modifier){result=modifier(result)}return result}}function maxfn(max){return function(v){return Math.max(0,Math.min(max,v))}}function assertArray(val){return Array.isArray(val)?val:[val]}function zeroArray(arr,length){for(var i=0;i=4&&hwba[3]!==1){a=", "+hwba[3]}return"hwb("+hwba[0]+", "+hwba[1]+"%, "+hwba[2]+"%"+a+")"};cs.to.keyword=function(rgb){return reverseNames[rgb.slice(0,3)]};function clamp(num,min,max){return Math.min(Math.max(min,num),max)}function hexDouble(num){var str=num.toString(16).toUpperCase();return str.length<2?"0"+str:str}},function(module,exports,__webpack_require__){"use strict";var isArrayish=__webpack_require__(19);var concat=Array.prototype.concat;var slice=Array.prototype.slice;var swizzle=module.exports=function swizzle(args){var results=[];for(var i=0,len=args.length;i=0&&obj.splice instanceof Function}},function(module,exports,__webpack_require__){var conversions=__webpack_require__(6);var route=__webpack_require__(21);var convert={};var models=Object.keys(conversions);function wrapRaw(fn){var wrappedFn=function(args){if(args===undefined||args===null){return args}if(arguments.length>1){args=Array.prototype.slice.call(arguments)}return fn(args)};if("conversion"in fn){wrappedFn.conversion=fn.conversion}return wrappedFn}function wrapRounded(fn){var wrappedFn=function(args){if(args===undefined||args===null){return args}if(arguments.length>1){args=Array.prototype.slice.call(arguments)}var result=fn(args);if(typeof result==="object"){for(var len=result.length,i=0;i1&&arguments[1]!==undefined?arguments[1]:true;var color=new _ColorItem2.default(this.resolveColorDelegate(val),this.format);if(!color.isValid()){if(fallbackOnInvalid){color=this.getFallbackColor()}this.colorpicker.trigger("colorpickerInvalid",color,val)}if(!this.isAlphaEnabled()){color.alpha=1}return color}},{key:"getFallbackColor",value:function getFallbackColor(){if(this.fallback&&this.fallback===this.color){return this.color}var fallback=this.resolveColorDelegate(this.fallback);var color=new _ColorItem2.default(fallback,this.format);if(!color.isValid()){console.warn("The fallback color is invalid. Falling back to the previous color or black if any.");return this.color?this.color:new _ColorItem2.default("#000000",this.format)}return color}},{key:"assureColor",value:function assureColor(){if(!this.hasColor()){this.color=this.getFallbackColor()}return this.color}},{key:"resolveColorDelegate",value:function resolveColorDelegate(color){var realColor=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var extResolvedColor=false;_jquery2.default.each(this.colorpicker.extensions,function(name,ext){if(extResolvedColor!==false){return}extResolvedColor=ext.resolveColor(color,realColor)});return extResolvedColor?extResolvedColor:color}},{key:"isInvalidColor",value:function isInvalidColor(){return!this.hasColor()||!this.color.isValid()}},{key:"isAlphaEnabled",value:function isAlphaEnabled(){return this.colorpicker.options.useAlpha!==false}},{key:"hasColor",value:function hasColor(){return this.color instanceof _ColorItem2.default}},{key:"fallback",get:function get(){return this.colorpicker.options.fallbackColor?this.colorpicker.options.fallbackColor:this.hasColor()?this.color:null}},{key:"format",get:function get(){if(this.colorpicker.options.format){return this.colorpicker.options.format}if(this.hasColor()&&this.color.hasTransparency()&&this.color.format.match(/^hex/)){return this.isAlphaEnabled()?"rgba":"hex"}if(this.hasColor()){return this.color.format}return"rgb"}},{key:"color",get:function get(){return this.colorpicker.element.data("color")},set:function set(value){this.colorpicker.element.data("color",value);if(value instanceof _ColorItem2.default&&this.colorpicker.options.format==="auto"){this.colorpicker.options.format=this.color.format}}}]);return ColorHandler}();exports.default=ColorHandler;module.exports=exports.default},function(module,exports,__webpack_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i0){icn.css(styles)}else{this.addon.css(styles)}}}]);return AddonHandler}();exports.default=AddonHandler;module.exports=exports.default}])});
-//# sourceMappingURL=bootstrap-colorpicker.min.js.map
\ No newline at end of file
diff --git a/hal-core/resources/web/js/lib/bootstrap-switch.LICENSE b/hal-core/resources/web/js/lib/bootstrap-switch.LICENSE
deleted file mode 100644
index 31e23cd1..00000000
--- a/hal-core/resources/web/js/lib/bootstrap-switch.LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013-2015 The authors of Bootstrap Switch
-
-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.
diff --git a/hal-core/resources/web/js/lib/bootstrap-switch.LICENSE.txt b/hal-core/resources/web/js/lib/bootstrap-switch.LICENSE.txt
deleted file mode 100644
index 31e23cd1..00000000
--- a/hal-core/resources/web/js/lib/bootstrap-switch.LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013-2015 The authors of Bootstrap Switch
-
-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.
diff --git a/hal-core/resources/web/js/lib/bootstrap-switch.js b/hal-core/resources/web/js/lib/bootstrap-switch.js
deleted file mode 100644
index 511f08fa..00000000
--- a/hal-core/resources/web/js/lib/bootstrap-switch.js
+++ /dev/null
@@ -1,784 +0,0 @@
-/**
- * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.
- *
- * @version v3.3.4
- * @homepage https://bttstrp.github.io/bootstrap-switch
- * @author Mattia Larentis (http://larentis.eu)
- * @license Apache-2.0
- */
-
-(function (global, factory) {
- if (typeof define === "function" && define.amd) {
- define(['jquery'], factory);
- } else if (typeof exports !== "undefined") {
- factory(require('jquery'));
- } else {
- var mod = {
- exports: {}
- };
- factory(global.jquery);
- global.bootstrapSwitch = mod.exports;
- }
-})(this, function (_jquery) {
- 'use strict';
-
- var _jquery2 = _interopRequireDefault(_jquery);
-
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
-
- var _extends = Object.assign || function (target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
-
- for (var key in source) {
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key];
- }
- }
- }
-
- return target;
- };
-
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
-
- var _createClass = function () {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
-
- return function (Constructor, protoProps, staticProps) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
- if (staticProps) defineProperties(Constructor, staticProps);
- return Constructor;
- };
- }();
-
- var $ = _jquery2.default || window.jQuery || window.$;
-
- var BootstrapSwitch = function () {
- function BootstrapSwitch(element) {
- var _this = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- _classCallCheck(this, BootstrapSwitch);
-
- this.$element = $(element);
- this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, this._getElementOptions(), options);
- this.prevOptions = {};
- this.$wrapper = $('
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'
'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
diff --git a/hal-core/resources/web/js/lib/c3.LICENSE b/hal-core/resources/web/js/lib/c3.LICENSE
deleted file mode 100644
index 29ce9cb0..00000000
--- a/hal-core/resources/web/js/lib/c3.LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Masayuki Tanaka
-
-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.
diff --git a/hal-core/resources/web/js/lib/c3.LICENSE.txt b/hal-core/resources/web/js/lib/c3.LICENSE.txt
deleted file mode 100644
index 29ce9cb0..00000000
--- a/hal-core/resources/web/js/lib/c3.LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Masayuki Tanaka
-
-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.
diff --git a/hal-core/resources/web/js/lib/c3.js b/hal-core/resources/web/js/lib/c3.js
deleted file mode 100644
index 2ce7f7e0..00000000
--- a/hal-core/resources/web/js/lib/c3.js
+++ /dev/null
@@ -1,8202 +0,0 @@
-(function (window) {
- 'use strict';
-
- /*global define, module, exports, require */
-
- var c3 = { version: "0.4.11" };
-
- var c3_chart_fn,
- c3_chart_internal_fn,
- c3_chart_internal_axis_fn;
-
- function API(owner) {
- this.owner = owner;
- }
-
- function inherit(base, derived) {
-
- if (Object.create) {
- derived.prototype = Object.create(base.prototype);
- } else {
- var f = function f() {};
- f.prototype = base.prototype;
- derived.prototype = new f();
- }
-
- derived.prototype.constructor = derived;
-
- return derived;
- }
-
- function Chart(config) {
- var $$ = this.internal = new ChartInternal(this);
- $$.loadConfig(config);
-
- $$.beforeInit(config);
- $$.init();
- $$.afterInit(config);
-
- // bind "this" to nested API
- (function bindThis(fn, target, argThis) {
- Object.keys(fn).forEach(function (key) {
- target[key] = fn[key].bind(argThis);
- if (Object.keys(fn[key]).length > 0) {
- bindThis(fn[key], target[key], argThis);
- }
- });
- })(c3_chart_fn, this, this);
- }
-
- function ChartInternal(api) {
- var $$ = this;
- $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
- $$.api = api;
- $$.config = $$.getDefaultConfig();
- $$.data = {};
- $$.cache = {};
- $$.axes = {};
- }
-
- c3.generate = function (config) {
- return new Chart(config);
- };
-
- c3.chart = {
- fn: Chart.prototype,
- internal: {
- fn: ChartInternal.prototype,
- axis: {
- fn: Axis.prototype
- }
- }
- };
- c3_chart_fn = c3.chart.fn;
- c3_chart_internal_fn = c3.chart.internal.fn;
- c3_chart_internal_axis_fn = c3.chart.internal.axis.fn;
-
- c3_chart_internal_fn.beforeInit = function () {
- // can do something
- };
- c3_chart_internal_fn.afterInit = function () {
- // can do something
- };
- c3_chart_internal_fn.init = function () {
- var $$ = this, config = $$.config;
-
- $$.initParams();
-
- if (config.data_url) {
- $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);
- }
- else if (config.data_json) {
- $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
- }
- else if (config.data_rows) {
- $$.initWithData($$.convertRowsToData(config.data_rows));
- }
- else if (config.data_columns) {
- $$.initWithData($$.convertColumnsToData(config.data_columns));
- }
- else {
- throw Error('url or json or rows or columns is required.');
- }
- };
-
- c3_chart_internal_fn.initParams = function () {
- var $$ = this, d3 = $$.d3, config = $$.config;
-
- // MEMO: clipId needs to be unique because it conflicts when multiple charts exist
- $$.clipId = "c3-" + (+new Date()) + '-clip',
- $$.clipIdForXAxis = $$.clipId + '-xaxis',
- $$.clipIdForYAxis = $$.clipId + '-yaxis',
- $$.clipIdForGrid = $$.clipId + '-grid',
- $$.clipIdForSubchart = $$.clipId + '-subchart',
- $$.clipPath = $$.getClipPath($$.clipId),
- $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis),
- $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
- $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid),
- $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart),
-
- $$.dragStart = null;
- $$.dragging = false;
- $$.flowing = false;
- $$.cancelClick = false;
- $$.mouseover = false;
- $$.transiting = false;
-
- $$.color = $$.generateColor();
- $$.levelColor = $$.generateLevelColor();
-
- $$.dataTimeFormat = config.data_xLocaltime ? d3.time.format : d3.time.format.utc;
- $$.axisTimeFormat = config.axis_x_localtime ? d3.time.format : d3.time.format.utc;
- $$.defaultAxisTimeFormat = $$.axisTimeFormat.multi([
- [".%L", function (d) { return d.getMilliseconds(); }],
- [":%S", function (d) { return d.getSeconds(); }],
- ["%I:%M", function (d) { return d.getMinutes(); }],
- ["%I %p", function (d) { return d.getHours(); }],
- ["%-m/%-d", function (d) { return d.getDay() && d.getDate() !== 1; }],
- ["%-m/%-d", function (d) { return d.getDate() !== 1; }],
- ["%-m/%-d", function (d) { return d.getMonth(); }],
- ["%Y/%-m/%-d", function () { return true; }]
- ]);
-
- $$.hiddenTargetIds = [];
- $$.hiddenLegendIds = [];
- $$.focusedTargetIds = [];
- $$.defocusedTargetIds = [];
-
- $$.xOrient = config.axis_rotated ? "left" : "bottom";
- $$.yOrient = config.axis_rotated ? (config.axis_y_inner ? "top" : "bottom") : (config.axis_y_inner ? "right" : "left");
- $$.y2Orient = config.axis_rotated ? (config.axis_y2_inner ? "bottom" : "top") : (config.axis_y2_inner ? "left" : "right");
- $$.subXOrient = config.axis_rotated ? "left" : "bottom";
-
- $$.isLegendRight = config.legend_position === 'right';
- $$.isLegendInset = config.legend_position === 'inset';
- $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right';
- $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left';
- $$.legendStep = 0;
- $$.legendItemWidth = 0;
- $$.legendItemHeight = 0;
-
- $$.currentMaxTickWidths = {
- x: 0,
- y: 0,
- y2: 0
- };
-
- $$.rotated_padding_left = 30;
- $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;
- $$.rotated_padding_top = 5;
-
- $$.withoutFadeIn = {};
-
- $$.intervalForObserveInserted = undefined;
-
- $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
- };
-
- c3_chart_internal_fn.initChartElements = function () {
- if (this.initBar) { this.initBar(); }
- if (this.initLine) { this.initLine(); }
- if (this.initArc) { this.initArc(); }
- if (this.initGauge) { this.initGauge(); }
- if (this.initText) { this.initText(); }
- };
-
- c3_chart_internal_fn.initWithData = function (data) {
- var $$ = this, d3 = $$.d3, config = $$.config;
- var defs, main, binding = true;
-
- $$.axis = new Axis($$);
-
- if ($$.initPie) { $$.initPie(); }
- if ($$.initBrush) { $$.initBrush(); }
- if ($$.initZoom) { $$.initZoom(); }
-
- if (!config.bindto) {
- $$.selectChart = d3.selectAll([]);
- }
- else if (typeof config.bindto.node === 'function') {
- $$.selectChart = config.bindto;
- }
- else {
- $$.selectChart = d3.select(config.bindto);
- }
- if ($$.selectChart.empty()) {
- $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0);
- $$.observeInserted($$.selectChart);
- binding = false;
- }
- $$.selectChart.html("").classed("c3", true);
-
- // Init data as targets
- $$.data.xs = {};
- $$.data.targets = $$.convertDataToTargets(data);
-
- if (config.data_filter) {
- $$.data.targets = $$.data.targets.filter(config.data_filter);
- }
-
- // Set targets to hide if needed
- if (config.data_hide) {
- $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide);
- }
- if (config.legend_hide) {
- $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide);
- }
-
- // when gauge, hide legend // TODO: fix
- if ($$.hasType('gauge')) {
- config.legend_show = false;
- }
-
- // Init sizes and scales
- $$.updateSizes();
- $$.updateScales();
-
- // Set domains for each scale
- $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));
- $$.y.domain($$.getYDomain($$.data.targets, 'y'));
- $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));
- $$.subX.domain($$.x.domain());
- $$.subY.domain($$.y.domain());
- $$.subY2.domain($$.y2.domain());
-
- // Save original x domain for zoom update
- $$.orgXDomain = $$.x.domain();
-
- // Set initialized scales to brush and zoom
- if ($$.brush) { $$.brush.scale($$.subX); }
- if (config.zoom_enabled) { $$.zoom.scale($$.x); }
-
- /*-- Basic Elements --*/
-
- // Define svgs
- $$.svg = $$.selectChart.append("svg")
- .style("overflow", "hidden")
- .on('mouseenter', function () { return config.onmouseover.call($$); })
- .on('mouseleave', function () { return config.onmouseout.call($$); });
-
- if ($$.config.svg_classname) {
- $$.svg.attr('class', $$.config.svg_classname);
- }
-
- // Define defs
- defs = $$.svg.append("defs");
- $$.clipChart = $$.appendClip(defs, $$.clipId);
- $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);
- $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);
- $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);
- $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);
- $$.updateSvgSize();
-
- // Define regions
- main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main'));
-
- if ($$.initSubchart) { $$.initSubchart(); }
- if ($$.initTooltip) { $$.initTooltip(); }
- if ($$.initLegend) { $$.initLegend(); }
- if ($$.initTitle) { $$.initTitle(); }
-
- /*-- Main Region --*/
-
- // text when empty
- main.append("text")
- .attr("class", CLASS.text + ' ' + CLASS.empty)
- .attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers.
- .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE.
-
- // Regions
- $$.initRegion();
-
- // Grids
- $$.initGrid();
-
- // Define g for chart area
- main.append('g')
- .attr("clip-path", $$.clipPath)
- .attr('class', CLASS.chart);
-
- // Grid lines
- if (config.grid_lines_front) { $$.initGridLines(); }
-
- // Cover whole with rects for events
- $$.initEventRect();
-
- // Define g for chart
- $$.initChartElements();
-
- // if zoom privileged, insert rect to forefront
- // TODO: is this needed?
- main.insert('rect', config.zoom_privileged ? null : 'g.' + CLASS.regions)
- .attr('class', CLASS.zoomRect)
- .attr('width', $$.width)
- .attr('height', $$.height)
- .style('opacity', 0)
- .on("dblclick.zoom", null);
-
- // Set default extent if defined
- if (config.axis_x_extent) { $$.brush.extent($$.getDefaultExtent()); }
-
- // Add Axis
- $$.axis.init();
-
- // Set targets
- $$.updateTargets($$.data.targets);
-
- // Draw with targets
- if (binding) {
- $$.updateDimension();
- $$.config.oninit.call($$);
- $$.redraw({
- withTransition: false,
- withTransform: true,
- withUpdateXDomain: true,
- withUpdateOrgXDomain: true,
- withTransitionForAxis: false
- });
- }
-
- // Bind resize event
- $$.bindResize();
-
- // export element of the chart
- $$.api.element = $$.selectChart.node();
- };
-
- c3_chart_internal_fn.smoothLines = function (el, type) {
- var $$ = this;
- if (type === 'grid') {
- el.each(function () {
- var g = $$.d3.select(this),
- x1 = g.attr('x1'),
- x2 = g.attr('x2'),
- y1 = g.attr('y1'),
- y2 = g.attr('y2');
- g.attr({
- 'x1': Math.ceil(x1),
- 'x2': Math.ceil(x2),
- 'y1': Math.ceil(y1),
- 'y2': Math.ceil(y2)
- });
- });
- }
- };
-
-
- c3_chart_internal_fn.updateSizes = function () {
- var $$ = this, config = $$.config;
- var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
- legendWidth = $$.legend ? $$.getLegendWidth() : 0,
- legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
- hasArc = $$.hasArcType(),
- xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),
- subchartHeight = config.subchart_show && !hasArc ? (config.subchart_size_height + xAxisHeight) : 0;
-
- $$.currentWidth = $$.getCurrentWidth();
- $$.currentHeight = $$.getCurrentHeight();
-
- // for main
- $$.margin = config.axis_rotated ? {
- top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),
- right: hasArc ? 0 : $$.getCurrentPaddingRight(),
- bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(),
- left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())
- } : {
- top: 4 + $$.getCurrentPaddingTop(), // for top tick text
- right: hasArc ? 0 : $$.getCurrentPaddingRight(),
- bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(),
- left: hasArc ? 0 : $$.getCurrentPaddingLeft()
- };
-
- // for subchart
- $$.margin2 = config.axis_rotated ? {
- top: $$.margin.top,
- right: NaN,
- bottom: 20 + legendHeightForBottom,
- left: $$.rotated_padding_left
- } : {
- top: $$.currentHeight - subchartHeight - legendHeightForBottom,
- right: NaN,
- bottom: xAxisHeight + legendHeightForBottom,
- left: $$.margin.left
- };
-
- // for legend
- $$.margin3 = {
- top: 0,
- right: NaN,
- bottom: 0,
- left: 0
- };
- if ($$.updateSizeForLegend) { $$.updateSizeForLegend(legendHeight, legendWidth); }
-
- $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;
- $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;
- if ($$.width < 0) { $$.width = 0; }
- if ($$.height < 0) { $$.height = 0; }
-
- $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width;
- $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;
- if ($$.width2 < 0) { $$.width2 = 0; }
- if ($$.height2 < 0) { $$.height2 = 0; }
-
- // for arc
- $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
- $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
- if ($$.hasType('gauge') && !config.gauge_fullCircle) {
- $$.arcHeight += $$.height - $$.getGaugeLabelHeight();
- }
- if ($$.updateRadius) { $$.updateRadius(); }
-
- if ($$.isLegendRight && hasArc) {
- $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;
- }
- };
-
- c3_chart_internal_fn.updateTargets = function (targets) {
- var $$ = this;
-
- /*-- Main --*/
-
- //-- Text --//
- $$.updateTargetsForText(targets);
-
- //-- Bar --//
- $$.updateTargetsForBar(targets);
-
- //-- Line --//
- $$.updateTargetsForLine(targets);
-
- //-- Arc --//
- if ($$.hasArcType() && $$.updateTargetsForArc) { $$.updateTargetsForArc(targets); }
-
- /*-- Sub --*/
-
- if ($$.updateTargetsForSubchart) { $$.updateTargetsForSubchart(targets); }
-
- // Fade-in each chart
- $$.showTargets();
- };
- c3_chart_internal_fn.showTargets = function () {
- var $$ = this;
- $$.svg.selectAll('.' + CLASS.target).filter(function (d) { return $$.isTargetToShow(d.id); })
- .transition().duration($$.config.transition_duration)
- .style("opacity", 1);
- };
-
- c3_chart_internal_fn.redraw = function (options, transitions) {
- var $$ = this, main = $$.main, d3 = $$.d3, config = $$.config;
- var areaIndices = $$.getShapeIndices($$.isAreaType), barIndices = $$.getShapeIndices($$.isBarType), lineIndices = $$.getShapeIndices($$.isLineType);
- var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis,
- withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend,
- withEventRect, withDimension, withUpdateXAxis;
- var hideAxis = $$.hasArcType();
- var drawArea, drawBar, drawLine, xForText, yForText;
- var duration, durationForExit, durationForAxis;
- var waitForDraw, flow;
- var targetsToShow = $$.filterTargetsToShow($$.data.targets), tickValues, i, intervalForCulling, xDomainForZoom;
- var xv = $$.xv.bind($$), cx, cy;
-
- options = options || {};
- withY = getOption(options, "withY", true);
- withSubchart = getOption(options, "withSubchart", true);
- withTransition = getOption(options, "withTransition", true);
- withTransform = getOption(options, "withTransform", false);
- withUpdateXDomain = getOption(options, "withUpdateXDomain", false);
- withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false);
- withTrimXDomain = getOption(options, "withTrimXDomain", true);
- withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain);
- withLegend = getOption(options, "withLegend", false);
- withEventRect = getOption(options, "withEventRect", true);
- withDimension = getOption(options, "withDimension", true);
- withTransitionForExit = getOption(options, "withTransitionForExit", withTransition);
- withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition);
-
- duration = withTransition ? config.transition_duration : 0;
- durationForExit = withTransitionForExit ? duration : 0;
- durationForAxis = withTransitionForAxis ? duration : 0;
-
- transitions = transitions || $$.axis.generateTransitions(durationForAxis);
-
- // update legend and transform each g
- if (withLegend && config.legend_show) {
- $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
- } else if (withDimension) {
- // need to update dimension (e.g. axis.y.tick.values) because y tick values should change
- // no need to update axis in it because they will be updated in redraw()
- $$.updateDimension(true);
- }
-
- // MEMO: needed for grids calculation
- if ($$.isCategorized() && targetsToShow.length === 0) {
- $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);
- }
-
- if (targetsToShow.length) {
- $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);
- if (!config.axis_x_tick_values) {
- tickValues = $$.axis.updateXAxisTickValues(targetsToShow);
- }
- } else {
- $$.xAxis.tickValues([]);
- $$.subXAxis.tickValues([]);
- }
-
- if (config.zoom_rescale && !options.flow) {
- xDomainForZoom = $$.x.orgDomain();
- }
-
- $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));
- $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));
-
- if (!config.axis_y_tick_values && config.axis_y_tick_count) {
- $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count));
- }
- if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {
- $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count));
- }
-
- // axes
- $$.axis.redraw(transitions, hideAxis);
-
- // Update axis label
- $$.axis.updateLabels(withTransition);
-
- // show/hide if manual culling needed
- if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {
- if (config.axis_x_tick_culling && tickValues) {
- for (i = 1; i < tickValues.length; i++) {
- if (tickValues.length / i < config.axis_x_tick_culling_max) {
- intervalForCulling = i;
- break;
- }
- }
- $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {
- var index = tickValues.indexOf(e);
- if (index >= 0) {
- d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');
- }
- });
- } else {
- $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block');
- }
- }
-
- // setup drawer - MEMO: these must be called after axis updated
- drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined;
- drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;
- drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined;
- xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
- yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);
-
- // Update sub domain
- if (withY) {
- $$.subY.domain($$.getYDomain(targetsToShow, 'y'));
- $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));
- }
-
- // xgrid focus
- $$.updateXgridFocus();
-
- // Data empty label positioning and text.
- main.select("text." + CLASS.text + '.' + CLASS.empty)
- .attr("x", $$.width / 2)
- .attr("y", $$.height / 2)
- .text(config.data_empty_label_text)
- .transition()
- .style('opacity', targetsToShow.length ? 0 : 1);
-
- // grid
- $$.updateGrid(duration);
-
- // rect for regions
- $$.updateRegion(duration);
-
- // bars
- $$.updateBar(durationForExit);
-
- // lines, areas and cricles
- $$.updateLine(durationForExit);
- $$.updateArea(durationForExit);
- $$.updateCircle();
-
- // text
- if ($$.hasDataLabel()) {
- $$.updateText(durationForExit);
- }
-
- // title
- if ($$.redrawTitle) { $$.redrawTitle(); }
-
- // arc
- if ($$.redrawArc) { $$.redrawArc(duration, durationForExit, withTransform); }
-
- // subchart
- if ($$.redrawSubchart) {
- $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);
- }
-
- // circles for select
- main.selectAll('.' + CLASS.selectedCircles)
- .filter($$.isBarType.bind($$))
- .selectAll('circle')
- .remove();
-
- // event rects will redrawn when flow called
- if (config.interaction_enabled && !options.flow && withEventRect) {
- $$.redrawEventRect();
- if ($$.updateZoom) { $$.updateZoom(); }
- }
-
- // update circleY based on updated parameters
- $$.updateCircleY();
-
- // generate circle x/y functions depending on updated params
- cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
- cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);
-
- if (options.flow) {
- flow = $$.generateFlow({
- targets: targetsToShow,
- flow: options.flow,
- duration: options.flow.duration,
- drawBar: drawBar,
- drawLine: drawLine,
- drawArea: drawArea,
- cx: cx,
- cy: cy,
- xv: xv,
- xForText: xForText,
- yForText: yForText
- });
- }
-
- if ((duration || flow) && $$.isTabVisible()) { // Only use transition if tab visible. See #938.
- // transition should be derived from one transition
- d3.transition().duration(duration).each(function () {
- var transitionsToWait = [];
-
- // redraw and gather transitions
- [
- $$.redrawBar(drawBar, true),
- $$.redrawLine(drawLine, true),
- $$.redrawArea(drawArea, true),
- $$.redrawCircle(cx, cy, true),
- $$.redrawText(xForText, yForText, options.flow, true),
- $$.redrawRegion(true),
- $$.redrawGrid(true),
- ].forEach(function (transitions) {
- transitions.forEach(function (transition) {
- transitionsToWait.push(transition);
- });
- });
-
- // Wait for end of transitions to call flow and onrendered callback
- waitForDraw = $$.generateWait();
- transitionsToWait.forEach(function (t) {
- waitForDraw.add(t);
- });
- })
- .call(waitForDraw, function () {
- if (flow) {
- flow();
- }
- if (config.onrendered) {
- config.onrendered.call($$);
- }
- });
- }
- else {
- $$.redrawBar(drawBar);
- $$.redrawLine(drawLine);
- $$.redrawArea(drawArea);
- $$.redrawCircle(cx, cy);
- $$.redrawText(xForText, yForText, options.flow);
- $$.redrawRegion();
- $$.redrawGrid();
- if (config.onrendered) {
- config.onrendered.call($$);
- }
- }
-
- // update fadein condition
- $$.mapToIds($$.data.targets).forEach(function (id) {
- $$.withoutFadeIn[id] = true;
- });
- };
-
- c3_chart_internal_fn.updateAndRedraw = function (options) {
- var $$ = this, config = $$.config, transitions;
- options = options || {};
- // same with redraw
- options.withTransition = getOption(options, "withTransition", true);
- options.withTransform = getOption(options, "withTransform", false);
- options.withLegend = getOption(options, "withLegend", false);
- // NOT same with redraw
- options.withUpdateXDomain = true;
- options.withUpdateOrgXDomain = true;
- options.withTransitionForExit = false;
- options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition);
- // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)
- $$.updateSizes();
- // MEMO: called in updateLegend in redraw if withLegend
- if (!(options.withLegend && config.legend_show)) {
- transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0);
- // Update scales
- $$.updateScales();
- $$.updateSvgSize();
- // Update g positions
- $$.transformAll(options.withTransitionForTransform, transitions);
- }
- // Draw with new sizes & scales
- $$.redraw(options, transitions);
- };
- c3_chart_internal_fn.redrawWithoutRescale = function () {
- this.redraw({
- withY: false,
- withSubchart: false,
- withEventRect: false,
- withTransitionForAxis: false
- });
- };
-
- c3_chart_internal_fn.isTimeSeries = function () {
- return this.config.axis_x_type === 'timeseries';
- };
- c3_chart_internal_fn.isCategorized = function () {
- return this.config.axis_x_type.indexOf('categor') >= 0;
- };
- c3_chart_internal_fn.isCustomX = function () {
- var $$ = this, config = $$.config;
- return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));
- };
-
- c3_chart_internal_fn.isTimeSeriesY = function () {
- return this.config.axis_y_type === 'timeseries';
- };
-
- c3_chart_internal_fn.getTranslate = function (target) {
- var $$ = this, config = $$.config, x, y;
- if (target === 'main') {
- x = asHalfPixel($$.margin.left);
- y = asHalfPixel($$.margin.top);
- } else if (target === 'context') {
- x = asHalfPixel($$.margin2.left);
- y = asHalfPixel($$.margin2.top);
- } else if (target === 'legend') {
- x = $$.margin3.left;
- y = $$.margin3.top;
- } else if (target === 'x') {
- x = 0;
- y = config.axis_rotated ? 0 : $$.height;
- } else if (target === 'y') {
- x = 0;
- y = config.axis_rotated ? $$.height : 0;
- } else if (target === 'y2') {
- x = config.axis_rotated ? 0 : $$.width;
- y = config.axis_rotated ? 1 : 0;
- } else if (target === 'subx') {
- x = 0;
- y = config.axis_rotated ? 0 : $$.height2;
- } else if (target === 'arc') {
- x = $$.arcWidth / 2;
- y = $$.arcHeight / 2;
- }
- return "translate(" + x + "," + y + ")";
- };
- c3_chart_internal_fn.initialOpacity = function (d) {
- return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;
- };
- c3_chart_internal_fn.initialOpacityForCircle = function (d) {
- return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0;
- };
- c3_chart_internal_fn.opacityForCircle = function (d) {
- var opacity = this.config.point_show ? 1 : 0;
- return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0;
- };
- c3_chart_internal_fn.opacityForText = function () {
- return this.hasDataLabel() ? 1 : 0;
- };
- c3_chart_internal_fn.xx = function (d) {
- return d ? this.x(d.x) : null;
- };
- c3_chart_internal_fn.xv = function (d) {
- var $$ = this, value = d.value;
- if ($$.isTimeSeries()) {
- value = $$.parseDate(d.value);
- }
- else if ($$.isCategorized() && typeof d.value === 'string') {
- value = $$.config.axis_x_categories.indexOf(d.value);
- }
- return Math.ceil($$.x(value));
- };
- c3_chart_internal_fn.yv = function (d) {
- var $$ = this,
- yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;
- return Math.ceil(yScale(d.value));
- };
- c3_chart_internal_fn.subxx = function (d) {
- return d ? this.subX(d.x) : null;
- };
-
- c3_chart_internal_fn.transformMain = function (withTransition, transitions) {
- var $$ = this,
- xAxis, yAxis, y2Axis;
- if (transitions && transitions.axisX) {
- xAxis = transitions.axisX;
- } else {
- xAxis = $$.main.select('.' + CLASS.axisX);
- if (withTransition) { xAxis = xAxis.transition(); }
- }
- if (transitions && transitions.axisY) {
- yAxis = transitions.axisY;
- } else {
- yAxis = $$.main.select('.' + CLASS.axisY);
- if (withTransition) { yAxis = yAxis.transition(); }
- }
- if (transitions && transitions.axisY2) {
- y2Axis = transitions.axisY2;
- } else {
- y2Axis = $$.main.select('.' + CLASS.axisY2);
- if (withTransition) { y2Axis = y2Axis.transition(); }
- }
- (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main'));
- xAxis.attr("transform", $$.getTranslate('x'));
- yAxis.attr("transform", $$.getTranslate('y'));
- y2Axis.attr("transform", $$.getTranslate('y2'));
- $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
- };
- c3_chart_internal_fn.transformAll = function (withTransition, transitions) {
- var $$ = this;
- $$.transformMain(withTransition, transitions);
- if ($$.config.subchart_show) { $$.transformContext(withTransition, transitions); }
- if ($$.legend) { $$.transformLegend(withTransition); }
- };
-
- c3_chart_internal_fn.updateSvgSize = function () {
- var $$ = this,
- brush = $$.svg.select(".c3-brush .background");
- $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
- $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect')
- .attr('width', $$.width)
- .attr('height', $$.height);
- $$.svg.select('#' + $$.clipIdForXAxis).select('rect')
- .attr('x', $$.getXAxisClipX.bind($$))
- .attr('y', $$.getXAxisClipY.bind($$))
- .attr('width', $$.getXAxisClipWidth.bind($$))
- .attr('height', $$.getXAxisClipHeight.bind($$));
- $$.svg.select('#' + $$.clipIdForYAxis).select('rect')
- .attr('x', $$.getYAxisClipX.bind($$))
- .attr('y', $$.getYAxisClipY.bind($$))
- .attr('width', $$.getYAxisClipWidth.bind($$))
- .attr('height', $$.getYAxisClipHeight.bind($$));
- $$.svg.select('#' + $$.clipIdForSubchart).select('rect')
- .attr('width', $$.width)
- .attr('height', brush.size() ? brush.attr('height') : 0);
- $$.svg.select('.' + CLASS.zoomRect)
- .attr('width', $$.width)
- .attr('height', $$.height);
- // MEMO: parent div's height will be bigger than svg when
- $$.selectChart.style('max-height', $$.currentHeight + "px");
- };
-
-
- c3_chart_internal_fn.updateDimension = function (withoutAxis) {
- var $$ = this;
- if (!withoutAxis) {
- if ($$.config.axis_rotated) {
- $$.axes.x.call($$.xAxis);
- $$.axes.subx.call($$.subXAxis);
- } else {
- $$.axes.y.call($$.yAxis);
- $$.axes.y2.call($$.y2Axis);
- }
- }
- $$.updateSizes();
- $$.updateScales();
- $$.updateSvgSize();
- $$.transformAll(false);
- };
-
- c3_chart_internal_fn.observeInserted = function (selection) {
- var $$ = this, observer;
- if (typeof MutationObserver === 'undefined') {
- window.console.error("MutationObserver not defined.");
- return;
- }
- observer= new MutationObserver(function (mutations) {
- mutations.forEach(function (mutation) {
- if (mutation.type === 'childList' && mutation.previousSibling) {
- observer.disconnect();
- // need to wait for completion of load because size calculation requires the actual sizes determined after that completion
- $$.intervalForObserveInserted = window.setInterval(function () {
- // parentNode will NOT be null when completed
- if (selection.node().parentNode) {
- window.clearInterval($$.intervalForObserveInserted);
- $$.updateDimension();
- if ($$.brush) { $$.brush.update(); }
- $$.config.oninit.call($$);
- $$.redraw({
- withTransform: true,
- withUpdateXDomain: true,
- withUpdateOrgXDomain: true,
- withTransition: false,
- withTransitionForTransform: false,
- withLegend: true
- });
- selection.transition().style('opacity', 1);
- }
- }, 10);
- }
- });
- });
- observer.observe(selection.node(), {attributes: true, childList: true, characterData: true});
- };
-
- c3_chart_internal_fn.bindResize = function () {
- var $$ = this, config = $$.config;
-
- $$.resizeFunction = $$.generateResize();
-
- $$.resizeFunction.add(function () {
- config.onresize.call($$);
- });
- if (config.resize_auto) {
- $$.resizeFunction.add(function () {
- if ($$.resizeTimeout !== undefined) {
- window.clearTimeout($$.resizeTimeout);
- }
- $$.resizeTimeout = window.setTimeout(function () {
- delete $$.resizeTimeout;
- $$.api.flush();
- }, 100);
- });
- }
- $$.resizeFunction.add(function () {
- config.onresized.call($$);
- });
-
- if (window.attachEvent) {
- window.attachEvent('onresize', $$.resizeFunction);
- } else if (window.addEventListener) {
- window.addEventListener('resize', $$.resizeFunction, false);
- } else {
- // fallback to this, if this is a very old browser
- var wrapper = window.onresize;
- if (!wrapper) {
- // create a wrapper that will call all charts
- wrapper = $$.generateResize();
- } else if (!wrapper.add || !wrapper.remove) {
- // there is already a handler registered, make sure we call it too
- wrapper = $$.generateResize();
- wrapper.add(window.onresize);
- }
- // add this graph to the wrapper, we will be removed if the user calls destroy
- wrapper.add($$.resizeFunction);
- window.onresize = wrapper;
- }
- };
-
- c3_chart_internal_fn.generateResize = function () {
- var resizeFunctions = [];
- function callResizeFunctions() {
- resizeFunctions.forEach(function (f) {
- f();
- });
- }
- callResizeFunctions.add = function (f) {
- resizeFunctions.push(f);
- };
- callResizeFunctions.remove = function (f) {
- for (var i = 0; i < resizeFunctions.length; i++) {
- if (resizeFunctions[i] === f) {
- resizeFunctions.splice(i, 1);
- break;
- }
- }
- };
- return callResizeFunctions;
- };
-
- c3_chart_internal_fn.endall = function (transition, callback) {
- var n = 0;
- transition
- .each(function () { ++n; })
- .each("end", function () {
- if (!--n) { callback.apply(this, arguments); }
- });
- };
- c3_chart_internal_fn.generateWait = function () {
- var transitionsToWait = [],
- f = function (transition, callback) {
- var timer = setInterval(function () {
- var done = 0;
- transitionsToWait.forEach(function (t) {
- if (t.empty()) {
- done += 1;
- return;
- }
- try {
- t.transition();
- } catch (e) {
- done += 1;
- }
- });
- if (done === transitionsToWait.length) {
- clearInterval(timer);
- if (callback) { callback(); }
- }
- }, 10);
- };
- f.add = function (transition) {
- transitionsToWait.push(transition);
- };
- return f;
- };
-
- c3_chart_internal_fn.parseDate = function (date) {
- var $$ = this, parsedDate;
- if (date instanceof Date) {
- parsedDate = date;
- } else if (typeof date === 'string') {
- parsedDate = $$.dataTimeFormat($$.config.data_xFormat).parse(date);
- } else if (typeof date === 'number' && !isNaN(date)) {
- parsedDate = new Date(+date);
- }
- if (!parsedDate || isNaN(+parsedDate)) {
- window.console.error("Failed to parse x '" + date + "' to Date object");
- }
- return parsedDate;
- };
-
- c3_chart_internal_fn.isTabVisible = function () {
- var hidden;
- if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
- hidden = "hidden";
- } else if (typeof document.mozHidden !== "undefined") {
- hidden = "mozHidden";
- } else if (typeof document.msHidden !== "undefined") {
- hidden = "msHidden";
- } else if (typeof document.webkitHidden !== "undefined") {
- hidden = "webkitHidden";
- }
-
- return document[hidden] ? false : true;
- };
-
- c3_chart_internal_fn.getDefaultConfig = function () {
- var config = {
- bindto: '#chart',
- svg_classname: undefined,
- size_width: undefined,
- size_height: undefined,
- padding_left: undefined,
- padding_right: undefined,
- padding_top: undefined,
- padding_bottom: undefined,
- resize_auto: true,
- zoom_enabled: false,
- zoom_extent: undefined,
- zoom_privileged: false,
- zoom_rescale: false,
- zoom_onzoom: function () {},
- zoom_onzoomstart: function () {},
- zoom_onzoomend: function () {},
- zoom_x_min: undefined,
- zoom_x_max: undefined,
- interaction_brighten: true,
- interaction_enabled: true,
- onmouseover: function () {},
- onmouseout: function () {},
- onresize: function () {},
- onresized: function () {},
- oninit: function () {},
- onrendered: function () {},
- transition_duration: 350,
- data_x: undefined,
- data_xs: {},
- data_xFormat: '%Y-%m-%d',
- data_xLocaltime: true,
- data_xSort: true,
- data_idConverter: function (id) { return id; },
- data_names: {},
- data_classes: {},
- data_groups: [],
- data_axes: {},
- data_type: undefined,
- data_types: {},
- data_labels: {},
- data_order: 'desc',
- data_regions: {},
- data_color: undefined,
- data_colors: {},
- data_hide: false,
- data_filter: undefined,
- data_selection_enabled: false,
- data_selection_grouped: false,
- data_selection_isselectable: function () { return true; },
- data_selection_multiple: true,
- data_selection_draggable: false,
- data_onclick: function () {},
- data_onmouseover: function () {},
- data_onmouseout: function () {},
- data_onselected: function () {},
- data_onunselected: function () {},
- data_url: undefined,
- data_headers: undefined,
- data_json: undefined,
- data_rows: undefined,
- data_columns: undefined,
- data_mimeType: undefined,
- data_keys: undefined,
- // configuration for no plot-able data supplied.
- data_empty_label_text: "",
- // subchart
- subchart_show: false,
- subchart_size_height: 60,
- subchart_axis_x_show: true,
- subchart_onbrush: function () {},
- // color
- color_pattern: [],
- color_threshold: {},
- // legend
- legend_show: true,
- legend_hide: false,
- legend_position: 'bottom',
- legend_inset_anchor: 'top-left',
- legend_inset_x: 10,
- legend_inset_y: 0,
- legend_inset_step: undefined,
- legend_item_onclick: undefined,
- legend_item_onmouseover: undefined,
- legend_item_onmouseout: undefined,
- legend_equally: false,
- legend_padding: 0,
- legend_item_tile_width: 10,
- legend_item_tile_height: 10,
- // axis
- axis_rotated: false,
- axis_x_show: true,
- axis_x_type: 'indexed',
- axis_x_localtime: true,
- axis_x_categories: [],
- axis_x_tick_centered: false,
- axis_x_tick_format: undefined,
- axis_x_tick_culling: {},
- axis_x_tick_culling_max: 10,
- axis_x_tick_count: undefined,
- axis_x_tick_fit: true,
- axis_x_tick_values: null,
- axis_x_tick_rotate: 0,
- axis_x_tick_outer: true,
- axis_x_tick_multiline: true,
- axis_x_tick_width: null,
- axis_x_max: undefined,
- axis_x_min: undefined,
- axis_x_padding: {},
- axis_x_height: undefined,
- axis_x_extent: undefined,
- axis_x_label: {},
- axis_y_show: true,
- axis_y_type: undefined,
- axis_y_max: undefined,
- axis_y_min: undefined,
- axis_y_inverted: false,
- axis_y_center: undefined,
- axis_y_inner: undefined,
- axis_y_label: {},
- axis_y_tick_format: undefined,
- axis_y_tick_outer: true,
- axis_y_tick_values: null,
- axis_y_tick_rotate: 0,
- axis_y_tick_count: undefined,
- axis_y_tick_time_value: undefined,
- axis_y_tick_time_interval: undefined,
- axis_y_padding: {},
- axis_y_default: undefined,
- axis_y2_show: false,
- axis_y2_max: undefined,
- axis_y2_min: undefined,
- axis_y2_inverted: false,
- axis_y2_center: undefined,
- axis_y2_inner: undefined,
- axis_y2_label: {},
- axis_y2_tick_format: undefined,
- axis_y2_tick_outer: true,
- axis_y2_tick_values: null,
- axis_y2_tick_count: undefined,
- axis_y2_padding: {},
- axis_y2_default: undefined,
- // grid
- grid_x_show: false,
- grid_x_type: 'tick',
- grid_x_lines: [],
- grid_y_show: false,
- // not used
- // grid_y_type: 'tick',
- grid_y_lines: [],
- grid_y_ticks: 10,
- grid_focus_show: true,
- grid_lines_front: true,
- // point - point of each data
- point_show: true,
- point_r: 2.5,
- point_sensitivity: 10,
- point_focus_expand_enabled: true,
- point_focus_expand_r: undefined,
- point_select_r: undefined,
- // line
- line_connectNull: false,
- line_step_type: 'step',
- // bar
- bar_width: undefined,
- bar_width_ratio: 0.6,
- bar_width_max: undefined,
- bar_zerobased: true,
- // area
- area_zerobased: true,
- area_above: false,
- // pie
- pie_label_show: true,
- pie_label_format: undefined,
- pie_label_threshold: 0.05,
- pie_label_ratio: undefined,
- pie_expand: {},
- pie_expand_duration: 50,
- // gauge
- gauge_fullCircle: false,
- gauge_label_show: true,
- gauge_label_format: undefined,
- gauge_min: 0,
- gauge_max: 100,
- gauge_startingAngle: -1 * Math.PI/2,
- gauge_units: undefined,
- gauge_width: undefined,
- gauge_expand: {},
- gauge_expand_duration: 50,
- // donut
- donut_label_show: true,
- donut_label_format: undefined,
- donut_label_threshold: 0.05,
- donut_label_ratio: undefined,
- donut_width: undefined,
- donut_title: "",
- donut_expand: {},
- donut_expand_duration: 50,
- // spline
- spline_interpolation_type: 'cardinal',
- // region - region to change style
- regions: [],
- // tooltip - show when mouseover on each data
- tooltip_show: true,
- tooltip_grouped: true,
- tooltip_format_title: undefined,
- tooltip_format_name: undefined,
- tooltip_format_value: undefined,
- tooltip_position: undefined,
- tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
- return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
- },
- tooltip_init_show: false,
- tooltip_init_x: 0,
- tooltip_init_position: {top: '0px', left: '50px'},
- tooltip_onshow: function () {},
- tooltip_onhide: function () {},
- // title
- title_text: undefined,
- title_padding: {
- top: 0,
- right: 0,
- bottom: 0,
- left: 0
- },
- title_position: 'top-center',
- };
-
- Object.keys(this.additionalConfig).forEach(function (key) {
- config[key] = this.additionalConfig[key];
- }, this);
-
- return config;
- };
- c3_chart_internal_fn.additionalConfig = {};
-
- c3_chart_internal_fn.loadConfig = function (config) {
- var this_config = this.config, target, keys, read;
- function find() {
- var key = keys.shift();
- // console.log("key =>", key, ", target =>", target);
- if (key && target && typeof target === 'object' && key in target) {
- target = target[key];
- return find();
- }
- else if (!key) {
- return target;
- }
- else {
- return undefined;
- }
- }
- Object.keys(this_config).forEach(function (key) {
- target = config;
- keys = key.split('_');
- read = find();
- // console.log("CONFIG : ", key, read);
- if (isDefined(read)) {
- this_config[key] = read;
- }
- });
- };
-
- c3_chart_internal_fn.getScale = function (min, max, forTimeseries) {
- return (forTimeseries ? this.d3.time.scale() : this.d3.scale.linear()).range([min, max]);
- };
- c3_chart_internal_fn.getX = function (min, max, domain, offset) {
- var $$ = this,
- scale = $$.getScale(min, max, $$.isTimeSeries()),
- _scale = domain ? scale.domain(domain) : scale, key;
- // Define customized scale if categorized axis
- if ($$.isCategorized()) {
- offset = offset || function () { return 0; };
- scale = function (d, raw) {
- var v = _scale(d) + offset(d);
- return raw ? v : Math.ceil(v);
- };
- } else {
- scale = function (d, raw) {
- var v = _scale(d);
- return raw ? v : Math.ceil(v);
- };
- }
- // define functions
- for (key in _scale) {
- scale[key] = _scale[key];
- }
- scale.orgDomain = function () {
- return _scale.domain();
- };
- // define custom domain() for categorized axis
- if ($$.isCategorized()) {
- scale.domain = function (domain) {
- if (!arguments.length) {
- domain = this.orgDomain();
- return [domain[0], domain[1] + 1];
- }
- _scale.domain(domain);
- return scale;
- };
- }
- return scale;
- };
- c3_chart_internal_fn.getY = function (min, max, domain) {
- var scale = this.getScale(min, max, this.isTimeSeriesY());
- if (domain) { scale.domain(domain); }
- return scale;
- };
- c3_chart_internal_fn.getYScale = function (id) {
- return this.axis.getId(id) === 'y2' ? this.y2 : this.y;
- };
- c3_chart_internal_fn.getSubYScale = function (id) {
- return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY;
- };
- c3_chart_internal_fn.updateScales = function () {
- var $$ = this, config = $$.config,
- forInit = !$$.x;
- // update edges
- $$.xMin = config.axis_rotated ? 1 : 0;
- $$.xMax = config.axis_rotated ? $$.height : $$.width;
- $$.yMin = config.axis_rotated ? 0 : $$.height;
- $$.yMax = config.axis_rotated ? $$.width : 1;
- $$.subXMin = $$.xMin;
- $$.subXMax = $$.xMax;
- $$.subYMin = config.axis_rotated ? 0 : $$.height2;
- $$.subYMax = config.axis_rotated ? $$.width2 : 1;
- // update scales
- $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () { return $$.xAxis.tickOffset(); });
- $$.y = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y_default : $$.y.domain());
- $$.y2 = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y2_default : $$.y2.domain());
- $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) { return d % 1 ? 0 : $$.subXAxis.tickOffset(); });
- $$.subY = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y_default : $$.subY.domain());
- $$.subY2 = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y2_default : $$.subY2.domain());
- // update axes
- $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();
- $$.xAxisTickValues = $$.axis.getXAxisTickValues();
- $$.yAxisTickValues = $$.axis.getYAxisTickValues();
- $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();
-
- $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
- $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
- $$.yAxis = $$.axis.getYAxis($$.y, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, config.axis_y_tick_outer);
- $$.y2Axis = $$.axis.getYAxis($$.y2, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, config.axis_y2_tick_outer);
-
- // Set initialized scales to brush and zoom
- if (!forInit) {
- if ($$.brush) { $$.brush.scale($$.subX); }
- if (config.zoom_enabled) { $$.zoom.scale($$.x); }
- }
- // update for arc
- if ($$.updateArc) { $$.updateArc(); }
- };
-
- c3_chart_internal_fn.getYDomainMin = function (targets) {
- var $$ = this, config = $$.config,
- ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets),
- j, k, baseId, idsInGroup, id, hasNegativeValue;
- if (config.data_groups.length > 0) {
- hasNegativeValue = $$.hasNegativeValueInTargets(targets);
- for (j = 0; j < config.data_groups.length; j++) {
- // Determine baseId
- idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; });
- if (idsInGroup.length === 0) { continue; }
- baseId = idsInGroup[0];
- // Consider negative values
- if (hasNegativeValue && ys[baseId]) {
- ys[baseId].forEach(function (v, i) {
- ys[baseId][i] = v < 0 ? v : 0;
- });
- }
- // Compute min
- for (k = 1; k < idsInGroup.length; k++) {
- id = idsInGroup[k];
- if (! ys[id]) { continue; }
- ys[id].forEach(function (v, i) {
- if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) {
- ys[baseId][i] += +v;
- }
- });
- }
- }
- }
- return $$.d3.min(Object.keys(ys).map(function (key) { return $$.d3.min(ys[key]); }));
- };
- c3_chart_internal_fn.getYDomainMax = function (targets) {
- var $$ = this, config = $$.config,
- ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets),
- j, k, baseId, idsInGroup, id, hasPositiveValue;
- if (config.data_groups.length > 0) {
- hasPositiveValue = $$.hasPositiveValueInTargets(targets);
- for (j = 0; j < config.data_groups.length; j++) {
- // Determine baseId
- idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; });
- if (idsInGroup.length === 0) { continue; }
- baseId = idsInGroup[0];
- // Consider positive values
- if (hasPositiveValue && ys[baseId]) {
- ys[baseId].forEach(function (v, i) {
- ys[baseId][i] = v > 0 ? v : 0;
- });
- }
- // Compute max
- for (k = 1; k < idsInGroup.length; k++) {
- id = idsInGroup[k];
- if (! ys[id]) { continue; }
- ys[id].forEach(function (v, i) {
- if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) {
- ys[baseId][i] += +v;
- }
- });
- }
- }
- }
- return $$.d3.max(Object.keys(ys).map(function (key) { return $$.d3.max(ys[key]); }));
- };
- c3_chart_internal_fn.getYDomain = function (targets, axisId, xDomain) {
- var $$ = this, config = $$.config,
- targetsByAxisId = targets.filter(function (t) { return $$.axis.getId(t.id) === axisId; }),
- yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId,
- yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,
- yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,
- yDomainMin = $$.getYDomainMin(yTargets),
- yDomainMax = $$.getYDomainMax(yTargets),
- domain, domainLength, padding, padding_top, padding_bottom,
- center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,
- yDomainAbs, lengths, diff, ratio, isAllPositive, isAllNegative,
- isZeroBased = ($$.hasType('bar', yTargets) && config.bar_zerobased) || ($$.hasType('area', yTargets) && config.area_zerobased),
- isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,
- showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,
- showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;
-
- // MEMO: avoid inverting domain unexpectedly
- yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? (yDomainMin < yMax ? yDomainMin : yMax - 10) : yDomainMin;
- yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? (yMin < yDomainMax ? yDomainMax : yMin + 10) : yDomainMax;
-
- if (yTargets.length === 0) { // use current domain if target of axisId is none
- return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();
- }
- if (isNaN(yDomainMin)) { // set minimum to zero when not number
- yDomainMin = 0;
- }
- if (isNaN(yDomainMax)) { // set maximum to have same value as yDomainMin
- yDomainMax = yDomainMin;
- }
- if (yDomainMin === yDomainMax) {
- yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0;
- }
- isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;
- isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;
-
- // Cancel zerobased if axis_*_min / axis_*_max specified
- if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {
- isZeroBased = false;
- }
-
- // Bar/Area chart should be 0-based if all positive|negative
- if (isZeroBased) {
- if (isAllPositive) { yDomainMin = 0; }
- if (isAllNegative) { yDomainMax = 0; }
- }
-
- domainLength = Math.abs(yDomainMax - yDomainMin);
- padding = padding_top = padding_bottom = domainLength * 0.1;
-
- if (typeof center !== 'undefined') {
- yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));
- yDomainMax = center + yDomainAbs;
- yDomainMin = center - yDomainAbs;
- }
- // add padding for data label
- if (showHorizontalDataLabel) {
- lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');
- diff = diffDomain($$.y.range());
- ratio = [lengths[0] / diff, lengths[1] / diff];
- padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));
- padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));
- } else if (showVerticalDataLabel) {
- lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');
- padding_top += $$.axis.convertPixelsToAxisPadding(lengths[1], domainLength);
- padding_bottom += $$.axis.convertPixelsToAxisPadding(lengths[0], domainLength);
- }
- if (axisId === 'y' && notEmpty(config.axis_y_padding)) {
- padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength);
- padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength);
- }
- if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {
- padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength);
- padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength);
- }
- // Bar/Area chart should be 0-based if all positive|negative
- if (isZeroBased) {
- if (isAllPositive) { padding_bottom = yDomainMin; }
- if (isAllNegative) { padding_top = -yDomainMax; }
- }
- domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];
- return isInverted ? domain.reverse() : domain;
- };
- c3_chart_internal_fn.getXDomainMin = function (targets) {
- var $$ = this, config = $$.config;
- return isDefined(config.axis_x_min) ?
- ($$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min) :
- $$.d3.min(targets, function (t) { return $$.d3.min(t.values, function (v) { return v.x; }); });
- };
- c3_chart_internal_fn.getXDomainMax = function (targets) {
- var $$ = this, config = $$.config;
- return isDefined(config.axis_x_max) ?
- ($$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max) :
- $$.d3.max(targets, function (t) { return $$.d3.max(t.values, function (v) { return v.x; }); });
- };
- c3_chart_internal_fn.getXDomainPadding = function (domain) {
- var $$ = this, config = $$.config,
- diff = domain[1] - domain[0],
- maxDataCount, padding, paddingLeft, paddingRight;
- if ($$.isCategorized()) {
- padding = 0;
- } else if ($$.hasType('bar')) {
- maxDataCount = $$.getMaxDataCount();
- padding = maxDataCount > 1 ? (diff / (maxDataCount - 1)) / 2 : 0.5;
- } else {
- padding = diff * 0.01;
- }
- if (typeof config.axis_x_padding === 'object' && notEmpty(config.axis_x_padding)) {
- paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding;
- paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding;
- } else if (typeof config.axis_x_padding === 'number') {
- paddingLeft = paddingRight = config.axis_x_padding;
- } else {
- paddingLeft = paddingRight = padding;
- }
- return {left: paddingLeft, right: paddingRight};
- };
- c3_chart_internal_fn.getXDomain = function (targets) {
- var $$ = this,
- xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],
- firstX = xDomain[0], lastX = xDomain[1],
- padding = $$.getXDomainPadding(xDomain),
- min = 0, max = 0;
- // show center of x domain if min and max are the same
- if ((firstX - lastX) === 0 && !$$.isCategorized()) {
- if ($$.isTimeSeries()) {
- firstX = new Date(firstX.getTime() * 0.5);
- lastX = new Date(lastX.getTime() * 1.5);
- } else {
- firstX = firstX === 0 ? 1 : (firstX * 0.5);
- lastX = lastX === 0 ? -1 : (lastX * 1.5);
- }
- }
- if (firstX || firstX === 0) {
- min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;
- }
- if (lastX || lastX === 0) {
- max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right;
- }
- return [min, max];
- };
- c3_chart_internal_fn.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {
- var $$ = this, config = $$.config;
-
- if (withUpdateOrgXDomain) {
- $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));
- $$.orgXDomain = $$.x.domain();
- if (config.zoom_enabled) { $$.zoom.scale($$.x).updateScaleExtent(); }
- $$.subX.domain($$.x.domain());
- if ($$.brush) { $$.brush.scale($$.subX); }
- }
- if (withUpdateXDomain) {
- $$.x.domain(domain ? domain : (!$$.brush || $$.brush.empty()) ? $$.orgXDomain : $$.brush.extent());
- if (config.zoom_enabled) { $$.zoom.scale($$.x).updateScaleExtent(); }
- }
-
- // Trim domain when too big by zoom mousemove event
- if (withTrim) { $$.x.domain($$.trimXDomain($$.x.orgDomain())); }
-
- return $$.x.domain();
- };
- c3_chart_internal_fn.trimXDomain = function (domain) {
- var zoomDomain = this.getZoomDomain(),
- min = zoomDomain[0], max = zoomDomain[1];
- if (domain[0] <= min) {
- domain[1] = +domain[1] + (min - domain[0]);
- domain[0] = min;
- }
- if (max <= domain[1]) {
- domain[0] = +domain[0] - (domain[1] - max);
- domain[1] = max;
- }
- return domain;
- };
-
- c3_chart_internal_fn.isX = function (key) {
- var $$ = this, config = $$.config;
- return (config.data_x && key === config.data_x) || (notEmpty(config.data_xs) && hasValue(config.data_xs, key));
- };
- c3_chart_internal_fn.isNotX = function (key) {
- return !this.isX(key);
- };
- c3_chart_internal_fn.getXKey = function (id) {
- var $$ = this, config = $$.config;
- return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null;
- };
- c3_chart_internal_fn.getXValuesOfXKey = function (key, targets) {
- var $$ = this,
- xValues, ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];
- ids.forEach(function (id) {
- if ($$.getXKey(id) === key) {
- xValues = $$.data.xs[id];
- }
- });
- return xValues;
- };
- c3_chart_internal_fn.getIndexByX = function (x) {
- var $$ = this,
- data = $$.filterByX($$.data.targets, x);
- return data.length ? data[0].index : null;
- };
- c3_chart_internal_fn.getXValue = function (id, i) {
- var $$ = this;
- return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
- };
- c3_chart_internal_fn.getOtherTargetXs = function () {
- var $$ = this,
- idsForX = Object.keys($$.data.xs);
- return idsForX.length ? $$.data.xs[idsForX[0]] : null;
- };
- c3_chart_internal_fn.getOtherTargetX = function (index) {
- var xs = this.getOtherTargetXs();
- return xs && index < xs.length ? xs[index] : null;
- };
- c3_chart_internal_fn.addXs = function (xs) {
- var $$ = this;
- Object.keys(xs).forEach(function (id) {
- $$.config.data_xs[id] = xs[id];
- });
- };
- c3_chart_internal_fn.hasMultipleX = function (xs) {
- return this.d3.set(Object.keys(xs).map(function (id) { return xs[id]; })).size() > 1;
- };
- c3_chart_internal_fn.isMultipleX = function () {
- return notEmpty(this.config.data_xs) || !this.config.data_xSort || this.hasType('scatter');
- };
- c3_chart_internal_fn.addName = function (data) {
- var $$ = this, name;
- if (data) {
- name = $$.config.data_names[data.id];
- data.name = name !== undefined ? name : data.id;
- }
- return data;
- };
- c3_chart_internal_fn.getValueOnIndex = function (values, index) {
- var valueOnIndex = values.filter(function (v) { return v.index === index; });
- return valueOnIndex.length ? valueOnIndex[0] : null;
- };
- c3_chart_internal_fn.updateTargetX = function (targets, x) {
- var $$ = this;
- targets.forEach(function (t) {
- t.values.forEach(function (v, i) {
- v.x = $$.generateTargetX(x[i], t.id, i);
- });
- $$.data.xs[t.id] = x;
- });
- };
- c3_chart_internal_fn.updateTargetXs = function (targets, xs) {
- var $$ = this;
- targets.forEach(function (t) {
- if (xs[t.id]) {
- $$.updateTargetX([t], xs[t.id]);
- }
- });
- };
- c3_chart_internal_fn.generateTargetX = function (rawX, id, index) {
- var $$ = this, x;
- if ($$.isTimeSeries()) {
- x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));
- }
- else if ($$.isCustomX() && !$$.isCategorized()) {
- x = isValue(rawX) ? +rawX : $$.getXValue(id, index);
- }
- else {
- x = index;
- }
- return x;
- };
- c3_chart_internal_fn.cloneTarget = function (target) {
- return {
- id : target.id,
- id_org : target.id_org,
- values : target.values.map(function (d) {
- return {x: d.x, value: d.value, id: d.id};
- })
- };
- };
- c3_chart_internal_fn.updateXs = function () {
- var $$ = this;
- if ($$.data.targets.length) {
- $$.xs = [];
- $$.data.targets[0].values.forEach(function (v) {
- $$.xs[v.index] = v.x;
- });
- }
- };
- c3_chart_internal_fn.getPrevX = function (i) {
- var x = this.xs[i - 1];
- return typeof x !== 'undefined' ? x : null;
- };
- c3_chart_internal_fn.getNextX = function (i) {
- var x = this.xs[i + 1];
- return typeof x !== 'undefined' ? x : null;
- };
- c3_chart_internal_fn.getMaxDataCount = function () {
- var $$ = this;
- return $$.d3.max($$.data.targets, function (t) { return t.values.length; });
- };
- c3_chart_internal_fn.getMaxDataCountTarget = function (targets) {
- var length = targets.length, max = 0, maxTarget;
- if (length > 1) {
- targets.forEach(function (t) {
- if (t.values.length > max) {
- maxTarget = t;
- max = t.values.length;
- }
- });
- } else {
- maxTarget = length ? targets[0] : null;
- }
- return maxTarget;
- };
- c3_chart_internal_fn.getEdgeX = function (targets) {
- var $$ = this;
- return !targets.length ? [0, 0] : [
- $$.d3.min(targets, function (t) { return t.values[0].x; }),
- $$.d3.max(targets, function (t) { return t.values[t.values.length - 1].x; })
- ];
- };
- c3_chart_internal_fn.mapToIds = function (targets) {
- return targets.map(function (d) { return d.id; });
- };
- c3_chart_internal_fn.mapToTargetIds = function (ids) {
- var $$ = this;
- return ids ? [].concat(ids) : $$.mapToIds($$.data.targets);
- };
- c3_chart_internal_fn.hasTarget = function (targets, id) {
- var ids = this.mapToIds(targets), i;
- for (i = 0; i < ids.length; i++) {
- if (ids[i] === id) {
- return true;
- }
- }
- return false;
- };
- c3_chart_internal_fn.isTargetToShow = function (targetId) {
- return this.hiddenTargetIds.indexOf(targetId) < 0;
- };
- c3_chart_internal_fn.isLegendToShow = function (targetId) {
- return this.hiddenLegendIds.indexOf(targetId) < 0;
- };
- c3_chart_internal_fn.filterTargetsToShow = function (targets) {
- var $$ = this;
- return targets.filter(function (t) { return $$.isTargetToShow(t.id); });
- };
- c3_chart_internal_fn.mapTargetsToUniqueXs = function (targets) {
- var $$ = this;
- var xs = $$.d3.set($$.d3.merge(targets.map(function (t) { return t.values.map(function (v) { return +v.x; }); }))).values();
- xs = $$.isTimeSeries() ? xs.map(function (x) { return new Date(+x); }) : xs.map(function (x) { return +x; });
- return xs.sort(function (a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; });
- };
- c3_chart_internal_fn.addHiddenTargetIds = function (targetIds) {
- this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds);
- };
- c3_chart_internal_fn.removeHiddenTargetIds = function (targetIds) {
- this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) { return targetIds.indexOf(id) < 0; });
- };
- c3_chart_internal_fn.addHiddenLegendIds = function (targetIds) {
- this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds);
- };
- c3_chart_internal_fn.removeHiddenLegendIds = function (targetIds) {
- this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) { return targetIds.indexOf(id) < 0; });
- };
- c3_chart_internal_fn.getValuesAsIdKeyed = function (targets) {
- var ys = {};
- targets.forEach(function (t) {
- ys[t.id] = [];
- t.values.forEach(function (v) {
- ys[t.id].push(v.value);
- });
- });
- return ys;
- };
- c3_chart_internal_fn.checkValueInTargets = function (targets, checker) {
- var ids = Object.keys(targets), i, j, values;
- for (i = 0; i < ids.length; i++) {
- values = targets[ids[i]].values;
- for (j = 0; j < values.length; j++) {
- if (checker(values[j].value)) {
- return true;
- }
- }
- }
- return false;
- };
- c3_chart_internal_fn.hasNegativeValueInTargets = function (targets) {
- return this.checkValueInTargets(targets, function (v) { return v < 0; });
- };
- c3_chart_internal_fn.hasPositiveValueInTargets = function (targets) {
- return this.checkValueInTargets(targets, function (v) { return v > 0; });
- };
- c3_chart_internal_fn.isOrderDesc = function () {
- var config = this.config;
- return typeof(config.data_order) === 'string' && config.data_order.toLowerCase() === 'desc';
- };
- c3_chart_internal_fn.isOrderAsc = function () {
- var config = this.config;
- return typeof(config.data_order) === 'string' && config.data_order.toLowerCase() === 'asc';
- };
- c3_chart_internal_fn.orderTargets = function (targets) {
- var $$ = this, config = $$.config, orderAsc = $$.isOrderAsc(), orderDesc = $$.isOrderDesc();
- if (orderAsc || orderDesc) {
- targets.sort(function (t1, t2) {
- var reducer = function (p, c) { return p + Math.abs(c.value); };
- var t1Sum = t1.values.reduce(reducer, 0),
- t2Sum = t2.values.reduce(reducer, 0);
- return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;
- });
- } else if (isFunction(config.data_order)) {
- targets.sort(config.data_order);
- } // TODO: accept name array for order
- return targets;
- };
- c3_chart_internal_fn.filterByX = function (targets, x) {
- return this.d3.merge(targets.map(function (t) { return t.values; })).filter(function (v) { return v.x - x === 0; });
- };
- c3_chart_internal_fn.filterRemoveNull = function (data) {
- return data.filter(function (d) { return isValue(d.value); });
- };
- c3_chart_internal_fn.filterByXDomain = function (targets, xDomain) {
- return targets.map(function (t) {
- return {
- id: t.id,
- id_org: t.id_org,
- values: t.values.filter(function (v) {
- return xDomain[0] <= v.x && v.x <= xDomain[1];
- })
- };
- });
- };
- c3_chart_internal_fn.hasDataLabel = function () {
- var config = this.config;
- if (typeof config.data_labels === 'boolean' && config.data_labels) {
- return true;
- } else if (typeof config.data_labels === 'object' && notEmpty(config.data_labels)) {
- return true;
- }
- return false;
- };
- c3_chart_internal_fn.getDataLabelLength = function (min, max, key) {
- var $$ = this,
- lengths = [0, 0], paddingCoef = 1.3;
- $$.selectChart.select('svg').selectAll('.dummy')
- .data([min, max])
- .enter().append('text')
- .text(function (d) { return $$.dataLabelFormat(d.id)(d); })
- .each(function (d, i) {
- lengths[i] = this.getBoundingClientRect()[key] * paddingCoef;
- })
- .remove();
- return lengths;
- };
- c3_chart_internal_fn.isNoneArc = function (d) {
- return this.hasTarget(this.data.targets, d.id);
- },
- c3_chart_internal_fn.isArc = function (d) {
- return 'data' in d && this.hasTarget(this.data.targets, d.data.id);
- };
- c3_chart_internal_fn.findSameXOfValues = function (values, index) {
- var i, targetX = values[index].x, sames = [];
- for (i = index - 1; i >= 0; i--) {
- if (targetX !== values[i].x) { break; }
- sames.push(values[i]);
- }
- for (i = index; i < values.length; i++) {
- if (targetX !== values[i].x) { break; }
- sames.push(values[i]);
- }
- return sames;
- };
-
- c3_chart_internal_fn.findClosestFromTargets = function (targets, pos) {
- var $$ = this, candidates;
-
- // map to array of closest points of each target
- candidates = targets.map(function (target) {
- return $$.findClosest(target.values, pos);
- });
-
- // decide closest point and return
- return $$.findClosest(candidates, pos);
- };
- c3_chart_internal_fn.findClosest = function (values, pos) {
- var $$ = this, minDist = $$.config.point_sensitivity, closest;
-
- // find mouseovering bar
- values.filter(function (v) { return v && $$.isBarType(v.id); }).forEach(function (v) {
- var shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node();
- if (!closest && $$.isWithinBar(shape)) {
- closest = v;
- }
- });
-
- // find closest point from non-bar
- values.filter(function (v) { return v && !$$.isBarType(v.id); }).forEach(function (v) {
- var d = $$.dist(v, pos);
- if (d < minDist) {
- minDist = d;
- closest = v;
- }
- });
-
- return closest;
- };
- c3_chart_internal_fn.dist = function (data, pos) {
- var $$ = this, config = $$.config,
- xIndex = config.axis_rotated ? 1 : 0,
- yIndex = config.axis_rotated ? 0 : 1,
- y = $$.circleY(data, data.index),
- x = $$.x(data.x);
- return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));
- };
- c3_chart_internal_fn.convertValuesToStep = function (values) {
- var converted = [].concat(values), i;
-
- if (!this.isCategorized()) {
- return values;
- }
-
- for (i = values.length + 1; 0 < i; i--) {
- converted[i] = converted[i - 1];
- }
-
- converted[0] = {
- x: converted[0].x - 1,
- value: converted[0].value,
- id: converted[0].id
- };
- converted[values.length + 1] = {
- x: converted[values.length].x + 1,
- value: converted[values.length].value,
- id: converted[values.length].id
- };
-
- return converted;
- };
- c3_chart_internal_fn.updateDataAttributes = function (name, attrs) {
- var $$ = this, config = $$.config, current = config['data_' + name];
- if (typeof attrs === 'undefined') { return current; }
- Object.keys(attrs).forEach(function (id) {
- current[id] = attrs[id];
- });
- $$.redraw({withLegend: true});
- return current;
- };
-
- c3_chart_internal_fn.convertUrlToData = function (url, mimeType, headers, keys, done) {
- var $$ = this, type = mimeType ? mimeType : 'csv';
- var req = $$.d3.xhr(url);
- if (headers) {
- Object.keys(headers).forEach(function (header) {
- req.header(header, headers[header]);
- });
- }
- req.get(function (error, data) {
- var d;
- if (!data) {
- throw new Error(error.responseURL + ' ' + error.status + ' (' + error.statusText + ')');
- }
- if (type === 'json') {
- d = $$.convertJsonToData(JSON.parse(data.response), keys);
- } else if (type === 'tsv') {
- d = $$.convertTsvToData(data.response);
- } else {
- d = $$.convertCsvToData(data.response);
- }
- done.call($$, d);
- });
- };
- c3_chart_internal_fn.convertXsvToData = function (xsv, parser) {
- var rows = parser.parseRows(xsv), d;
- if (rows.length === 1) {
- d = [{}];
- rows[0].forEach(function (id) {
- d[0][id] = null;
- });
- } else {
- d = parser.parse(xsv);
- }
- return d;
- };
- c3_chart_internal_fn.convertCsvToData = function (csv) {
- return this.convertXsvToData(csv, this.d3.csv);
- };
- c3_chart_internal_fn.convertTsvToData = function (tsv) {
- return this.convertXsvToData(tsv, this.d3.tsv);
- };
- c3_chart_internal_fn.convertJsonToData = function (json, keys) {
- var $$ = this,
- new_rows = [], targetKeys, data;
- if (keys) { // when keys specified, json would be an array that includes objects
- if (keys.x) {
- targetKeys = keys.value.concat(keys.x);
- $$.config.data_x = keys.x;
- } else {
- targetKeys = keys.value;
- }
- new_rows.push(targetKeys);
- json.forEach(function (o) {
- var new_row = [];
- targetKeys.forEach(function (key) {
- // convert undefined to null because undefined data will be removed in convertDataToTargets()
- var v = $$.findValueInJson(o, key);
- if (isUndefined(v)) {
- v = null;
- }
- new_row.push(v);
- });
- new_rows.push(new_row);
- });
- data = $$.convertRowsToData(new_rows);
- } else {
- Object.keys(json).forEach(function (key) {
- new_rows.push([key].concat(json[key]));
- });
- data = $$.convertColumnsToData(new_rows);
- }
- return data;
- };
- c3_chart_internal_fn.findValueInJson = function (object, path) {
- path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
- path = path.replace(/^\./, ''); // strip a leading dot
- var pathArray = path.split('.');
- for (var i = 0; i < pathArray.length; ++i) {
- var k = pathArray[i];
- if (k in object) {
- object = object[k];
- } else {
- return;
- }
- }
- return object;
- };
- c3_chart_internal_fn.convertRowsToData = function (rows) {
- var keys = rows[0], new_row = {}, new_rows = [], i, j;
- for (i = 1; i < rows.length; i++) {
- new_row = {};
- for (j = 0; j < rows[i].length; j++) {
- if (isUndefined(rows[i][j])) {
- throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
- }
- new_row[keys[j]] = rows[i][j];
- }
- new_rows.push(new_row);
- }
- return new_rows;
- };
- c3_chart_internal_fn.convertColumnsToData = function (columns) {
- var new_rows = [], i, j, key;
- for (i = 0; i < columns.length; i++) {
- key = columns[i][0];
- for (j = 1; j < columns[i].length; j++) {
- if (isUndefined(new_rows[j - 1])) {
- new_rows[j - 1] = {};
- }
- if (isUndefined(columns[i][j])) {
- throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
- }
- new_rows[j - 1][key] = columns[i][j];
- }
- }
- return new_rows;
- };
- c3_chart_internal_fn.convertDataToTargets = function (data, appendXs) {
- var $$ = this, config = $$.config,
- ids = $$.d3.keys(data[0]).filter($$.isNotX, $$),
- xs = $$.d3.keys(data[0]).filter($$.isX, $$),
- targets;
-
- // save x for update data by load when custom x and c3.x API
- ids.forEach(function (id) {
- var xKey = $$.getXKey(id);
-
- if ($$.isCustomX() || $$.isTimeSeries()) {
- // if included in input data
- if (xs.indexOf(xKey) >= 0) {
- $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat(
- data.map(function (d) { return d[xKey]; })
- .filter(isValue)
- .map(function (rawX, i) { return $$.generateTargetX(rawX, id, i); })
- );
- }
- // if not included in input data, find from preloaded data of other id's x
- else if (config.data_x) {
- $$.data.xs[id] = $$.getOtherTargetXs();
- }
- // if not included in input data, find from preloaded data
- else if (notEmpty(config.data_xs)) {
- $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);
- }
- // MEMO: if no x included, use same x of current will be used
- } else {
- $$.data.xs[id] = data.map(function (d, i) { return i; });
- }
- });
-
-
- // check x is defined
- ids.forEach(function (id) {
- if (!$$.data.xs[id]) {
- throw new Error('x is not defined for id = "' + id + '".');
- }
- });
-
- // convert to target
- targets = ids.map(function (id, index) {
- var convertedId = config.data_idConverter(id);
- return {
- id: convertedId,
- id_org: id,
- values: data.map(function (d, i) {
- var xKey = $$.getXKey(id), rawX = d[xKey],
- value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, x;
- // use x as categories if custom x and categorized
- if ($$.isCustomX() && $$.isCategorized() && index === 0 && !isUndefined(rawX)) {
- if (index === 0 && i === 0) {
- config.axis_x_categories = [];
- }
- x = config.axis_x_categories.indexOf(rawX);
- if (x === -1) {
- x = config.axis_x_categories.length;
- config.axis_x_categories.push(rawX);
- }
- } else {
- x = $$.generateTargetX(rawX, id, i);
- }
- // mark as x = undefined if value is undefined and filter to remove after mapped
- if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {
- x = undefined;
- }
- return {x: x, value: value, id: convertedId};
- }).filter(function (v) { return isDefined(v.x); })
- };
- });
-
- // finish targets
- targets.forEach(function (t) {
- var i;
- // sort values by its x
- if (config.data_xSort) {
- t.values = t.values.sort(function (v1, v2) {
- var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,
- x2 = v2.x || v2.x === 0 ? v2.x : Infinity;
- return x1 - x2;
- });
- }
- // indexing each value
- i = 0;
- t.values.forEach(function (v) {
- v.index = i++;
- });
- // this needs to be sorted because its index and value.index is identical
- $$.data.xs[t.id].sort(function (v1, v2) {
- return v1 - v2;
- });
- });
-
- // cache information about values
- $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);
- $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets);
-
- // set target types
- if (config.data_type) {
- $$.setTargetType($$.mapToIds(targets).filter(function (id) { return ! (id in config.data_types); }), config.data_type);
- }
-
- // cache as original id keyed
- targets.forEach(function (d) {
- $$.addCache(d.id_org, d);
- });
-
- return targets;
- };
-
- c3_chart_internal_fn.load = function (targets, args) {
- var $$ = this;
- if (targets) {
- // filter loading targets if needed
- if (args.filter) {
- targets = targets.filter(args.filter);
- }
- // set type if args.types || args.type specified
- if (args.type || args.types) {
- targets.forEach(function (t) {
- var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;
- $$.setTargetType(t.id, type);
- });
- }
- // Update/Add data
- $$.data.targets.forEach(function (d) {
- for (var i = 0; i < targets.length; i++) {
- if (d.id === targets[i].id) {
- d.values = targets[i].values;
- targets.splice(i, 1);
- break;
- }
- }
- });
- $$.data.targets = $$.data.targets.concat(targets); // add remained
- }
-
- // Set targets
- $$.updateTargets($$.data.targets);
-
- // Redraw with new targets
- $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
-
- if (args.done) { args.done(); }
- };
- c3_chart_internal_fn.loadFromArgs = function (args) {
- var $$ = this;
- if (args.data) {
- $$.load($$.convertDataToTargets(args.data), args);
- }
- else if (args.url) {
- $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {
- $$.load($$.convertDataToTargets(data), args);
- });
- }
- else if (args.json) {
- $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);
- }
- else if (args.rows) {
- $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);
- }
- else if (args.columns) {
- $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);
- }
- else {
- $$.load(null, args);
- }
- };
- c3_chart_internal_fn.unload = function (targetIds, done) {
- var $$ = this;
- if (!done) {
- done = function () {};
- }
- // filter existing target
- targetIds = targetIds.filter(function (id) { return $$.hasTarget($$.data.targets, id); });
- // If no target, call done and return
- if (!targetIds || targetIds.length === 0) {
- done();
- return;
- }
- $$.svg.selectAll(targetIds.map(function (id) { return $$.selectorTarget(id); }))
- .transition()
- .style('opacity', 0)
- .remove()
- .call($$.endall, done);
- targetIds.forEach(function (id) {
- // Reset fadein for future load
- $$.withoutFadeIn[id] = false;
- // Remove target's elements
- if ($$.legend) {
- $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove();
- }
- // Remove target
- $$.data.targets = $$.data.targets.filter(function (t) {
- return t.id !== id;
- });
- });
- };
-
- c3_chart_internal_fn.categoryName = function (i) {
- var config = this.config;
- return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;
- };
-
- c3_chart_internal_fn.initEventRect = function () {
- var $$ = this;
- $$.main.select('.' + CLASS.chart).append("g")
- .attr("class", CLASS.eventRects)
- .style('fill-opacity', 0);
- };
- c3_chart_internal_fn.redrawEventRect = function () {
- var $$ = this, config = $$.config,
- eventRectUpdate, maxDataCountTarget,
- isMultipleX = $$.isMultipleX();
-
- // rects for mouseover
- var eventRects = $$.main.select('.' + CLASS.eventRects)
- .style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null)
- .classed(CLASS.eventRectsMultiple, isMultipleX)
- .classed(CLASS.eventRectsSingle, !isMultipleX);
-
- // clear old rects
- eventRects.selectAll('.' + CLASS.eventRect).remove();
-
- // open as public variable
- $$.eventRect = eventRects.selectAll('.' + CLASS.eventRect);
-
- if (isMultipleX) {
- eventRectUpdate = $$.eventRect.data([0]);
- // enter : only one rect will be added
- $$.generateEventRectsForMultipleXs(eventRectUpdate.enter());
- // update
- $$.updateEventRect(eventRectUpdate);
- // exit : not needed because always only one rect exists
- }
- else {
- // Set data and update $$.eventRect
- maxDataCountTarget = $$.getMaxDataCountTarget($$.data.targets);
- eventRects.datum(maxDataCountTarget ? maxDataCountTarget.values : []);
- $$.eventRect = eventRects.selectAll('.' + CLASS.eventRect);
- eventRectUpdate = $$.eventRect.data(function (d) { return d; });
- // enter
- $$.generateEventRectsForSingleX(eventRectUpdate.enter());
- // update
- $$.updateEventRect(eventRectUpdate);
- // exit
- eventRectUpdate.exit().remove();
- }
- };
- c3_chart_internal_fn.updateEventRect = function (eventRectUpdate) {
- var $$ = this, config = $$.config,
- x, y, w, h, rectW, rectX;
-
- // set update selection if null
- eventRectUpdate = eventRectUpdate || $$.eventRect.data(function (d) { return d; });
-
- if ($$.isMultipleX()) {
- // TODO: rotated not supported yet
- x = 0;
- y = 0;
- w = $$.width;
- h = $$.height;
- }
- else {
- if (($$.isCustomX() || $$.isTimeSeries()) && !$$.isCategorized()) {
-
- // update index for x that is used by prevX and nextX
- $$.updateXs();
-
- rectW = function (d) {
- var prevX = $$.getPrevX(d.index), nextX = $$.getNextX(d.index);
-
- // if there this is a single data point make the eventRect full width (or height)
- if (prevX === null && nextX === null) {
- return config.axis_rotated ? $$.height : $$.width;
- }
-
- if (prevX === null) { prevX = $$.x.domain()[0]; }
- if (nextX === null) { nextX = $$.x.domain()[1]; }
-
- return Math.max(0, ($$.x(nextX) - $$.x(prevX)) / 2);
- };
- rectX = function (d) {
- var prevX = $$.getPrevX(d.index), nextX = $$.getNextX(d.index),
- thisX = $$.data.xs[d.id][d.index];
-
- // if there this is a single data point position the eventRect at 0
- if (prevX === null && nextX === null) {
- return 0;
- }
-
- if (prevX === null) { prevX = $$.x.domain()[0]; }
-
- return ($$.x(thisX) + $$.x(prevX)) / 2;
- };
- } else {
- rectW = $$.getEventRectWidth();
- rectX = function (d) {
- return $$.x(d.x) - (rectW / 2);
- };
- }
- x = config.axis_rotated ? 0 : rectX;
- y = config.axis_rotated ? rectX : 0;
- w = config.axis_rotated ? $$.width : rectW;
- h = config.axis_rotated ? rectW : $$.height;
- }
-
- eventRectUpdate
- .attr('class', $$.classEvent.bind($$))
- .attr("x", x)
- .attr("y", y)
- .attr("width", w)
- .attr("height", h);
- };
- c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
- var $$ = this, d3 = $$.d3, config = $$.config;
- eventRectEnter.append("rect")
- .attr("class", $$.classEvent.bind($$))
- .style("cursor", config.data_selection_enabled && config.data_selection_grouped ? "pointer" : null)
- .on('mouseover', function (d) {
- var index = d.index;
-
- if ($$.dragging || $$.flowing) { return; } // do nothing while dragging/flowing
- if ($$.hasArcType()) { return; }
-
- // Expand shapes for selection
- if (config.point_focus_expand_enabled) { $$.expandCircles(index, null, true); }
- $$.expandBars(index, null, true);
-
- // Call event handler
- $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
- config.data_onmouseover.call($$.api, d);
- });
- })
- .on('mouseout', function (d) {
- var index = d.index;
- if (!$$.config) { return; } // chart is destroyed
- if ($$.hasArcType()) { return; }
- $$.hideXGridFocus();
- $$.hideTooltip();
- // Undo expanded shapes
- $$.unexpandCircles();
- $$.unexpandBars();
- // Call event handler
- $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
- config.data_onmouseout.call($$.api, d);
- });
- })
- .on('mousemove', function (d) {
- var selectedData, index = d.index,
- eventRect = $$.svg.select('.' + CLASS.eventRect + '-' + index);
-
- if ($$.dragging || $$.flowing) { return; } // do nothing while dragging/flowing
- if ($$.hasArcType()) { return; }
-
- if ($$.isStepType(d) && $$.config.line_step_type === 'step-after' && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
- index -= 1;
- }
-
- // Show tooltip
- selectedData = $$.filterTargetsToShow($$.data.targets).map(function (t) {
- return $$.addName($$.getValueOnIndex(t.values, index));
- });
-
- if (config.tooltip_grouped) {
- $$.showTooltip(selectedData, this);
- $$.showXGridFocus(selectedData);
- }
-
- if (config.tooltip_grouped && (!config.data_selection_enabled || config.data_selection_grouped)) {
- return;
- }
-
- $$.main.selectAll('.' + CLASS.shape + '-' + index)
- .each(function () {
- d3.select(this).classed(CLASS.EXPANDED, true);
- if (config.data_selection_enabled) {
- eventRect.style('cursor', config.data_selection_grouped ? 'pointer' : null);
- }
- if (!config.tooltip_grouped) {
- $$.hideXGridFocus();
- $$.hideTooltip();
- if (!config.data_selection_grouped) {
- $$.unexpandCircles(index);
- $$.unexpandBars(index);
- }
- }
- })
- .filter(function (d) {
- return $$.isWithinShape(this, d);
- })
- .each(function (d) {
- if (config.data_selection_enabled && (config.data_selection_grouped || config.data_selection_isselectable(d))) {
- eventRect.style('cursor', 'pointer');
- }
- if (!config.tooltip_grouped) {
- $$.showTooltip([d], this);
- $$.showXGridFocus([d]);
- if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
- $$.expandBars(index, d.id, true);
- }
- });
- })
- .on('click', function (d) {
- var index = d.index;
- if ($$.hasArcType() || !$$.toggleShape) { return; }
- if ($$.cancelClick) {
- $$.cancelClick = false;
- return;
- }
- if ($$.isStepType(d) && config.line_step_type === 'step-after' && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
- index -= 1;
- }
- $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
- if (config.data_selection_grouped || $$.isWithinShape(this, d)) {
- $$.toggleShape(this, d, index);
- $$.config.data_onclick.call($$.api, d, this);
- }
- });
- })
- .call(
- config.data_selection_draggable && $$.drag ? (
- d3.behavior.drag().origin(Object)
- .on('drag', function () { $$.drag(d3.mouse(this)); })
- .on('dragstart', function () { $$.dragstart(d3.mouse(this)); })
- .on('dragend', function () { $$.dragend(); })
- ) : function () {}
- );
- };
-
- c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) {
- var $$ = this, d3 = $$.d3, config = $$.config;
-
- function mouseout() {
- $$.svg.select('.' + CLASS.eventRect).style('cursor', null);
- $$.hideXGridFocus();
- $$.hideTooltip();
- $$.unexpandCircles();
- $$.unexpandBars();
- }
-
- eventRectEnter.append('rect')
- .attr('x', 0)
- .attr('y', 0)
- .attr('width', $$.width)
- .attr('height', $$.height)
- .attr('class', CLASS.eventRect)
- .on('mouseout', function () {
- if (!$$.config) { return; } // chart is destroyed
- if ($$.hasArcType()) { return; }
- mouseout();
- })
- .on('mousemove', function () {
- var targetsToShow = $$.filterTargetsToShow($$.data.targets);
- var mouse, closest, sameXData, selectedData;
-
- if ($$.dragging) { return; } // do nothing when dragging
- if ($$.hasArcType(targetsToShow)) { return; }
-
- mouse = d3.mouse(this);
- closest = $$.findClosestFromTargets(targetsToShow, mouse);
-
- if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id)) {
- config.data_onmouseout.call($$.api, $$.mouseover);
- $$.mouseover = undefined;
- }
-
- if (! closest) {
- mouseout();
- return;
- }
-
- if ($$.isScatterType(closest) || !config.tooltip_grouped) {
- sameXData = [closest];
- } else {
- sameXData = $$.filterByX(targetsToShow, closest.x);
- }
-
- // show tooltip when cursor is close to some point
- selectedData = sameXData.map(function (d) {
- return $$.addName(d);
- });
- $$.showTooltip(selectedData, this);
-
- // expand points
- if (config.point_focus_expand_enabled) {
- $$.expandCircles(closest.index, closest.id, true);
- }
- $$.expandBars(closest.index, closest.id, true);
-
- // Show xgrid focus line
- $$.showXGridFocus(selectedData);
-
- // Show cursor as pointer if point is close to mouse position
- if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
- $$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer');
- if (!$$.mouseover) {
- config.data_onmouseover.call($$.api, closest);
- $$.mouseover = closest;
- }
- }
- })
- .on('click', function () {
- var targetsToShow = $$.filterTargetsToShow($$.data.targets);
- var mouse, closest;
- if ($$.hasArcType(targetsToShow)) { return; }
-
- mouse = d3.mouse(this);
- closest = $$.findClosestFromTargets(targetsToShow, mouse);
- if (! closest) { return; }
- // select if selection enabled
- if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
- $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).selectAll('.' + CLASS.shape + '-' + closest.index).each(function () {
- if (config.data_selection_grouped || $$.isWithinShape(this, closest)) {
- $$.toggleShape(this, closest, closest.index);
- $$.config.data_onclick.call($$.api, closest, this);
- }
- });
- }
- })
- .call(
- config.data_selection_draggable && $$.drag ? (
- d3.behavior.drag().origin(Object)
- .on('drag', function () { $$.drag(d3.mouse(this)); })
- .on('dragstart', function () { $$.dragstart(d3.mouse(this)); })
- .on('dragend', function () { $$.dragend(); })
- ) : function () {}
- );
- };
- c3_chart_internal_fn.dispatchEvent = function (type, index, mouse) {
- var $$ = this,
- selector = '.' + CLASS.eventRect + (!$$.isMultipleX() ? '-' + index : ''),
- eventRect = $$.main.select(selector).node(),
- box = eventRect.getBoundingClientRect(),
- x = box.left + (mouse ? mouse[0] : 0),
- y = box.top + (mouse ? mouse[1] : 0),
- event = document.createEvent("MouseEvents");
-
- event.initMouseEvent(type, true, true, window, 0, x, y, x, y,
- false, false, false, false, 0, null);
- eventRect.dispatchEvent(event);
- };
-
- c3_chart_internal_fn.getCurrentWidth = function () {
- var $$ = this, config = $$.config;
- return config.size_width ? config.size_width : $$.getParentWidth();
- };
- c3_chart_internal_fn.getCurrentHeight = function () {
- var $$ = this, config = $$.config,
- h = config.size_height ? config.size_height : $$.getParentHeight();
- return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);
- };
- c3_chart_internal_fn.getCurrentPaddingTop = function () {
- var $$ = this,
- config = $$.config,
- padding = isValue(config.padding_top) ? config.padding_top : 0;
- if ($$.title && $$.title.node()) {
- padding += $$.getTitlePadding();
- }
- return padding;
- };
- c3_chart_internal_fn.getCurrentPaddingBottom = function () {
- var config = this.config;
- return isValue(config.padding_bottom) ? config.padding_bottom : 0;
- };
- c3_chart_internal_fn.getCurrentPaddingLeft = function (withoutRecompute) {
- var $$ = this, config = $$.config;
- if (isValue(config.padding_left)) {
- return config.padding_left;
- } else if (config.axis_rotated) {
- return !config.axis_x_show ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);
- } else if (!config.axis_y_show || config.axis_y_inner) { // && !config.axis_rotated
- return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1;
- } else {
- return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));
- }
- };
- c3_chart_internal_fn.getCurrentPaddingRight = function () {
- var $$ = this, config = $$.config,
- defaultPadding = 10, legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;
- if (isValue(config.padding_right)) {
- return config.padding_right + 1; // 1 is needed not to hide tick line
- } else if (config.axis_rotated) {
- return defaultPadding + legendWidthOnRight;
- } else if (!config.axis_y2_show || config.axis_y2_inner) { // && !config.axis_rotated
- return 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);
- } else {
- return ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;
- }
- };
-
- c3_chart_internal_fn.getParentRectValue = function (key) {
- var parent = this.selectChart.node(), v;
- while (parent && parent.tagName !== 'BODY') {
- try {
- v = parent.getBoundingClientRect()[key];
- } catch(e) {
- if (key === 'width') {
- // In IE in certain cases getBoundingClientRect
- // will cause an "unspecified error"
- v = parent.offsetWidth;
- }
- }
- if (v) {
- break;
- }
- parent = parent.parentNode;
- }
- return v;
- };
- c3_chart_internal_fn.getParentWidth = function () {
- return this.getParentRectValue('width');
- };
- c3_chart_internal_fn.getParentHeight = function () {
- var h = this.selectChart.style('height');
- return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;
- };
-
-
- c3_chart_internal_fn.getSvgLeft = function (withoutRecompute) {
- var $$ = this, config = $$.config,
- hasLeftAxisRect = config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner),
- leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,
- leftAxis = $$.main.select('.' + leftAxisClass).node(),
- svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : {right: 0},
- chartRect = $$.selectChart.node().getBoundingClientRect(),
- hasArc = $$.hasArcType(),
- svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));
- return svgLeft > 0 ? svgLeft : 0;
- };
-
-
- c3_chart_internal_fn.getAxisWidthByAxisId = function (id, withoutRecompute) {
- var $$ = this, position = $$.axis.getLabelPositionById(id);
- return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40);
- };
- c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) {
- var $$ = this, config = $$.config, h = 30;
- if (axisId === 'x' && !config.axis_x_show) { return 8; }
- if (axisId === 'x' && config.axis_x_height) { return config.axis_x_height; }
- if (axisId === 'y' && !config.axis_y_show) {
- return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;
- }
- if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; }
- // Calculate x axis height when tick rotated
- if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
- h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - config.axis_x_tick_rotate) / 180);
- }
- // Calculate y axis height when tick rotated
- if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {
- h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - config.axis_y_tick_rotate) / 180);
- }
- return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0);
- };
-
- c3_chart_internal_fn.getEventRectWidth = function () {
- return Math.max(0, this.xAxis.tickInterval());
- };
-
- c3_chart_internal_fn.getShapeIndices = function (typeFilter) {
- var $$ = this, config = $$.config,
- indices = {}, i = 0, j, k;
- $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {
- for (j = 0; j < config.data_groups.length; j++) {
- if (config.data_groups[j].indexOf(d.id) < 0) { continue; }
- for (k = 0; k < config.data_groups[j].length; k++) {
- if (config.data_groups[j][k] in indices) {
- indices[d.id] = indices[config.data_groups[j][k]];
- break;
- }
- }
- }
- if (isUndefined(indices[d.id])) { indices[d.id] = i++; }
- });
- indices.__max__ = i - 1;
- return indices;
- };
- c3_chart_internal_fn.getShapeX = function (offset, targetsNum, indices, isSub) {
- var $$ = this, scale = isSub ? $$.subX : $$.x;
- return function (d) {
- var index = d.id in indices ? indices[d.id] : 0;
- return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;
- };
- };
- c3_chart_internal_fn.getShapeY = function (isSub) {
- var $$ = this;
- return function (d) {
- var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);
- return scale(d.value);
- };
- };
- c3_chart_internal_fn.getShapeOffset = function (typeFilter, indices, isSub) {
- var $$ = this,
- targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))),
- targetIds = targets.map(function (t) { return t.id; });
- return function (d, i) {
- var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),
- y0 = scale(0), offset = y0;
- targets.forEach(function (t) {
- var values = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values;
- if (t.id === d.id || indices[t.id] !== indices[d.id]) { return; }
- if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {
- // check if the x values line up
- if (typeof values[i] === 'undefined' || +values[i].x !== +d.x) { // "+" for timeseries
- // if not, try to find the value that does line up
- i = -1;
- values.forEach(function (v, j) {
- if (v.x === d.x) {
- i = j;
- }
- });
- }
- if (i in values && values[i].value * d.value >= 0) {
- offset += scale(values[i].value) - y0;
- }
- }
- });
- return offset;
- };
- };
- c3_chart_internal_fn.isWithinShape = function (that, d) {
- var $$ = this,
- shape = $$.d3.select(that), isWithin;
- if (!$$.isTargetToShow(d.id)) {
- isWithin = false;
- }
- else if (that.nodeName === 'circle') {
- isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);
- }
- else if (that.nodeName === 'path') {
- isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar(that) : true;
- }
- return isWithin;
- };
-
-
- c3_chart_internal_fn.getInterpolate = function (d) {
- var $$ = this,
- interpolation = $$.isInterpolationType($$.config.spline_interpolation_type) ? $$.config.spline_interpolation_type : 'cardinal';
- return $$.isSplineType(d) ? interpolation : $$.isStepType(d) ? $$.config.line_step_type : "linear";
- };
-
- c3_chart_internal_fn.initLine = function () {
- var $$ = this;
- $$.main.select('.' + CLASS.chart).append("g")
- .attr("class", CLASS.chartLines);
- };
- c3_chart_internal_fn.updateTargetsForLine = function (targets) {
- var $$ = this, config = $$.config,
- mainLineUpdate, mainLineEnter,
- classChartLine = $$.classChartLine.bind($$),
- classLines = $$.classLines.bind($$),
- classAreas = $$.classAreas.bind($$),
- classCircles = $$.classCircles.bind($$),
- classFocus = $$.classFocus.bind($$);
- mainLineUpdate = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine)
- .data(targets)
- .attr('class', function (d) { return classChartLine(d) + classFocus(d); });
- mainLineEnter = mainLineUpdate.enter().append('g')
- .attr('class', classChartLine)
- .style('opacity', 0)
- .style("pointer-events", "none");
- // Lines for each data
- mainLineEnter.append('g')
- .attr("class", classLines);
- // Areas
- mainLineEnter.append('g')
- .attr('class', classAreas);
- // Circles for each data point on lines
- mainLineEnter.append('g')
- .attr("class", function (d) { return $$.generateClass(CLASS.selectedCircles, d.id); });
- mainLineEnter.append('g')
- .attr("class", classCircles)
- .style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; });
- // Update date for selected circles
- targets.forEach(function (t) {
- $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) {
- d.value = t.values[d.index].value;
- });
- });
- // MEMO: can not keep same color...
- //mainLineUpdate.exit().remove();
- };
- c3_chart_internal_fn.updateLine = function (durationForExit) {
- var $$ = this;
- $$.mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line)
- .data($$.lineData.bind($$));
- $$.mainLine.enter().append('path')
- .attr('class', $$.classLine.bind($$))
- .style("stroke", $$.color);
- $$.mainLine
- .style("opacity", $$.initialOpacity.bind($$))
- .style('shape-rendering', function (d) { return $$.isStepType(d) ? 'crispEdges' : ''; })
- .attr('transform', null);
- $$.mainLine.exit().transition().duration(durationForExit)
- .style('opacity', 0)
- .remove();
- };
- c3_chart_internal_fn.redrawLine = function (drawLine, withTransition) {
- return [
- (withTransition ? this.mainLine.transition(Math.random().toString()) : this.mainLine)
- .attr("d", drawLine)
- .style("stroke", this.color)
- .style("opacity", 1)
- ];
- };
- c3_chart_internal_fn.generateDrawLine = function (lineIndices, isSub) {
- var $$ = this, config = $$.config,
- line = $$.d3.svg.line(),
- getPoints = $$.generateGetLinePoints(lineIndices, isSub),
- yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
- xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); },
- yValue = function (d, i) {
- return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value);
- };
-
- line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue);
- if (!config.line_connectNull) { line = line.defined(function (d) { return d.value != null; }); }
- return function (d) {
- var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
- x = isSub ? $$.x : $$.subX, y = yScaleGetter.call($$, d.id), x0 = 0, y0 = 0, path;
- if ($$.isLineType(d)) {
- if (config.data_regions[d.id]) {
- path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);
- } else {
- if ($$.isStepType(d)) { values = $$.convertValuesToStep(values); }
- path = line.interpolate($$.getInterpolate(d))(values);
- }
- } else {
- if (values[0]) {
- x0 = x(values[0].x);
- y0 = y(values[0].value);
- }
- path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
- }
- return path ? path : "M 0 0";
- };
- };
- c3_chart_internal_fn.generateGetLinePoints = function (lineIndices, isSub) { // partial duplication of generateGetBarPoints
- var $$ = this, config = $$.config,
- lineTargetsNum = lineIndices.__max__ + 1,
- x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),
- y = $$.getShapeY(!!isSub),
- lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),
- yScale = isSub ? $$.getSubYScale : $$.getYScale;
- return function (d, i) {
- var y0 = yScale.call($$, d.id)(0),
- offset = lineOffset(d, i) || y0, // offset is for stacked area chart
- posX = x(d), posY = y(d);
- // fix posY not to overflow opposite quadrant
- if (config.axis_rotated) {
- if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; }
- }
- // 1 point that marks the line position
- return [
- [posX, posY - (y0 - offset)],
- [posX, posY - (y0 - offset)], // needed for compatibility
- [posX, posY - (y0 - offset)], // needed for compatibility
- [posX, posY - (y0 - offset)] // needed for compatibility
- ];
- };
- };
-
-
- c3_chart_internal_fn.lineWithRegions = function (d, x, y, _regions) {
- var $$ = this, config = $$.config,
- prev = -1, i, j,
- s = "M", sWithRegion,
- xp, yp, dx, dy, dd, diff, diffx2,
- xOffset = $$.isCategorized() ? 0.5 : 0,
- xValue, yValue,
- regions = [];
-
- function isWithinRegions(x, regions) {
- var i;
- for (i = 0; i < regions.length; i++) {
- if (regions[i].start < x && x <= regions[i].end) { return true; }
- }
- return false;
- }
-
- // Check start/end of regions
- if (isDefined(_regions)) {
- for (i = 0; i < _regions.length; i++) {
- regions[i] = {};
- if (isUndefined(_regions[i].start)) {
- regions[i].start = d[0].x;
- } else {
- regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start;
- }
- if (isUndefined(_regions[i].end)) {
- regions[i].end = d[d.length - 1].x;
- } else {
- regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end;
- }
- }
- }
-
- // Set scales
- xValue = config.axis_rotated ? function (d) { return y(d.value); } : function (d) { return x(d.x); };
- yValue = config.axis_rotated ? function (d) { return x(d.x); } : function (d) { return y(d.value); };
-
- // Define svg generator function for region
- function generateM(points) {
- return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1];
- }
- if ($$.isTimeSeries()) {
- sWithRegion = function (d0, d1, j, diff) {
- var x0 = d0.x.getTime(), x_diff = d1.x - d0.x,
- xv0 = new Date(x0 + x_diff * j),
- xv1 = new Date(x0 + x_diff * (j + diff)),
- points;
- if (config.axis_rotated) {
- points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]];
- } else {
- points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]];
- }
- return generateM(points);
- };
- } else {
- sWithRegion = function (d0, d1, j, diff) {
- var points;
- if (config.axis_rotated) {
- points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]];
- } else {
- points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]];
- }
- return generateM(points);
- };
- }
-
- // Generate
- for (i = 0; i < d.length; i++) {
-
- // Draw as normal
- if (isUndefined(regions) || ! isWithinRegions(d[i].x, regions)) {
- s += " " + xValue(d[i]) + " " + yValue(d[i]);
- }
- // Draw with region // TODO: Fix for horizotal charts
- else {
- xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries());
- yp = $$.getScale(d[i - 1].value, d[i].value);
-
- dx = x(d[i].x) - x(d[i - 1].x);
- dy = y(d[i].value) - y(d[i - 1].value);
- dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
- diff = 2 / dd;
- diffx2 = diff * 2;
-
- for (j = diff; j <= 1; j += diffx2) {
- s += sWithRegion(d[i - 1], d[i], j, diff);
- }
- }
- prev = d[i].x;
- }
-
- return s;
- };
-
-
- c3_chart_internal_fn.updateArea = function (durationForExit) {
- var $$ = this, d3 = $$.d3;
- $$.mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area)
- .data($$.lineData.bind($$));
- $$.mainArea.enter().append('path')
- .attr("class", $$.classArea.bind($$))
- .style("fill", $$.color)
- .style("opacity", function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; });
- $$.mainArea
- .style("opacity", $$.orgAreaOpacity);
- $$.mainArea.exit().transition().duration(durationForExit)
- .style('opacity', 0)
- .remove();
- };
- c3_chart_internal_fn.redrawArea = function (drawArea, withTransition) {
- return [
- (withTransition ? this.mainArea.transition(Math.random().toString()) : this.mainArea)
- .attr("d", drawArea)
- .style("fill", this.color)
- .style("opacity", this.orgAreaOpacity)
- ];
- };
- c3_chart_internal_fn.generateDrawArea = function (areaIndices, isSub) {
- var $$ = this, config = $$.config, area = $$.d3.svg.area(),
- getPoints = $$.generateGetAreaPoints(areaIndices, isSub),
- yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
- xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); },
- value0 = function (d, i) {
- return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id));
- },
- value1 = function (d, i) {
- return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value);
- };
-
- area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1);
- if (!config.line_connectNull) {
- area = area.defined(function (d) { return d.value !== null; });
- }
-
- return function (d) {
- var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
- x0 = 0, y0 = 0, path;
- if ($$.isAreaType(d)) {
- if ($$.isStepType(d)) { values = $$.convertValuesToStep(values); }
- path = area.interpolate($$.getInterpolate(d))(values);
- } else {
- if (values[0]) {
- x0 = $$.x(values[0].x);
- y0 = $$.getYScale(d.id)(values[0].value);
- }
- path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
- }
- return path ? path : "M 0 0";
- };
- };
- c3_chart_internal_fn.getAreaBaseValue = function () {
- return 0;
- };
- c3_chart_internal_fn.generateGetAreaPoints = function (areaIndices, isSub) { // partial duplication of generateGetBarPoints
- var $$ = this, config = $$.config,
- areaTargetsNum = areaIndices.__max__ + 1,
- x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),
- y = $$.getShapeY(!!isSub),
- areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),
- yScale = isSub ? $$.getSubYScale : $$.getYScale;
- return function (d, i) {
- var y0 = yScale.call($$, d.id)(0),
- offset = areaOffset(d, i) || y0, // offset is for stacked area chart
- posX = x(d), posY = y(d);
- // fix posY not to overflow opposite quadrant
- if (config.axis_rotated) {
- if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; }
- }
- // 1 point that marks the area position
- return [
- [posX, offset],
- [posX, posY - (y0 - offset)],
- [posX, posY - (y0 - offset)], // needed for compatibility
- [posX, offset] // needed for compatibility
- ];
- };
- };
-
-
- c3_chart_internal_fn.updateCircle = function () {
- var $$ = this;
- $$.mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle)
- .data($$.lineOrScatterData.bind($$));
- $$.mainCircle.enter().append("circle")
- .attr("class", $$.classCircle.bind($$))
- .attr("r", $$.pointR.bind($$))
- .style("fill", $$.color);
- $$.mainCircle
- .style("opacity", $$.initialOpacityForCircle.bind($$));
- $$.mainCircle.exit().remove();
- };
- c3_chart_internal_fn.redrawCircle = function (cx, cy, withTransition) {
- var selectedCircles = this.main.selectAll('.' + CLASS.selectedCircle);
- return [
- (withTransition ? this.mainCircle.transition(Math.random().toString()) : this.mainCircle)
- .style('opacity', this.opacityForCircle.bind(this))
- .style("fill", this.color)
- .attr("cx", cx)
- .attr("cy", cy),
- (withTransition ? selectedCircles.transition(Math.random().toString()) : selectedCircles)
- .attr("cx", cx)
- .attr("cy", cy)
- ];
- };
- c3_chart_internal_fn.circleX = function (d) {
- return d.x || d.x === 0 ? this.x(d.x) : null;
- };
- c3_chart_internal_fn.updateCircleY = function () {
- var $$ = this, lineIndices, getPoints;
- if ($$.config.data_groups.length > 0) {
- lineIndices = $$.getShapeIndices($$.isLineType),
- getPoints = $$.generateGetLinePoints(lineIndices);
- $$.circleY = function (d, i) {
- return getPoints(d, i)[0][1];
- };
- } else {
- $$.circleY = function (d) {
- return $$.getYScale(d.id)(d.value);
- };
- }
- };
- c3_chart_internal_fn.getCircles = function (i, id) {
- var $$ = this;
- return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
- };
- c3_chart_internal_fn.expandCircles = function (i, id, reset) {
- var $$ = this,
- r = $$.pointExpandedR.bind($$);
- if (reset) { $$.unexpandCircles(); }
- $$.getCircles(i, id)
- .classed(CLASS.EXPANDED, true)
- .attr('r', r);
- };
- c3_chart_internal_fn.unexpandCircles = function (i) {
- var $$ = this,
- r = $$.pointR.bind($$);
- $$.getCircles(i)
- .filter(function () { return $$.d3.select(this).classed(CLASS.EXPANDED); })
- .classed(CLASS.EXPANDED, false)
- .attr('r', r);
- };
- c3_chart_internal_fn.pointR = function (d) {
- var $$ = this, config = $$.config;
- return $$.isStepType(d) ? 0 : (isFunction(config.point_r) ? config.point_r(d) : config.point_r);
- };
- c3_chart_internal_fn.pointExpandedR = function (d) {
- var $$ = this, config = $$.config;
- return config.point_focus_expand_enabled ? (config.point_focus_expand_r ? config.point_focus_expand_r : $$.pointR(d) * 1.75) : $$.pointR(d);
- };
- c3_chart_internal_fn.pointSelectR = function (d) {
- var $$ = this, config = $$.config;
- return isFunction(config.point_select_r) ? config.point_select_r(d) : ((config.point_select_r) ? config.point_select_r : $$.pointR(d) * 4);
- };
- c3_chart_internal_fn.isWithinCircle = function (that, r) {
- var d3 = this.d3,
- mouse = d3.mouse(that), d3_this = d3.select(that),
- cx = +d3_this.attr("cx"), cy = +d3_this.attr("cy");
- return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r;
- };
- c3_chart_internal_fn.isWithinStep = function (that, y) {
- return Math.abs(y - this.d3.mouse(that)[1]) < 30;
- };
-
- c3_chart_internal_fn.initBar = function () {
- var $$ = this;
- $$.main.select('.' + CLASS.chart).append("g")
- .attr("class", CLASS.chartBars);
- };
- c3_chart_internal_fn.updateTargetsForBar = function (targets) {
- var $$ = this, config = $$.config,
- mainBarUpdate, mainBarEnter,
- classChartBar = $$.classChartBar.bind($$),
- classBars = $$.classBars.bind($$),
- classFocus = $$.classFocus.bind($$);
- mainBarUpdate = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar)
- .data(targets)
- .attr('class', function (d) { return classChartBar(d) + classFocus(d); });
- mainBarEnter = mainBarUpdate.enter().append('g')
- .attr('class', classChartBar)
- .style('opacity', 0)
- .style("pointer-events", "none");
- // Bars for each data
- mainBarEnter.append('g')
- .attr("class", classBars)
- .style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; });
-
- };
- c3_chart_internal_fn.updateBar = function (durationForExit) {
- var $$ = this,
- barData = $$.barData.bind($$),
- classBar = $$.classBar.bind($$),
- initialOpacity = $$.initialOpacity.bind($$),
- color = function (d) { return $$.color(d.id); };
- $$.mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar)
- .data(barData);
- $$.mainBar.enter().append('path')
- .attr("class", classBar)
- .style("stroke", color)
- .style("fill", color);
- $$.mainBar
- .style("opacity", initialOpacity);
- $$.mainBar.exit().transition().duration(durationForExit)
- .style('opacity', 0)
- .remove();
- };
- c3_chart_internal_fn.redrawBar = function (drawBar, withTransition) {
- return [
- (withTransition ? this.mainBar.transition(Math.random().toString()) : this.mainBar)
- .attr('d', drawBar)
- .style("fill", this.color)
- .style("opacity", 1)
- ];
- };
- c3_chart_internal_fn.getBarW = function (axis, barTargetsNum) {
- var $$ = this, config = $$.config,
- w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum : 0;
- return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w;
- };
- c3_chart_internal_fn.getBars = function (i, id) {
- var $$ = this;
- return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
- };
- c3_chart_internal_fn.expandBars = function (i, id, reset) {
- var $$ = this;
- if (reset) { $$.unexpandBars(); }
- $$.getBars(i, id).classed(CLASS.EXPANDED, true);
- };
- c3_chart_internal_fn.unexpandBars = function (i) {
- var $$ = this;
- $$.getBars(i).classed(CLASS.EXPANDED, false);
- };
- c3_chart_internal_fn.generateDrawBar = function (barIndices, isSub) {
- var $$ = this, config = $$.config,
- getPoints = $$.generateGetBarPoints(barIndices, isSub);
- return function (d, i) {
- // 4 points that make a bar
- var points = getPoints(d, i);
-
- // switch points if axis is rotated, not applicable for sub chart
- var indexX = config.axis_rotated ? 1 : 0;
- var indexY = config.axis_rotated ? 0 : 1;
-
- var path = 'M ' + points[0][indexX] + ',' + points[0][indexY] + ' ' +
- 'L' + points[1][indexX] + ',' + points[1][indexY] + ' ' +
- 'L' + points[2][indexX] + ',' + points[2][indexY] + ' ' +
- 'L' + points[3][indexX] + ',' + points[3][indexY] + ' ' +
- 'z';
-
- return path;
- };
- };
- c3_chart_internal_fn.generateGetBarPoints = function (barIndices, isSub) {
- var $$ = this,
- axis = isSub ? $$.subXAxis : $$.xAxis,
- barTargetsNum = barIndices.__max__ + 1,
- barW = $$.getBarW(axis, barTargetsNum),
- barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),
- barY = $$.getShapeY(!!isSub),
- barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),
- yScale = isSub ? $$.getSubYScale : $$.getYScale;
- return function (d, i) {
- var y0 = yScale.call($$, d.id)(0),
- offset = barOffset(d, i) || y0, // offset is for stacked bar chart
- posX = barX(d), posY = barY(d);
- // fix posY not to overflow opposite quadrant
- if ($$.config.axis_rotated) {
- if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; }
- }
- // 4 points that make a bar
- return [
- [posX, offset],
- [posX, posY - (y0 - offset)],
- [posX + barW, posY - (y0 - offset)],
- [posX + barW, offset]
- ];
- };
- };
- c3_chart_internal_fn.isWithinBar = function (that) {
- var mouse = this.d3.mouse(that), box = that.getBoundingClientRect(),
- seg0 = that.pathSegList.getItem(0), seg1 = that.pathSegList.getItem(1),
- x = Math.min(seg0.x, seg1.x), y = Math.min(seg0.y, seg1.y),
- w = box.width, h = box.height, offset = 2,
- sx = x - offset, ex = x + w + offset, sy = y + h + offset, ey = y - offset;
- return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy;
- };
-
- c3_chart_internal_fn.initText = function () {
- var $$ = this;
- $$.main.select('.' + CLASS.chart).append("g")
- .attr("class", CLASS.chartTexts);
- $$.mainText = $$.d3.selectAll([]);
- };
- c3_chart_internal_fn.updateTargetsForText = function (targets) {
- var $$ = this, mainTextUpdate, mainTextEnter,
- classChartText = $$.classChartText.bind($$),
- classTexts = $$.classTexts.bind($$),
- classFocus = $$.classFocus.bind($$);
- mainTextUpdate = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText)
- .data(targets)
- .attr('class', function (d) { return classChartText(d) + classFocus(d); });
- mainTextEnter = mainTextUpdate.enter().append('g')
- .attr('class', classChartText)
- .style('opacity', 0)
- .style("pointer-events", "none");
- mainTextEnter.append('g')
- .attr('class', classTexts);
- };
- c3_chart_internal_fn.updateText = function (durationForExit) {
- var $$ = this, config = $$.config,
- barOrLineData = $$.barOrLineData.bind($$),
- classText = $$.classText.bind($$);
- $$.mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text)
- .data(barOrLineData);
- $$.mainText.enter().append('text')
- .attr("class", classText)
- .attr('text-anchor', function (d) { return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'; })
- .style("stroke", 'none')
- .style("fill", function (d) { return $$.color(d); })
- .style("fill-opacity", 0);
- $$.mainText
- .text(function (d, i, j) { return $$.dataLabelFormat(d.id)(d.value, d.id, i, j); });
- $$.mainText.exit()
- .transition().duration(durationForExit)
- .style('fill-opacity', 0)
- .remove();
- };
- c3_chart_internal_fn.redrawText = function (xForText, yForText, forFlow, withTransition) {
- return [
- (withTransition ? this.mainText.transition() : this.mainText)
- .attr('x', xForText)
- .attr('y', yForText)
- .style("fill", this.color)
- .style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this))
- ];
- };
- c3_chart_internal_fn.getTextRect = function (text, cls, element) {
- var dummy = this.d3.select('body').append('div').classed('c3', true),
- svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0),
- font = this.d3.select(element).style('font'),
- rect;
- svg.selectAll('.dummy')
- .data([text])
- .enter().append('text')
- .classed(cls ? cls : "", true)
- .style('font', font)
- .text(text)
- .each(function () { rect = this.getBoundingClientRect(); });
- dummy.remove();
- return rect;
- };
- c3_chart_internal_fn.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {
- var $$ = this,
- getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),
- getBarPoints = $$.generateGetBarPoints(barIndices, false),
- getLinePoints = $$.generateGetLinePoints(lineIndices, false),
- getter = forX ? $$.getXForText : $$.getYForText;
- return function (d, i) {
- var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints;
- return getter.call($$, getPoints(d, i), d, this);
- };
- };
- c3_chart_internal_fn.getXForText = function (points, d, textElement) {
- var $$ = this,
- box = textElement.getBoundingClientRect(), xPos, padding;
- if ($$.config.axis_rotated) {
- padding = $$.isBarType(d) ? 4 : 6;
- xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);
- } else {
- xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];
- }
- // show labels regardless of the domain if value is null
- if (d.value === null) {
- if (xPos > $$.width) {
- xPos = $$.width - box.width;
- } else if (xPos < 0) {
- xPos = 4;
- }
- }
- return xPos;
- };
- c3_chart_internal_fn.getYForText = function (points, d, textElement) {
- var $$ = this,
- box = textElement.getBoundingClientRect(),
- yPos;
- if ($$.config.axis_rotated) {
- yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;
- } else {
- yPos = points[2][1];
- if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) {
- yPos += box.height;
- if ($$.isBarType(d) && $$.isSafari()) {
- yPos -= 3;
- }
- else if (!$$.isBarType(d) && $$.isChrome()) {
- yPos += 3;
- }
- } else {
- yPos += $$.isBarType(d) ? -3 : -6;
- }
- }
- // show labels regardless of the domain if value is null
- if (d.value === null && !$$.config.axis_rotated) {
- if (yPos < box.height) {
- yPos = box.height;
- } else if (yPos > this.height) {
- yPos = this.height - 4;
- }
- }
- return yPos;
- };
-
- c3_chart_internal_fn.setTargetType = function (targetIds, type) {
- var $$ = this, config = $$.config;
- $$.mapToTargetIds(targetIds).forEach(function (id) {
- $$.withoutFadeIn[id] = (type === config.data_types[id]);
- config.data_types[id] = type;
- });
- if (!targetIds) {
- config.data_type = type;
- }
- };
- c3_chart_internal_fn.hasType = function (type, targets) {
- var $$ = this, types = $$.config.data_types, has = false;
- targets = targets || $$.data.targets;
- if (targets && targets.length) {
- targets.forEach(function (target) {
- var t = types[target.id];
- if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) {
- has = true;
- }
- });
- } else if (Object.keys(types).length) {
- Object.keys(types).forEach(function (id) {
- if (types[id] === type) { has = true; }
- });
- } else {
- has = $$.config.data_type === type;
- }
- return has;
- };
- c3_chart_internal_fn.hasArcType = function (targets) {
- return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets);
- };
- c3_chart_internal_fn.isLineType = function (d) {
- var config = this.config, id = isString(d) ? d : d.id;
- return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0;
- };
- c3_chart_internal_fn.isStepType = function (d) {
- var id = isString(d) ? d : d.id;
- return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
- };
- c3_chart_internal_fn.isSplineType = function (d) {
- var id = isString(d) ? d : d.id;
- return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;
- };
- c3_chart_internal_fn.isAreaType = function (d) {
- var id = isString(d) ? d : d.id;
- return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
- };
- c3_chart_internal_fn.isBarType = function (d) {
- var id = isString(d) ? d : d.id;
- return this.config.data_types[id] === 'bar';
- };
- c3_chart_internal_fn.isScatterType = function (d) {
- var id = isString(d) ? d : d.id;
- return this.config.data_types[id] === 'scatter';
- };
- c3_chart_internal_fn.isPieType = function (d) {
- var id = isString(d) ? d : d.id;
- return this.config.data_types[id] === 'pie';
- };
- c3_chart_internal_fn.isGaugeType = function (d) {
- var id = isString(d) ? d : d.id;
- return this.config.data_types[id] === 'gauge';
- };
- c3_chart_internal_fn.isDonutType = function (d) {
- var id = isString(d) ? d : d.id;
- return this.config.data_types[id] === 'donut';
- };
- c3_chart_internal_fn.isArcType = function (d) {
- return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);
- };
- c3_chart_internal_fn.lineData = function (d) {
- return this.isLineType(d) ? [d] : [];
- };
- c3_chart_internal_fn.arcData = function (d) {
- return this.isArcType(d.data) ? [d] : [];
- };
- /* not used
- function scatterData(d) {
- return isScatterType(d) ? d.values : [];
- }
- */
- c3_chart_internal_fn.barData = function (d) {
- return this.isBarType(d) ? d.values : [];
- };
- c3_chart_internal_fn.lineOrScatterData = function (d) {
- return this.isLineType(d) || this.isScatterType(d) ? d.values : [];
- };
- c3_chart_internal_fn.barOrLineData = function (d) {
- return this.isBarType(d) || this.isLineType(d) ? d.values : [];
- };
- c3_chart_internal_fn.isInterpolationType = function (type) {
- return ['linear', 'linear-closed', 'basis', 'basis-open', 'basis-closed', 'bundle', 'cardinal', 'cardinal-open', 'cardinal-closed', 'monotone'].indexOf(type) >= 0;
- };
-
- c3_chart_internal_fn.initGrid = function () {
- var $$ = this, config = $$.config, d3 = $$.d3;
- $$.grid = $$.main.append('g')
- .attr("clip-path", $$.clipPathForGrid)
- .attr('class', CLASS.grid);
- if (config.grid_x_show) {
- $$.grid.append("g").attr("class", CLASS.xgrids);
- }
- if (config.grid_y_show) {
- $$.grid.append('g').attr('class', CLASS.ygrids);
- }
- if (config.grid_focus_show) {
- $$.grid.append('g')
- .attr("class", CLASS.xgridFocus)
- .append('line')
- .attr('class', CLASS.xgridFocus);
- }
- $$.xgrid = d3.selectAll([]);
- if (!config.grid_lines_front) { $$.initGridLines(); }
- };
- c3_chart_internal_fn.initGridLines = function () {
- var $$ = this, d3 = $$.d3;
- $$.gridLines = $$.main.append('g')
- .attr("clip-path", $$.clipPathForGrid)
- .attr('class', CLASS.grid + ' ' + CLASS.gridLines);
- $$.gridLines.append('g').attr("class", CLASS.xgridLines);
- $$.gridLines.append('g').attr('class', CLASS.ygridLines);
- $$.xgridLines = d3.selectAll([]);
- };
- c3_chart_internal_fn.updateXGrid = function (withoutUpdate) {
- var $$ = this, config = $$.config, d3 = $$.d3,
- xgridData = $$.generateGridData(config.grid_x_type, $$.x),
- tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;
-
- $$.xgridAttr = config.axis_rotated ? {
- 'x1': 0,
- 'x2': $$.width,
- 'y1': function (d) { return $$.x(d) - tickOffset; },
- 'y2': function (d) { return $$.x(d) - tickOffset; }
- } : {
- 'x1': function (d) { return $$.x(d) + tickOffset; },
- 'x2': function (d) { return $$.x(d) + tickOffset; },
- 'y1': 0,
- 'y2': $$.height
- };
-
- $$.xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid)
- .data(xgridData);
- $$.xgrid.enter().append('line').attr("class", CLASS.xgrid);
- if (!withoutUpdate) {
- $$.xgrid.attr($$.xgridAttr)
- .style("opacity", function () { return +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1') === (config.axis_rotated ? $$.height : 0) ? 0 : 1; });
- }
- $$.xgrid.exit().remove();
- };
-
- c3_chart_internal_fn.updateYGrid = function () {
- var $$ = this, config = $$.config,
- gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);
- $$.ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid)
- .data(gridValues);
- $$.ygrid.enter().append('line')
- .attr('class', CLASS.ygrid);
- $$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0)
- .attr("x2", config.axis_rotated ? $$.y : $$.width)
- .attr("y1", config.axis_rotated ? 0 : $$.y)
- .attr("y2", config.axis_rotated ? $$.height : $$.y);
- $$.ygrid.exit().remove();
- $$.smoothLines($$.ygrid, 'grid');
- };
-
- c3_chart_internal_fn.gridTextAnchor = function (d) {
- return d.position ? d.position : "end";
- };
- c3_chart_internal_fn.gridTextDx = function (d) {
- return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4;
- };
- c3_chart_internal_fn.xGridTextX = function (d) {
- return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0;
- };
- c3_chart_internal_fn.yGridTextX = function (d) {
- return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width;
- };
- c3_chart_internal_fn.updateGrid = function (duration) {
- var $$ = this, main = $$.main, config = $$.config,
- xgridLine, ygridLine, yv;
-
- // hide if arc type
- $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
-
- main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
- if (config.grid_x_show) {
- $$.updateXGrid();
- }
- $$.xgridLines = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine)
- .data(config.grid_x_lines);
- // enter
- xgridLine = $$.xgridLines.enter().append('g')
- .attr("class", function (d) { return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : ''); });
- xgridLine.append('line')
- .style("opacity", 0);
- xgridLine.append('text')
- .attr("text-anchor", $$.gridTextAnchor)
- .attr("transform", config.axis_rotated ? "" : "rotate(-90)")
- .attr('dx', $$.gridTextDx)
- .attr('dy', -5)
- .style("opacity", 0);
- // udpate
- // done in d3.transition() of the end of this function
- // exit
- $$.xgridLines.exit().transition().duration(duration)
- .style("opacity", 0)
- .remove();
-
- // Y-Grid
- if (config.grid_y_show) {
- $$.updateYGrid();
- }
- $$.ygridLines = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine)
- .data(config.grid_y_lines);
- // enter
- ygridLine = $$.ygridLines.enter().append('g')
- .attr("class", function (d) { return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : ''); });
- ygridLine.append('line')
- .style("opacity", 0);
- ygridLine.append('text')
- .attr("text-anchor", $$.gridTextAnchor)
- .attr("transform", config.axis_rotated ? "rotate(-90)" : "")
- .attr('dx', $$.gridTextDx)
- .attr('dy', -5)
- .style("opacity", 0);
- // update
- yv = $$.yv.bind($$);
- $$.ygridLines.select('line')
- .transition().duration(duration)
- .attr("x1", config.axis_rotated ? yv : 0)
- .attr("x2", config.axis_rotated ? yv : $$.width)
- .attr("y1", config.axis_rotated ? 0 : yv)
- .attr("y2", config.axis_rotated ? $$.height : yv)
- .style("opacity", 1);
- $$.ygridLines.select('text')
- .transition().duration(duration)
- .attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$))
- .attr("y", yv)
- .text(function (d) { return d.text; })
- .style("opacity", 1);
- // exit
- $$.ygridLines.exit().transition().duration(duration)
- .style("opacity", 0)
- .remove();
- };
- c3_chart_internal_fn.redrawGrid = function (withTransition) {
- var $$ = this, config = $$.config, xv = $$.xv.bind($$),
- lines = $$.xgridLines.select('line'),
- texts = $$.xgridLines.select('text');
- return [
- (withTransition ? lines.transition() : lines)
- .attr("x1", config.axis_rotated ? 0 : xv)
- .attr("x2", config.axis_rotated ? $$.width : xv)
- .attr("y1", config.axis_rotated ? xv : 0)
- .attr("y2", config.axis_rotated ? xv : $$.height)
- .style("opacity", 1),
- (withTransition ? texts.transition() : texts)
- .attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$))
- .attr("y", xv)
- .text(function (d) { return d.text; })
- .style("opacity", 1)
- ];
- };
- c3_chart_internal_fn.showXGridFocus = function (selectedData) {
- var $$ = this, config = $$.config,
- dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); }),
- focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),
- xx = $$.xx.bind($$);
- if (! config.tooltip_show) { return; }
- // Hide when scatter plot exists
- if ($$.hasType('scatter') || $$.hasArcType()) { return; }
- focusEl
- .style("visibility", "visible")
- .data([dataToShow[0]])
- .attr(config.axis_rotated ? 'y1' : 'x1', xx)
- .attr(config.axis_rotated ? 'y2' : 'x2', xx);
- $$.smoothLines(focusEl, 'grid');
- };
- c3_chart_internal_fn.hideXGridFocus = function () {
- this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
- };
- c3_chart_internal_fn.updateXgridFocus = function () {
- var $$ = this, config = $$.config;
- $$.main.select('line.' + CLASS.xgridFocus)
- .attr("x1", config.axis_rotated ? 0 : -10)
- .attr("x2", config.axis_rotated ? $$.width : -10)
- .attr("y1", config.axis_rotated ? -10 : 0)
- .attr("y2", config.axis_rotated ? -10 : $$.height);
- };
- c3_chart_internal_fn.generateGridData = function (type, scale) {
- var $$ = this,
- gridData = [], xDomain, firstYear, lastYear, i,
- tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size();
- if (type === 'year') {
- xDomain = $$.getXDomain();
- firstYear = xDomain[0].getFullYear();
- lastYear = xDomain[1].getFullYear();
- for (i = firstYear; i <= lastYear; i++) {
- gridData.push(new Date(i + '-01-01 00:00:00'));
- }
- } else {
- gridData = scale.ticks(10);
- if (gridData.length > tickNum) { // use only int
- gridData = gridData.filter(function (d) { return ("" + d).indexOf('.') < 0; });
- }
- }
- return gridData;
- };
- c3_chart_internal_fn.getGridFilterToRemove = function (params) {
- return params ? function (line) {
- var found = false;
- [].concat(params).forEach(function (param) {
- if ((('value' in param && line.value === param.value) || ('class' in param && line['class'] === param['class']))) {
- found = true;
- }
- });
- return found;
- } : function () { return true; };
- };
- c3_chart_internal_fn.removeGridLines = function (params, forX) {
- var $$ = this, config = $$.config,
- toRemove = $$.getGridFilterToRemove(params),
- toShow = function (line) { return !toRemove(line); },
- classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,
- classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;
- $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove)
- .transition().duration(config.transition_duration)
- .style('opacity', 0).remove();
- if (forX) {
- config.grid_x_lines = config.grid_x_lines.filter(toShow);
- } else {
- config.grid_y_lines = config.grid_y_lines.filter(toShow);
- }
- };
-
- c3_chart_internal_fn.initTooltip = function () {
- var $$ = this, config = $$.config, i;
- $$.tooltip = $$.selectChart
- .style("position", "relative")
- .append("div")
- .attr('class', CLASS.tooltipContainer)
- .style("position", "absolute")
- .style("pointer-events", "none")
- .style("display", "none");
- // Show tooltip if needed
- if (config.tooltip_init_show) {
- if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {
- config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);
- for (i = 0; i < $$.data.targets[0].values.length; i++) {
- if (($$.data.targets[0].values[i].x - config.tooltip_init_x) === 0) { break; }
- }
- config.tooltip_init_x = i;
- }
- $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {
- return $$.addName(d.values[config.tooltip_init_x]);
- }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));
- $$.tooltip.style("top", config.tooltip_init_position.top)
- .style("left", config.tooltip_init_position.left)
- .style("display", "block");
- }
- };
- c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {
- var $$ = this, config = $$.config,
- titleFormat = config.tooltip_format_title || defaultTitleFormat,
- nameFormat = config.tooltip_format_name || function (name) { return name; },
- valueFormat = config.tooltip_format_value || defaultValueFormat,
- text, i, title, value, name, bgcolor,
- orderAsc = $$.isOrderAsc();
-
- if (config.data_groups.length === 0) {
- d.sort(function(a, b){
- var v1 = a ? a.value : null, v2 = b ? b.value : null;
- return orderAsc ? v1 - v2 : v2 - v1;
- });
- } else {
- var ids = $$.orderTargets($$.data.targets).map(function (i) {
- return i.id;
- });
- d.sort(function(a, b) {
- var v1 = a ? a.value : null, v2 = b ? b.value : null;
- if (v1 > 0 && v2 > 0) {
- v1 = a ? ids.indexOf(a.id) : null;
- v2 = b ? ids.indexOf(b.id) : null;
- }
- return orderAsc ? v1 - v2 : v2 - v1;
- });
- }
-
- for (i = 0; i < d.length; i++) {
- if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }
-
- if (! text) {
- title = sanitise(titleFormat ? titleFormat(d[i].x) : d[i].x);
- text = "
" + (title || title === 0 ? "
" + title + "
" : "");
- }
-
- value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));
- if (value !== undefined) {
- // Skip elements when their name is set to null
- if (d[i].name === null) { continue; }
- name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));
- bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
-
- text += "