Merge pull request #655 from exodus4d/develop

v1.4.0
This commit is contained in:
Mark Friedrich
2018-07-20 23:40:19 +02:00
committed by GitHub
210 changed files with 5409 additions and 11190 deletions

View File

@@ -1,4 +1,4 @@
## *PATHFINDER*
# ![Pathfinder logo](favicon/favicon-32x32.png "Logo") *PATHFINDER*
Mapping tool for [*EVE ONLINE*](https://www.eveonline.com)
- Project URL [https://www.pathfinder-w.space](https://www.pathfinder-w.space)
@@ -40,11 +40,10 @@ Issues should be reported in the [Issue](https://github.com/exodus4d/pathfinder/
|-- routes.ini --> config - routes
|-- [0755] export/ --> static data
|-- csv/ --> *.csv used by /setup page
|-- json/ --> *.json used by /setup page
|-- sql/ --> DB dump for import (pathfinder.sql)
|-- sql/ --> DB dump for import (eve_universe.sql.zip)
|-- [0755] favicon/ --> Favicons
|-- [0777] history/ --> log files (map history logs) [optional]
|-- [0755] js/ --> JS source files (raw)
|-- [0755] js/ --> JS source files
|-- app/ --> "PASTHFINDER" core files (not used for production)
|-- lib/ --> 3rd partie extension/library (not used for production)
|-- app.js --> require.js config (!required for production!)

View File

@@ -56,5 +56,8 @@ deleteExpiredCacheData = Cron\Cache->deleteExpiredData, @downtime
; delete old statistics (activity log) data
deleteStatisticsData = Cron\StatisticsUpdate->deleteStatisticsData, @weekly
; updates small amount of static system data from CCP API
updateUniverseSystems = Cron\Universe->updateUniverseSystems, @instant
; setup universe DB with static data from ESI
; setup = Cron\Universe->setup, @instant
;setup = Cron\Universe->setup, @instant

View File

@@ -26,12 +26,6 @@ DB_UNIVERSE_NAME = eve_universe
DB_UNIVERSE_USER = root
DB_UNIVERSE_PASS =
; EVE-Online CCP database export
DB_CCP_DNS = mysql:host=localhost;port=3306;dbname=
DB_CCP_NAME = eve_lifeblood_min
DB_CCP_USER = root
DB_CCP_PASS =
; CCP SSO (OAuth2) - visit: https://developers.eveonline.com/applications
CCP_SSO_URL = https://sisilogin.testeveonline.com
CCP_SSO_CLIENT_ID =

View File

@@ -6,7 +6,7 @@ class Cron extends \Prefab {
const
E_Undefined='Undefined property: %s::$%s',
E_Invalid='"%s" is not a valid name: it should only contain alphanumeric characters',
E_NotFound='Job %s doesn\' exist',
E_NotFound='Job %s doesn\'t exist',
E_Callable='Job %s cannot be called';
//@}
@@ -43,6 +43,9 @@ class Cron extends \Prefab {
'hourly'=>'0 * * * *',
);
/** @var bool */
private $windows;
/**
* Set binary path after checking that it can be executed and is CLI
* @param string $path
@@ -113,9 +116,13 @@ class Cron extends \Prefab {
// Failing to do so will cause PHP to hang until the execution of the program ends.
$dir=dirname($this->script);
$file=basename($this->script);
if (@$dir[0]!='/')
if (!preg_match($this->windows?'/^[A-Z]:\\\\/i':'/^\//',$dir))
$dir=getcwd().'/'.$dir;
exec(sprintf('cd "%s";%s %s /cron/%s > /dev/null 2>/dev/null &',$dir,$this->binary,$file,$job));
if ($this->windows) {
pclose(popen(sprintf('start "cron" "%s" "%s\\%s" "/cron/%s"',$this->binary,$dir,$file,$job),'r'));
} else {
exec(sprintf('cd "%s" & %s %s /cron/%s >/dev/null 2>/dev/null &',$dir,$this->binary,$file,$job));
}
return FALSE;
}
$start=microtime(TRUE);
@@ -245,7 +252,8 @@ class Cron extends \Prefab {
foreach(array('php','php-cli') as $path) // try to guess the binary name
if ($this->binary($path))
break;
$this->windows=(bool)preg_match('/^win/i',PHP_OS);
$f3->route(array('GET /cron','GET /cron/@job'),array($this,'route'));
}
}
}

View File

@@ -223,11 +223,11 @@ class Cortex extends Cursor {
protected function applyWhitelist() {
if ($this->dbsType == 'sql') {
// fetch full schema
if (!$this->fluid && isset(self::$schema_cache[$this->table]))
$schema = self::$schema_cache[$this->table];
if (!$this->fluid && isset(self::$schema_cache[$this->table.$this->db->uuid()]))
$schema = self::$schema_cache[$this->table.$this->db->uuid()];
else {
$schema = $this->mapper->schema();
self::$schema_cache[$this->table] = $schema;
self::$schema_cache[$this->table.$this->db->uuid()] = $schema;
}
// apply reduced fields schema
if ($this->whitelist)

View File

@@ -56,8 +56,10 @@ class Connection extends Controller\AccessController {
$connection = Model\BasicModel::getNew('ConnectionModel');
$connection->getById( (int)$connectionData['id'] );
$connectionData['mapId'] = $map;
$connection->setData($connectionData);
$connection->mapId = $map;
$connection->source = $source;
$connection->target = $target;
$connection->copyfrom($connectionData, ['scope', 'type']);
// change the default type for the new connection
$connection->setDefaultTypeData();

View File

@@ -55,9 +55,11 @@ class Map extends Controller\AccessController {
public function initData(\Base $f3){
// expire time in seconds
$expireTimeCache = 60 * 60;
$expireTimeSQL = 60 * 60 * 12;
if( !$f3->exists(self::CACHE_KEY_INIT, $return )){
// response should not be cached if invalid -> e.g. missing static data
$validInitData = true;
$return = (object) [];
$return->error = [];
@@ -66,7 +68,7 @@ class Map extends Controller\AccessController {
// get all available map types ----------------------------------------------------------------------------
$mapType = Model\BasicModel::getNew('MapTypeModel');
$rows = $mapType->find('active = 1', null, $expireTimeSQL);
$rows = $mapType->find('active = 1');
// default map type config
$mapsDefaultConfig = Config::getMapsDefaultConfig();
@@ -83,9 +85,11 @@ class Map extends Controller\AccessController {
}
$return->mapTypes = $mapTypeData;
$validInitData = $validInitData ? !empty($mapTypeData) : $validInitData;
// get all available map scopes ---------------------------------------------------------------------------
$mapScope = Model\BasicModel::getNew('MapScopeModel');
$rows = $mapScope->find('active = 1', null, $expireTimeSQL);
$rows = $mapScope->find('active = 1');
$mapScopeData = [];
foreach((array)$rows as $rowData){
$data = [
@@ -96,9 +100,11 @@ class Map extends Controller\AccessController {
}
$return->mapScopes = $mapScopeData;
$validInitData = $validInitData ? !empty($mapScopeData) : $validInitData;
// get all available system status ------------------------------------------------------------------------
$systemStatus = Model\BasicModel::getNew('SystemStatusModel');
$rows = $systemStatus->find('active = 1', null, $expireTimeSQL);
$rows = $systemStatus->find('active = 1');
$systemScopeData = [];
foreach((array)$rows as $rowData){
$data = [
@@ -110,9 +116,11 @@ class Map extends Controller\AccessController {
}
$return->systemStatus = $systemScopeData;
$validInitData = $validInitData ? !empty($systemScopeData) : $validInitData;
// get all available system types -------------------------------------------------------------------------
$systemType = Model\BasicModel::getNew('SystemTypeModel');
$rows = $systemType->find('active = 1', null, $expireTimeSQL);
$rows = $systemType->find('active = 1');
$systemTypeData = [];
foreach((array)$rows as $rowData){
$data = [
@@ -123,9 +131,11 @@ class Map extends Controller\AccessController {
}
$return->systemType = $systemTypeData;
$validInitData = $validInitData ? !empty($systemTypeData) : $validInitData;
// get available connection scopes ------------------------------------------------------------------------
$connectionScope = Model\BasicModel::getNew('ConnectionScopeModel');
$rows = $connectionScope->find('active = 1', null, $expireTimeSQL);
$rows = $connectionScope->find('active = 1');
$connectionScopeData = [];
foreach((array)$rows as $rowData){
$data = [
@@ -137,20 +147,11 @@ class Map extends Controller\AccessController {
}
$return->connectionScopes = $connectionScopeData;
// get available wormhole types ---------------------------------------------------------------------------
$wormholes = Model\BasicModel::getNew('WormholeModel');
$rows = $wormholes->find('id > 0', null, $expireTimeSQL);
$wormholesData = [];
if($rows){
foreach((array)$rows as $rowData){
$wormholesData[$rowData->name] = $rowData->getData();
}
}
$return->wormholes = $wormholesData;
$validInitData = $validInitData ? !empty($connectionScopeData) : $validInitData;
// get available character status -------------------------------------------------------------------------
$characterStatus = Model\BasicModel::getNew('CharacterStatusModel');
$rows = $characterStatus->find('active = 1', null, $expireTimeSQL);
$rows = $characterStatus->find('active = 1');
$characterStatusData = [];
foreach((array)$rows as $rowData){
$data = [
@@ -162,11 +163,13 @@ class Map extends Controller\AccessController {
}
$return->characterStatus = $characterStatusData;
$validInitData = $validInitData ? !empty($characterStatusData) : $validInitData;
// route search config ------------------------------------------------------------------------------------
$return->routeSearch = [
'defaultCount' => Config::getPathfinderData('route.search_default_count'),
'maxDefaultCount' => Config::getPathfinderData('route.max_default_count'),
'limit' => Config::getPathfinderData('route.limit')
'defaultCount' => Config::getPathfinderData('route.search_default_count'),
'maxDefaultCount' => Config::getPathfinderData('route.max_default_count'),
'limit' => Config::getPathfinderData('route.limit')
];
// get program routes -------------------------------------------------------------------------------------
@@ -176,18 +179,18 @@ class Map extends Controller\AccessController {
// get third party APIs -----------------------------------------------------------------------------------
$return->url = [
'ccpImageServer' => Config::getPathfinderData('api.ccp_image_server'),
'zKillboard' => Config::getPathfinderData('api.z_killboard')
'ccpImageServer' => Config::getPathfinderData('api.ccp_image_server'),
'zKillboard' => Config::getPathfinderData('api.z_killboard')
];
// Slack integration status -------------------------------------------------------------------------------
$return->slack = [
'status' => (bool)Config::getPathfinderData('slack.status')
'status' => (bool)Config::getPathfinderData('slack.status')
];
// Slack integration status -------------------------------------------------------------------------------
$return->discord = [
'status' => (bool)Config::getPathfinderData('discord.status')
'status' => (bool)Config::getPathfinderData('discord.status')
];
// structure status ---------------------------------------------------------------------------------------
@@ -198,10 +201,30 @@ class Map extends Controller\AccessController {
}
$return->structureStatus = $structureData;
// universe category data ---------------------------------------------------------------------------------
$return->universeCategories = [65 => Model\Universe\BasicUniverseModel::getNew('CategoryModel')->getById(65)->getData()];
$validInitData = $validInitData ? !empty($structureData) : $validInitData;
$f3->set(self::CACHE_KEY_INIT, $return, $expireTimeCache );
// get available wormhole types ---------------------------------------------------------------------------
$wormhole = Model\Universe\BasicUniverseModel::getNew('WormholeModel');
$wormholesData = [];
if($rows = $wormhole->find(null, ['order' => 'name asc'])){
foreach($rows as $rowData){
$wormholesData[$rowData->name] = $rowData->getData();
}
}
$return->wormholes = $wormholesData;
$validInitData = $validInitData ? !empty($wormholesData) : $validInitData;
// universe category data ---------------------------------------------------------------------------------
$return->universeCategories = [
65 => Model\Universe\BasicUniverseModel::getNew('CategoryModel')->getById(65)->getData()
];
$validInitData = $validInitData ? !empty($return->universeCategories[65]) : $validInitData;
if($validInitData){
$f3->set(self::CACHE_KEY_INIT, $return, $expireTimeCache );
}
}
// Add data that should not be cached =========================================================================
@@ -249,99 +272,115 @@ class Map extends Controller\AccessController {
$map = Model\BasicModel::getNew('MapModel');
/**
* @var $system Model\SystemModel
* @var $mapType Model\MapTypeModel
*/
$system = Model\BasicModel::getNew('SystemModel');
$system->setActivityLogging(false);
$mapType = Model\BasicModel::getNew('MapTypeModel');
$mapType->getById((int)$importData['typeId']);
/**
* @var $connection Model\ConnectionModel
*/
$connection = Model\BasicModel::getNew('ConnectionModel');
$connection->setActivityLogging(false);
// to many systems for import
$mapTypeModel = Model\BasicModel::getNew('MapTypeModel');
$mapTypeModel->getById( (int)$importData['typeId'] );
if( !$mapTypeModel->dry() ){
$defaultConfig = Config::getMapsDefaultConfig($mapTypeModel->name);
if( !$mapType->dry() ){
$defaultConfig = Config::getMapsDefaultConfig($mapType->name);
foreach($importData['mapData'] as $mapData){
if(
isset($mapData['config']) &&
isset($mapData['data'])
){
$mapDataConfig = (array)$mapData['config'];
$mapDataData = (array)$mapData['data'];
if(
isset($mapData['data']['systems']) &&
isset($mapData['data']['connections'])
){
$systemCount = count($mapData['data']['systems']);
if( $systemCount <= $defaultConfig['max_systems']){
/**
* @var $mapScope Model\MapScopeModel
*/
$mapScope = Model\BasicModel::getNew('MapScopeModel');
$mapScope->getById((int)$mapDataConfig['scope']['id']);
$map->setData($mapData['config']);
$map->typeId = (int)$importData['typeId'];
$map->save($activeCharacter);
if( !$mapScope->dry() ){
if(
isset($mapDataData['systems']) &&
isset($mapDataData['connections'])
){
$mapDataSystems = (array)$mapDataData['systems'];
$mapDataConnections = (array)$mapDataData['connections'];
$systemCount = count($mapDataSystems);
if( $systemCount <= $defaultConfig['max_systems']){
// new system IDs will be generated
// therefore we need to temp store a mapping between IDs
$tempSystemIdMapping = [];
$map->copyfrom($mapDataConfig, ['name', 'icon', 'position', 'locked', 'rallyUpdated', 'rallyPoke']);
$map->typeId = $mapType;
$map->scopeId = $mapScope;
$map->save($activeCharacter);
foreach($mapData['data']['systems'] as $systemData){
if(isset($systemData['id'])){
$oldId = (int)$systemData['id'];
// new system IDs will be generated
// therefore we need to temp store a mapping between IDs
$tempSystemIdMapping = [];
$system->setData($systemData);
$system->mapId = $map;
$system->save($activeCharacter);
foreach($mapDataSystems as $systemData){
if(
($oldId = (int)$systemData['id']) &&
($systemId = (int)$systemData['systemId'])
){
$system = $map->getNewSystem($systemId);
$system->copyfrom($systemData, ['alias', 'status', 'locked', 'rallyUpdated', 'rallyPoke', 'position']);
$system = $map->saveSystem($system, $activeCharacter, $system->posX, $system->posY);
$tempSystemIdMapping[$oldId] = $system->id;
$system->reset();
$tempSystemIdMapping[$oldId] = $system->_id;
}
}
}
foreach($mapData['data']['connections'] as $connectionData){
// check if source and target IDs match with new system ID
if(
isset( $tempSystemIdMapping[$connectionData['source']] ) &&
isset( $tempSystemIdMapping[$connectionData['target']] )
){
$connection->setData($connectionData);
$connection->mapId = $map;
$connection->source = $tempSystemIdMapping[$connectionData['source']];
$connection->target = $tempSystemIdMapping[$connectionData['target']];
$connection->save($activeCharacter);
/**
* @var $connection Model\ConnectionModel
*/
$connection = Model\BasicModel::getNew('ConnectionModel');
$connection->setActivityLogging(false);
$connection->reset();
}
}
foreach($mapDataConnections as $connectionData){
// check if source and target IDs match with new system ID
if(
($sourceSystemId = $tempSystemIdMapping[(int)$connectionData['source']]) &&
($targetSystemId = $tempSystemIdMapping[(int)$connectionData['target']])
){
$connection->source = $sourceSystemId;
$connection->target = $targetSystemId;
$connection->copyfrom($connectionData, ['scope', 'type']);
$map->saveConnection($connection, $activeCharacter);
// map access info should not automatically imported
if($map->isPrivate()){
$map->setAccess($activeCharacter);
}elseif($map->isCorporation()){
if($corporation = $activeCharacter->getCorporation()){
$map->setAccess($corporation);
$connection->reset();
}
}
}elseif($map->isAlliance()){
if($alliance = $activeCharacter->getAlliance()){
$map->setAccess($alliance);
// map access info should not automatically imported
if($map->isPrivate()){
$map->setAccess($activeCharacter);
}elseif($map->isCorporation()){
if($corporation = $activeCharacter->getCorporation()){
$map->setAccess($corporation);
}
}elseif($map->isAlliance()){
if($alliance = $activeCharacter->getAlliance()){
$map->setAccess($alliance);
}
}
// broadcast map Access -> and send map Data
$this->broadcastMapAccess($map);
}else{
$maxSystemsError = (object) [];
$maxSystemsError->type = 'error';
$maxSystemsError->message = 'Map has to many systems (' . $systemCount . ').'
.' Max system count is ' . $defaultConfig['max_systems'] . ' for ' . $mapType->name . ' maps.';
$return->error[] = $maxSystemsError;
}
}else{
$maxSystemsError = (object) [];
$maxSystemsError->type = 'error';
$maxSystemsError->message = 'Map has to many systems (' . $systemCount . ').'
.' Max system count is ' . $defaultConfig['max_systems'] . ' for ' . $mapTypeModel->name . ' maps.';
$return->error[] = $maxSystemsError;
// systems || connections missing
$missingConfigError = (object) [];
$missingConfigError->type = 'error';
$missingConfigError->message = 'Map data not valid (systems || connections) missing';
$return->error[] = $missingConfigError;
}
}else{
// systems || connections missing
$missingConfigError = (object) [];
$missingConfigError->type = 'error';
$missingConfigError->message = 'Map data not valid (systems || connections) missing';
$return->error[] = $missingConfigError;
$unknownMapScope= (object) [];
$unknownMapScope->type = 'error';
$unknownMapScope->message = 'Map scope unknown!';
$return->error[] = $unknownMapScope;
}
}else{
// map config || systems/connections missing
@@ -531,14 +570,8 @@ class Map extends Controller\AccessController {
// this makes sure all data is up2date
$map->getById( $map->_id, 0 );
$charactersData = $map->getCharactersData();
$characterIds = array_map(function ($data){
return $data->id;
}, $charactersData);
// broadcast map Access -> and send map Data
$this->broadcastMapAccess($map, $characterIds);
$this->broadcastMapAccess($map);
$return->mapData = $map->getData();
}catch(Exception\ValidationException $e){
@@ -548,7 +581,6 @@ class Map extends Controller\AccessController {
$validationError->message = $e->getMessage();
$return->error[] = $validationError;
}
}else{
// map access denied
$captchaError = (object) [];
@@ -604,15 +636,17 @@ class Map extends Controller\AccessController {
* broadcast characters with map access rights to WebSocket server
* -> if characters with map access found -> broadcast mapData to them
* @param Model\MapModel $map
* @param array $characterIds
* @throws Exception
* @throws Exception\PathfinderException
* @throws \ZMQSocketException
*/
protected function broadcastMapAccess($map, $characterIds){
protected function broadcastMapAccess(Model\MapModel $map){
$mapAccess = [
'id' => $map->_id,
'characterIds' => $characterIds
'characterIds' => array_map(function ($data){
return $data->id;
}, $map->getCharactersData())
];
(new Socket( Config::getSocketUri() ))->sendData('mapAccess', $mapAccess);
@@ -741,12 +775,11 @@ class Map extends Controller\AccessController {
// system belongs to the current map
if(is_object($filteredMap->systems)){
// update
/**
* @var $system Model\SystemModel
*/
$system = $filteredMap->systems->current();
$system->setData($systemData);
$system->copyfrom($systemData, ['alias', 'status', 'position', 'locked', 'rallyUpdated', 'rallyPoke']);
if($system->save($activeCharacter)){
$mapChanged = true;
@@ -765,7 +798,7 @@ class Map extends Controller\AccessController {
// check if the current connection belongs to the current map
$map->filter('connections', ['id = ?', $connectionData['id'] ]);
$filteredMap = $map->find(
['id = ?', $map->id ],
['id = ?', $map->_id ],
['limit' => 1]
);
@@ -776,12 +809,11 @@ class Map extends Controller\AccessController {
// connection belongs to the current map
if(is_object($filteredMap->connections)){
// update
/**
* @var $connection Model\ConnectionModel
*/
$connection = $filteredMap->connections->current();
$connection->setData($connectionData);
$connection->copyfrom($connectionData, ['scope', 'type']);
if($connection->save($activeCharacter)){
$mapChanged = true;
@@ -883,6 +915,8 @@ class Map extends Controller\AccessController {
// data for currently selected system
$return->system = $system->getData();
$return->system->signatures = $system->getSignaturesData();
$return->system->structures = $system->getStructuresData();
}
}
}

View File

@@ -7,11 +7,12 @@
*/
namespace Controller\Api;
use Controller;
use Controller\Ccp\Universe;
use lib\Config;
use Model;
/**
* Routes controller
* Class Route
@@ -101,6 +102,7 @@ class Route extends Controller\AccessController {
* -> (e.g. new system added, connection added/updated, ...)
* @param array $mapIds
* @param array $filterData
* @throws \Exception
*/
private function setDynamicJumpData($mapIds = [], $filterData = []){
// make sure, mapIds are integers (protect against SQL injections)
@@ -171,13 +173,10 @@ class Route extends Controller\AccessController {
}
$query = "SELECT
`system_src`.`regionId` regionId,
`system_src`.`constellationId` constellationId,
`system_src`.`name` systemName,
`system_src`.`systemId` systemId,
(
SELECT
GROUP_CONCAT( NULLIF(`system_tar`.`name`, NULL) SEPARATOR ':')
GROUP_CONCAT( NULLIF(`system_tar`.`systemId`, NULL) SEPARATOR ':')
FROM
`connection` INNER JOIN
`system` system_tar ON
@@ -193,8 +192,7 @@ class Route extends Controller\AccessController {
" . $whereQuery . "
`system_tar`.`id` != `system_src`.`id` AND
`system_tar`.`active` = 1
) jumpNodes,
`system_src`.`trueSec` trueSec
) jumpNodes
FROM
`system` `system_src` INNER JOIN
`map` ON
@@ -211,6 +209,17 @@ class Route extends Controller\AccessController {
$rows = $this->getDB()->exec($query, null, $this->dynamicJumpDataCacheTime);
if(count($rows) > 0){
// enrich $row data with static system data (from universe DB)
$universe = new Universe();
for($i = 0; $i < count($rows); $i++){
if($staticData = $universe->getSystemData($rows[$i]['systemId'])){
$rows[$i]['systemName'] = $staticData->name;
$rows[$i]['constellationId'] = $staticData->constellation->id;
$rows[$i]['regionId'] = $staticData->constellation->region->id;
$rows[$i]['trueSec'] = $staticData->trueSec;
}
}
// update jump data for this instance
$this->updateJumpData($rows);
}
@@ -229,7 +238,7 @@ class Route extends Controller\AccessController {
foreach($rows as &$row){
$regionId = (int)$row['regionId'];
$constId = (int)$row['constellationId'];
$systemName = strtoupper($row['systemName']);
$systemName = (string)($row['systemName']);
$systemId = (int)$row['systemId'];
$secStatus = (float)$row['trueSec'];
@@ -242,19 +251,19 @@ class Route extends Controller\AccessController {
}
// fill "idArray" data ------------------------------------------------------------------------------------
if( !isset($this->idArray[$systemName]) ){
$this->idArray[$systemName] = $systemId;
if( !isset($this->idArray[$systemId]) ){
$this->idArray[$systemId] = $systemName;
}
// fill "jumpArray" data ----------------------------------------------------------------------------------
if( !is_array($this->jumpArray[$systemName]) ){
$this->jumpArray[$systemName] = [];
if( !is_array($this->jumpArray[$systemId]) ){
$this->jumpArray[$systemId] = [];
}
$this->jumpArray[$systemName] = array_merge( explode(':', strtoupper($row['jumpNodes'])), $this->jumpArray[$systemName] );
$this->jumpArray[$systemId] = array_merge(array_map('intval', explode(':', $row['jumpNodes'])), $this->jumpArray[$systemId]);
// add systemId to end (if not already there)
if(end($this->jumpArray[$systemName]) != $systemId){
array_push($this->jumpArray[$systemName],$systemId);
// add systemName to end (if not already there)
if(end($this->jumpArray[$systemId]) != $systemName){
array_push($this->jumpArray[$systemId], $systemName);
}
}
}
@@ -267,24 +276,23 @@ class Route extends Controller\AccessController {
private function filterJumpData($filterData = [], $keepSystems = []){
if($filterData['flag'] == 'secure'){
// remove all systems (TrueSec < 0.5) from search arrays
$this->jumpArray = array_filter($this->jumpArray, function($jumpData) use($keepSystems) {
// systemId is always last entry
$systemId = end($jumpData);
$this->jumpArray = array_filter($this->jumpArray, function($systemId) use($keepSystems) {
$systemNameData = $this->nameArray[$systemId];
$systemSec = $systemNameData[3];
if($systemSec < 0.45 && !in_array($systemId, $keepSystems)){
// remove system from nameArray as well
if(
$systemSec < 0.45 &&
!in_array($systemId, $keepSystems) &&
!preg_match('/^j\d+$/i', $this->idArray[$systemId]) // WHs are supposed to be "secure"
){
// remove system from nameArray and idArray
unset($this->nameArray[$systemId]);
// remove system from idArray as well
$systemName = $systemNameData[0];
unset($this->idArray[$systemName]);
unset($this->idArray[$systemId]);
return false;
}else{
return true;
}
});
}, ARRAY_FILTER_USE_KEY );
}
}
@@ -298,16 +306,16 @@ class Route extends Controller\AccessController {
$info = null;
switch($option){
case 'systemName':
$info = $this->nameArray[ $systemId ][0];
$info = $this->nameArray[$systemId][0];
break;
case 'regionId':
$info = $this->nameArray[ $systemId ][1];
$info = $this->nameArray[$systemId][1];
break;
case 'constellationId':
$info = $this->nameArray[ $systemId ][2];
$info = $this->nameArray[$systemId][2];
break;
case 'trueSec':
$info = $this->nameArray[ $systemId ][3];
$info = $this->nameArray[$systemId][3];
break;
}
@@ -387,13 +395,13 @@ class Route extends Controller\AccessController {
/**
* get formatted jump node data
* @param $systemName
* @param int $systemId
* @return array
*/
protected function getJumpNodeData($systemName) : array {
protected function getJumpNodeData(int $systemId) : array {
return [
'system' => $systemName,
'security' => $this->getSystemInfoBySystemId($this->idArray[$systemName], 'trueSec')
'system' => $this->getSystemInfoBySystemId($systemId, 'systemName'),
'security' => $this->getSystemInfoBySystemId($systemId, 'trueSec')
];
}
@@ -430,6 +438,7 @@ class Route extends Controller\AccessController {
* @param array $mapIds
* @param array $filterData
* @return array
* @throws \Exception
* @throws \Exception\PathfinderException
*/
private function searchRouteCustom(int $systemFromId, int $systemToId, $searchDepth = 0, array $mapIds = [], array $filterData = []) : array {
@@ -454,19 +463,16 @@ class Route extends Controller\AccessController {
// --> don´t filter some systems (e.g. systemFrom, systemTo) even if they are are WH,LS,0.0
$this->filterJumpData($filterData, [$systemFromId, $systemToId]);
$systemFrom = $this->getSystemInfoBySystemId($systemFromId, 'systemName');
$systemTo = $this->getSystemInfoBySystemId($systemToId, 'systemName');
// search route -------------------------------------------------------------------------------------------
// jump counter
$jumpNum = 0;
$depthSearched = 0;
if( isset($this->jumpArray[$systemFrom]) ){
if( isset($this->jumpArray[$systemFromId]) ){
// check if the system we are looking for is a direct neighbour
foreach( $this->jumpArray[$systemFrom] as $n ) {
if ($n == $systemTo) {
foreach( $this->jumpArray[$systemFromId] as $n ) {
if ($n == $systemToId) {
$jumpNum = 2;
$routeData['route'][] = $this->getJumpNodeData($n);
break;
@@ -475,11 +481,11 @@ class Route extends Controller\AccessController {
// system is not a direct neighbour -> search recursive its neighbours
if ($jumpNum == 0) {
$searchResult = $this->graph_find_path( $this->jumpArray, $systemFrom, $systemTo, $searchDepth );
$searchResult = $this->graph_find_path( $this->jumpArray, $systemFromId, $systemToId, $searchDepth );
$depthSearched = $searchResult['depth'];
foreach( $searchResult['path'] as $systemName ) {
foreach( $searchResult['path'] as $systemId ) {
if ($jumpNum > 0) {
$routeData['route'][] = $this->getJumpNodeData($systemName);
$routeData['route'][] = $this->getJumpNodeData($systemId);
}
$jumpNum++;
}
@@ -489,7 +495,7 @@ class Route extends Controller\AccessController {
// route found
$routeData['routePossible'] = true;
// insert "from" system on top
array_unshift($routeData['route'], $this->getJumpNodeData($systemFrom));
array_unshift($routeData['route'], $this->getJumpNodeData($systemFromId));
} else {
// route not found
$routeData['routePossible'] = false;
@@ -512,6 +518,7 @@ class Route extends Controller\AccessController {
* @param array $mapIds
* @param array $filterData
* @return array
* @throws \Exception
* @throws \Exception\PathfinderException
*/
private function searchRouteESI(int $systemFromId, int $systemToId, int $searchDepth = 0, array $mapIds = [], array $filterData = []) : array {
@@ -540,18 +547,16 @@ class Route extends Controller\AccessController {
$this->filterJumpData($filterData, [$systemFromId, $systemToId]);
$connections = [];
foreach($this->jumpArray as $systemSourceName => $jumpData){
foreach($this->jumpArray as $systemSourceId => $jumpData){
$count = count($jumpData);
if($count > 1){
// ... should always > 1
$systemSourceId = (int)$this->idArray[$systemSourceName];
// loop all connections for current source system
foreach($jumpData as $systemTargetName) {
foreach($jumpData as $systemTargetId) {
// skip last entry
if(--$count <= 0){
break;
}
$systemTargetId = (int)$this->idArray[$systemTargetName];
// systemIds exist and wer not removed before in filterJumpData()
if($systemSourceId && $systemTargetId){
@@ -599,8 +604,7 @@ class Route extends Controller\AccessController {
$this->setStaticJumpData();
foreach($result['route'] as $systemId){
$systemName = $this->getSystemInfoBySystemId($systemId, 'systemName');
$routeData['route'][] = $this->getJumpNodeData($systemName);
$routeData['route'][] = $this->getJumpNodeData($systemId);
}
}else{
$depthSearched = $routeData['maxDepth'];

View File

@@ -59,7 +59,7 @@ class Setup extends Controller\Controller {
$controller = new Controller\Ccp\Universe();
switch($type){
case 'Systems':
$length = 200;
$length = 100;
$offset = $count * $length;
$buildInfo = $controller->buildSystemsIndex($offset, $length);
$return->countAll = $buildInfo['countAll'];
@@ -91,11 +91,11 @@ class Setup extends Controller\Controller {
$return->countBuildAll = $categoryUniverseModel->getById($categoryId, 0)->getTypesCount(false);
$return->progress = $percent($return->countAll, $return->countBuildAll);
break;
case 'SystemNeighbourModel':
case 'SystemNeighbour':
// Becomes deprecated with new Universe DB!!!
$this->setupSystemJumpTable();
$return->countAll = 5214;
$return->countAll = (int)$f3->get('REQUIREMENTS.DATA.NEIGHBOURS');
$return->countBuild = Database::instance()->getRowCount('system_neighbour');
$return->countBuildAll = $return->countBuild;
$return->progress = $percent($return->countAll, $return->countBuildAll);
@@ -144,67 +144,87 @@ class Setup extends Controller\Controller {
* for system jump calculation. Call this function manually when CCP adds Systems/Stargates
*/
protected function setupSystemJumpTable(){
$pfDB = $this->getDB('PF');
$ccpDB = $this->getDB('CCP');
$universeDB = $this->getDB('UNIVERSE');
$query = "SELECT
map_sys.solarSystemID system_id,
map_sys.regionID region_id,
map_sys.constellationID constellation_id,
map_sys.solarSystemName system_name,
ROUND( map_sys.security, 4) system_security,
(
SELECT
GROUP_CONCAT( NULLIF(map_sys_inner.solarSystemName, NULL) SEPARATOR ':')
`system`.`id` `systemId`,
`system`.`name` `systemName`,
`system`.`constellationId` `constellationId`,
ROUND( `system`.`securityStatus`, 4) `trueSec`,
`constellation`.`regionId` `regionId`,
(
SELECT
GROUP_CONCAT( NULLIF(`sys_inner`.`id`, NULL) SEPARATOR ':')
FROM
`stargate` INNER JOIN
`system` `sys_inner` ON
`sys_inner`.`id` = `stargate`.`destinationSystemId`
WHERE
`stargate`.`systemId` = `system`.`id`
) `jumpNodes`
FROM
mapSolarSystemJumps map_jump INNER JOIN
mapSolarSystems map_sys_inner ON
map_sys_inner.solarSystemID = map_jump.toSolarSystemID
`system` INNER JOIN
`constellation` ON
`constellation`.`id` = `system`.`constellationId`
WHERE
map_jump.fromSolarSystemID = map_sys.solarSystemID
) system_neighbours
FROM
mapSolarSystems map_sys
HAVING
-- skip systems without neighbors (e.g. WHs)
system_neighbours IS NOT NULL
";
`constellation`.`regionId` != :regionIdJove1 AND
`constellation`.`regionId` != :regionIdJove2 AND
`constellation`.`regionId` != :regionIdJove3 AND
(
`system`.`security` = :ns OR
`system`.`security` = :ls OR
`system`.`security` = :hs
)
";
$rows = $ccpDB->exec($query);
$rows = $universeDB->exec($query, [
':regionIdJove1' => 10000017,
':regionIdJove2' => 10000019,
':regionIdJove3' => 10000004,
':ns' => '0.0',
':ls' => 'L',
':hs' => 'H'
]);
if(count($rows) > 0){
// switch DB back to pathfinder DB
if(count($rows)){
$pfDB = $this->getDB('PF');
// clear cache table
$pfDB->exec("TRUNCATE system_neighbour");
foreach($rows as $row){
if(!$row['jumpNodes']){
// should never happen!
continue;
}
$pfDB->exec("
INSERT INTO
system_neighbour(
regionId,
constellationId,
systemName,
systemId,
jumpNodes,
trueSec
)
VALUES(
:regionId,
:constellationId,
:systemName,
:systemId,
:jumpNodes,
:trueSec
)",
[
':regionId' => $row['region_id'],
':constellationId' => $row['constellation_id'],
':systemName' => $row['system_name'],
':systemId' => $row['system_id'],
':jumpNodes' => $row['system_neighbours'],
':trueSec' => $row['system_security']
]);
INSERT INTO
system_neighbour(
regionId,
constellationId,
systemName,
systemId,
jumpNodes,
trueSec
)
VALUES(
:regionId,
:constellationId,
:systemName,
:systemId,
:jumpNodes,
:trueSec
)",
[
':regionId' => $row['regionId'],
':constellationId' => $row['constellationId'],
':systemName' => $row['systemName'],
':systemId' => $row['systemId'],
':jumpNodes' => $row['jumpNodes'],
':trueSec' => $row['trueSec']
]
);
}
}
}

View File

@@ -13,40 +13,6 @@ use Model;
class Signature extends Controller\AccessController {
/**
* get signature data for systems
* -> return value of this is limited to a "SINGLE" system
* @param \Base $f3
* @throws \Exception
*/
public function getAll(\Base $f3){
$signatureData = [];
$systemIds = (array)$f3->get('POST.systemIds');
if( !empty($systemIds) ){
$activeCharacter = $this->getCharacter();
/**
* @var Model\SystemModel $system
*/
$system = Model\BasicModel::getNew('SystemModel');
foreach($systemIds as $systemId){
$system->getById($systemId);
if(
!$system->dry() &&
$system->hasAccess($activeCharacter)
){
$signatureData = $system->getSignaturesData();
}
$system->reset();
}
}
echo json_encode($signatureData);
}
/**
* save or update a full signature data set
* or save/update just single or multiple signature data
@@ -86,9 +52,6 @@ class Signature extends Controller\AccessController {
// update/add all submitted signatures
foreach($signatureData as $data){
// this key should not be saved (it is an obj)
unset($data['updated']);
$system->getById( (int)$data['systemId'], 0);
if( !$system->dry() ){
@@ -106,16 +69,14 @@ class Signature extends Controller\AccessController {
}
if( is_null($signature) ){
$signature = Model\BasicModel::getNew('SystemSignatureModel');
$signature = $system->rel('signatures');
}
if($signature->dry()){
// new signature
$signature->systemId = $system;
$signature->setData($data);
$signature->copyfrom($data, ['name', 'groupId', 'typeId', 'description', 'connectionId']);
}else{
// update signature
if(
isset($data['name']) &&
isset($data['value'])
@@ -141,9 +102,6 @@ class Signature extends Controller\AccessController {
}else{
// update complete signature (signature reader dialog)
// systemId should not be updated
unset( $data['systemId'] );
// description should not overwrite existing description
if( !empty($signature->description) ){
unset( $data['description'] );
@@ -171,23 +129,14 @@ class Signature extends Controller\AccessController {
}
if( $signature->hasChanged($newData) ){
$signature->setData($newData);
$signature->copyfrom($newData, ['name', 'groupId', 'typeId', 'description', 'connectionId']);
}
}
$signature->save($activeCharacter);
$updatedSignatureIds[] = $signature->id;
$system->saveSignature($signature, $activeCharacter);
// get a fresh signature object with the new data. This is a bad work around!
// but i could not figure out what the problem was when using the signature model, saved above :(
// -> some caching problems
/**
* @var $newSignature Model\SystemSignatureModel
*/
$newSignature = Model\BasicModel::getNew('SystemSignatureModel');
$newSignature->getById( $signature->id, 0);
$return->signatures[] = $newSignature->getData();
$updatedSignatureIds[] = $signature->_id;
$return->signatures[] = $signature->getData();
$signature->reset();
}
@@ -207,13 +156,11 @@ class Signature extends Controller\AccessController {
){
$allSignatures = $system->getSignatures();
foreach($allSignatures as $tempSignature){
if( !in_array($tempSignature->id, $updatedSignatureIds)){
if( !in_array($tempSignature->_id, $updatedSignatureIds)){
$tempSignature->delete( $activeCharacter );
}
}
}
}
}

View File

@@ -34,7 +34,7 @@ class Structure extends Controller\AccessController {
* @var $structure Model\StructureModel
*/
$structure = Model\BasicModel::getNew('StructureModel');
foreach ($structuresData as $structureData){
foreach($structuresData as $structureData){
// reset on loop start because of potential "continue"
$structure->reset();
@@ -46,7 +46,7 @@ class Structure extends Controller\AccessController {
}
}elseif( !isset($structureData['id']) ){
// from clipboard -> search by structure by name
$structure->getByName($activeCharacter->getCorporation(), (string)$structureData['name']);
$structure->getByName($activeCharacter->getCorporation(), (string)$structureData['name'], (int)$structureData['systemId']);
}
$newStructure = $structure->dry();

View File

@@ -9,170 +9,10 @@
namespace Controller\Api;
use Controller;
use Data\Mapper as Mapper;
use lib\Config;
use Model;
class System extends Controller\AccessController {
private $mainQuery = "SELECT
map_sys.constellationID `connstallation_id`,
map_sys.solarSystemID `system_id`,
map_sys.solarSystemName `system_name`,
map_sys.security `system_security`,
map_con.constellationName `constallation_name`,
map_reg.regionID `region_id`,
map_reg.regionName `region_name`,
'0' `trueSec`,
'' `type`,
IFNULL(
(
SELECT
LOWER( system_effect.typeName )
FROM
invTypes system_effect INNER JOIN
mapDenormalize map_norm ON
map_norm.typeID = system_effect.typeID
WHERE
system_effect.groupID = 995 AND
map_norm.solarSystemID = map_sys.solarSystemID
LIMIT 1
), '') `effect`,
IFNULL(
(
SELECT
map_worm_class.wormholeClassID system_class
FROM
mapLocationWormholeClasses map_worm_class
WHERE
map_worm_class.locationID = map_sys.regionID
LIMIT 1
), 7) `security`
FROM
mapSolarSystems map_sys INNER JOIN
mapConstellations map_con ON
map_sys.constellationID = map_con.constellationID INNER JOIN
mapRegions map_reg ON
map_con.regionID = map_reg.regionID";
private $whereQuery = "";
// exclude Jove Space
private $havingQuery = "HAVING
security IS NOT NULL";
private $orderByQuery = "ORDER BY
system_name";
private $limitQuery = "";
/**
* build query
* @return string
*/
private function _getQuery(){
$query = $this->mainQuery;
$query .= ' ' . $this->whereQuery;
$query .= ' ' . $this->havingQuery;
$query .= ' ' . $this->orderByQuery;
$query .= ' ' . $this->limitQuery;
return $query;
}
/**
* get system Data from CCPs [SDE]
* search column for IDs can be (solarSystemID, regionID, constellationID)
* @param array $columnIDs
* @param string $column
* @return Model\SystemModel[]
* @throws \Exception
*/
public function getSystemModelByIds($columnIDs = [], $column = 'solarSystemID'){
$systemModels = [];
$ccpDB = $this->getDB('CCP');
$this->whereQuery = "WHERE
map_sys." . $column . " IN (" . implode(',', $columnIDs) . ")";
$query = $this->_getQuery();
$rows = $ccpDB->exec($query, null, 60 * 60 * 24);
// format result
$ccpSystemsData = (new Mapper\CcpSystemsMapper($rows))->getData();
foreach($ccpSystemsData as $ccpSystemData){
/**
* @var Model\SystemModel $system
*/
$system = Model\BasicModel::getNew('SystemModel');
$system->setData($ccpSystemData);
$systemModels[] = $system;
}
return $systemModels;
}
/**
* Get all static system Data from CCP DB (long cache timer)
* @return array
*/
public function getSystems(){
$ccpDB = $this->getDB('CCP');
$query = $this->_getQuery();
$rows = $ccpDB->exec($query, null, 60 * 60 * 24);
// format result
$mapper = new Mapper\CcpSystemsMapper($rows);
return $mapper->getData();
}
/**
* search systems by name
* @param \Base $f3
* @param array $params
*/
public function search(\Base $f3, $params){
$ccpDB = $this->getDB('CCP');
$searchToken = '';
// check for search parameter
if( isset($params['arg1']) ){
$searchToken = $params['arg1'];
}
// some "edge cases" for testing trueSec rounding...
//$searchToken = 'H472-N'; // -0.000001 -> 0.0
//$searchToken = 'X1E-OQ'; // -0.099426 -> -0.10
//$searchToken = 'BKK4-H'; // -0.049954 -> -0.05
//$searchToken = 'Uhtafal'; // 0.499612 -> 0.5 (HS)
//$searchToken = 'Oshaima'; // 0.453128 -> 0.5 (HS)
//$searchToken = 'Ayeroilen'; // 0.446568 -> 0.4 (LS)
//$searchToken = 'Enderailen'; // 0.448785 -> 0.4 (LS)
//$searchToken = 'Neziel'; // 0.449943 -> 0.4 (LS)
//$searchToken = 'Naga'; // 0.033684 -> 0.1 (LS)
$this->whereQuery = "WHERE
map_sys.solarSystemName LIKE '%" . $searchToken . "%'";
$query = $this->_getQuery();
$rows = $ccpDB->exec($query);
// format result
$mapper = new Mapper\CcpSystemsMapper($rows);
$data = $mapper->getData();
echo json_encode($data);
}
/**
* save a new system to a a map
* @param \Base $f3
@@ -203,59 +43,36 @@ class System extends Controller\AccessController {
}
if( isset($systemData['id']) ){
// update existing system (e.g. changed system description) -------------------------------------------
// update existing system (e.g. set description) ------------------------------------------------------
/**
* @var $system Model\SystemModel
*/
$system = Model\BasicModel::getNew('SystemModel');
$system->getById($systemData['id']);
if( !$system->dry() ){
if( $system->hasAccess($activeCharacter) ){
// system model found
$systemModel = $system;
}
if(
!$system->dry() &&
$system->hasAccess($activeCharacter)
){
// system model found
// activate system (e.g. was inactive))
$system->setActive(true);
$systemModel = $system;
}
}elseif( isset($mapData['id']) ){
// save NEW system ------------------------------------------------------------------------------------
/**
* @var $map Model\MapModel
*/
$map = Model\BasicModel::getNew('MapModel');
$map->getById($mapData['id']);
if( $map->hasAccess($activeCharacter) ){
// make sure system is not already on map
// --> (e.g. multiple simultaneously save() calls for the same system)
$systemModel = $map->getSystemByCCPId($systemData['systemId']);
if( is_null($systemModel) ){
// system not found on map -> get static system data (CCP DB)
$systemModel = $map->getNewSystem($systemData['systemId']);
$defaultStatusId = 1;
}else{
// system already exists (e.g. was inactive)
$defaultStatusId = $systemModel->statusId;
}
if( !is_null($systemModel) ){
$systemModel->statusId = isset($systemData['statusId']) ? $systemData['statusId'] : $defaultStatusId;
}
// map is not changeable for a system! (security)
$systemData['mapId'] = $map;
if($map->hasAccess($activeCharacter)){
$systemModel = $map->getNewSystem($systemData['systemId']);
}
}
if( !is_null($systemModel) ){
// "statusId" was set above
unset($systemData['statusId']);
unset($systemData['mapId']);
// set/update system
$systemModel->setData($systemData);
// activate system (e.g. was inactive))
$systemModel->setActive(true);
// set/update system custom data
$systemModel->copyfrom($systemData, ['locked', 'rallyUpdated', 'position', 'description']);
if($systemModel->save($activeCharacter)){
// get data from "fresh" model (e.g. some relational data has changed: "statusId")
@@ -263,7 +80,7 @@ class System extends Controller\AccessController {
* @var $newSystemModel Model\SystemModel
*/
$newSystemModel = Model\BasicModel::getNew('SystemModel');
$newSystemModel->getById( $systemModel->id, 0);
$newSystemModel->getById( $systemModel->_id, 0);
$newSystemModel->clearCacheData();
$return->systemData = $newSystemModel->getData();
@@ -330,43 +147,6 @@ class System extends Controller\AccessController {
echo json_encode($graphData);
}
/**
* get system data for all systems within a constellation
* @param \Base $f3
* @param array $params
* @throws \Exception
* @throws \Exception\PathfinderException
*/
public function constellationData(\Base $f3, $params){
$return = (object) [];
$return->error = [];
$return->systemData = [];
$constellationId = 0;
// check for search parameter
if( isset($params['arg1']) ){
$constellationId = (int)$params['arg1'];
}
$cacheKey = 'CACHE_CONSTELLATION_SYSTEMS_' . self::formatHiveKey($constellationId);
if($f3->exists($cacheKey, $cachedData)){
$return->systemData = $cachedData;
}else{
if($constellationId > 0){
$systemModels = $this->getSystemModelByIds([$constellationId], 'constellationID');
foreach($systemModels as $systemModel){
$return->systemData[] = $systemModel->getData();
}
$f3->set($cacheKey, $return->systemData, Config::getPathfinderData('cache.constellation_systems'));
}
}
echo json_encode($return);
}
/**
* set destination for specific systemIds
* @param \Base $f3

View File

@@ -10,9 +10,12 @@ namespace Controller\Api;
use Controller;
use Controller\Ccp as Ccp;
use Model;
class Universe extends Controller\AccessController {
const PAGE_SIZE_SYSTEMS = 50;
/**
* search static Universe data by string within categories
* @param \Base $f3
@@ -33,4 +36,93 @@ class Universe extends Controller\AccessController {
echo json_encode($universeNameData);
}
/**
* search systems by name
* @param \Base $f3
* @param $params
* @throws \Exception
*/
public function systems(\Base $f3, $params){
$getData = (array)$f3->get('GET');
$page = isset($getData['page']) ? (int)max($getData['page'],1) : 1;
$search = isset($params['arg1']) ? (string)$params['arg1'] : '';
$morePages = false;
$count = 0;
$return = (object) [];
$return->results = [];
// some "edge cases" for testing trueSec rounding...
//$searchToken = 'H472-N'; // -0.000001 -> 0.0
//$searchToken = 'X1E-OQ'; // -0.099426 -> -0.10
//$searchToken = 'BKK4-H'; // -0.049954 -> -0.05
//$searchToken = 'Uhtafal'; // 0.499612 -> 0.5 (HS)
//$searchToken = 'Oshaima'; // 0.453128 -> 0.5 (HS)
//$searchToken = 'Ayeroilen'; // 0.446568 -> 0.4 (LS)
//$searchToken = 'Enderailen'; // 0.448785 -> 0.4 (LS)
//$searchToken = 'Neziel'; // 0.449943 -> 0.4 (LS)
//$searchToken = 'Naga'; // 0.033684 -> 0.1 (LS)
if( strlen($search) >= 3 ){
$offset = ($page - 1) * self::PAGE_SIZE_SYSTEMS;
$system = Model\Universe\BasicUniverseModel::getNew('SystemModel');
$filter = [
'id LIKE :id OR name LIKE :name',
':id' => $search . '%', // -> match first
':name' => '%' . $search . '%' // -> match between
];
$options = [
'order' => 'name',
'offset' => $offset,
'limit' => self::PAGE_SIZE_SYSTEMS
];
$count = $system->count($filter);
$endCount = $offset + self::PAGE_SIZE_SYSTEMS;
$morePages = $endCount < $count;
$systems = $system->find($filter, $options);
if($systems){
foreach($systems as $system){
if($systemData = $system->fromIndex()){
$return->results[] = $systemData;
}
}
}
}
$return->pagination = ['more' => $morePages, 'count' => $count];
echo json_encode($return);
}
/**
* get system data for all systems within a constellation
* @param \Base $f3
* @param array $params
* @throws \Exception
*/
public function constellationData(\Base $f3, $params){
$constellationId = isset($params['arg1']) ? (int)$params['arg1'] : 0;
$return = (object) [];
$return->error = [];
$return->systemsData = [];
$constellation = Model\Universe\BasicUniverseModel::getNew('ConstellationModel');
$constellation->getById($constellationId);
if( !$constellation->dry() && $constellation->systems){
/**
* @var Model\Universe\SystemModel $system
*/
foreach($constellation->systems as $system){
if($systemData = $system->fromIndex()){
$return->systemsData[] = $systemData;
}
}
}
echo json_encode($return);
}
}

View File

@@ -8,25 +8,12 @@
namespace Controller\Ccp;
use Controller\Controller;
use lib\Util;
use Model;
class Universe extends Controller {
/**
* Set up "Universe" Database
* @param \Base $f3
* @throws \Exception
*/
public function setupDB(\Base $f3){
//$this->setupWormholes($f3);
//var_dump($this->getSystemsIndex());
//var_dump($this->getSystemData(30000001));
//var_dump($this->getSystemData(30000002));
//var_dump($this->getSystemData('Lashesih'));
}
/* currently not used
protected function setupRegions(\Base $f3){
@@ -101,7 +88,7 @@ class Universe extends Controller {
* @return array
* @throws \Exception
*/
public function setupCategories(array $categoriesWhitelist = []){
protected function setupCategories(array $categoriesWhitelist = []){
$return = [];
$categoryIds = $this->getF3()->ccpClient->getUniverseCategories();
$categoryIds = array_intersect ($categoriesWhitelist, $categoryIds);
@@ -137,6 +124,8 @@ class Universe extends Controller {
return $return;
}
// system search index methods ====================================================================================
/**
* build search index from all systems data
* @param int $offset
@@ -144,7 +133,7 @@ class Universe extends Controller {
* @return array
* @throws \Exception
*/
public function buildSystemsIndex(int $offset = 0, int $length = 10){
public function buildSystemsIndex(int $offset = 0, int $length = 10) : array {
/**
* @var $system Model\Universe\SystemModel
*/
@@ -194,15 +183,26 @@ class Universe extends Controller {
/**
* look for existing systemData in index
* -> id is either a valid systemId OR systemName
* @param int|string $id
* -> if not exists -> try to build
* @param int $systemId
* @return null|\stdClass
* @throws \Exception
*/
protected function getSystemData($id){
public function getSystemData(int $systemId){
$data = null;
if($id){
$cacheKeyRow = Model\Universe\BasicUniverseModel::generateHashKeyRow('system', $id);
if($systemId){
// ...check index for data
$cacheKeyRow = Model\Universe\BasicUniverseModel::generateHashKeyRow('system', $systemId);
$data = $this->get($cacheKeyRow);
if(!$data){
// .. try to build index
/**
* @var $system Model\Universe\SystemModel
*/
$system = Model\Universe\BasicUniverseModel::getNew('SystemModel');
$system->getById($systemId);
$data = $system->buildIndex();
}
}
return $data;
}
@@ -212,7 +212,7 @@ class Universe extends Controller {
* @param string $cacheKey
* @return null|\stdClass
*/
protected function get(string $cacheKey){
private function get(string $cacheKey){
$data = null;
if($this->getF3()->exists($cacheKey,$value)) {
if(is_string($value) && strpos($value, Model\Universe\BasicUniverseModel::CACHE_KEY_PREFIX) === 0) {
@@ -230,7 +230,7 @@ class Universe extends Controller {
* clear cacheKey
* @param string $cacheKey
*/
protected function clear(string $cacheKey){
private function clear(string $cacheKey){
if($this->getF3()->exists($cacheKey,$value)) {
if(is_string($value) && strpos($value, Model\Universe\BasicUniverseModel::CACHE_KEY_PREFIX) === 0) {
// value references another cacheKey -> clear that one as well

View File

@@ -112,7 +112,6 @@ class Controller {
* @param \Base $f3
*/
protected function initSession(\Base $f3){
$sessionCacheKey = $f3->get('SESSION_CACHE');
$session = null;
/**
@@ -135,10 +134,13 @@ class Controller {
};
if(
$sessionCacheKey === 'mysql' &&
$f3->get('SESSION_CACHE') === 'mysql' &&
$this->getDB('PF') instanceof DB\SQL
){
$session = new DB\SQL\Session($this->getDB('PF'), 'sessions', true, $onSuspect);
if(!headers_sent() && session_status()!=PHP_SESSION_ACTIVE){
$session = new DB\SQL\Session($this->getDB('PF'), 'sessions', true, $onSuspect);
}
}
}
@@ -597,6 +599,24 @@ class Controller {
return $userAgent;
}
/**
* print error information in CLI mode
* @param \stdClass $error
*/
protected function echoErrorCLI(\stdClass $error){
echo '[' . date('H:i:s') . '] ───────────────────────────' . PHP_EOL;
foreach(get_object_vars($error) as $key => $value){
$row = str_pad(' ',2 ) . str_pad($key . ':',10 );
if($key == 'trace'){
$value = preg_replace("/\r\n|\r|\n/", "\n" . str_pad(' ',12 ), $value);
$row .= PHP_EOL . str_pad(' ',12 ) . $value;
}else{
$row .= $value;
}
echo $row . PHP_EOL;
}
}
/**
* onError() callback function
* -> on AJAX request -> return JSON with error information
@@ -631,7 +651,11 @@ class Controller {
$f3->status($error->code);
}
if($f3->get('AJAX')){
if($f3->get('CLI')){
$this->echoErrorCLI($error);
// no further processing (no HTML output)
return false;
}elseif($f3->get('AJAX')){
$return = (object) [];
$return->error[] = $error;
echo json_encode($return);

View File

@@ -32,10 +32,10 @@ class Setup extends Controller {
'DB_PF_NAME',
'DB_PF_USER',
'DB_PF_PASS',
'DB_CCP_DNS',
'DB_CCP_NAME',
'DB_CCP_USER',
'DB_CCP_PASS',
'DB_UNIVERSE_DNS',
'DB_UNIVERSE_NAME',
'DB_UNIVERSE_USER',
'DB_UNIVERSE_PASS',
'CCP_SSO_URL',
'CCP_SSO_CLIENT_ID',
'CCP_SSO_SECRET_KEY',
@@ -67,7 +67,6 @@ class Setup extends Controller {
'Model\SystemTypeModel',
'Model\SystemStatusModel',
'Model\SystemNeighbourModel',
'Model\WormholeModel',
'Model\RightModel',
'Model\RoleModel',
'Model\StructureModel',
@@ -89,8 +88,6 @@ class Setup extends Controller {
'Model\CharacterLogModel',
'Model\SystemModel',
'Model\SystemWormholeModel',
'Model\ConstellationWormholeModel',
'Model\ConnectionModel',
'Model\ConnectionLogModel',
@@ -102,8 +99,7 @@ class Setup extends Controller {
'Model\SystemPodKillModel',
'Model\SystemFactionKillModel',
'Model\SystemJumpModel'
],
'tables' => []
]
],
'UNIVERSE' => [
'info' => [],
@@ -112,30 +108,15 @@ class Setup extends Controller {
'Model\Universe\GroupModel',
'Model\Universe\CategoryModel',
'Model\Universe\StructureModel',
// 'Model\Universe\WormholeModel',
// 'Model\Universe\StargateModel',
// 'Model\Universe\StarModel',
// 'Model\Universe\PlanetModel',
// 'Model\Universe\SystemModel',
// 'Model\Universe\ConstellationModel',
// 'Model\Universe\RegionModel',
// 'Model\Universe\SystemStaticModel'
],
'tables' => []
],
'CCP' => [
'info' => [],
'models' => [],
'tables' => [
'invTypes',
'mapConstellations',
'mapDenormalize',
'mapLocationWormholeClasses',
'mapRegions',
'mapSolarSystemJumps',
'mapSolarSystems'
'Model\Universe\WormholeModel',
'Model\Universe\StargateModel',
'Model\Universe\StarModel',
'Model\Universe\PlanetModel',
'Model\Universe\SystemModel',
'Model\Universe\ConstellationModel',
'Model\Universe\RegionModel',
'Model\Universe\SystemStaticModel'
]
]
];
@@ -277,98 +258,6 @@ class Setup extends Controller {
$f3->set('cacheSize', $this->getCacheData($f3));
}
/**
* IMPORTANT: This function is not required for setup. It just imports *.json -> DB
*
* imports wormhole static data for "shattered" systems
* into table "system_wormhole"
* -> a *.csv dump of this *.json file can e found under /export/csv
* @param \Base $f3
* @throws \Exception
*/
protected function importSystemWormholesFromJson(\Base $f3){
$path = $f3->get('EXPORT') .'json/statics.json';
$pfDB = $this->getDB('PF');
$ccpDB = $this->getDB('CCP');
$content = file_get_contents($path);
$jsonIterator = new \RecursiveIteratorIterator(
new \RecursiveArrayIterator(json_decode($content, TRUE)),
\RecursiveIteratorIterator::SELF_FIRST);
$staticNames = [];
$data = [];
$tmpVal = (object) [];
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
if(isset($tmpVal->name)){
$data[] = $tmpVal;
}
$tmpVal = (object) [];
$tmpVal->name = $key;
} else {
$tmpVal->wh = isset($tmpVal->wh) ? array_merge($tmpVal->wh, [$val]) : [$val];
$staticNames[] = $val;
}
}
$data[] = $tmpVal;
// get static IDs by name ------------------------------
$staticNames = array_unique($staticNames);
$staticNames = array_flip($staticNames);
foreach($staticNames as $name => $index){
$result = $pfDB->exec("
SELECT
id
FROM " . $pfDB->quotekey(Model\BasicModel::getNew('WormholeModel')->getTable()) . "
WHERE " . $pfDB->quotekey('name') . " = :name",
[':name' => $name]
);
$id = (int)$result[0]['id'];
if($id){
$staticNames[$name] = (int)$result[0]['id'];
}else{
$f3->error(500, 'Wormhole data missing in table "wormhole" for "name" = "' . $name . '"');
}
}
// import data -----------------------------------------
$systemWormhole = Model\BasicModel::getNew('SystemWormholeModel');
foreach($data as $staticData){
$result = $ccpDB->exec("
SELECT
solarSystemID
FROM " . $ccpDB->quotekey('mapSolarSystems') . "
WHERE
" . $ccpDB->quotekey('solarSystemName') . " = :systemName",
[':systemName' => $staticData->name]
);
$solarSystemID = (int)$result[0]['solarSystemID'];
if($solarSystemID){
foreach($staticData->wh as $wh){
$staticId = (int)$staticNames[$wh];
if($staticId){
// check if entry already exists
$systemWormhole->load(['systemId=? AND wormholeId=?', $solarSystemID, $staticId]);
if( $systemWormhole->dry() ){
$systemWormhole->systemId = $solarSystemID;
$systemWormhole->wormholeId = $staticId;
$systemWormhole->save();
$systemWormhole->reset();
}
}else{
$f3->error(500, 'Wormhole data missing for "name" = "' . $wh . '"');
}
}
}else{
$f3->error(500, 'System "' . $staticData->name . '" not found on CCP´s [SDE] database');
}
}
}
/**
* set environment information
* @param \Base $f3
@@ -378,8 +267,8 @@ class Setup extends Controller {
$environmentData = [];
// exclude some sensitive data (e.g. database, passwords)
$excludeVars = [
'DB_PF_DNS', 'DB_PF_NAME', 'DB_PF_USER', 'DB_PF_PASS',
'DB_CCP_DNS', 'DB_CCP_NAME', 'DB_CCP_USER', 'DB_CCP_PASS'
'DB_PF_DNS', 'DB_PF_NAME', 'DB_PF_USER', 'DB_PF_PASS',
'DB_UNIVERSE_DNS', 'DB_UNIVERSE_NAME', 'DB_UNIVERSE_USER', 'DB_UNIVERSE_PASS'
];
// obscure some values
@@ -651,6 +540,13 @@ class Setup extends Controller {
'check' => function_exists('exec') == $f3->get('REQUIREMENTS.PHP.EXEC'),
'tooltip' => 'exec() funktion. Check "disable_functions" in php.ini'
],
'memoryLimit' => [
'label' => 'memory_limit',
'required' => $f3->get('REQUIREMENTS.PHP.MEMORY_LIMIT'),
'version' => ini_get('memory_limit'),
'check' => ini_get('memory_limit') >= $f3->get('REQUIREMENTS.PHP.MEMORY_LIMIT'),
'tooltip' => 'PHP default = 64MB.'
],
'maxInputVars' => [
'label' => 'max_input_vars',
'required' => $f3->get('REQUIREMENTS.PHP.MAX_INPUT_VARS'),
@@ -885,7 +781,6 @@ class Setup extends Controller {
switch($dbKey){
case 'PF': $dbLabel = 'Pathfinder'; break;
case 'UNIVERSE': $dbLabel = 'EVE-Online universe'; break;
case 'CCP': $dbLabel = 'EVE-Online [SDE]'; break;
}
$dbName = $dbConfigValues['NAME'];
@@ -912,15 +807,6 @@ class Setup extends Controller {
];
}
break;
case 'CCP':
// get table model from static table array
foreach($dbData['tables'] as $tableName){
$requiredTables[$tableName] = [
'exists' => false,
'empty' => true
];
}
break;
}
// db connect was successful
@@ -1352,14 +1238,10 @@ class Setup extends Controller {
// active DB and tables are required for obtain index data
if(!$this->databaseHasError){
$categoryUniverseModel = Model\Universe\BasicUniverseModel::getNew('CategoryModel');
//$systemUniverseModel = Model\Universe\BasicUniverseModel::getNew('SystemModel');
$systemUniverseModel = Model\Universe\BasicUniverseModel::getNew('SystemModel');
$systemNeighbourModel = Model\BasicModel::getNew('SystemNeighbourModel');
$wormholeModel = Model\BasicModel::getNew('WormholeModel');
$systemWormholeModel = Model\BasicModel::getNew('SystemWormholeModel');
$constellationWormholeModel = Model\BasicModel::getNew('ConstellationWormholeModel');
$indexInfo = [
/*
'Systems' => [
'task' => [
[
@@ -1378,7 +1260,7 @@ class Setup extends Controller {
'countBuild' => count((new Universe())->getSystemsIndex()),
'countAll' => $this->dbLib->getRowCount($systemUniverseModel->getTable(), 'UNIVERSE'),
'tooltip' => 'build up a static search index over all systems found on DB. Do not refresh page until import is complete (check progress)! Runtime: ~5min'
], */
],
'Structures' => [
'task' => [
[
@@ -1392,7 +1274,7 @@ class Setup extends Controller {
'countBuild' => $categoryUniverseModel->getById(65, 0)->getTypesCount(false),
'countAll' => (int)$f3->get('REQUIREMENTS.DATA.STRUCTURES'),
'tooltip' => 'import all structure types (e.g. Citadels) from ESI. Runtime: ~15s'
], /*
],
'Ships' => [
'task' => [
[
@@ -1406,9 +1288,8 @@ class Setup extends Controller {
'countBuild' => $categoryUniverseModel->getById(6, 0)->getTypesCount(false),
'countAll' => (int)$f3->get('REQUIREMENTS.DATA.SHIPS'),
'tooltip' => 'import all ships types from ESI. Runtime: ~2min'
], */
// All following rows become deprecated
'SystemNeighbourModel' => [
],
'SystemNeighbour' => [
'task' => [
[
'action' => 'buildIndex',
@@ -1417,10 +1298,14 @@ class Setup extends Controller {
'btn' => 'btn-primary'
]
],
'label' => 'system_neighbour',
'label' => 'build neighbour index',
'countBuild' => $this->dbLib->getRowCount($systemNeighbourModel->getTable()),
'countAll' => 5214
'countAll' => (int)$f3->get('REQUIREMENTS.DATA.NEIGHBOURS'),
'tooltip' => 'build up a static search index for route search. This is used as fallback in case ESI is down. Runtime: ~30s'
],
// All following rows become deprecated
/*
'WormholeModel' => [
'task' => [
[
@@ -1438,53 +1323,18 @@ class Setup extends Controller {
'label' => 'wormhole',
'countBuild' => $this->dbLib->getRowCount($wormholeModel->getTable()),
'countAll' => 89
],
'SystemWormholeModel' => [
'task' => [
[
'action' => 'exportTable',
'label' => 'Export',
'icon' => 'fa-download',
'btn' => 'btn-default'
],[
'action' => 'importTable',
'label' => 'Import',
'icon' => 'fa-upload',
'btn' => 'btn-primary'
]
],
'label' => 'system_wormhole',
'countBuild' => $this->dbLib->getRowCount($systemWormholeModel->getTable()),
'countAll' => 234
],
'ConstellationWormholeModel' => [
'task' => [
[
'action' => 'exportTable',
'label' => 'Export',
'icon' => 'fa-download',
'btn' => 'btn-default'
],[
'action' => 'importTable',
'label' => 'Import',
'icon' => 'fa-upload',
'btn' => 'btn-primary'
]
],
'label' => 'constellation_wormhole',
'countBuild' => $this->dbLib->getRowCount( $constellationWormholeModel->getTable() ),
'countAll' => 461
]
*/
];
}else{
$indexInfo = [
'SystemNeighbourModel' => [
'SystemNeighbour' => [
'task' => [],
'label' => 'Fix database errors first!'
]
];
}
//var_dump($indexInfo); die();
return $indexInfo;
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Created by PhpStorm.
* User: exodu
* Date: 17.06.2018
* Time: 12:13
*/
namespace cron;
abstract class AbstractCron {
// default max_execution_time for cronJobs
// -> should be less then execution period
const DEFAULT_MAX_EXECUTION_TIME = 50;
/**
* set max execution time for cronjobs
* -> Default CLI execution time is "0" -> infinite!
* php.ini settings are ignored! http://php.net/manual/en/info.configuration.php#ini.max-execution-time
* @param int $time
*/
protected function setMaxExecutionTime(int $time = self::DEFAULT_MAX_EXECUTION_TIME){
ini_set('max_execution_time', $time);
}
}

View File

@@ -10,7 +10,7 @@ namespace cron;
use data\filesystem\Search;
class Cache {
class Cache extends AbstractCron {
const LOG_TEXT = '%s [%\'_10s] files, size [%\'_10s] byte, not writable [%\'_10s] files, errors [%\'_10s], exec (%.3Fs)';
@@ -34,6 +34,7 @@ class Cache {
* @param \Base $f3
*/
function deleteExpiredData(\Base $f3){
$this->setMaxExecutionTime();
$time_start = microtime(true);
// cache dir (dir is recursively searched...)

View File

@@ -7,10 +7,9 @@
*/
namespace Cron;
use Controller;
use DB;
class CcpSystemsUpdate {
class CcpSystemsUpdate extends AbstractCron {
const LOG_TEXT = '%s prepare table (%.3F s), jump (%.3F s), kill (%.3F s), update all (%.3F s)';
@@ -24,43 +23,63 @@ class CcpSystemsUpdate {
* @var array
*/
protected $logTables = [
'jumps' => 'system_jumps',
'ship_kills' => 'system_kills_ships',
'pod_kills' => 'system_kills_pods',
'npc_kills' => 'system_kills_factions'
'jumps' => 'system_jumps',
'ship_kills' => 'system_kills_ships',
'pod_kills' => 'system_kills_pods',
'npc_kills' => 'system_kills_factions'
];
/**
* checks if a table exists in DB or not
* @param DB\SQL $db
* @param string $table
* @return bool
*/
protected function tableExists (DB\SQL $db, string $table) : bool {
return !empty($db->exec('SHOW TABLES LIKE :table', [':table' => $table]));
}
/**
* check all system log tables for the correct number of system entries that will be locked
* @return array
*/
private function prepareSystemLogTables(){
private function prepareSystemLogTables() : array {
$systemsData = [];
// get information for all systems from CCP DB
$systemController = new Controller\Api\System();
$systemsData = $systemController->getSystems();
// get all available systems from "universe" DB
$universeDB = DB\Database::instance()->getDB('UNIVERSE');
$pfDB = DB\Database::instance()->getDB('PF');
if($this->tableExists($universeDB, 'system')){
$systemsData = $universeDB->exec('SELECT
`id`
FROM
`system`
WHERE
`security` = :ns OR
`security` = :ls OR
`security` = :hs
',
[':ns' => '0.0', ':ls' => 'L', ':hs' => 'H']
);
// insert systems into each log table if not exist
$pfDB->begin();
foreach($this->logTables as $tableName){
$pfDB = DB\Database::instance()->getDB('PF');
// insert systems into jump log table
$sqlInsertSystem = "INSERT IGNORE INTO " . $tableName . " (systemId)
// insert systems into each log table if not exist
$pfDB->begin();
foreach($this->logTables as $tableName){
// insert systems into jump log table
$sqlInsertSystem = "INSERT IGNORE INTO " . $tableName . " (systemId)
VALUES(:systemId)";
foreach($systemsData as $systemData){
// skip WH systems -> no jump data available
if($systemData['type']['name'] == 'k-space'){
foreach($systemsData as $systemData){
$pfDB->exec($sqlInsertSystem, array(
':systemId' => $systemData['systemId']
':systemId' => $systemData['id']
), 0, false);
}
}
}
$pfDB->commit();
}
$pfDB->commit();
return $systemsData;
}
@@ -71,7 +90,8 @@ class CcpSystemsUpdate {
* >> php index.php "/cron/importSystemData"
* @param \Base $f3
*/
function importSystemData($f3){
function importSystemData(\Base $f3){
$this->setMaxExecutionTime();
// prepare system jump log table ------------------------------------------------------------------------------
$time_start = microtime(true);
@@ -135,7 +155,7 @@ class CcpSystemsUpdate {
";
foreach($systemsData as $systemData){
$systemId = $systemData['systemId'];
$systemId = $systemData['id'];
// update data (if available)
$currentData = 0;

View File

@@ -11,7 +11,7 @@ use DB;
use Model;
class CharacterUpdate {
class CharacterUpdate extends AbstractCron {
/**
* default character_log time until a log entry get re-checked by cronjob
@@ -29,7 +29,7 @@ class CharacterUpdate {
* @return int
*/
protected function getCharacterLogInactiveTime(\Base $f3){
$logInactiveTime = (int)$f3->get('PATHFINDER.CACHE.CHARACTER_LOG_INACTIVE');
$logInactiveTime = (int)$f3->get('PATHFINDER.CACHE.CHARACTER_LOG_INACTIVE');
return ($logInactiveTime >= 0) ? $logInactiveTime : self::CHARACTER_LOG_INACTIVE;
}
@@ -41,13 +41,14 @@ class CharacterUpdate {
* @throws \Exception
*/
function deleteLogData(\Base $f3){
$this->setMaxExecutionTime();
DB\Database::instance()->getDB('PF');
$logInactiveTime = $this->getCharacterLogInactiveTime($f3);
/**
* @var $characterLogModel Model\CharacterLogModel
*/
$characterLogModel = Model\BasicModel::getNew('CharacterLogModel', 0);
$characterLogModel = Model\BasicModel::getNew('CharacterLogModel');
// find character logs that were not checked recently and update
$characterLogs = $characterLogModel->find([
@@ -84,19 +85,19 @@ class CharacterUpdate {
* @throws \Exception
*/
function cleanUpCharacterData(\Base $f3){
$this->setMaxExecutionTime();
DB\Database::instance()->getDB('PF');
/**
* @var $characterModel Model\CharacterModel
*/
$characterModel = Model\BasicModel::getNew('CharacterModel', 0);
$characterModel = Model\BasicModel::getNew('CharacterModel');
$characters = $characterModel->find([
'active = :active AND TIMESTAMPDIFF(SECOND, kicked, NOW() ) > 0',
':active' => 1
]);
if(is_object($characters)){
foreach($characters as $character){
/**
@@ -115,13 +116,14 @@ class CharacterUpdate {
* @param \Base $f3
* @throws \Exception
*/
function deleteAuthenticationData($f3){
function deleteAuthenticationData(\Base $f3){
$this->setMaxExecutionTime();
DB\Database::instance()->getDB('PF');
/**
* @var $authenticationModel Model\CharacterAuthenticationModel
*/
$authenticationModel = Model\BasicModel::getNew('CharacterAuthenticationModel', 0);
$authenticationModel = Model\BasicModel::getNew('CharacterAuthenticationModel');
// find expired authentication data
$authentications = $authenticationModel->find([

View File

@@ -11,7 +11,7 @@ use DB;
use lib\Config;
use Model;
class MapUpdate {
class MapUpdate extends AbstractCron {
const LOG_TEXT_MAPS = '%s (%d maps)';
@@ -25,6 +25,7 @@ class MapUpdate {
* @throws \Exception\PathfinderException
*/
function deactivateMapData(\Base $f3){
$this->setMaxExecutionTime();
$privateMapLifetime = (int)Config::getMapsDefaultConfig('private.lifetime');
if($privateMapLifetime > 0){
@@ -49,6 +50,7 @@ class MapUpdate {
* @throws \Exception
*/
function deleteMapData(\Base $f3){
$this->setMaxExecutionTime();
$pfDB = DB\Database::instance()->getDB('PF');
$deletedMapsCount = 0;
@@ -87,6 +89,7 @@ class MapUpdate {
* @throws \Exception
*/
function deleteEolConnections(\Base $f3){
$this->setMaxExecutionTime();
$eolExpire = (int)$f3->get('PATHFINDER.CACHE.EXPIRE_CONNECTIONS_EOL');
if($eolExpire > 0){
@@ -131,6 +134,7 @@ class MapUpdate {
* @throws \Exception
*/
function deleteExpiredConnections(\Base $f3){
$this->setMaxExecutionTime();
$whExpire = (int)$f3->get('PATHFINDER.CACHE.EXPIRE_CONNECTIONS_WH');
if($whExpire > 0){
@@ -176,19 +180,20 @@ class MapUpdate {
* @param \Base $f3
*/
function deleteSignatures(\Base $f3){
$this->setMaxExecutionTime();
$signatureExpire = (int)$f3->get('PATHFINDER.CACHE.EXPIRE_SIGNATURES');
if($signatureExpire > 0){
$pfDB = DB\Database::instance()->getDB('PF');
if($pfDB){
$sqlDeleteExpiredSignatures = "DELETE `sigs` FROM
`system_signature` `sigs` INNER JOIN
`system` ON
`system`.`id` = `sigs`.`systemId`
WHERE
`system`.`active` = 0 AND
TIMESTAMPDIFF(SECOND, `sigs`.`updated`, NOW() ) > :lifetime
";
`system_signature` `sigs` INNER JOIN
`system` ON
`system`.`id` = `sigs`.`systemId`
WHERE
`system`.`active` = 0 AND
TIMESTAMPDIFF(SECOND, `sigs`.`updated`, NOW() ) > :lifetime
";
$pfDB->exec($sqlDeleteExpiredSignatures, ['lifetime' => $signatureExpire]);
}

View File

@@ -9,7 +9,7 @@
namespace cron;
use DB;
class StatisticsUpdate {
class StatisticsUpdate extends AbstractCron {
const LOG_TEXT_STATISTICS = '%s (%d rows)';
@@ -20,6 +20,8 @@ class StatisticsUpdate {
* @param \Base $f3
*/
function deleteStatisticsData(\Base $f3){
$this->setMaxExecutionTime();
$currentYear = (int)date('o');
$currentWeek = (int)date('W');
$expiredYear = $currentYear - 1;

View File

@@ -10,7 +10,7 @@ namespace Cron;
use Model;
class Universe {
class Universe extends AbstractCron {
const LOG_TEXT = '%s type: %s %s/%s peak: %s total: %s msg: %s';
@@ -242,5 +242,23 @@ class Universe {
$this->formatSeconds(microtime(true) - $timeTotalStart), $msg) );
}
/**
* update static universe system data from ESI
* -> updates small chunk of systems at once
* >> php index.php "/cron/updateUniverseSystems"
* @param \Base $f3
* @throws \Exception
*/
function updateUniverseSystems(\Base $f3){
$this->setMaxExecutionTime();
$system = Model\Universe\BasicUniverseModel::getNew('SystemModel');
$systems = $system->find( null, ['order' => 'updated', 'limit' => 2]);
if($systems){
foreach ($systems as $system){
$system->updateModel();
}
}
}
}

View File

@@ -1,221 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 14.02.15
* Time: 21:28
*/
namespace Data\Mapper;
class CcpSystemsMapper extends AbstractIterator {
protected static $map = [
'system_id' => 'systemId',
'system_name' => 'name',
'connstallation_id' => ['constellation' => 'id'],
'constallation_name' => ['constellation' => 'name'],
'region_id' => ['region' => 'id'],
'region_name' => ['region' => 'name']
];
/**
* map iterator
* @return array
*/
public function getData(){
// "system trueSec" mapping -------------------------------------------
self::$map['trueSec'] = function($iterator){
$trueSec = self::formatTrueSec($iterator['system_security']);
return $trueSec;
};
// "system effect" mapping --------------------------------------------
self::$map['effect'] = function($iterator){
$effect = $iterator['effect'];
switch($iterator['effect']){
case 'magnetar':
$effect = 'magnetar';
break;
case 'red giant':
$effect = 'redGiant';
break;
case 'pulsar':
$effect = 'pulsar';
break;
case 'wolf-rayet star':
$effect = 'wolfRayet';
break;
case 'cataclysmic variable':
$effect = 'cataclysmic';
break;
case 'black hole':
$effect = 'blackHole';
break;
}
return $effect;
};
// "system security" mapping ------------------------------------------
self::$map['security'] = function($iterator){
$security = '';
if(
$iterator['constellation']['id'] >= 22000001 &&
$iterator['constellation']['id'] <= 22000025
){
// "Abyssal" system
$security = 'A';
}elseif(
$iterator['security'] == 7 ||
$iterator['security'] == 8 ||
$iterator['security'] == 9
){
// k-space system
$trueSec = self::formatTrueSec($iterator['system_security']);
if($trueSec <= 0){
$security = '0.0';
}elseif($trueSec < 0.5){
$security = 'L';
}else{
$security = 'H';
}
}elseif(
$iterator['security'] == 1 ||
$iterator['security'] == 2 ||
$iterator['security'] == 3 ||
$iterator['security'] == 4 ||
$iterator['security'] == 5 ||
$iterator['security'] == 6
){
// standard wormhole system
$security = 'C' . $iterator['security'];
}elseif(
$iterator['security'] == 13
){
// shattered wormhole system
$security = 'SH';
}
return $security;
};
// "system type" mapping ----------------------------------------------
self::$map['type'] = function($iterator){
// TODO refactor
$type = 'w-space';
$typeId = 1;
if(
$iterator['constellation']['id'] >= 22000001 &&
$iterator['constellation']['id'] <= 22000025
){
// "Abyssal" system
$type = 'a-space';
$typeId = 3;
}elseif(
$iterator['security'] == 7 ||
$iterator['security'] == 8 ||
$iterator['security'] == 9
){
$type = 'k-space';
$typeId = 2;
}
return [
'id' => $typeId,
'name' => $type
];
};
iterator_apply($this, 'self::recursiveIterator', [$this]);
return iterator_to_array($this, false);
}
/**
* format trueSec
* @param $trueSec
* @return float
*/
static function formatTrueSec($trueSec){
$positive = ($trueSec > 0);
$trueSec = round((float)$trueSec, 1, PHP_ROUND_HALF_DOWN);
if($positive && $trueSec <= 0){
$trueSec = 0.1;
}
return $trueSec;
}
static function recursiveIterator($iterator){
while ( $iterator -> valid() ) {
if ( $iterator->hasChildren() ) {
$iterator->offsetSet($iterator->key(), self::recursiveIterator( $iterator->getChildren() )->getArrayCopy() );
}else {
while( $iterator -> valid() ){
// check for mapping key
if(array_key_exists($iterator->key(), self::$map)){
if(is_array(self::$map[$iterator->key()])){
// a -> array mapping
$parentKey = array_keys( self::$map[$iterator->key()] )[0];
$entryKey = array_values( self::$map[$iterator->key()] )[0];
// check if key already exists
if($iterator->offsetExists($parentKey)){
$currentValue = $iterator->offsetGet($parentKey);
// add new array entry
$currentValue[$entryKey] = $iterator->current();
$iterator->offsetSet( $parentKey, $currentValue );
}else{
$iterator->offsetSet( $parentKey, [$entryKey => $iterator->current() ] );
}
$removeOldEntry = true;
}elseif(is_object(self::$map[$iterator->key()])){
// a -> a (format by function)
$formatFunction = self::$map[$iterator->key()];
$iterator->offsetSet( $iterator->key(), call_user_func($formatFunction, $iterator) );
// just value change no key change
$removeOldEntry = false;
$iterator->next();
}else{
// a -> b mapping
$iterator->offsetSet( self::$map[$iterator->key()], $iterator->current() );
$removeOldEntry = true;
}
// remove "old" entry
if($removeOldEntry){
$iterator->offsetUnset($iterator->key());
}
}else{
// continue with next entry
$iterator -> next();
}
}
}
$iterator -> next();
}
return $iterator;
}
}

View File

@@ -10,10 +10,9 @@ namespace Model;
use DB\SQL\Schema;
class SystemApiBasicModel extends BasicModel {
abstract class AbstractSystemApiBasicModel extends BasicModel {
public function __construct($db = NULL, $table = NULL, $fluid = NULL, $ttl = 0){
$this->addStaticKillFieldConfig();
parent::__construct($db, $table, $fluid, $ttl);
@@ -23,9 +22,7 @@ class SystemApiBasicModel extends BasicModel {
* extent the fieldConf Array with static fields for each table
*/
private function addStaticKillFieldConfig(){
if(is_array($this->fieldConf)){
$staticFieldConfig = [];
for($i = 1; $i <= 24; $i++){
$staticFieldConfig['value' . $i] = [

View File

@@ -514,7 +514,7 @@ abstract class BasicModel extends \DB\Cortex {
* -> this will not work (prevent abuse)
* @param bool $active
*/
public function setActive($active){
public function setActive(bool $active){
// enables "active" change for this model
$this->allowActiveChange = true;
$this->active = $active;
@@ -896,6 +896,18 @@ abstract class BasicModel extends \DB\Cortex {
$cache->set(self::getF3()->hash($key).'.var', $data, $ttl);
}
/**
* check whether a cache $key exists
* -> §val (reference) get updated with the cache data
* -> equivalent to $f3->exists()
* @param string $key
* @param null $val
* @return bool
*/
public static function existsCacheValue(string $key, &$val = null){
return self::getF3()->exists($key, $val);
}
/**
* debug log function
* @param string $text

View File

@@ -219,7 +219,7 @@ class CharacterLogModel extends BasicModel {
public function clearCacheData(){
// clear character "LOG" cache
// -> character data without "LOG" has not changed!
if($this->characterId){
if(is_object($this->characterId)){
// characterId relation could be deleted by cron therefore check again first...
$this->characterId->clearCacheDataWithPrefix(CharacterModel::DATA_CACHE_KEY_LOG);

View File

@@ -331,10 +331,9 @@ class CharacterModel extends BasicModel {
$logLocation = (bool)$logLocation;
if(
!$logLocation &&
$logLocation !== $this->logLocation &&
$this->hasLog()
$logLocation !== $this->logLocation
){
$this->getLog()->erase();
$this->deleteLog();
}
return $logLocation;
@@ -918,12 +917,8 @@ class CharacterModel extends BasicModel {
}
}
if(
$deleteLog &&
$this->hasLog()
){
// delete existing log
$this->characterLog->erase();
if($deleteLog){
$this->deleteLog();
}
return $this;

View File

@@ -80,29 +80,6 @@ class ConnectionModel extends AbstractMapTrackingModel {
]
];
/**
* set an array with all data for a system
* @param array $data
*/
public function setData($data){
unset($data['id']);
unset($data['created']);
unset($data['updated']);
unset($data['createdCharacterId']);
unset($data['updatedCharacterId']);
foreach((array)$data as $key => $value){
if( !is_array($value) ){
if( $this->exists($key) ){
$this->$key = $value;
}
}elseif($key == 'type'){
// json field
$this->$key = $value;
}
}
}
/**
* get connection data
* @param bool $addSignatureData
@@ -400,6 +377,11 @@ class ConnectionModel extends AbstractMapTrackingModel {
return $logsData;
}
/**
* log new mass for this connection
* @param CharacterLogModel $characterLog
* @return $this
*/
public function logMass(CharacterLogModel $characterLog){
if( !$characterLog->dry() ){
$log = $this->rel('connectionLog');

View File

@@ -1,62 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 07.06.15
* Time: 18:16
*/
namespace Model;
use DB\SQL\Schema;
class ConstellationWormholeModel extends BasicModel {
protected $table = 'constellation_wormhole';
public static $enableDataExport = true;
public static $enableDataImport = true;
protected $fieldConf = [
'constellationId' => [
'type' => Schema::DT_INT,
'index' => true,
],
'wormholeId' => [
'type' => Schema::DT_INT,
'index' => true,
'belongs-to-one' => 'Model\WormholeModel',
'constraint' => [
[
'table' => 'wormhole',
'on-delete' => 'CASCADE'
]
]
],
];
/**
* get wormhole data as object
* @return object
*/
public function getData(){
return $this->wormholeId->getData();
}
/**
* overwrites parent
* @param null $db
* @param null $table
* @param null $fields
* @return bool
*/
public static function setup($db=null, $table=null, $fields=null){
$status = parent::setup($db,$table,$fields);
if($status === true){
$status = parent::setMultiColumnIndex(['constellationId', 'wormholeId'], true);
}
return $status;
}
}

View File

@@ -285,7 +285,10 @@ class CorporationModel extends BasicModel {
!empty($accessToken) &&
!$this->isNPC
){
$characterRolesData = self::getF3()->ccpClient->getCorporationRoles($this->_id, $accessToken);
$response = self::getF3()->ccpClient->getCorporationRoles($this->_id, $accessToken);
if( !empty($response['roles']) ){
$characterRolesData = (array)$response['roles'];
}
}
return $characterRolesData;

View File

@@ -8,7 +8,6 @@
namespace Model;
use Controller\Api\System;
use DB\SQL\Schema;
use data\file\FileHandler;
use lib\Config;
@@ -279,7 +278,7 @@ class MapModel extends AbstractMapTrackingModel {
$characterData[] = $character->getData();
}
$mapData->access->character = $characterData;
} elseif($this->isCorporation()){
}elseif($this->isCorporation()){
$corporations = $this->getCorporations();
$corporationData = [];
@@ -287,7 +286,7 @@ class MapModel extends AbstractMapTrackingModel {
$corporationData[] = $corporation->getData();
}
$mapData->access->corporation = $corporationData;
} elseif($this->isAlliance()){
}elseif($this->isAlliance()){
$alliances = $this->getAlliances();
$allianceData = [];
@@ -302,10 +301,10 @@ class MapModel extends AbstractMapTrackingModel {
$mapDataAll->mapData = $mapData;
// map system data ----------------------------------------------------------------------------------------
$mapDataAll->systems = $this->getSystemData();
$mapDataAll->systems = $this->getSystemsData();
// map connection data ------------------------------------------------------------------------------------
$mapDataAll->connections = $this->getConnectionData();
$mapDataAll->connections = $this->getConnectionsData();
// max caching time for a map
// the cached date has to be cleared manually on any change
@@ -470,25 +469,20 @@ class MapModel extends AbstractMapTrackingModel {
* @return SystemModel
* @throws \Exception
*/
public function getNewSystem($systemId){
public function getNewSystem(int $systemId) : SystemModel {
// check for "inactive" system
$system = $this->getSystemByCCPId($systemId);
if(is_null($system)){
// get blank system
$systemController = new System();
$systems = $systemController->getSystemModelByIds([$systemId]);
if(count($systems)){
$system = reset($systems);
$system->mapId = $this->_id;
}else{
// should NEVER happen -> systemId does NOT exist in New Eden!!
$this->getF3()->error(500, 'SystemId "' . $systemId . '"" does not exist in EVE!' );
}
/**
* @var $system SystemModel
*/
$system = $this->rel('systems');
$system->systemId = $systemId;
$system->mapId = $this;
$system->setType();
}
if($system){
$system->setActive(true);
}
$system->setActive(true);
return $system;
}
@@ -499,7 +493,7 @@ class MapModel extends AbstractMapTrackingModel {
* @param SystemModel $targetSystem
* @return ConnectionModel
*/
public function getNewConnection(SystemModel $sourceSystem, SystemModel $targetSystem){
public function getNewConnection(SystemModel $sourceSystem, SystemModel $targetSystem) : ConnectionModel {
/**
* @var $connection ConnectionModel
*/
@@ -562,7 +556,7 @@ class MapModel extends AbstractMapTrackingModel {
* get either all system models in this map
* @return SystemModel[]
*/
public function getSystems(){
protected function getSystems(){
$systems = [];
// orderBy x-Coordinate for smoother frontend animation (left to right)
@@ -582,7 +576,7 @@ class MapModel extends AbstractMapTrackingModel {
* @return \stdClass[]
* @throws \Exception
*/
public function getSystemData(){
public function getSystemsData(){
$systemData = [];
$systems = $this->getSystems();
@@ -651,7 +645,7 @@ class MapModel extends AbstractMapTrackingModel {
* get all connection data in this map
* @return \stdClass[]
*/
public function getConnectionData() : array {
public function getConnectionsData() : array {
$connectionData = [];
$connections = $this->getConnections();
@@ -1265,7 +1259,7 @@ class MapModel extends AbstractMapTrackingModel {
* @param int $posY
* @return false|ConnectionModel
*/
public function saveSystem( SystemModel $system, CharacterModel $character, $posX = 10, $posY = 0){
public function saveSystem(SystemModel $system, CharacterModel $character, $posX = 10, $posY = 0){
$system->setActive(true);
$system->mapId = $this->id;
$system->posX = $posX;

View File

@@ -16,7 +16,7 @@ class StructureModel extends BasicModel {
protected $table = 'structure';
/**
* categoryId (from CCP´s SDE) that holds all "groups" with structure "types"
* categoryId (from ESI) that holds all "groups" with structure "types"
*/
const CATEGORY_STRUCTURE_ID = 65;
@@ -225,11 +225,12 @@ class StructureModel extends BasicModel {
return $structuresData;
}
public function getByName(CorporationModel $corporation, string $name) {
public function getByName(CorporationModel $corporation, string $name, int $systemId) {
if( !$corporation->dry() && $name){
$this->has('structureCorporations', ['corporationId = :corporationId', ':corporationId' => $corporation->_id]);
$this->load(['name = :name AND active = :active',
$this->load(['name = :name AND systemId = :systemId AND active = :active',
':name' => $name,
':systemId' => $systemId,
':active' => 1
]);
}

View File

@@ -10,7 +10,7 @@ namespace Model;
use DB\SQL\Schema;
class SystemFactionKillModel extends SystemApiBasicModel {
class SystemFactionKillModel extends AbstractSystemApiBasicModel {
protected $table = 'system_kills_factions';

View File

@@ -10,7 +10,7 @@ namespace Model;
use DB\SQL\Schema;
class SystemJumpModel extends SystemApiBasicModel {
class SystemJumpModel extends AbstractSystemApiBasicModel {
protected $table = 'system_jumps';

View File

@@ -10,6 +10,7 @@ namespace Model;
use DB\SQL\Schema;
use lib\logging;
use Controller\Ccp\Universe;
class SystemModel extends AbstractMapTrackingModel {
@@ -18,6 +19,8 @@ class SystemModel extends AbstractMapTrackingModel {
protected $table = 'system';
protected $staticSystemDataCache = [];
protected $fieldConf = [
'active' => [
'type' => Schema::DT_BOOL,
@@ -40,11 +43,7 @@ class SystemModel extends AbstractMapTrackingModel {
'systemId' => [
'type' => Schema::DT_INT,
'index' => true,
],
'name' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
'validate' => true
],
'alias' => [
'type' => Schema::DT_VARCHAR128,
@@ -52,29 +51,6 @@ class SystemModel extends AbstractMapTrackingModel {
'default' => '',
'activity-log' => true
],
'regionId' => [
'type' => Schema::DT_INT,
'index' => true,
],
'region' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
],
'constellationId' => [
'type' => Schema::DT_INT,
'index' => true,
],
'constellation' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
],
'effect' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
],
'typeId' => [
'type' => Schema::DT_INT,
'index' => true,
@@ -86,16 +62,6 @@ class SystemModel extends AbstractMapTrackingModel {
]
]
],
'security' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
],
'trueSec' => [
'type' => Schema::DT_FLOAT,
'nullable' => false,
'default' => 1
],
'statusId' => [
'type' => Schema::DT_INT,
'nullable' => false,
@@ -153,42 +119,6 @@ class SystemModel extends AbstractMapTrackingModel {
]
];
/**
* set an array with all data for a system
* @param array $data
*/
public function setData($data){
unset($data['id']);
unset($data['created']);
unset($data['updated']);
unset($data['createdCharacterId']);
unset($data['updatedCharacterId']);
foreach((array)$data as $key => $value){
if(!is_array($value)){
if($this->exists($key)){
$this->$key = $value;
}
}else{
// special array data
if($key == 'constellation'){
$this->constellationId = (int)$value['id'];
$this->constellation = $value['name'];
}elseif($key == 'region'){
$this->regionId = (int)$value['id'];
$this->region = $value['name'];
}elseif($key == 'type'){
$this->typeId = (int)$value['id'];
}elseif($key == 'status'){
$this->statusId = (int)$value['id'];
}elseif($key == 'position'){
$this->posX = (int)$value['x'];
$this->posY = (int)$value['y'];
}
}
}
}
/**
* get map data as object
* @return \stdClass
@@ -202,56 +132,59 @@ class SystemModel extends AbstractMapTrackingModel {
if(is_null($systemData)){
// no cached system data found
$systemData = (object) [];
$systemData->id = $this->_id;
$systemData->mapId = is_object($this->mapId) ? $this->get('mapId', true) : 0;
$systemData->systemId = $this->systemId;
$systemData->name = $this->name;
$systemData->alias = $this->alias;
$systemData->effect = $this->effect;
$systemData->security = $this->security;
$systemData->trueSec = $this->trueSec;
$systemData = (object) [];
$systemData->id = $this->_id;
$systemData->mapId = is_object($this->mapId) ? $this->get('mapId', true) : 0;
$systemData->systemId = $this->systemId;
$systemData->alias = $this->alias;
$systemData->region = (object) [];
$systemData->region->id = $this->regionId;
$systemData->region->name = $this->region;
if(is_object($this->typeId)){
$systemData->type = $this->typeId->getData();
}
$systemData->constellation = (object) [];
$systemData->constellation->id = $this->constellationId;
$systemData->constellation->name = $this->constellation;
$systemData->status = (object) [];
$systemData->status->id = is_object($this->statusId) ? $this->statusId->id : 1;
$systemData->status->name = is_object($this->statusId) ? $this->statusId->name : 'unknown';
$systemData->type = (object) [];
$systemData->type->id = $this->typeId->id;
$systemData->type->name = $this->typeId->name;
$systemData->locked = $this->locked;
$systemData->rallyUpdated = strtotime($this->rallyUpdated);
$systemData->rallyPoke = $this->rallyPoke;
$systemData->description = $this->description;
$systemData->status = (object) [];
$systemData->status->id = is_object($this->statusId) ? $this->statusId->id : 1;
$systemData->status->name = is_object($this->statusId) ? $this->statusId->name : 'unknown';
$systemData->position = (object) [];
$systemData->position->x = $this->posX;
$systemData->position->y = $this->posY;
$systemData->locked = $this->locked;
$systemData->rallyUpdated = strtotime($this->rallyUpdated);
$systemData->rallyPoke = $this->rallyPoke;
$systemData->description = $this->description;
$systemData->statics = $this->getStaticWormholeData();
$systemData->position = (object) [];
$systemData->position->x = $this->posX;
$systemData->position->y = $this->posY;
$systemData->created = (object) [];
$systemData->created->created = strtotime($this->created);
$systemData->created = (object) [];
$systemData->created->created = strtotime($this->created);
if(is_object($this->createdCharacterId)){
$systemData->created->character = $this->createdCharacterId->getData();
}
$systemData->updated = (object) [];
$systemData->updated->updated = strtotime($this->updated);
$systemData->updated = (object) [];
$systemData->updated->updated = strtotime($this->updated);
if(is_object($this->updatedCharacterId)){
$systemData->updated->character = $this->updatedCharacterId->getData();
}
// static system data -------------------------------------------------------------------------------------
$systemData->name = $this->name;
$systemData->security = $this->security;
$systemData->trueSec = $this->trueSec;
$systemData->effect = $this->effect;
$systemData->shattered = $this->shattered;
$systemData->constellation = (object) [];
$systemData->constellation->id = $this->constellationId;
$systemData->constellation->name = $this->constellation;
$systemData->region = (object) [];
$systemData->region->id = $this->regionId;
$systemData->region->name = $this->region;
$systemData->planets = $this->planets ? : [];
$systemData->statics = $this->statics ? : [];
// max caching time for a system
// the cached date has to be cleared manually on any change
// this includes system, connection,... changes (all dependencies)
@@ -262,7 +195,58 @@ class SystemModel extends AbstractMapTrackingModel {
}
/**
* setter for system alias
* get all static data
* @return mixed|null|\stdClass
* @throws \Exception
*/
private function getStaticSystemData(){
$staticData = null;
if( !empty($this->staticSystemDataCache[$this->systemId]) ){
$staticData = $this->staticSystemDataCache[$this->systemId];
}else{
$staticData = (new Universe())->getSystemData($this->systemId);
if($staticData){
$this->staticSystemDataCache = [$this->systemId => $staticData];
}
}
return $staticData;
}
/**
* get static system data by key
* @param string $key
* @return null
* @throws \Exception
*/
private function getStaticSystemValue(string $key){
$value = null;
if( $staticData = $this->getStaticSystemData()){
if(isset($staticData->$key)){
$value = $staticData->$key;
}
}
return $value;
}
/**
* @param string $key
* @param int $val
* @return bool
* @throws \Exception
*/
protected function validate_systemId(string $key, int $val): bool {
$valid = true;
// check if static system data exists for systemId = $val
if( !(bool)(new Universe())->getSystemData($val) ){
$valid = false;
$this->throwValidationException($key, 'Validation failed: "' . $key . '" = "' . $val . '"');
}
return $valid;
}
/**
* setter for system alias
* @param string $alias
* @return string
*/
@@ -278,30 +262,35 @@ class SystemModel extends AbstractMapTrackingModel {
}
/**
* setter for system security value
* @param float $trueSec
* @return float
* setter for statusId
* @param $status
*/
public function set_trueSec($trueSec){
if(
$trueSec > 0 &&
$trueSec < 0.1
){
// 0.3 is still a LS -> no rounding
$trueSec = 0.1;
}else{
$trueSec = round($trueSec, 1);
public function set_status($status){
if($statusId = (int)$status['id']){
$this->statusId = $statusId;
}
return $trueSec;
}
/**
* setter validation for x coordinate
* setter for position array
* @param $position
* @return null
*/
public function set_position($position){
$position = (array)$position;
if(count($position) === 2){
$this->posX = $position['x'];
$this->posY = $position['y'];
}
return null;
}
/**
* setter for x coordinate
* @param int $posX
* @return int
*/
public function set_posX($posX){
public function set_posX(int $posX) : int {
$posX = abs($posX);
if($posX > self::MAX_POS_X){
$posX = self::MAX_POS_X;
@@ -311,11 +300,11 @@ class SystemModel extends AbstractMapTrackingModel {
}
/**
* setter validation for y coordinate
* setter for y coordinate
* @param int $posY
* @return int
*/
public function set_posY($posY){
public function set_posY(int $posY) : int{
$posY = abs($posY);
if($posY > self::MAX_POS_Y){
$posY = self::MAX_POS_Y;
@@ -348,6 +337,54 @@ class SystemModel extends AbstractMapTrackingModel {
return $rally;
}
public function get_name(){
return $this->getStaticSystemValue('name');
}
public function get_constellationId(){
$constellationData = $this->getStaticSystemValue('constellation');
return $constellationData ? $constellationData->id : null;
}
public function get_constellation(){
$constellationData = $this->getStaticSystemValue('constellation');
return $constellationData ? $constellationData->name : null;
}
public function get_regionId(){
$constellationData = $this->getStaticSystemValue('constellation');
return ($constellationData && $constellationData->region) ? $constellationData->region->id : null;
}
public function get_region(){
$constellationData = $this->getStaticSystemValue('constellation');
return ($constellationData && $constellationData->region) ? $constellationData->region->name : null;
}
public function get_security(){
return $this->getStaticSystemValue('security');
}
public function get_trueSec(){
return $this->getStaticSystemValue('trueSec');
}
public function get_effect(){
return $this->getStaticSystemValue('effect');
}
public function get_shattered(){
return $this->getStaticSystemValue('shattered');
}
public function get_statics(){
return $this->getStaticSystemValue('statics');
}
public function get_planets(){
return $this->getStaticSystemValue('planets');
}
/**
* Event "Hook" function
* @param self $self
@@ -369,9 +406,6 @@ class SystemModel extends AbstractMapTrackingModel {
$status = parent::beforeUpdateEvent($self, $pkeys);
if( !$self->isActive()){
// system becomes inactive
$self->alias = '';
// reset "rally point" fields
$self->rallyUpdated = 0;
$self->rallyPoke = false;
@@ -558,14 +592,6 @@ class SystemModel extends AbstractMapTrackingModel {
return ($this->typeId->id === 1);
}
/**
* check whether this system is a shattered wormhole
* @return bool
*/
public function isShatteredWormhole() : bool {
return ($this->isWormhole() && $this->security === 'SH');
}
/**
* check whether this system is an Abyss system
* @return bool
@@ -634,44 +660,39 @@ class SystemModel extends AbstractMapTrackingModel {
}
/**
* get static WH data for this system
* -> any WH system has at least one static WH
* @return \stdClass[]
* @throws \Exception
* set system type based on security
*/
protected function getStaticWormholeData(){
$wormholeData = [];
// only wormholes have "static" connections
if($this->isWormhole()){
// get static systems by "constellationId" --------------------------------------------
$constellationWormholeModel = self::getNew('ConstellationWormholeModel');
$systemStatics = $constellationWormholeModel->find([
'constellationId = :constellationId',
':constellationId' => $this->constellationId
]);
if( is_object($systemStatics) ){
foreach($systemStatics as $systemStatic){
$wormholeData[] = $systemStatic->getData();
}
}
// get static systems by "systemId" (shattered wormholes) -----------------------------
$systemWormholeModel = self::getNew('SystemWormholeModel');
$systemStatics = $systemWormholeModel->find([
'systemId = :systemId',
':systemId' => $this->systemId
]);
if( is_object($systemStatics) ){
foreach($systemStatics as $systemStatic){
$wormholeData[] = $systemStatic->getData();
}
}
public function setType(){
switch($this->security){
case 'H':
case 'L':
case '0.0':
$typeId = 2; // k-space
break;
case 'A':
$typeId = 3; // a-space
break;
default:
$typeId = 1; // w-space
}
return $wormholeData;
/**
* @var $type MapTypeModel
*/
$type = $this->rel('typeId');
$type->getById($typeId);
$this->typeId = $type;
}
/**
* save signature for this system
* @param SystemSignatureModel $signature
* @param CharacterModel $character
* @return false|ConnectionModel
*/
public function saveSignature(SystemSignatureModel $signature, CharacterModel $character){
$signature->systemId = $this;
return $signature->save($character);
}
/**

View File

@@ -10,7 +10,7 @@ namespace Model;
use DB\SQL\Schema;
class SystemPodKillModel extends SystemApiBasicModel {
class SystemPodKillModel extends AbstractSystemApiBasicModel {
protected $table = 'system_kills_pods';

View File

@@ -10,7 +10,7 @@ namespace Model;
use DB\SQL\Schema;
class SystemShipKillModel extends SystemApiBasicModel {
class SystemShipKillModel extends AbstractSystemApiBasicModel {
protected $table = 'system_kills_ships';

View File

@@ -74,26 +74,6 @@ class SystemSignatureModel extends AbstractMapTrackingModel {
]
];
/**
* set an array with all data for a system
* @param $data
*/
public function setData($data){
unset($data['id']);
unset($data['created']);
unset($data['updated']);
unset($data['createdCharacterId']);
unset($data['updatedCharacterId']);
foreach((array)$data as $key => $value){
if(!is_array($value)){
if($this->exists($key)){
$this->$key = $value;
}
}
}
}
/**
* get signature data
* @return \stdClass
@@ -207,10 +187,10 @@ class SystemSignatureModel extends AbstractMapTrackingModel {
/**
* compares a new data set (array) with the current values
* and checks if something has changed
* @param $signatureData
* @param array $signatureData
* @return bool
*/
public function hasChanged($signatureData){
public function hasChanged(array $signatureData) : bool {
$hasChanged = false;
foreach((array)$signatureData as $key => $value){

View File

@@ -43,4 +43,17 @@ class SystemTypeModel extends BasicModel {
]
];
/**
* get system type data
* @return \stdClass
*/
public function getData(){
$typeData = (object)[];
$typeData->id = $this->_id;
$typeData->name = $this->name;
return $typeData;
}
}

View File

@@ -1,62 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 16.07.2016
* Time: 12:19
*/
namespace Model;
use DB\SQL\Schema;
class SystemWormholeModel extends BasicModel {
protected $table = 'system_wormhole';
public static $enableDataExport = true;
public static $enableDataImport = true;
protected $fieldConf = [
'systemId' => [
'type' => Schema::DT_INT,
'index' => true,
],
'wormholeId' => [
'type' => Schema::DT_INT,
'index' => true,
'belongs-to-one' => 'Model\WormholeModel',
'constraint' => [
[
'table' => 'wormhole',
'on-delete' => 'CASCADE'
]
]
],
];
/**
* get wormhole data as object
* @return object
*/
public function getData(){
return $this->wormholeId->getData();
}
/**
* overwrites parent
* @param null $db
* @param null $table
* @param null $fields
* @return bool
*/
public static function setup($db=null, $table=null, $fields=null){
$status = parent::setup($db,$table,$fields);
if($status === true){
$status = parent::setMultiColumnIndex(['systemId', 'wormholeId'], true);
}
return $status;
}
}

View File

@@ -8,7 +8,6 @@
namespace Model\Universe;
use DB\Database;
use Model\BasicModel;
@@ -97,8 +96,11 @@ abstract class BasicUniverseModel extends BasicModel {
/**
* build up a "search" index for this model
* -> stores getData() result into Cache (RAM) for faster access
* @return null|\stdClass
*/
public function buildIndex(){
$data = null;
if($hashKeyId = $this->getHashKey()){
$f3 = self::getF3();
$hashKeyTable = self::generateHashKeyTable($this->getTable());
@@ -115,10 +117,29 @@ abstract class BasicUniverseModel extends BasicModel {
$f3->clear($hashKeyId);
$f3->clear($hashKeyTable);
$data = $this->getData();
// straight into cache (no $f->set() ), no sync with hive here -> save ram
self::setCacheValue($hashKeyId, $this->getData(), self::CACHE_INDEX_EXPIRE_KEY);
self::setCacheValue($hashKeyId, $data, self::CACHE_INDEX_EXPIRE_KEY);
self::setCacheValue($hashKeyTable, $cachedData, self::CACHE_INDEX_EXPIRE_KEY);
}
return $data;
}
/**
* get data from "search" index for this model
* -> if data not found -> try to build up index for this model
* @return null|\stdClass
*/
public function fromIndex(){
$data = null;
if($hashKeyId = $this->getHashKey()){
if( !self::existsCacheValue($hashKeyId, $data)){
$data = $this->buildIndex();
}
}
return $data;
}
/**
@@ -138,21 +159,6 @@ abstract class BasicUniverseModel extends BasicModel {
}
}
/**
* load data by foreign key or other column than "id"
* @param string $key
* @param $value
*/
public function loadByKey(string $key, $value){
/**
* @var $model self
*/
$model = $this->getByForeignKey($key, $value, ['limit' => 1]);
if($model->isOutdated()){
$model->loadDataByKey($key, $value);
}
}
/**
* load data from API into $this and save $this
* @param int $id
@@ -161,8 +167,6 @@ abstract class BasicUniverseModel extends BasicModel {
*/
abstract protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []);
protected function loadDataByKey(string $key, $value){}
/**
* generate hashKey for a table row data for search index build
* @param string $table

View File

@@ -67,13 +67,10 @@ class PlanetModel extends BasicUniverseModel {
*/
public function getData(){
$planetData = (object) [];
$planetData->id = $this->_id;
$planetData->name = $this->name;
$planetData->position = (object) [];
$planetData->position->x = $this->x;
$planetData->position->y = $this->y;
$planetData->position->z = $this->z;
$planetData->type = (object) [];
$planetData->type->name = $this->typeId->name;
return $planetData;
}

View File

@@ -108,12 +108,12 @@ class SystemModel extends BasicUniverseModel {
$systemData->name = $this->name;
$systemData->constellation = $this->constellationId->getData();
$systemData->security = $this->security;
$systemData->trueSec = $this->trueSec;
$systemData->trueSec = (float)$this->trueSec;
$systemData->effect = $this->effect;
$systemData->shattered = $this->shattered;
$systemData->shattered = (bool)$this->shattered;
if($this->starId){
$systemData->star = $this->starId->getData();
$systemData->star = $this->starId->getData();
}
if( !empty($planetsData = $this->getPlanetsData()) ){
@@ -125,7 +125,7 @@ class SystemModel extends BasicUniverseModel {
}
if( !empty($stargatesData = $this->getStargatesData()) ){
$systemData->stargates = $stargatesData;
$systemData->stargates = $stargatesData;
}
return $systemData;
@@ -226,7 +226,6 @@ class SystemModel extends BasicUniverseModel {
* return false will stop any further action
* @param self $self
* @param $pkeys
* @throws \Exception\ValidationException
*/
public function afterUpdateEvent($self, $pkeys){
$staticNames = (array)$self->staticNames;
@@ -318,6 +317,16 @@ class SystemModel extends BasicUniverseModel {
return $stargatesData;
}
/**
* update system from ESI
*/
public function updateModel(){
if( !$this->dry() ){
$this->loadData($this->_id);
$this->loadPlanetsData();
}
}
/**
* @param int $id
* @param string $accessToken

View File

@@ -77,6 +77,33 @@ class WormholeModel extends BasicUniverseModel {
]
];
/**
* get wormhole data
* @return \stdClass
*/
public function getData(){
$wormholeData = (object) [];
$wormholeData->name = $this->name;
$wormholeData->static = $this->static;
$wormholeData->security = $this->security;
$wormholeData->massTotal = $this->massTotal;
$wormholeData->massIndividual = $this->massIndividual;
if($this->massRegeneration){
$wormholeData->massRegeneration = $this->massRegeneration;
}
$wormholeData->maxStableTime = $this->maxStableTime;
// signature strength as defined by http://wiki.eve-inspiracy.com/index.php?title=Wormhole_Signature_Strength_List
if($this->signatureStrength){
$wormholeData->signatureStrength = $this->signatureStrength;
}
return $wormholeData;
}
/**
* setter for typeId
* @param string $typeId
@@ -155,25 +182,6 @@ class WormholeModel extends BasicUniverseModel {
return parent::exportData($fields);
}
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){
var_dump('loadData');
var_dump($id);
/*
$data = self::getF3()->ccpClient->getUniverseTypesData($id, $additionalOptions);
if(!empty($data)){
$group = $this->rel('groupId');
$group->loadById($data['groupId'], $accessToken, $additionalOptions);
$data['groupId'] = $group;
$this->copyfrom($data);
$this->save();
} */
}
protected function loadDataByKey(string $key, $value){
var_dump('loadData');
var_dump($key);
var_dump($value);
}
protected function loadData(int $id, string $accessToken = '', array $additionalOptions = []){}
}

View File

@@ -46,20 +46,6 @@ class UserCharacterModel extends BasicModel {
]
];
/**
* set an array with all data for a character
* @param $characterData
*/
public function setData($characterData){
foreach((array)$characterData as $key => $value){
if(!is_array($value)){
if($this->exists($key)){
$this->$key = $value;
}
}
}
}
/**
* event "Hook"
* -> remove user if there are no other characters bound to this user

View File

@@ -1,110 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 14.11.2015
* Time: 22:21
*/
namespace Model;
use DB\SQL\Schema;
class WormholeModel extends BasicModel {
protected $table = 'wormhole';
public static $enableDataExport = true;
public static $enableDataImport = true;
protected $fieldConf = [
'name' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => '',
'index' => true,
'unique' => true
],
'security' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
],
'massTotal' => [
'type' => Schema::DT_VARCHAR128, // varchar because > max int value
'nullable' => false,
'default' => 0
],
'massIndividual' => [
'type' => Schema::DT_VARCHAR128, // varchar because > max int value
'nullable' => false,
'default' => 0
],
'massRegeneration' => [
'type' => Schema::DT_VARCHAR128, // varchar because > max int value
'nullable' => false,
'default' => 0
],
'maxStableTime' => [
'type' => Schema::DT_INT,
'nullable' => false,
'default' => 1,
'index' => true,
],
'signatureStrength' => [
'type' => Schema::DT_FLOAT,
'nullable' => true,
'default' => null
]
];
/**
* No static columns added
* @var bool
*/
protected $addStaticFields = false;
/**
* setter for "signatureStrength"
* @param $value
* @return mixed|null|string
* @throws \Exception
*/
public function set_signatureStrength($value){
$value = (float)$value ? $value : null;
return $value;
}
/**
* get wormhole data as object
* @return object
*/
public function getData(){
$systemStaticData = (object) [];
$systemStaticData->name = $this->name;
$systemStaticData->security = $this->security;
// total (max) available wormhole mass
$systemStaticData->massTotal = $this->massTotal;
// individual jump mass (max) per jump
$systemStaticData->massIndividual = $this->massIndividual;
// lifetime (max) for this wormhole
$systemStaticData->maxStableTime = $this->maxStableTime;
// mass regeneration value per day
if($this->massRegeneration > 0){
$systemStaticData->massRegeneration = $this->massRegeneration;
}
// signature strength as defined by http://wiki.eve-inspiracy.com/index.php?title=Wormhole_Signature_Strength_List
if($this->signatureStrength){
$systemStaticData->signatureStrength = $this->signatureStrength;
}
return $systemStaticData;
}
}

View File

@@ -3,7 +3,7 @@
[PATHFINDER]
NAME = Pathfinder
; installed version (used for CSS/JS cache busting)
VERSION = v1.3.5
VERSION = v1.4.0
; contact information [optional]
CONTACT = https://github.com/exodus4d
; public contact email [optional]
@@ -171,8 +171,6 @@ EXECUTION_LIMIT = 50
[PATHFINDER.CACHE]
; delete character log data if if nothing (ship/system/...) for X seconds (seconds) (default: 3min)
CHARACTER_LOG_INACTIVE = 180
; expire time for static system data (seconds) (default: 20d)
CONSTELLATION_SYSTEMS = 1728000
; max expire time. Expired cache files will be deleted by cronjob (seconds) (default: 10d)
EXPIRE_MAX = 864000
; expire time for EOL (end of life) connections (seconds) (default: 4h + 15min)

View File

@@ -36,6 +36,10 @@ EXEC = 1
; max execution time for requests (seconds)
MAX_EXECUTION_TIME = 10
; max memory limit
; some requests e.g. build indexes on /setup page require more RAM
MEMORY_LIMIT = 128M
; max variable size for $_GET, $_POST and $_COOKIE
; this is required for importing larger maps
; http://php.net/manual/en/info.configuration.php
@@ -75,3 +79,4 @@ NPM = 3.10.0
[REQUIREMENTS.DATA]
STRUCTURES = 33
SHIPS = 490
NEIGHBOURS = 5201

View File

@@ -27,6 +27,6 @@
"monolog/monolog": "1.*",
"websoftwares/monolog-zmq-handler": "0.2.*",
"swiftmailer/swiftmailer": "^6.0",
"exodus4d/pathfinder_esi": "dev-master#v1.2.4"
"exodus4d/pathfinder_esi": "dev-master#v1.2.5"
}
}

View File

@@ -1,462 +0,0 @@
"Id";"Created";"Updated";"ConstellationId";"WormholeId";
"1";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000001";"39";
"2";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000002";"39";
"3";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000003";"39";
"4";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000004";"39";
"5";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000005";"39";
"6";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000006";"39";
"7";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000007";"39";
"8";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000008";"39";
"9";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000009";"39";
"10";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000010";"39";
"11";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000011";"39";
"12";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000012";"39";
"13";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000013";"39";
"14";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000014";"39";
"15";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000015";"39";
"16";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000016";"39";
"17";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000017";"39";
"18";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000018";"39";
"19";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000019";"39";
"20";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000020";"39";
"21";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000021";"6";
"22";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000022";"6";
"23";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000023";"6";
"24";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000024";"6";
"25";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000025";"6";
"26";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000026";"6";
"27";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000027";"6";
"28";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000028";"6";
"29";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000029";"6";
"30";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000030";"6";
"31";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000021";"47";
"32";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000022";"47";
"33";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000023";"47";
"34";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000024";"47";
"35";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000025";"47";
"36";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000026";"47";
"37";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000027";"47";
"38";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000028";"47";
"39";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000029";"47";
"40";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000030";"47";
"41";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000031";"6";
"42";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000032";"6";
"43";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000033";"6";
"44";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000034";"6";
"45";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000035";"6";
"46";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000036";"6";
"47";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000037";"6";
"48";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000038";"6";
"49";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000039";"6";
"50";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000040";"6";
"51";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000031";"69";
"52";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000032";"69";
"53";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000033";"69";
"54";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000034";"69";
"55";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000035";"69";
"56";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000036";"69";
"57";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000037";"69";
"58";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000038";"69";
"59";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000039";"69";
"60";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000040";"69";
"61";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000041";"2";
"62";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000042";"2";
"63";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000043";"2";
"64";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000044";"2";
"65";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000045";"2";
"66";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000046";"2";
"67";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000047";"2";
"68";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000048";"2";
"69";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000049";"2";
"70";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000050";"2";
"71";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000051";"2";
"72";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000052";"2";
"73";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000053";"2";
"74";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000054";"2";
"75";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000041";"16";
"76";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000042";"16";
"77";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000043";"16";
"78";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000044";"16";
"79";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000045";"16";
"80";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000046";"16";
"81";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000047";"16";
"82";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000048";"16";
"83";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000049";"16";
"84";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000050";"16";
"85";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000051";"16";
"86";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000052";"16";
"87";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000053";"16";
"88";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000054";"16";
"89";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000055";"21";
"90";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000056";"21";
"91";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000057";"21";
"92";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000058";"21";
"93";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000059";"21";
"94";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000055";"38";
"95";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000056";"38";
"96";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000057";"38";
"97";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000058";"38";
"98";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000059";"53";
"99";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000060";"6";
"100";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000061";"6";
"101";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000062";"6";
"102";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000063";"6";
"103";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000064";"6";
"104";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000065";"6";
"105";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000066";"6";
"106";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000067";"6";
"107";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000068";"6";
"108";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000069";"6";
"109";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000070";"6";
"110";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000071";"6";
"111";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000072";"6";
"112";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000073";"6";
"113";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000074";"6";
"114";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000075";"6";
"115";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000060";"75";
"116";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000061";"75";
"117";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000063";"75";
"118";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000064";"75";
"119";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000065";"75";
"120";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000066";"75";
"121";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000067";"75";
"122";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000068";"75";
"123";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000069";"75";
"124";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000070";"75";
"125";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000071";"75";
"126";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000072";"75";
"127";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000073";"75";
"128";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000074";"75";
"129";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000075";"75";
"130";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000076";"59";
"131";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000077";"59";
"132";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000078";"59";
"133";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000079";"59";
"134";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000080";"59";
"135";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000081";"59";
"136";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000082";"59";
"137";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000083";"59";
"138";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000084";"59";
"139";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000085";"59";
"140";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000086";"59";
"141";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000087";"59";
"142";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000088";"59";
"143";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000089";"59";
"144";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000090";"59";
"145";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000091";"59";
"146";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000092";"59";
"147";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000093";"59";
"148";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000094";"59";
"149";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000095";"59";
"150";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000096";"59";
"151";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000097";"59";
"152";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000098";"59";
"153";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000099";"59";
"154";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000100";"59";
"155";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000101";"59";
"156";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000102";"59";
"157";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000103";"59";
"158";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000104";"59";
"159";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000105";"59";
"160";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000106";"18";
"161";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000107";"18";
"162";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000108";"18";
"163";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000109";"18";
"164";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000110";"18";
"165";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000111";"18";
"166";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000112";"18";
"167";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000113";"18";
"168";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000114";"18";
"169";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000115";"18";
"170";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000116";"18";
"171";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000117";"18";
"172";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000118";"18";
"173";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000119";"18";
"174";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000120";"18";
"175";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000121";"18";
"176";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000122";"59";
"177";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000123";"59";
"178";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000124";"59";
"179";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000125";"59";
"180";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000126";"59";
"181";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000127";"59";
"182";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000128";"59";
"183";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000129";"30";
"184";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000130";"30";
"185";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000131";"30";
"186";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000132";"30";
"187";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000133";"30";
"188";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000134";"30";
"189";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000135";"30";
"190";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000136";"30";
"191";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000137";"30";
"192";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000138";"30";
"193";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000139";"30";
"194";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000140";"30";
"195";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000141";"30";
"196";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000142";"30";
"197";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000143";"30";
"198";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000144";"59";
"199";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000145";"59";
"200";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000146";"59";
"201";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000147";"59";
"202";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000148";"59";
"203";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000149";"59";
"204";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000150";"59";
"205";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000151";"59";
"206";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000152";"59";
"207";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000153";"42";
"208";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000154";"42";
"209";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000155";"42";
"210";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000156";"42";
"211";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000157";"42";
"212";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000158";"42";
"213";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000159";"42";
"214";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000160";"42";
"215";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000161";"42";
"216";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000162";"61";
"217";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000163";"61";
"218";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000164";"61";
"219";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000165";"61";
"220";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000166";"49";
"221";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000167";"49";
"222";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000168";"49";
"223";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000169";"49";
"224";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000170";"49";
"225";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000171";"49";
"226";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000172";"49";
"227";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000173";"68";
"228";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000174";"68";
"229";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000175";"68";
"230";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000176";"68";
"231";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000177";"68";
"232";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000178";"68";
"233";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000179";"68";
"234";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000180";"68";
"235";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000181";"68";
"236";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000182";"68";
"237";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000183";"68";
"238";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000184";"68";
"239";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000185";"68";
"240";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000186";"68";
"241";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000187";"68";
"242";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000188";"68";
"243";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000189";"68";
"244";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000190";"68";
"245";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000191";"68";
"246";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000192";"68";
"247";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000193";"68";
"248";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000194";"68";
"249";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000195";"12";
"250";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000196";"12";
"251";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000197";"12";
"252";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000198";"12";
"253";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000199";"12";
"254";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000200";"12";
"255";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000201";"12";
"256";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000202";"12";
"257";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000203";"12";
"258";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000204";"12";
"259";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000205";"12";
"260";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000206";"12";
"261";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000207";"12";
"262";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000208";"12";
"263";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000209";"12";
"264";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000210";"12";
"265";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000211";"12";
"266";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000212";"12";
"267";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000213";"26";
"268";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000214";"26";
"269";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000215";"26";
"270";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000216";"26";
"271";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000217";"26";
"272";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000218";"26";
"273";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000219";"26";
"274";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000220";"26";
"275";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000221";"26";
"276";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000222";"26";
"277";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000223";"26";
"278";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000224";"26";
"279";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000225";"26";
"280";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000226";"26";
"281";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000227";"12";
"282";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000228";"12";
"283";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000229";"12";
"284";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000230";"12";
"285";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000231";"12";
"286";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000232";"25";
"287";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000233";"70";
"288";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000234";"15";
"289";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000235";"15";
"290";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000236";"25";
"291";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000237";"15";
"292";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000238";"15";
"293";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000239";"70";
"294";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000240";"25";
"295";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000241";"25";
"296";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000242";"25";
"297";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000243";"25";
"298";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000244";"25";
"299";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000245";"25";
"300";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000246";"25";
"301";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000247";"25";
"302";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000248";"25";
"303";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000249";"25";
"304";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000250";"25";
"305";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000251";"25";
"306";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000252";"25";
"307";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000253";"25";
"308";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000254";"25";
"309";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000255";"25";
"310";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000256";"64";
"311";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000257";"64";
"312";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000258";"64";
"313";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000259";"64";
"314";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000260";"64";
"315";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000261";"64";
"316";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000262";"64";
"317";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000263";"64";
"318";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000264";"64";
"319";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000265";"35";
"320";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000266";"35";
"321";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000267";"35";
"322";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000268";"35";
"323";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000269";"35";
"324";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000270";"35";
"325";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000271";"35";
"326";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000272";"35";
"327";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000273";"35";
"328";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000274";"25";
"329";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000275";"25";
"330";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000276";"25";
"331";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000277";"25";
"332";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000278";"25";
"333";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000279";"25";
"334";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000280";"25";
"335";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000281";"25";
"336";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000282";"25";
"337";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000283";"25";
"338";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000284";"25";
"339";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000285";"25";
"340";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000286";"20";
"341";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000287";"20";
"342";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000288";"20";
"343";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000289";"20";
"344";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000290";"20";
"345";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000291";"20";
"346";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000292";"20";
"347";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000293";"20";
"348";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000294";"20";
"349";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000295";"20";
"350";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000296";"20";
"351";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000297";"23";
"352";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000298";"66";
"353";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000299";"65";
"354";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000300";"32";
"355";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000301";"51";
"356";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000302";"74";
"357";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000303";"66";
"358";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000304";"32";
"359";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000305";"74";
"360";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000306";"65";
"361";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000307";"65";
"362";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000308";"65";
"363";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000309";"65";
"364";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000310";"65";
"365";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000311";"72";
"366";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000312";"72";
"367";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000313";"72";
"368";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000314";"28";
"369";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000315";"28";
"370";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000316";"28";
"371";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000317";"28";
"372";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000318";"28";
"373";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000319";"28";
"374";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000320";"28";
"375";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000321";"28";
"376";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000322";"28";
"377";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000323";"28";
"378";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000153";"68";
"379";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000154";"68";
"380";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000155";"68";
"381";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000156";"49";
"382";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000157";"26";
"383";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000158";"26";
"384";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000159";"12";
"385";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000160";"26";
"386";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000161";"12";
"387";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000162";"26";
"388";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000163";"12";
"389";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000164";"26";
"390";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000165";"68";
"391";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000166";"12";
"392";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000167";"42";
"393";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000168";"26";
"394";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000169";"68";
"395";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000170";"42";
"396";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000171";"68";
"397";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000172";"12";
"398";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000173";"42";
"399";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000174";"49";
"400";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000175";"12";
"401";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000176";"12";
"402";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000177";"12";
"403";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000178";"61";
"404";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000179";"26";
"405";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000180";"26";
"406";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000181";"26";
"407";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000182";"61";
"408";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000183";"12";
"409";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000184";"12";
"410";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000185";"26";
"411";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000186";"26";
"412";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000187";"42";
"413";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000188";"26";
"414";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000189";"42";
"415";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000190";"42";
"416";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000191";"12";
"417";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000192";"42";
"418";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000193";"49";
"419";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000194";"12";
"420";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000195";"68";
"421";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000196";"49";
"422";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000197";"26";
"423";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000198";"42";
"424";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000199";"42";
"425";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000200";"68";
"426";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000201";"68";
"427";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000202";"42";
"428";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000203";"26";
"429";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000204";"26";
"430";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000205";"49";
"431";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000206";"68";
"432";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000207";"68";
"433";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000208";"26";
"434";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000209";"26";
"435";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000210";"26";
"436";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000211";"61";
"437";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000212";"42";
"438";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000213";"12";
"439";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000214";"68";
"440";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000215";"12";
"441";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000216";"68";
"442";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000217";"42";
"443";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000218";"12";
"444";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000219";"12";
"445";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000220";"68";
"446";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000221";"42";
"447";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000222";"68";
"448";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000223";"12";
"449";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000224";"42";
"450";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000225";"49";
"451";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000226";"61";
"452";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000227";"68";
"453";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000228";"42";
"454";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000229";"68";
"455";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000230";"68";
"456";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000231";"49";
"457";"2015-12-26 16:19:18";"2015-12-26 16:19:18";"21000329";"20";
"458";"2016-07-15 18:45:01";"2016-07-15 18:45:01";"21000324";"81";
"459";"2016-07-15 18:45:01";"2016-07-15 18:45:01";"21000324";"82";
"460";"2016-07-15 18:45:09";"2016-07-15 18:45:09";"21000324";"83";
"461";"2016-07-15 19:55:26";"2016-07-15 19:55:26";"21000062";"75";
1 Id Created Updated ConstellationId WormholeId
2 1 2015-12-26 16:19:18 2015-12-26 16:19:18 21000001 39
3 2 2015-12-26 16:19:18 2015-12-26 16:19:18 21000002 39
4 3 2015-12-26 16:19:18 2015-12-26 16:19:18 21000003 39
5 4 2015-12-26 16:19:18 2015-12-26 16:19:18 21000004 39
6 5 2015-12-26 16:19:18 2015-12-26 16:19:18 21000005 39
7 6 2015-12-26 16:19:18 2015-12-26 16:19:18 21000006 39
8 7 2015-12-26 16:19:18 2015-12-26 16:19:18 21000007 39
9 8 2015-12-26 16:19:18 2015-12-26 16:19:18 21000008 39
10 9 2015-12-26 16:19:18 2015-12-26 16:19:18 21000009 39
11 10 2015-12-26 16:19:18 2015-12-26 16:19:18 21000010 39
12 11 2015-12-26 16:19:18 2015-12-26 16:19:18 21000011 39
13 12 2015-12-26 16:19:18 2015-12-26 16:19:18 21000012 39
14 13 2015-12-26 16:19:18 2015-12-26 16:19:18 21000013 39
15 14 2015-12-26 16:19:18 2015-12-26 16:19:18 21000014 39
16 15 2015-12-26 16:19:18 2015-12-26 16:19:18 21000015 39
17 16 2015-12-26 16:19:18 2015-12-26 16:19:18 21000016 39
18 17 2015-12-26 16:19:18 2015-12-26 16:19:18 21000017 39
19 18 2015-12-26 16:19:18 2015-12-26 16:19:18 21000018 39
20 19 2015-12-26 16:19:18 2015-12-26 16:19:18 21000019 39
21 20 2015-12-26 16:19:18 2015-12-26 16:19:18 21000020 39
22 21 2015-12-26 16:19:18 2015-12-26 16:19:18 21000021 6
23 22 2015-12-26 16:19:18 2015-12-26 16:19:18 21000022 6
24 23 2015-12-26 16:19:18 2015-12-26 16:19:18 21000023 6
25 24 2015-12-26 16:19:18 2015-12-26 16:19:18 21000024 6
26 25 2015-12-26 16:19:18 2015-12-26 16:19:18 21000025 6
27 26 2015-12-26 16:19:18 2015-12-26 16:19:18 21000026 6
28 27 2015-12-26 16:19:18 2015-12-26 16:19:18 21000027 6
29 28 2015-12-26 16:19:18 2015-12-26 16:19:18 21000028 6
30 29 2015-12-26 16:19:18 2015-12-26 16:19:18 21000029 6
31 30 2015-12-26 16:19:18 2015-12-26 16:19:18 21000030 6
32 31 2015-12-26 16:19:18 2015-12-26 16:19:18 21000021 47
33 32 2015-12-26 16:19:18 2015-12-26 16:19:18 21000022 47
34 33 2015-12-26 16:19:18 2015-12-26 16:19:18 21000023 47
35 34 2015-12-26 16:19:18 2015-12-26 16:19:18 21000024 47
36 35 2015-12-26 16:19:18 2015-12-26 16:19:18 21000025 47
37 36 2015-12-26 16:19:18 2015-12-26 16:19:18 21000026 47
38 37 2015-12-26 16:19:18 2015-12-26 16:19:18 21000027 47
39 38 2015-12-26 16:19:18 2015-12-26 16:19:18 21000028 47
40 39 2015-12-26 16:19:18 2015-12-26 16:19:18 21000029 47
41 40 2015-12-26 16:19:18 2015-12-26 16:19:18 21000030 47
42 41 2015-12-26 16:19:18 2015-12-26 16:19:18 21000031 6
43 42 2015-12-26 16:19:18 2015-12-26 16:19:18 21000032 6
44 43 2015-12-26 16:19:18 2015-12-26 16:19:18 21000033 6
45 44 2015-12-26 16:19:18 2015-12-26 16:19:18 21000034 6
46 45 2015-12-26 16:19:18 2015-12-26 16:19:18 21000035 6
47 46 2015-12-26 16:19:18 2015-12-26 16:19:18 21000036 6
48 47 2015-12-26 16:19:18 2015-12-26 16:19:18 21000037 6
49 48 2015-12-26 16:19:18 2015-12-26 16:19:18 21000038 6
50 49 2015-12-26 16:19:18 2015-12-26 16:19:18 21000039 6
51 50 2015-12-26 16:19:18 2015-12-26 16:19:18 21000040 6
52 51 2015-12-26 16:19:18 2015-12-26 16:19:18 21000031 69
53 52 2015-12-26 16:19:18 2015-12-26 16:19:18 21000032 69
54 53 2015-12-26 16:19:18 2015-12-26 16:19:18 21000033 69
55 54 2015-12-26 16:19:18 2015-12-26 16:19:18 21000034 69
56 55 2015-12-26 16:19:18 2015-12-26 16:19:18 21000035 69
57 56 2015-12-26 16:19:18 2015-12-26 16:19:18 21000036 69
58 57 2015-12-26 16:19:18 2015-12-26 16:19:18 21000037 69
59 58 2015-12-26 16:19:18 2015-12-26 16:19:18 21000038 69
60 59 2015-12-26 16:19:18 2015-12-26 16:19:18 21000039 69
61 60 2015-12-26 16:19:18 2015-12-26 16:19:18 21000040 69
62 61 2015-12-26 16:19:18 2015-12-26 16:19:18 21000041 2
63 62 2015-12-26 16:19:18 2015-12-26 16:19:18 21000042 2
64 63 2015-12-26 16:19:18 2015-12-26 16:19:18 21000043 2
65 64 2015-12-26 16:19:18 2015-12-26 16:19:18 21000044 2
66 65 2015-12-26 16:19:18 2015-12-26 16:19:18 21000045 2
67 66 2015-12-26 16:19:18 2015-12-26 16:19:18 21000046 2
68 67 2015-12-26 16:19:18 2015-12-26 16:19:18 21000047 2
69 68 2015-12-26 16:19:18 2015-12-26 16:19:18 21000048 2
70 69 2015-12-26 16:19:18 2015-12-26 16:19:18 21000049 2
71 70 2015-12-26 16:19:18 2015-12-26 16:19:18 21000050 2
72 71 2015-12-26 16:19:18 2015-12-26 16:19:18 21000051 2
73 72 2015-12-26 16:19:18 2015-12-26 16:19:18 21000052 2
74 73 2015-12-26 16:19:18 2015-12-26 16:19:18 21000053 2
75 74 2015-12-26 16:19:18 2015-12-26 16:19:18 21000054 2
76 75 2015-12-26 16:19:18 2015-12-26 16:19:18 21000041 16
77 76 2015-12-26 16:19:18 2015-12-26 16:19:18 21000042 16
78 77 2015-12-26 16:19:18 2015-12-26 16:19:18 21000043 16
79 78 2015-12-26 16:19:18 2015-12-26 16:19:18 21000044 16
80 79 2015-12-26 16:19:18 2015-12-26 16:19:18 21000045 16
81 80 2015-12-26 16:19:18 2015-12-26 16:19:18 21000046 16
82 81 2015-12-26 16:19:18 2015-12-26 16:19:18 21000047 16
83 82 2015-12-26 16:19:18 2015-12-26 16:19:18 21000048 16
84 83 2015-12-26 16:19:18 2015-12-26 16:19:18 21000049 16
85 84 2015-12-26 16:19:18 2015-12-26 16:19:18 21000050 16
86 85 2015-12-26 16:19:18 2015-12-26 16:19:18 21000051 16
87 86 2015-12-26 16:19:18 2015-12-26 16:19:18 21000052 16
88 87 2015-12-26 16:19:18 2015-12-26 16:19:18 21000053 16
89 88 2015-12-26 16:19:18 2015-12-26 16:19:18 21000054 16
90 89 2015-12-26 16:19:18 2015-12-26 16:19:18 21000055 21
91 90 2015-12-26 16:19:18 2015-12-26 16:19:18 21000056 21
92 91 2015-12-26 16:19:18 2015-12-26 16:19:18 21000057 21
93 92 2015-12-26 16:19:18 2015-12-26 16:19:18 21000058 21
94 93 2015-12-26 16:19:18 2015-12-26 16:19:18 21000059 21
95 94 2015-12-26 16:19:18 2015-12-26 16:19:18 21000055 38
96 95 2015-12-26 16:19:18 2015-12-26 16:19:18 21000056 38
97 96 2015-12-26 16:19:18 2015-12-26 16:19:18 21000057 38
98 97 2015-12-26 16:19:18 2015-12-26 16:19:18 21000058 38
99 98 2015-12-26 16:19:18 2015-12-26 16:19:18 21000059 53
100 99 2015-12-26 16:19:18 2015-12-26 16:19:18 21000060 6
101 100 2015-12-26 16:19:18 2015-12-26 16:19:18 21000061 6
102 101 2015-12-26 16:19:18 2015-12-26 16:19:18 21000062 6
103 102 2015-12-26 16:19:18 2015-12-26 16:19:18 21000063 6
104 103 2015-12-26 16:19:18 2015-12-26 16:19:18 21000064 6
105 104 2015-12-26 16:19:18 2015-12-26 16:19:18 21000065 6
106 105 2015-12-26 16:19:18 2015-12-26 16:19:18 21000066 6
107 106 2015-12-26 16:19:18 2015-12-26 16:19:18 21000067 6
108 107 2015-12-26 16:19:18 2015-12-26 16:19:18 21000068 6
109 108 2015-12-26 16:19:18 2015-12-26 16:19:18 21000069 6
110 109 2015-12-26 16:19:18 2015-12-26 16:19:18 21000070 6
111 110 2015-12-26 16:19:18 2015-12-26 16:19:18 21000071 6
112 111 2015-12-26 16:19:18 2015-12-26 16:19:18 21000072 6
113 112 2015-12-26 16:19:18 2015-12-26 16:19:18 21000073 6
114 113 2015-12-26 16:19:18 2015-12-26 16:19:18 21000074 6
115 114 2015-12-26 16:19:18 2015-12-26 16:19:18 21000075 6
116 115 2015-12-26 16:19:18 2015-12-26 16:19:18 21000060 75
117 116 2015-12-26 16:19:18 2015-12-26 16:19:18 21000061 75
118 117 2015-12-26 16:19:18 2015-12-26 16:19:18 21000063 75
119 118 2015-12-26 16:19:18 2015-12-26 16:19:18 21000064 75
120 119 2015-12-26 16:19:18 2015-12-26 16:19:18 21000065 75
121 120 2015-12-26 16:19:18 2015-12-26 16:19:18 21000066 75
122 121 2015-12-26 16:19:18 2015-12-26 16:19:18 21000067 75
123 122 2015-12-26 16:19:18 2015-12-26 16:19:18 21000068 75
124 123 2015-12-26 16:19:18 2015-12-26 16:19:18 21000069 75
125 124 2015-12-26 16:19:18 2015-12-26 16:19:18 21000070 75
126 125 2015-12-26 16:19:18 2015-12-26 16:19:18 21000071 75
127 126 2015-12-26 16:19:18 2015-12-26 16:19:18 21000072 75
128 127 2015-12-26 16:19:18 2015-12-26 16:19:18 21000073 75
129 128 2015-12-26 16:19:18 2015-12-26 16:19:18 21000074 75
130 129 2015-12-26 16:19:18 2015-12-26 16:19:18 21000075 75
131 130 2015-12-26 16:19:18 2015-12-26 16:19:18 21000076 59
132 131 2015-12-26 16:19:18 2015-12-26 16:19:18 21000077 59
133 132 2015-12-26 16:19:18 2015-12-26 16:19:18 21000078 59
134 133 2015-12-26 16:19:18 2015-12-26 16:19:18 21000079 59
135 134 2015-12-26 16:19:18 2015-12-26 16:19:18 21000080 59
136 135 2015-12-26 16:19:18 2015-12-26 16:19:18 21000081 59
137 136 2015-12-26 16:19:18 2015-12-26 16:19:18 21000082 59
138 137 2015-12-26 16:19:18 2015-12-26 16:19:18 21000083 59
139 138 2015-12-26 16:19:18 2015-12-26 16:19:18 21000084 59
140 139 2015-12-26 16:19:18 2015-12-26 16:19:18 21000085 59
141 140 2015-12-26 16:19:18 2015-12-26 16:19:18 21000086 59
142 141 2015-12-26 16:19:18 2015-12-26 16:19:18 21000087 59
143 142 2015-12-26 16:19:18 2015-12-26 16:19:18 21000088 59
144 143 2015-12-26 16:19:18 2015-12-26 16:19:18 21000089 59
145 144 2015-12-26 16:19:18 2015-12-26 16:19:18 21000090 59
146 145 2015-12-26 16:19:18 2015-12-26 16:19:18 21000091 59
147 146 2015-12-26 16:19:18 2015-12-26 16:19:18 21000092 59
148 147 2015-12-26 16:19:18 2015-12-26 16:19:18 21000093 59
149 148 2015-12-26 16:19:18 2015-12-26 16:19:18 21000094 59
150 149 2015-12-26 16:19:18 2015-12-26 16:19:18 21000095 59
151 150 2015-12-26 16:19:18 2015-12-26 16:19:18 21000096 59
152 151 2015-12-26 16:19:18 2015-12-26 16:19:18 21000097 59
153 152 2015-12-26 16:19:18 2015-12-26 16:19:18 21000098 59
154 153 2015-12-26 16:19:18 2015-12-26 16:19:18 21000099 59
155 154 2015-12-26 16:19:18 2015-12-26 16:19:18 21000100 59
156 155 2015-12-26 16:19:18 2015-12-26 16:19:18 21000101 59
157 156 2015-12-26 16:19:18 2015-12-26 16:19:18 21000102 59
158 157 2015-12-26 16:19:18 2015-12-26 16:19:18 21000103 59
159 158 2015-12-26 16:19:18 2015-12-26 16:19:18 21000104 59
160 159 2015-12-26 16:19:18 2015-12-26 16:19:18 21000105 59
161 160 2015-12-26 16:19:18 2015-12-26 16:19:18 21000106 18
162 161 2015-12-26 16:19:18 2015-12-26 16:19:18 21000107 18
163 162 2015-12-26 16:19:18 2015-12-26 16:19:18 21000108 18
164 163 2015-12-26 16:19:18 2015-12-26 16:19:18 21000109 18
165 164 2015-12-26 16:19:18 2015-12-26 16:19:18 21000110 18
166 165 2015-12-26 16:19:18 2015-12-26 16:19:18 21000111 18
167 166 2015-12-26 16:19:18 2015-12-26 16:19:18 21000112 18
168 167 2015-12-26 16:19:18 2015-12-26 16:19:18 21000113 18
169 168 2015-12-26 16:19:18 2015-12-26 16:19:18 21000114 18
170 169 2015-12-26 16:19:18 2015-12-26 16:19:18 21000115 18
171 170 2015-12-26 16:19:18 2015-12-26 16:19:18 21000116 18
172 171 2015-12-26 16:19:18 2015-12-26 16:19:18 21000117 18
173 172 2015-12-26 16:19:18 2015-12-26 16:19:18 21000118 18
174 173 2015-12-26 16:19:18 2015-12-26 16:19:18 21000119 18
175 174 2015-12-26 16:19:18 2015-12-26 16:19:18 21000120 18
176 175 2015-12-26 16:19:18 2015-12-26 16:19:18 21000121 18
177 176 2015-12-26 16:19:18 2015-12-26 16:19:18 21000122 59
178 177 2015-12-26 16:19:18 2015-12-26 16:19:18 21000123 59
179 178 2015-12-26 16:19:18 2015-12-26 16:19:18 21000124 59
180 179 2015-12-26 16:19:18 2015-12-26 16:19:18 21000125 59
181 180 2015-12-26 16:19:18 2015-12-26 16:19:18 21000126 59
182 181 2015-12-26 16:19:18 2015-12-26 16:19:18 21000127 59
183 182 2015-12-26 16:19:18 2015-12-26 16:19:18 21000128 59
184 183 2015-12-26 16:19:18 2015-12-26 16:19:18 21000129 30
185 184 2015-12-26 16:19:18 2015-12-26 16:19:18 21000130 30
186 185 2015-12-26 16:19:18 2015-12-26 16:19:18 21000131 30
187 186 2015-12-26 16:19:18 2015-12-26 16:19:18 21000132 30
188 187 2015-12-26 16:19:18 2015-12-26 16:19:18 21000133 30
189 188 2015-12-26 16:19:18 2015-12-26 16:19:18 21000134 30
190 189 2015-12-26 16:19:18 2015-12-26 16:19:18 21000135 30
191 190 2015-12-26 16:19:18 2015-12-26 16:19:18 21000136 30
192 191 2015-12-26 16:19:18 2015-12-26 16:19:18 21000137 30
193 192 2015-12-26 16:19:18 2015-12-26 16:19:18 21000138 30
194 193 2015-12-26 16:19:18 2015-12-26 16:19:18 21000139 30
195 194 2015-12-26 16:19:18 2015-12-26 16:19:18 21000140 30
196 195 2015-12-26 16:19:18 2015-12-26 16:19:18 21000141 30
197 196 2015-12-26 16:19:18 2015-12-26 16:19:18 21000142 30
198 197 2015-12-26 16:19:18 2015-12-26 16:19:18 21000143 30
199 198 2015-12-26 16:19:18 2015-12-26 16:19:18 21000144 59
200 199 2015-12-26 16:19:18 2015-12-26 16:19:18 21000145 59
201 200 2015-12-26 16:19:18 2015-12-26 16:19:18 21000146 59
202 201 2015-12-26 16:19:18 2015-12-26 16:19:18 21000147 59
203 202 2015-12-26 16:19:18 2015-12-26 16:19:18 21000148 59
204 203 2015-12-26 16:19:18 2015-12-26 16:19:18 21000149 59
205 204 2015-12-26 16:19:18 2015-12-26 16:19:18 21000150 59
206 205 2015-12-26 16:19:18 2015-12-26 16:19:18 21000151 59
207 206 2015-12-26 16:19:18 2015-12-26 16:19:18 21000152 59
208 207 2015-12-26 16:19:18 2015-12-26 16:19:18 21000153 42
209 208 2015-12-26 16:19:18 2015-12-26 16:19:18 21000154 42
210 209 2015-12-26 16:19:18 2015-12-26 16:19:18 21000155 42
211 210 2015-12-26 16:19:18 2015-12-26 16:19:18 21000156 42
212 211 2015-12-26 16:19:18 2015-12-26 16:19:18 21000157 42
213 212 2015-12-26 16:19:18 2015-12-26 16:19:18 21000158 42
214 213 2015-12-26 16:19:18 2015-12-26 16:19:18 21000159 42
215 214 2015-12-26 16:19:18 2015-12-26 16:19:18 21000160 42
216 215 2015-12-26 16:19:18 2015-12-26 16:19:18 21000161 42
217 216 2015-12-26 16:19:18 2015-12-26 16:19:18 21000162 61
218 217 2015-12-26 16:19:18 2015-12-26 16:19:18 21000163 61
219 218 2015-12-26 16:19:18 2015-12-26 16:19:18 21000164 61
220 219 2015-12-26 16:19:18 2015-12-26 16:19:18 21000165 61
221 220 2015-12-26 16:19:18 2015-12-26 16:19:18 21000166 49
222 221 2015-12-26 16:19:18 2015-12-26 16:19:18 21000167 49
223 222 2015-12-26 16:19:18 2015-12-26 16:19:18 21000168 49
224 223 2015-12-26 16:19:18 2015-12-26 16:19:18 21000169 49
225 224 2015-12-26 16:19:18 2015-12-26 16:19:18 21000170 49
226 225 2015-12-26 16:19:18 2015-12-26 16:19:18 21000171 49
227 226 2015-12-26 16:19:18 2015-12-26 16:19:18 21000172 49
228 227 2015-12-26 16:19:18 2015-12-26 16:19:18 21000173 68
229 228 2015-12-26 16:19:18 2015-12-26 16:19:18 21000174 68
230 229 2015-12-26 16:19:18 2015-12-26 16:19:18 21000175 68
231 230 2015-12-26 16:19:18 2015-12-26 16:19:18 21000176 68
232 231 2015-12-26 16:19:18 2015-12-26 16:19:18 21000177 68
233 232 2015-12-26 16:19:18 2015-12-26 16:19:18 21000178 68
234 233 2015-12-26 16:19:18 2015-12-26 16:19:18 21000179 68
235 234 2015-12-26 16:19:18 2015-12-26 16:19:18 21000180 68
236 235 2015-12-26 16:19:18 2015-12-26 16:19:18 21000181 68
237 236 2015-12-26 16:19:18 2015-12-26 16:19:18 21000182 68
238 237 2015-12-26 16:19:18 2015-12-26 16:19:18 21000183 68
239 238 2015-12-26 16:19:18 2015-12-26 16:19:18 21000184 68
240 239 2015-12-26 16:19:18 2015-12-26 16:19:18 21000185 68
241 240 2015-12-26 16:19:18 2015-12-26 16:19:18 21000186 68
242 241 2015-12-26 16:19:18 2015-12-26 16:19:18 21000187 68
243 242 2015-12-26 16:19:18 2015-12-26 16:19:18 21000188 68
244 243 2015-12-26 16:19:18 2015-12-26 16:19:18 21000189 68
245 244 2015-12-26 16:19:18 2015-12-26 16:19:18 21000190 68
246 245 2015-12-26 16:19:18 2015-12-26 16:19:18 21000191 68
247 246 2015-12-26 16:19:18 2015-12-26 16:19:18 21000192 68
248 247 2015-12-26 16:19:18 2015-12-26 16:19:18 21000193 68
249 248 2015-12-26 16:19:18 2015-12-26 16:19:18 21000194 68
250 249 2015-12-26 16:19:18 2015-12-26 16:19:18 21000195 12
251 250 2015-12-26 16:19:18 2015-12-26 16:19:18 21000196 12
252 251 2015-12-26 16:19:18 2015-12-26 16:19:18 21000197 12
253 252 2015-12-26 16:19:18 2015-12-26 16:19:18 21000198 12
254 253 2015-12-26 16:19:18 2015-12-26 16:19:18 21000199 12
255 254 2015-12-26 16:19:18 2015-12-26 16:19:18 21000200 12
256 255 2015-12-26 16:19:18 2015-12-26 16:19:18 21000201 12
257 256 2015-12-26 16:19:18 2015-12-26 16:19:18 21000202 12
258 257 2015-12-26 16:19:18 2015-12-26 16:19:18 21000203 12
259 258 2015-12-26 16:19:18 2015-12-26 16:19:18 21000204 12
260 259 2015-12-26 16:19:18 2015-12-26 16:19:18 21000205 12
261 260 2015-12-26 16:19:18 2015-12-26 16:19:18 21000206 12
262 261 2015-12-26 16:19:18 2015-12-26 16:19:18 21000207 12
263 262 2015-12-26 16:19:18 2015-12-26 16:19:18 21000208 12
264 263 2015-12-26 16:19:18 2015-12-26 16:19:18 21000209 12
265 264 2015-12-26 16:19:18 2015-12-26 16:19:18 21000210 12
266 265 2015-12-26 16:19:18 2015-12-26 16:19:18 21000211 12
267 266 2015-12-26 16:19:18 2015-12-26 16:19:18 21000212 12
268 267 2015-12-26 16:19:18 2015-12-26 16:19:18 21000213 26
269 268 2015-12-26 16:19:18 2015-12-26 16:19:18 21000214 26
270 269 2015-12-26 16:19:18 2015-12-26 16:19:18 21000215 26
271 270 2015-12-26 16:19:18 2015-12-26 16:19:18 21000216 26
272 271 2015-12-26 16:19:18 2015-12-26 16:19:18 21000217 26
273 272 2015-12-26 16:19:18 2015-12-26 16:19:18 21000218 26
274 273 2015-12-26 16:19:18 2015-12-26 16:19:18 21000219 26
275 274 2015-12-26 16:19:18 2015-12-26 16:19:18 21000220 26
276 275 2015-12-26 16:19:18 2015-12-26 16:19:18 21000221 26
277 276 2015-12-26 16:19:18 2015-12-26 16:19:18 21000222 26
278 277 2015-12-26 16:19:18 2015-12-26 16:19:18 21000223 26
279 278 2015-12-26 16:19:18 2015-12-26 16:19:18 21000224 26
280 279 2015-12-26 16:19:18 2015-12-26 16:19:18 21000225 26
281 280 2015-12-26 16:19:18 2015-12-26 16:19:18 21000226 26
282 281 2015-12-26 16:19:18 2015-12-26 16:19:18 21000227 12
283 282 2015-12-26 16:19:18 2015-12-26 16:19:18 21000228 12
284 283 2015-12-26 16:19:18 2015-12-26 16:19:18 21000229 12
285 284 2015-12-26 16:19:18 2015-12-26 16:19:18 21000230 12
286 285 2015-12-26 16:19:18 2015-12-26 16:19:18 21000231 12
287 286 2015-12-26 16:19:18 2015-12-26 16:19:18 21000232 25
288 287 2015-12-26 16:19:18 2015-12-26 16:19:18 21000233 70
289 288 2015-12-26 16:19:18 2015-12-26 16:19:18 21000234 15
290 289 2015-12-26 16:19:18 2015-12-26 16:19:18 21000235 15
291 290 2015-12-26 16:19:18 2015-12-26 16:19:18 21000236 25
292 291 2015-12-26 16:19:18 2015-12-26 16:19:18 21000237 15
293 292 2015-12-26 16:19:18 2015-12-26 16:19:18 21000238 15
294 293 2015-12-26 16:19:18 2015-12-26 16:19:18 21000239 70
295 294 2015-12-26 16:19:18 2015-12-26 16:19:18 21000240 25
296 295 2015-12-26 16:19:18 2015-12-26 16:19:18 21000241 25
297 296 2015-12-26 16:19:18 2015-12-26 16:19:18 21000242 25
298 297 2015-12-26 16:19:18 2015-12-26 16:19:18 21000243 25
299 298 2015-12-26 16:19:18 2015-12-26 16:19:18 21000244 25
300 299 2015-12-26 16:19:18 2015-12-26 16:19:18 21000245 25
301 300 2015-12-26 16:19:18 2015-12-26 16:19:18 21000246 25
302 301 2015-12-26 16:19:18 2015-12-26 16:19:18 21000247 25
303 302 2015-12-26 16:19:18 2015-12-26 16:19:18 21000248 25
304 303 2015-12-26 16:19:18 2015-12-26 16:19:18 21000249 25
305 304 2015-12-26 16:19:18 2015-12-26 16:19:18 21000250 25
306 305 2015-12-26 16:19:18 2015-12-26 16:19:18 21000251 25
307 306 2015-12-26 16:19:18 2015-12-26 16:19:18 21000252 25
308 307 2015-12-26 16:19:18 2015-12-26 16:19:18 21000253 25
309 308 2015-12-26 16:19:18 2015-12-26 16:19:18 21000254 25
310 309 2015-12-26 16:19:18 2015-12-26 16:19:18 21000255 25
311 310 2015-12-26 16:19:18 2015-12-26 16:19:18 21000256 64
312 311 2015-12-26 16:19:18 2015-12-26 16:19:18 21000257 64
313 312 2015-12-26 16:19:18 2015-12-26 16:19:18 21000258 64
314 313 2015-12-26 16:19:18 2015-12-26 16:19:18 21000259 64
315 314 2015-12-26 16:19:18 2015-12-26 16:19:18 21000260 64
316 315 2015-12-26 16:19:18 2015-12-26 16:19:18 21000261 64
317 316 2015-12-26 16:19:18 2015-12-26 16:19:18 21000262 64
318 317 2015-12-26 16:19:18 2015-12-26 16:19:18 21000263 64
319 318 2015-12-26 16:19:18 2015-12-26 16:19:18 21000264 64
320 319 2015-12-26 16:19:18 2015-12-26 16:19:18 21000265 35
321 320 2015-12-26 16:19:18 2015-12-26 16:19:18 21000266 35
322 321 2015-12-26 16:19:18 2015-12-26 16:19:18 21000267 35
323 322 2015-12-26 16:19:18 2015-12-26 16:19:18 21000268 35
324 323 2015-12-26 16:19:18 2015-12-26 16:19:18 21000269 35
325 324 2015-12-26 16:19:18 2015-12-26 16:19:18 21000270 35
326 325 2015-12-26 16:19:18 2015-12-26 16:19:18 21000271 35
327 326 2015-12-26 16:19:18 2015-12-26 16:19:18 21000272 35
328 327 2015-12-26 16:19:18 2015-12-26 16:19:18 21000273 35
329 328 2015-12-26 16:19:18 2015-12-26 16:19:18 21000274 25
330 329 2015-12-26 16:19:18 2015-12-26 16:19:18 21000275 25
331 330 2015-12-26 16:19:18 2015-12-26 16:19:18 21000276 25
332 331 2015-12-26 16:19:18 2015-12-26 16:19:18 21000277 25
333 332 2015-12-26 16:19:18 2015-12-26 16:19:18 21000278 25
334 333 2015-12-26 16:19:18 2015-12-26 16:19:18 21000279 25
335 334 2015-12-26 16:19:18 2015-12-26 16:19:18 21000280 25
336 335 2015-12-26 16:19:18 2015-12-26 16:19:18 21000281 25
337 336 2015-12-26 16:19:18 2015-12-26 16:19:18 21000282 25
338 337 2015-12-26 16:19:18 2015-12-26 16:19:18 21000283 25
339 338 2015-12-26 16:19:18 2015-12-26 16:19:18 21000284 25
340 339 2015-12-26 16:19:18 2015-12-26 16:19:18 21000285 25
341 340 2015-12-26 16:19:18 2015-12-26 16:19:18 21000286 20
342 341 2015-12-26 16:19:18 2015-12-26 16:19:18 21000287 20
343 342 2015-12-26 16:19:18 2015-12-26 16:19:18 21000288 20
344 343 2015-12-26 16:19:18 2015-12-26 16:19:18 21000289 20
345 344 2015-12-26 16:19:18 2015-12-26 16:19:18 21000290 20
346 345 2015-12-26 16:19:18 2015-12-26 16:19:18 21000291 20
347 346 2015-12-26 16:19:18 2015-12-26 16:19:18 21000292 20
348 347 2015-12-26 16:19:18 2015-12-26 16:19:18 21000293 20
349 348 2015-12-26 16:19:18 2015-12-26 16:19:18 21000294 20
350 349 2015-12-26 16:19:18 2015-12-26 16:19:18 21000295 20
351 350 2015-12-26 16:19:18 2015-12-26 16:19:18 21000296 20
352 351 2015-12-26 16:19:18 2015-12-26 16:19:18 21000297 23
353 352 2015-12-26 16:19:18 2015-12-26 16:19:18 21000298 66
354 353 2015-12-26 16:19:18 2015-12-26 16:19:18 21000299 65
355 354 2015-12-26 16:19:18 2015-12-26 16:19:18 21000300 32
356 355 2015-12-26 16:19:18 2015-12-26 16:19:18 21000301 51
357 356 2015-12-26 16:19:18 2015-12-26 16:19:18 21000302 74
358 357 2015-12-26 16:19:18 2015-12-26 16:19:18 21000303 66
359 358 2015-12-26 16:19:18 2015-12-26 16:19:18 21000304 32
360 359 2015-12-26 16:19:18 2015-12-26 16:19:18 21000305 74
361 360 2015-12-26 16:19:18 2015-12-26 16:19:18 21000306 65
362 361 2015-12-26 16:19:18 2015-12-26 16:19:18 21000307 65
363 362 2015-12-26 16:19:18 2015-12-26 16:19:18 21000308 65
364 363 2015-12-26 16:19:18 2015-12-26 16:19:18 21000309 65
365 364 2015-12-26 16:19:18 2015-12-26 16:19:18 21000310 65
366 365 2015-12-26 16:19:18 2015-12-26 16:19:18 21000311 72
367 366 2015-12-26 16:19:18 2015-12-26 16:19:18 21000312 72
368 367 2015-12-26 16:19:18 2015-12-26 16:19:18 21000313 72
369 368 2015-12-26 16:19:18 2015-12-26 16:19:18 21000314 28
370 369 2015-12-26 16:19:18 2015-12-26 16:19:18 21000315 28
371 370 2015-12-26 16:19:18 2015-12-26 16:19:18 21000316 28
372 371 2015-12-26 16:19:18 2015-12-26 16:19:18 21000317 28
373 372 2015-12-26 16:19:18 2015-12-26 16:19:18 21000318 28
374 373 2015-12-26 16:19:18 2015-12-26 16:19:18 21000319 28
375 374 2015-12-26 16:19:18 2015-12-26 16:19:18 21000320 28
376 375 2015-12-26 16:19:18 2015-12-26 16:19:18 21000321 28
377 376 2015-12-26 16:19:18 2015-12-26 16:19:18 21000322 28
378 377 2015-12-26 16:19:18 2015-12-26 16:19:18 21000323 28
379 378 2015-12-26 16:19:18 2015-12-26 16:19:18 21000153 68
380 379 2015-12-26 16:19:18 2015-12-26 16:19:18 21000154 68
381 380 2015-12-26 16:19:18 2015-12-26 16:19:18 21000155 68
382 381 2015-12-26 16:19:18 2015-12-26 16:19:18 21000156 49
383 382 2015-12-26 16:19:18 2015-12-26 16:19:18 21000157 26
384 383 2015-12-26 16:19:18 2015-12-26 16:19:18 21000158 26
385 384 2015-12-26 16:19:18 2015-12-26 16:19:18 21000159 12
386 385 2015-12-26 16:19:18 2015-12-26 16:19:18 21000160 26
387 386 2015-12-26 16:19:18 2015-12-26 16:19:18 21000161 12
388 387 2015-12-26 16:19:18 2015-12-26 16:19:18 21000162 26
389 388 2015-12-26 16:19:18 2015-12-26 16:19:18 21000163 12
390 389 2015-12-26 16:19:18 2015-12-26 16:19:18 21000164 26
391 390 2015-12-26 16:19:18 2015-12-26 16:19:18 21000165 68
392 391 2015-12-26 16:19:18 2015-12-26 16:19:18 21000166 12
393 392 2015-12-26 16:19:18 2015-12-26 16:19:18 21000167 42
394 393 2015-12-26 16:19:18 2015-12-26 16:19:18 21000168 26
395 394 2015-12-26 16:19:18 2015-12-26 16:19:18 21000169 68
396 395 2015-12-26 16:19:18 2015-12-26 16:19:18 21000170 42
397 396 2015-12-26 16:19:18 2015-12-26 16:19:18 21000171 68
398 397 2015-12-26 16:19:18 2015-12-26 16:19:18 21000172 12
399 398 2015-12-26 16:19:18 2015-12-26 16:19:18 21000173 42
400 399 2015-12-26 16:19:18 2015-12-26 16:19:18 21000174 49
401 400 2015-12-26 16:19:18 2015-12-26 16:19:18 21000175 12
402 401 2015-12-26 16:19:18 2015-12-26 16:19:18 21000176 12
403 402 2015-12-26 16:19:18 2015-12-26 16:19:18 21000177 12
404 403 2015-12-26 16:19:18 2015-12-26 16:19:18 21000178 61
405 404 2015-12-26 16:19:18 2015-12-26 16:19:18 21000179 26
406 405 2015-12-26 16:19:18 2015-12-26 16:19:18 21000180 26
407 406 2015-12-26 16:19:18 2015-12-26 16:19:18 21000181 26
408 407 2015-12-26 16:19:18 2015-12-26 16:19:18 21000182 61
409 408 2015-12-26 16:19:18 2015-12-26 16:19:18 21000183 12
410 409 2015-12-26 16:19:18 2015-12-26 16:19:18 21000184 12
411 410 2015-12-26 16:19:18 2015-12-26 16:19:18 21000185 26
412 411 2015-12-26 16:19:18 2015-12-26 16:19:18 21000186 26
413 412 2015-12-26 16:19:18 2015-12-26 16:19:18 21000187 42
414 413 2015-12-26 16:19:18 2015-12-26 16:19:18 21000188 26
415 414 2015-12-26 16:19:18 2015-12-26 16:19:18 21000189 42
416 415 2015-12-26 16:19:18 2015-12-26 16:19:18 21000190 42
417 416 2015-12-26 16:19:18 2015-12-26 16:19:18 21000191 12
418 417 2015-12-26 16:19:18 2015-12-26 16:19:18 21000192 42
419 418 2015-12-26 16:19:18 2015-12-26 16:19:18 21000193 49
420 419 2015-12-26 16:19:18 2015-12-26 16:19:18 21000194 12
421 420 2015-12-26 16:19:18 2015-12-26 16:19:18 21000195 68
422 421 2015-12-26 16:19:18 2015-12-26 16:19:18 21000196 49
423 422 2015-12-26 16:19:18 2015-12-26 16:19:18 21000197 26
424 423 2015-12-26 16:19:18 2015-12-26 16:19:18 21000198 42
425 424 2015-12-26 16:19:18 2015-12-26 16:19:18 21000199 42
426 425 2015-12-26 16:19:18 2015-12-26 16:19:18 21000200 68
427 426 2015-12-26 16:19:18 2015-12-26 16:19:18 21000201 68
428 427 2015-12-26 16:19:18 2015-12-26 16:19:18 21000202 42
429 428 2015-12-26 16:19:18 2015-12-26 16:19:18 21000203 26
430 429 2015-12-26 16:19:18 2015-12-26 16:19:18 21000204 26
431 430 2015-12-26 16:19:18 2015-12-26 16:19:18 21000205 49
432 431 2015-12-26 16:19:18 2015-12-26 16:19:18 21000206 68
433 432 2015-12-26 16:19:18 2015-12-26 16:19:18 21000207 68
434 433 2015-12-26 16:19:18 2015-12-26 16:19:18 21000208 26
435 434 2015-12-26 16:19:18 2015-12-26 16:19:18 21000209 26
436 435 2015-12-26 16:19:18 2015-12-26 16:19:18 21000210 26
437 436 2015-12-26 16:19:18 2015-12-26 16:19:18 21000211 61
438 437 2015-12-26 16:19:18 2015-12-26 16:19:18 21000212 42
439 438 2015-12-26 16:19:18 2015-12-26 16:19:18 21000213 12
440 439 2015-12-26 16:19:18 2015-12-26 16:19:18 21000214 68
441 440 2015-12-26 16:19:18 2015-12-26 16:19:18 21000215 12
442 441 2015-12-26 16:19:18 2015-12-26 16:19:18 21000216 68
443 442 2015-12-26 16:19:18 2015-12-26 16:19:18 21000217 42
444 443 2015-12-26 16:19:18 2015-12-26 16:19:18 21000218 12
445 444 2015-12-26 16:19:18 2015-12-26 16:19:18 21000219 12
446 445 2015-12-26 16:19:18 2015-12-26 16:19:18 21000220 68
447 446 2015-12-26 16:19:18 2015-12-26 16:19:18 21000221 42
448 447 2015-12-26 16:19:18 2015-12-26 16:19:18 21000222 68
449 448 2015-12-26 16:19:18 2015-12-26 16:19:18 21000223 12
450 449 2015-12-26 16:19:18 2015-12-26 16:19:18 21000224 42
451 450 2015-12-26 16:19:18 2015-12-26 16:19:18 21000225 49
452 451 2015-12-26 16:19:18 2015-12-26 16:19:18 21000226 61
453 452 2015-12-26 16:19:18 2015-12-26 16:19:18 21000227 68
454 453 2015-12-26 16:19:18 2015-12-26 16:19:18 21000228 42
455 454 2015-12-26 16:19:18 2015-12-26 16:19:18 21000229 68
456 455 2015-12-26 16:19:18 2015-12-26 16:19:18 21000230 68
457 456 2015-12-26 16:19:18 2015-12-26 16:19:18 21000231 49
458 457 2015-12-26 16:19:18 2015-12-26 16:19:18 21000329 20
459 458 2016-07-15 18:45:01 2016-07-15 18:45:01 21000324 81
460 459 2016-07-15 18:45:01 2016-07-15 18:45:01 21000324 82
461 460 2016-07-15 18:45:09 2016-07-15 18:45:09 21000324 83
462 461 2016-07-15 19:55:26 2016-07-15 19:55:26 21000062 75

View File

@@ -1,235 +0,0 @@
"Id";"Created";"Updated";"SystemId";"WormholeId";
"1";"2016-07-16 13:53:19";"2017-02-11 17:11:18";"31002572";"59";
"2";"2016-07-16 13:53:19";"2017-02-11 17:11:18";"31002572";"25";
"3";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002518";"6";
"4";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002518";"21";
"5";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002543";"12";
"6";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002543";"68";
"7";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002528";"18";
"8";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002528";"59";
"9";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002535";"18";
"10";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002535";"59";
"11";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002530";"18";
"12";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002530";"59";
"13";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002557";"59";
"14";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002557";"25";
"15";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002548";"12";
"16";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002548";"68";
"17";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002564";"59";
"18";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002564";"25";
"19";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002524";"6";
"20";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002524";"21";
"21";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002514";"39";
"22";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002514";"28";
"23";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002542";"12";
"24";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002542";"68";
"25";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002538";"12";
"26";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002538";"68";
"27";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002511";"39";
"28";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002511";"28";
"29";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002529";"18";
"30";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002529";"59";
"31";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002525";"6";
"32";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002525";"21";
"33";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002562";"59";
"34";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002562";"25";
"35";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002563";"59";
"36";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002563";"25";
"37";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002532";"18";
"38";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002532";"59";
"39";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002569";"59";
"40";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002569";"25";
"41";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002558";"59";
"42";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002558";"25";
"43";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002570";"59";
"44";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002570";"25";
"45";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002549";"12";
"46";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002549";"68";
"47";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002537";"30";
"48";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002537";"59";
"49";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002513";"39";
"50";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002513";"28";
"51";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002539";"12";
"52";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002539";"68";
"53";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002526";"6";
"54";"2016-07-16 13:53:19";"2017-02-11 17:11:19";"31002526";"21";
"55";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002512";"39";
"56";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002512";"28";
"57";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002574";"59";
"58";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002574";"25";
"59";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002561";"59";
"60";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002561";"25";
"61";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002571";"59";
"62";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002571";"25";
"63";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002567";"59";
"64";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002567";"20";
"65";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002546";"12";
"66";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002546";"68";
"67";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002555";"12";
"68";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002555";"68";
"69";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002552";"12";
"70";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002552";"68";
"71";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002515";"6";
"72";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002515";"21";
"73";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002568";"59";
"74";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002568";"25";
"75";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002573";"59";
"76";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002573";"25";
"77";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002506";"39";
"78";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002506";"28";
"79";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002550";"12";
"80";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002550";"68";
"81";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002516";"6";
"82";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002516";"21";
"83";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002534";"30";
"84";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002534";"59";
"85";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002508";"39";
"86";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002508";"28";
"87";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002547";"12";
"88";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002547";"68";
"89";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002523";"6";
"90";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002523";"21";
"91";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002541";"12";
"92";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002541";"68";
"93";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002576";"30";
"94";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002576";"65";
"95";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002544";"12";
"96";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002544";"68";
"97";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002509";"39";
"98";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002509";"28";
"99";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002556";"59";
"100";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002556";"25";
"101";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002579";"30";
"102";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002579";"65";
"103";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002554";"12";
"104";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002554";"68";
"105";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002519";"6";
"106";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002519";"21";
"107";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002536";"18";
"108";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002536";"59";
"109";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002553";"12";
"110";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002553";"68";
"111";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002551";"12";
"112";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002551";"68";
"113";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002527";"18";
"114";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002527";"59";
"115";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002545";"12";
"116";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002545";"68";
"117";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002559";"59";
"118";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002559";"25";
"119";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002540";"12";
"120";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002540";"68";
"121";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002510";"39";
"122";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002510";"28";
"123";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002507";"39";
"124";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002507";"28";
"125";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002577";"30";
"126";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002577";"65";
"127";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002565";"59";
"128";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002565";"25";
"129";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002522";"6";
"130";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002522";"21";
"131";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002575";"30";
"132";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002575";"65";
"133";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002521";"6";
"134";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002521";"21";
"135";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002566";"59";
"136";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002566";"25";
"137";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002533";"18";
"138";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002533";"59";
"139";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002517";"6";
"140";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002517";"21";
"141";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002520";"6";
"142";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002520";"21";
"143";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002560";"59";
"144";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002560";"25";
"145";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002531";"18";
"146";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002531";"59";
"147";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002505";"39";
"148";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002505";"28";
"149";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002578";"30";
"150";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002578";"13";
"151";"2016-07-16 13:53:20";"2017-02-11 17:11:19";"31002578";"66";
"152";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002572";"35";
"153";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002518";"16";
"154";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002543";"30";
"155";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002543";"26";
"156";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002543";"61";
"157";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002535";"30";
"158";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002530";"30";
"159";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002557";"30";
"160";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002548";"30";
"161";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002548";"26";
"162";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002524";"2";
"163";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002524";"75";
"164";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002514";"72";
"165";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002542";"18";
"166";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002542";"49";
"167";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002542";"42";
"168";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002538";"59";
"169";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002511";"72";
"170";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002529";"30";
"171";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002525";"2";
"172";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002525";"38";
"173";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002562";"15";
"174";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002563";"35";
"175";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002569";"30";
"176";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002569";"20";
"177";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002558";"30";
"178";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002549";"18";
"179";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002549";"42";
"180";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002539";"59";
"181";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002526";"2";
"182";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002526";"47";
"183";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002574";"30";
"184";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002571";"30";
"185";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002571";"64";
"186";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002546";"18";
"187";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002555";"59";
"188";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002552";"30";
"189";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002552";"26";
"190";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002515";"2";
"191";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002515";"75";
"192";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002573";"30";
"193";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002506";"72";
"194";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002550";"59";
"195";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002550";"49";
"196";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002516";"2";
"197";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002516";"69";
"198";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002547";"30";
"199";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002547";"26";
"200";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002547";"61";
"201";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002523";"75";
"202";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002523";"16";
"203";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002541";"59";
"204";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002541";"42";
"205";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002576";"66";
"206";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002544";"18";
"207";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002544";"49";
"208";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002544";"42";
"209";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002556";"30";
"210";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002556";"64";
"211";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002554";"59";
"212";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002554";"26";
"213";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002519";"69";
"214";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002551";"59";
"215";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002551";"26";
"216";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002545";"18";
"217";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002545";"49";
"218";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002559";"17";
"219";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002559";"30";
"220";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002559";"35";
"221";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002540";"59";
"222";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002510";"72";
"223";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002507";"72";
"224";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002522";"2";
"225";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002521";"47";
"226";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002566";"20";
"227";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002533";"30";
"228";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002517";"2";
"229";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002517";"53";
"230";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002520";"2";
"231";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002520";"16";
"232";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002560";"30";
"233";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31002505";"72";
"234";"2017-02-25 17:52:14";"2017-02-25 17:52:14";"31000001";"16";
1 Id Created Updated SystemId WormholeId
2 1 2016-07-16 13:53:19 2017-02-11 17:11:18 31002572 59
3 2 2016-07-16 13:53:19 2017-02-11 17:11:18 31002572 25
4 3 2016-07-16 13:53:19 2017-02-11 17:11:19 31002518 6
5 4 2016-07-16 13:53:19 2017-02-11 17:11:19 31002518 21
6 5 2016-07-16 13:53:19 2017-02-11 17:11:19 31002543 12
7 6 2016-07-16 13:53:19 2017-02-11 17:11:19 31002543 68
8 7 2016-07-16 13:53:19 2017-02-11 17:11:19 31002528 18
9 8 2016-07-16 13:53:19 2017-02-11 17:11:19 31002528 59
10 9 2016-07-16 13:53:19 2017-02-11 17:11:19 31002535 18
11 10 2016-07-16 13:53:19 2017-02-11 17:11:19 31002535 59
12 11 2016-07-16 13:53:19 2017-02-11 17:11:19 31002530 18
13 12 2016-07-16 13:53:19 2017-02-11 17:11:19 31002530 59
14 13 2016-07-16 13:53:19 2017-02-11 17:11:19 31002557 59
15 14 2016-07-16 13:53:19 2017-02-11 17:11:19 31002557 25
16 15 2016-07-16 13:53:19 2017-02-11 17:11:19 31002548 12
17 16 2016-07-16 13:53:19 2017-02-11 17:11:19 31002548 68
18 17 2016-07-16 13:53:19 2017-02-11 17:11:19 31002564 59
19 18 2016-07-16 13:53:19 2017-02-11 17:11:19 31002564 25
20 19 2016-07-16 13:53:19 2017-02-11 17:11:19 31002524 6
21 20 2016-07-16 13:53:19 2017-02-11 17:11:19 31002524 21
22 21 2016-07-16 13:53:19 2017-02-11 17:11:19 31002514 39
23 22 2016-07-16 13:53:19 2017-02-11 17:11:19 31002514 28
24 23 2016-07-16 13:53:19 2017-02-11 17:11:19 31002542 12
25 24 2016-07-16 13:53:19 2017-02-11 17:11:19 31002542 68
26 25 2016-07-16 13:53:19 2017-02-11 17:11:19 31002538 12
27 26 2016-07-16 13:53:19 2017-02-11 17:11:19 31002538 68
28 27 2016-07-16 13:53:19 2017-02-11 17:11:19 31002511 39
29 28 2016-07-16 13:53:19 2017-02-11 17:11:19 31002511 28
30 29 2016-07-16 13:53:19 2017-02-11 17:11:19 31002529 18
31 30 2016-07-16 13:53:19 2017-02-11 17:11:19 31002529 59
32 31 2016-07-16 13:53:19 2017-02-11 17:11:19 31002525 6
33 32 2016-07-16 13:53:19 2017-02-11 17:11:19 31002525 21
34 33 2016-07-16 13:53:19 2017-02-11 17:11:19 31002562 59
35 34 2016-07-16 13:53:19 2017-02-11 17:11:19 31002562 25
36 35 2016-07-16 13:53:19 2017-02-11 17:11:19 31002563 59
37 36 2016-07-16 13:53:19 2017-02-11 17:11:19 31002563 25
38 37 2016-07-16 13:53:19 2017-02-11 17:11:19 31002532 18
39 38 2016-07-16 13:53:19 2017-02-11 17:11:19 31002532 59
40 39 2016-07-16 13:53:19 2017-02-11 17:11:19 31002569 59
41 40 2016-07-16 13:53:19 2017-02-11 17:11:19 31002569 25
42 41 2016-07-16 13:53:19 2017-02-11 17:11:19 31002558 59
43 42 2016-07-16 13:53:19 2017-02-11 17:11:19 31002558 25
44 43 2016-07-16 13:53:19 2017-02-11 17:11:19 31002570 59
45 44 2016-07-16 13:53:19 2017-02-11 17:11:19 31002570 25
46 45 2016-07-16 13:53:19 2017-02-11 17:11:19 31002549 12
47 46 2016-07-16 13:53:19 2017-02-11 17:11:19 31002549 68
48 47 2016-07-16 13:53:19 2017-02-11 17:11:19 31002537 30
49 48 2016-07-16 13:53:19 2017-02-11 17:11:19 31002537 59
50 49 2016-07-16 13:53:19 2017-02-11 17:11:19 31002513 39
51 50 2016-07-16 13:53:19 2017-02-11 17:11:19 31002513 28
52 51 2016-07-16 13:53:19 2017-02-11 17:11:19 31002539 12
53 52 2016-07-16 13:53:19 2017-02-11 17:11:19 31002539 68
54 53 2016-07-16 13:53:19 2017-02-11 17:11:19 31002526 6
55 54 2016-07-16 13:53:19 2017-02-11 17:11:19 31002526 21
56 55 2016-07-16 13:53:20 2017-02-11 17:11:19 31002512 39
57 56 2016-07-16 13:53:20 2017-02-11 17:11:19 31002512 28
58 57 2016-07-16 13:53:20 2017-02-11 17:11:19 31002574 59
59 58 2016-07-16 13:53:20 2017-02-11 17:11:19 31002574 25
60 59 2016-07-16 13:53:20 2017-02-11 17:11:19 31002561 59
61 60 2016-07-16 13:53:20 2017-02-11 17:11:19 31002561 25
62 61 2016-07-16 13:53:20 2017-02-11 17:11:19 31002571 59
63 62 2016-07-16 13:53:20 2017-02-11 17:11:19 31002571 25
64 63 2016-07-16 13:53:20 2017-02-11 17:11:19 31002567 59
65 64 2016-07-16 13:53:20 2017-02-11 17:11:19 31002567 20
66 65 2016-07-16 13:53:20 2017-02-11 17:11:19 31002546 12
67 66 2016-07-16 13:53:20 2017-02-11 17:11:19 31002546 68
68 67 2016-07-16 13:53:20 2017-02-11 17:11:19 31002555 12
69 68 2016-07-16 13:53:20 2017-02-11 17:11:19 31002555 68
70 69 2016-07-16 13:53:20 2017-02-11 17:11:19 31002552 12
71 70 2016-07-16 13:53:20 2017-02-11 17:11:19 31002552 68
72 71 2016-07-16 13:53:20 2017-02-11 17:11:19 31002515 6
73 72 2016-07-16 13:53:20 2017-02-11 17:11:19 31002515 21
74 73 2016-07-16 13:53:20 2017-02-11 17:11:19 31002568 59
75 74 2016-07-16 13:53:20 2017-02-11 17:11:19 31002568 25
76 75 2016-07-16 13:53:20 2017-02-11 17:11:19 31002573 59
77 76 2016-07-16 13:53:20 2017-02-11 17:11:19 31002573 25
78 77 2016-07-16 13:53:20 2017-02-11 17:11:19 31002506 39
79 78 2016-07-16 13:53:20 2017-02-11 17:11:19 31002506 28
80 79 2016-07-16 13:53:20 2017-02-11 17:11:19 31002550 12
81 80 2016-07-16 13:53:20 2017-02-11 17:11:19 31002550 68
82 81 2016-07-16 13:53:20 2017-02-11 17:11:19 31002516 6
83 82 2016-07-16 13:53:20 2017-02-11 17:11:19 31002516 21
84 83 2016-07-16 13:53:20 2017-02-11 17:11:19 31002534 30
85 84 2016-07-16 13:53:20 2017-02-11 17:11:19 31002534 59
86 85 2016-07-16 13:53:20 2017-02-11 17:11:19 31002508 39
87 86 2016-07-16 13:53:20 2017-02-11 17:11:19 31002508 28
88 87 2016-07-16 13:53:20 2017-02-11 17:11:19 31002547 12
89 88 2016-07-16 13:53:20 2017-02-11 17:11:19 31002547 68
90 89 2016-07-16 13:53:20 2017-02-11 17:11:19 31002523 6
91 90 2016-07-16 13:53:20 2017-02-11 17:11:19 31002523 21
92 91 2016-07-16 13:53:20 2017-02-11 17:11:19 31002541 12
93 92 2016-07-16 13:53:20 2017-02-11 17:11:19 31002541 68
94 93 2016-07-16 13:53:20 2017-02-11 17:11:19 31002576 30
95 94 2016-07-16 13:53:20 2017-02-11 17:11:19 31002576 65
96 95 2016-07-16 13:53:20 2017-02-11 17:11:19 31002544 12
97 96 2016-07-16 13:53:20 2017-02-11 17:11:19 31002544 68
98 97 2016-07-16 13:53:20 2017-02-11 17:11:19 31002509 39
99 98 2016-07-16 13:53:20 2017-02-11 17:11:19 31002509 28
100 99 2016-07-16 13:53:20 2017-02-11 17:11:19 31002556 59
101 100 2016-07-16 13:53:20 2017-02-11 17:11:19 31002556 25
102 101 2016-07-16 13:53:20 2017-02-11 17:11:19 31002579 30
103 102 2016-07-16 13:53:20 2017-02-11 17:11:19 31002579 65
104 103 2016-07-16 13:53:20 2017-02-11 17:11:19 31002554 12
105 104 2016-07-16 13:53:20 2017-02-11 17:11:19 31002554 68
106 105 2016-07-16 13:53:20 2017-02-11 17:11:19 31002519 6
107 106 2016-07-16 13:53:20 2017-02-11 17:11:19 31002519 21
108 107 2016-07-16 13:53:20 2017-02-11 17:11:19 31002536 18
109 108 2016-07-16 13:53:20 2017-02-11 17:11:19 31002536 59
110 109 2016-07-16 13:53:20 2017-02-11 17:11:19 31002553 12
111 110 2016-07-16 13:53:20 2017-02-11 17:11:19 31002553 68
112 111 2016-07-16 13:53:20 2017-02-11 17:11:19 31002551 12
113 112 2016-07-16 13:53:20 2017-02-11 17:11:19 31002551 68
114 113 2016-07-16 13:53:20 2017-02-11 17:11:19 31002527 18
115 114 2016-07-16 13:53:20 2017-02-11 17:11:19 31002527 59
116 115 2016-07-16 13:53:20 2017-02-11 17:11:19 31002545 12
117 116 2016-07-16 13:53:20 2017-02-11 17:11:19 31002545 68
118 117 2016-07-16 13:53:20 2017-02-11 17:11:19 31002559 59
119 118 2016-07-16 13:53:20 2017-02-11 17:11:19 31002559 25
120 119 2016-07-16 13:53:20 2017-02-11 17:11:19 31002540 12
121 120 2016-07-16 13:53:20 2017-02-11 17:11:19 31002540 68
122 121 2016-07-16 13:53:20 2017-02-11 17:11:19 31002510 39
123 122 2016-07-16 13:53:20 2017-02-11 17:11:19 31002510 28
124 123 2016-07-16 13:53:20 2017-02-11 17:11:19 31002507 39
125 124 2016-07-16 13:53:20 2017-02-11 17:11:19 31002507 28
126 125 2016-07-16 13:53:20 2017-02-11 17:11:19 31002577 30
127 126 2016-07-16 13:53:20 2017-02-11 17:11:19 31002577 65
128 127 2016-07-16 13:53:20 2017-02-11 17:11:19 31002565 59
129 128 2016-07-16 13:53:20 2017-02-11 17:11:19 31002565 25
130 129 2016-07-16 13:53:20 2017-02-11 17:11:19 31002522 6
131 130 2016-07-16 13:53:20 2017-02-11 17:11:19 31002522 21
132 131 2016-07-16 13:53:20 2017-02-11 17:11:19 31002575 30
133 132 2016-07-16 13:53:20 2017-02-11 17:11:19 31002575 65
134 133 2016-07-16 13:53:20 2017-02-11 17:11:19 31002521 6
135 134 2016-07-16 13:53:20 2017-02-11 17:11:19 31002521 21
136 135 2016-07-16 13:53:20 2017-02-11 17:11:19 31002566 59
137 136 2016-07-16 13:53:20 2017-02-11 17:11:19 31002566 25
138 137 2016-07-16 13:53:20 2017-02-11 17:11:19 31002533 18
139 138 2016-07-16 13:53:20 2017-02-11 17:11:19 31002533 59
140 139 2016-07-16 13:53:20 2017-02-11 17:11:19 31002517 6
141 140 2016-07-16 13:53:20 2017-02-11 17:11:19 31002517 21
142 141 2016-07-16 13:53:20 2017-02-11 17:11:19 31002520 6
143 142 2016-07-16 13:53:20 2017-02-11 17:11:19 31002520 21
144 143 2016-07-16 13:53:20 2017-02-11 17:11:19 31002560 59
145 144 2016-07-16 13:53:20 2017-02-11 17:11:19 31002560 25
146 145 2016-07-16 13:53:20 2017-02-11 17:11:19 31002531 18
147 146 2016-07-16 13:53:20 2017-02-11 17:11:19 31002531 59
148 147 2016-07-16 13:53:20 2017-02-11 17:11:19 31002505 39
149 148 2016-07-16 13:53:20 2017-02-11 17:11:19 31002505 28
150 149 2016-07-16 13:53:20 2017-02-11 17:11:19 31002578 30
151 150 2016-07-16 13:53:20 2017-02-11 17:11:19 31002578 13
152 151 2016-07-16 13:53:20 2017-02-11 17:11:19 31002578 66
153 152 2017-02-25 17:52:14 2017-02-25 17:52:14 31002572 35
154 153 2017-02-25 17:52:14 2017-02-25 17:52:14 31002518 16
155 154 2017-02-25 17:52:14 2017-02-25 17:52:14 31002543 30
156 155 2017-02-25 17:52:14 2017-02-25 17:52:14 31002543 26
157 156 2017-02-25 17:52:14 2017-02-25 17:52:14 31002543 61
158 157 2017-02-25 17:52:14 2017-02-25 17:52:14 31002535 30
159 158 2017-02-25 17:52:14 2017-02-25 17:52:14 31002530 30
160 159 2017-02-25 17:52:14 2017-02-25 17:52:14 31002557 30
161 160 2017-02-25 17:52:14 2017-02-25 17:52:14 31002548 30
162 161 2017-02-25 17:52:14 2017-02-25 17:52:14 31002548 26
163 162 2017-02-25 17:52:14 2017-02-25 17:52:14 31002524 2
164 163 2017-02-25 17:52:14 2017-02-25 17:52:14 31002524 75
165 164 2017-02-25 17:52:14 2017-02-25 17:52:14 31002514 72
166 165 2017-02-25 17:52:14 2017-02-25 17:52:14 31002542 18
167 166 2017-02-25 17:52:14 2017-02-25 17:52:14 31002542 49
168 167 2017-02-25 17:52:14 2017-02-25 17:52:14 31002542 42
169 168 2017-02-25 17:52:14 2017-02-25 17:52:14 31002538 59
170 169 2017-02-25 17:52:14 2017-02-25 17:52:14 31002511 72
171 170 2017-02-25 17:52:14 2017-02-25 17:52:14 31002529 30
172 171 2017-02-25 17:52:14 2017-02-25 17:52:14 31002525 2
173 172 2017-02-25 17:52:14 2017-02-25 17:52:14 31002525 38
174 173 2017-02-25 17:52:14 2017-02-25 17:52:14 31002562 15
175 174 2017-02-25 17:52:14 2017-02-25 17:52:14 31002563 35
176 175 2017-02-25 17:52:14 2017-02-25 17:52:14 31002569 30
177 176 2017-02-25 17:52:14 2017-02-25 17:52:14 31002569 20
178 177 2017-02-25 17:52:14 2017-02-25 17:52:14 31002558 30
179 178 2017-02-25 17:52:14 2017-02-25 17:52:14 31002549 18
180 179 2017-02-25 17:52:14 2017-02-25 17:52:14 31002549 42
181 180 2017-02-25 17:52:14 2017-02-25 17:52:14 31002539 59
182 181 2017-02-25 17:52:14 2017-02-25 17:52:14 31002526 2
183 182 2017-02-25 17:52:14 2017-02-25 17:52:14 31002526 47
184 183 2017-02-25 17:52:14 2017-02-25 17:52:14 31002574 30
185 184 2017-02-25 17:52:14 2017-02-25 17:52:14 31002571 30
186 185 2017-02-25 17:52:14 2017-02-25 17:52:14 31002571 64
187 186 2017-02-25 17:52:14 2017-02-25 17:52:14 31002546 18
188 187 2017-02-25 17:52:14 2017-02-25 17:52:14 31002555 59
189 188 2017-02-25 17:52:14 2017-02-25 17:52:14 31002552 30
190 189 2017-02-25 17:52:14 2017-02-25 17:52:14 31002552 26
191 190 2017-02-25 17:52:14 2017-02-25 17:52:14 31002515 2
192 191 2017-02-25 17:52:14 2017-02-25 17:52:14 31002515 75
193 192 2017-02-25 17:52:14 2017-02-25 17:52:14 31002573 30
194 193 2017-02-25 17:52:14 2017-02-25 17:52:14 31002506 72
195 194 2017-02-25 17:52:14 2017-02-25 17:52:14 31002550 59
196 195 2017-02-25 17:52:14 2017-02-25 17:52:14 31002550 49
197 196 2017-02-25 17:52:14 2017-02-25 17:52:14 31002516 2
198 197 2017-02-25 17:52:14 2017-02-25 17:52:14 31002516 69
199 198 2017-02-25 17:52:14 2017-02-25 17:52:14 31002547 30
200 199 2017-02-25 17:52:14 2017-02-25 17:52:14 31002547 26
201 200 2017-02-25 17:52:14 2017-02-25 17:52:14 31002547 61
202 201 2017-02-25 17:52:14 2017-02-25 17:52:14 31002523 75
203 202 2017-02-25 17:52:14 2017-02-25 17:52:14 31002523 16
204 203 2017-02-25 17:52:14 2017-02-25 17:52:14 31002541 59
205 204 2017-02-25 17:52:14 2017-02-25 17:52:14 31002541 42
206 205 2017-02-25 17:52:14 2017-02-25 17:52:14 31002576 66
207 206 2017-02-25 17:52:14 2017-02-25 17:52:14 31002544 18
208 207 2017-02-25 17:52:14 2017-02-25 17:52:14 31002544 49
209 208 2017-02-25 17:52:14 2017-02-25 17:52:14 31002544 42
210 209 2017-02-25 17:52:14 2017-02-25 17:52:14 31002556 30
211 210 2017-02-25 17:52:14 2017-02-25 17:52:14 31002556 64
212 211 2017-02-25 17:52:14 2017-02-25 17:52:14 31002554 59
213 212 2017-02-25 17:52:14 2017-02-25 17:52:14 31002554 26
214 213 2017-02-25 17:52:14 2017-02-25 17:52:14 31002519 69
215 214 2017-02-25 17:52:14 2017-02-25 17:52:14 31002551 59
216 215 2017-02-25 17:52:14 2017-02-25 17:52:14 31002551 26
217 216 2017-02-25 17:52:14 2017-02-25 17:52:14 31002545 18
218 217 2017-02-25 17:52:14 2017-02-25 17:52:14 31002545 49
219 218 2017-02-25 17:52:14 2017-02-25 17:52:14 31002559 17
220 219 2017-02-25 17:52:14 2017-02-25 17:52:14 31002559 30
221 220 2017-02-25 17:52:14 2017-02-25 17:52:14 31002559 35
222 221 2017-02-25 17:52:14 2017-02-25 17:52:14 31002540 59
223 222 2017-02-25 17:52:14 2017-02-25 17:52:14 31002510 72
224 223 2017-02-25 17:52:14 2017-02-25 17:52:14 31002507 72
225 224 2017-02-25 17:52:14 2017-02-25 17:52:14 31002522 2
226 225 2017-02-25 17:52:14 2017-02-25 17:52:14 31002521 47
227 226 2017-02-25 17:52:14 2017-02-25 17:52:14 31002566 20
228 227 2017-02-25 17:52:14 2017-02-25 17:52:14 31002533 30
229 228 2017-02-25 17:52:14 2017-02-25 17:52:14 31002517 2
230 229 2017-02-25 17:52:14 2017-02-25 17:52:14 31002517 53
231 230 2017-02-25 17:52:14 2017-02-25 17:52:14 31002520 2
232 231 2017-02-25 17:52:14 2017-02-25 17:52:14 31002520 16
233 232 2017-02-25 17:52:14 2017-02-25 17:52:14 31002560 30
234 233 2017-02-25 17:52:14 2017-02-25 17:52:14 31002505 72
235 234 2017-02-25 17:52:14 2017-02-25 17:52:14 31000001 16

View File

@@ -1,76 +0,0 @@
{"J001025":["U210","M267"],
"J001057":["B274","E545","D382"],
"J001302":["K346","H900","U574"],
"J001348":["D845","U210"],
"J001398":["U210","K346"],
"J001670":["U210","K346"],
"J001694":["K346","H296"],
"J001769":["K346","X877","H900"],
"J001820":["U210","H296"],
"J001890":["B274","A239","Z647"],
"J002216":["J244","Z060"],
"J002423":["D845","P060","N766"],
"J002625":["U210","C247","X877"],
"J002757":["N110","Z060"],
"J002838":["U210","K346"],
"J002964":["A239","E545","N062"],
"J003382":["U210","D364"],
"J003546":["U210","M267"],
"J003789":["D845","U210"],
"J003793":["K346","E175"],
"J003941":["K346","H296"],
"J004128":["U210","H296"],
"J004150":["D845","N766","C247"],
"J004283":["U210","K346"],
"J004317":["N110","J244"],
"J004470":["U210","C247","X877"],
"J004686":["A239","E545","O477"],
"J004791":["N110","J244"],
"J004921":["K346","H296"],
"J004998":["U210","H296"],
"J005070":["K346","V753"],
"J005223":["U210","E175"],
"J005259":["D845","C247","X877"],
"J005280":["U210","C247","X877"],
"J005299":["K346","C247","H900"],
"J005482":["B274","A239","Z647"],
"J005663":["U210"],
"J005724":["K346","H296"],
"J005834":["N110","Z060"],
"J005872":["U210","P060","C247"],
"J005900":["A239","E545","Y683"],
"J005923":["U210","K346"],
"J005926":["N110","J244"],
"J005969":["K346","H900","U574"],
"J010000":["B274","Z647","D382"],
"J010247":["U210","N766","X877"],
"J010366":["W237"],
"J010556":["D845","P060","N766"],
"J010569":["N110","J244"],
"J010811":["K346","V753"],
"J010951":["K346","V911"],
"J011195":["U210","X877","H900"],
"J011321":["B274","E545","Y683"],
"J011339":["D845","U210"],
"J011355":["C247","X877"],
"J011376":["U210","X877","H900"],
"J011563":["D845","U210"],
"J011778":["D845","P060","C247"],
"J011790":["D792","K346","M267"],
"J011824":["U210","C247","X877"],
"J012157":["J244","Z060"],
"J012402":["N110","Z060"],
"J012475":["K346","V911"],
"J012578":["U210","H296"],
"J012635":["B274","A239"],
"J012686":["K346","V911"],
"J012735":["B274","E545","O477"],
"J012773":["E175"],
"J012794":["U210","K346"],
"J013070":["A239","E545","R474"],
"J013123":["B274","A239","D382"],
"J013146":["K346","H296"],
"J014348":["D845","U210"],
"J015092":["N110","Z060"],
"J015227":["K346","W237"],
"J055520":["D382"]}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ requirejs.config({
admin: './app/admin', // initial start "admin page" view
notification: './app/notification', // "notification" view
jquery: 'lib/jquery-3.1.1.min', // v3.1.1 jQuery
jquery: 'lib/jquery-3.3.1.min', // v3.3.1 jQuery
bootstrap: 'lib/bootstrap.min', // v3.3.0 Bootstrap js code - http://getbootstrap.com/javascript
text: 'lib/requirejs/text', // v2.0.12 A RequireJS/AMD loader plugin for loading text resources.
mustache: 'lib/mustache.min', // v1.0.0 Javascript template engine - http://mustache.github.io
@@ -71,7 +71,7 @@ requirejs.config({
'datatables.plugins.render.ellipsis': 'lib/datatables/plugins/render/ellipsis',
// notification plugin
pnotify: 'lib/pnotify/pnotify', // v3.0.0 PNotify - notification core file - https://sciactive.com/pnotify/
pnotify: 'lib/pnotify/pnotify', // v3.2.0 PNotify - notification core file - https://sciactive.com/pnotify/
'pnotify.buttons': 'lib/pnotify/pnotify.buttons', // PNotify - buttons notification extension
'pnotify.confirm': 'lib/pnotify/pnotify.confirm', // PNotify - confirmation notification extension
'pnotify.nonblock': 'lib/pnotify/pnotify.nonblock', // PNotify - notification non-block extension (hover effect)

View File

@@ -6,7 +6,7 @@
* proofed, signature names (copy & paste from scanning window)
*/
define(['jquery'], function($) {
define(['jquery'], ($) => {
'use strict';
@@ -95,6 +95,7 @@ define(['jquery'], function($) {
5: 'Ordinary Perimeter Reservoir' //*
},
5: { // Wormhole
// all k-space exits are static or K162
1: 'H121 - C1',
2: 'C125 - C2',
3: 'O883 - C3',
@@ -138,12 +139,8 @@ define(['jquery'], function($) {
5: 'Ordinary Perimeter Reservoir' //*
},
5: { // Wormhole
1: 'Z647 - C1',
2: 'D382 - C2',
3: 'O477 - C3',
4: 'Y683 - C4',
5: 'N062 - C5',
6: 'R474 - C6',
// all w-space -> w-space are statics or K162
// all w-space -> k-space are statics or k162
7: 'F135 - Thera'
},
6: { // ORE
@@ -183,6 +180,7 @@ define(['jquery'], function($) {
7: 'Vast Frontier Reservoir' //*
},
5: { // Wormhole
// all k-space exits are static or K162
1: 'V301 - C1',
2: 'I182 - C2',
3: 'N968 - C3',
@@ -228,8 +226,11 @@ define(['jquery'], function($) {
7: 'Bountiful Frontier Reservoir' //*
},
5: { // Wormhole
// no *wandering* w-space -> k-space wormholes
// no *wandering* w-space -> w-space
// all holes are statics or K162
1: 'S047 - HS',
2: 'N290 - LS',
3: 'K329 - 0.0'
},
6: { // ORE
1: 'Ordinary Perimeter Deposit', //*
@@ -272,8 +273,7 @@ define(['jquery'], function($) {
5: { // Wormhole
1: 'D792 - HS',
2: 'C140 - LS',
3: 'Z142 - 0.0',
4: 'F135 - Thera'
3: 'Z142 - 0.0'
},
6: { // ORE
1: 'Average Frontier Deposit', //*
@@ -318,10 +318,12 @@ define(['jquery'], function($) {
9: 'Vital Core Reservoir' //*
},
5: { // Wormhole
1: 'D792 - HS',
2: 'C391 - LS',
3: 'C248 - 0.0',
4: 'F135 - Thera'
1: 'B520 - HS',
2: 'D792 - HS',
3: 'C140 - LS',
4: 'C391 - LS',
5: 'C248 - 0.0',
6: 'Z142 - 0.0'
},
6: { // ORE
1: 'Ordinary Perimeter Deposit', //*
@@ -376,13 +378,13 @@ define(['jquery'], function($) {
1: 'Z971 - C1',
2: 'R943 - C2',
3: 'X702 - C3',
// no C4
4: 'M555 - C5',
5: 'B041 - C6',
6: 'A641 - HS',
7: 'R051 - LS',
8: 'V283 - 0.0',
9: 'T458 - Thera'
4: 'O128 - C4',
5: 'M555 - C5',
6: 'B041 - C6',
7: 'A641 - HS',
8: 'R051 - LS',
9: 'V283 - 0.0',
10: 'T458 - Thera'
}
},
11: { // Low Sec
@@ -390,13 +392,13 @@ define(['jquery'], function($) {
1: 'Z971 - C1',
2: 'R943 - C2',
3: 'X702 - C3',
// no C4
4: 'N432 - C5',
5: 'U319 - C6',
6: 'B449 - HS',
7: 'N944 - LS',
8: 'S199 - 0.0',
9: 'M164 - Thera'
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
9: 'S199 - 0.0',
10: 'M164 - Thera'
}
},
12: { // 0.0
@@ -404,13 +406,13 @@ define(['jquery'], function($) {
1: 'Z971 - C1',
2: 'R943 - C2',
3: 'X702 - C3',
// no C4
4: 'N432 - C5',
5: 'U319 - C6',
6: 'B449 - HS',
7: 'N944 - LS',
8: 'S199 - 0.0',
9: 'L031 - Thera'
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
9: 'S199 - 0.0',
10: 'L031 - Thera'
}
}
}

View File

@@ -34,18 +34,15 @@ define(['jquery'], ($) => {
getMapLogData: '/api/map/getLogData', // ajax URL - get logs data
// system API
getSystemData: '/api/system/getData', // ajax URL - get system data
searchSystem: '/api/system/search', // ajax URL - search system by name
saveSystem: '/api/system/save', // ajax URL - saves system to map
deleteSystem: '/api/system/delete', // ajax URL - delete system from map
getSystemGraphData: '/api/system/graphData', // ajax URL - get all system graph data
getConstellationData: '/api/system/constellationData', // ajax URL - get system constellation data
setDestination: '/api/system/setDestination', // ajax URL - set destination
pokeRally: '/api/system/pokeRally', // ajax URL - send rally point pokes
// connection API
saveConnection: '/api/connection/save', // ajax URL - save new connection to map
deleteConnection: '/api/connection/delete', // ajax URL - delete connection from map
// signature API
getSignatures: '/api/signature/getAll', // ajax URL - get all signature data for system
saveSignatureData: '/api/signature/save', // ajax URL - save signature data for system
deleteSignatureData: '/api/signature/delete', // ajax URL - delete signature data for system
// structure API
@@ -56,7 +53,9 @@ define(['jquery'], ($) => {
// stats API
getStatisticsData: '/api/statistic/getData', // ajax URL - get statistics data (activity log)
// universe API
searchUniverseData: '/api/universe/search', // ajax URL - search universe data
searchUniverseData: '/api/universe/search', // ajax URL - search universe data by category Ids
searchUniverseSystemData: '/api/universe/systems', // ajax URL - search universe system data by name
getConstellationData: '/api/universe/constellationData', // ajax URL - get system constellation data
// GitHub API
gitHubReleases: '/api/github/releases' // ajax URL - get release info from GitHub
},
@@ -113,6 +112,10 @@ define(['jquery'], ($) => {
class: 'fa-anchor',
label: 'anchor',
unicode: '&#xf13d;'
},{
class: 'fa-fire',
label: 'fire',
unicode: '&#xf06d;'
},{
class: 'fa-bookmark',
label: 'bookmark',

View File

@@ -284,10 +284,12 @@ define([
};
let evKeyUp = (e) => {
let key = e.key.toUpperCase();
if(e.key){
let key = e.key.toUpperCase();
if(map.hasOwnProperty(key)){
delete map[key];
if(map.hasOwnProperty(key)){
delete map[key];
}
}
};

View File

@@ -35,6 +35,7 @@ define([
systemLockedClass: 'pf-system-locked', // class for locked systems on a map
systemHeadClass: 'pf-system-head', // class for system head
systemHeadNameClass: 'pf-system-head-name', // class for system name
systemHeadCounterClass: 'pf-system-head-counter', // class for system user counter
systemHeadExpandClass: 'pf-system-head-expand', // class for system head expand arrow
systemHeadInfoClass: 'pf-system-head-info', // class for system info
systemBodyClass: 'pf-system-body', // class for system body
@@ -58,8 +59,6 @@ define([
systemDialogId: 'pf-system-dialog', // id for system dialog
systemDialogSelectClass: 'pf-system-dialog-select', // class for system select Element
popoverTriggerClass: 'pf-popover-trigger', // class for "popover" trigger elements
// system security classes
systemSec: 'pf-system-sec'
};
@@ -90,11 +89,11 @@ define([
};
// jsPlumb config
let globalMapConfig = {
let globalMapConfig = {
source: {
filter: filterSystemHeadEvent,
//isSource:true,
isTarget:true, // add target Endpoint to each system (e.g. for drag&drop)
isTarget: true, // add target Endpoint to each system (e.g. for drag&drop)
allowLoopback: false, // loopBack connections are not allowed
cssClass: config.endpointSourceClass,
uniqueEndpoint: false, // each connection has its own endpoint visible
@@ -107,7 +106,7 @@ define([
},
target: {
filter: filterSystemHeadEvent,
isSource:true,
isSource: true,
//isTarget:true,
//allowLoopBack: false, // loopBack connections are not allowed
cssClass: config.endpointTargetClass,
@@ -127,16 +126,21 @@ define([
* @param map
* @param data
* @param currentUserIsHere boolean - if the current user is in this system
* @param options
*/
$.fn.updateSystemUserData = function(map, data, currentUserIsHere){
$.fn.updateSystemUserData = function(map, data, currentUserIsHere, options){
let system = $(this);
let systemId = system.attr('id');
let compactView = Util.getObjVal(options, 'compactView');
// find countElement -> minimizedUI
let systemCount = system.find('.' + config.systemHeadCounterClass);
// find system body
let systemBody = $( system.find('.' + config.systemBodyClass) );
let systemBody = system.find('.' + config.systemBodyClass);
// find expand arrow
let systemHeadExpand = $( system.find('.' + config.systemHeadExpandClass) );
let systemHeadExpand = system.find('.' + config.systemHeadExpandClass);
let oldCacheKey = system.data('userCache');
let oldUserCount = system.data('userCount');
@@ -156,6 +160,11 @@ define([
data.user
){
let cacheArray = [];
// we need to add "view mode" option to key
// -> if view mode change detected -> key no longer valid
cacheArray.push(compactView ? 'compact' : 'default');
// loop all active pilots and build cache-key
for(let i = 0; i < data.user.length; i++){
userCounter++;
@@ -173,71 +182,73 @@ define([
// remove all content
systemBody.empty();
// loop "again" and build DOM object with user information
for(let j = 0; j < data.user.length; j++){
let userData = data.user[j];
if(compactView){
// compact system layout-> pilot count shown in systemHead
systemCount.text(userCounter);
let statusClass = Util.getStatusInfoForCharacter(userData, 'class');
let userName = userData.name;
system.toggleSystemTooltip('destroy', {});
systemHeadExpand.hide();
system.toggleBody(false, map, {});
let item = $('<div>', {
class: config.systemBodyItemClass
}).append(
$('<span>', {
text: userData.log.ship.typeName,
class: config.systemBodyRightClass
})
).append(
$('<i>', {
class: ['fas', 'fa-circle', config.systemBodyItemStatusClass, statusClass].join(' ')
})
).append(
$('<span>', {
class: config.systemBodyItemNameClass,
text: userName
})
);
map.revalidate(systemId);
}else{
systemCount.empty();
systemBody.append(item);
}
// show active pilots in body + pilots count tooltip
// loop "again" and build DOM object with user information
for(let j = 0; j < data.user.length; j++){
let userData = data.user[j];
let statusClass = Util.getStatusInfoForCharacter(userData, 'class');
let userName = userData.name;
// ====================================================================================================
let item = $('<div>', {
class: config.systemBodyItemClass
}).append(
$('<span>', {
text: userData.log.ship.typeName,
class: config.systemBodyRightClass
})
).append(
$('<i>', {
class: ['fas', 'fa-circle', config.systemBodyItemStatusClass, statusClass].join(' ')
})
).append(
$('<span>', {
class: config.systemBodyItemNameClass,
text: userName
})
);
// user count changed -> change tooltip content
systemBody.append(item);
}
// set tooltip color
let highlight = '';
if(userCounter > oldUserCount){
highlight = 'good';
}else if(userCounter < oldUserCount){
highlight = 'bad';
}
// user count changed -> change tooltip content
let highlight = '';
if(userCounter >= oldUserCount){
highlight = 'good';
}else if(userCounter < oldUserCount){
highlight = 'bad';
}
let tooltipOptions = {
systemId: systemId,
highlight: highlight,
userCount: userCounter
};
let tooltipOptions = {
systemId: systemId,
highlight: highlight,
userCount: userCounter
};
// show system head
systemHeadExpand.velocity('stop', true).velocity({
width: '10px'
},{
duration: 50,
display: 'inline-block',
progress: function(){
//re-validate element size and repaint
map.revalidate( systemId );
},
complete: function(){
// show system body
system.toggleBody(true, map, {complete: function(system){
// show system head
systemHeadExpand.css('display', 'inline-block');
// show system body
system.toggleBody(true, map, {
complete: function(system){
// show active user tooltip
system.toggleSystemTooltip('show', tooltipOptions);
}});
}
});
map.revalidate( systemId );
}
});
}
}
}else{
// no user data found for this system
@@ -249,16 +260,13 @@ define([
oldCacheKey &&
oldCacheKey.length > 0
){
// remove tooltip
// reset all elements
systemCount.empty();
system.toggleSystemTooltip('destroy', {});
systemHeadExpand.hide();
system.toggleBody(false, map, {});
// no user -> clear SystemBody
systemHeadExpand.velocity('stop').velocity('reverse',{
display: 'none',
complete: function(){
system.toggleBody(false, map, {});
}
});
map.revalidate(systemId);
}
}
};
@@ -307,7 +315,7 @@ define([
begin: function(){
},
progress: function(){
// revalidate element size and repaint
// re-validate element size and repaint
map.revalidate( systemDomId );
},
complete: function(){
@@ -391,13 +399,17 @@ define([
$('<span>', {
class: systemHeadClasses.join(' '),
}).attr('data-value', systemName),
// System users count
$('<span>', {
class: [config.systemHeadCounterClass, Util.config.popoverTriggerClass].join(' ')
}),
// System locked status
$('<i>', {
class: ['fas', 'fa-lock', 'fa-fw'].join(' ')
}).attr('title', 'locked'),
// System effect color
$('<i>', {
class: ['fas', 'fa-square', 'fa-fw', effectBasicClass, effectClass, config.popoverTriggerClass].join(' ')
class: ['fas', 'fa-square', 'fa-fw', effectBasicClass, effectClass, Util.config.popoverTriggerClass].join(' ')
}),
// expand option
$('<i>', {
@@ -482,6 +494,8 @@ define([
system.data('region', data.region.name);
system.data('constellationId', parseInt(data.constellation.id));
system.data('constellation', data.constellation.name);
system.data('planets', data.planets);
system.data('shattered', data.shattered);
system.data('statics', data.statics);
system.data('updated', parseInt(data.updated.updated));
system.data('changed', false);
@@ -519,11 +533,9 @@ define([
e.stopPropagation();
// trigger menu "open
// get invisible menu entries
let hideOptions = getHiddenContextMenuOptions(component);
let activeOptions = getActiveContextMenuOptions(component);
$(e.target).trigger('pf:openContextMenu', [e, component, hideOptions, activeOptions]);
Promise.all([getHiddenContextMenuOptions(component), getActiveContextMenuOptions(component)]).then(payload => {
$(e.target).trigger('pf:openContextMenu', [e, component, payload[0], payload[1]]);
});
return false;
});
@@ -1129,7 +1141,24 @@ define([
});
};
return new Promise(updateMapExecutor);
return new Promise(updateMapExecutor).then(payload => {
let filterMapByScopesExecutor = (resolve, reject) => {
// apply current active scope filter ==================================================================
let promiseStore = MapUtil.getLocaleData('map', payload.data.mapConfig.config.id);
promiseStore.then(dataStore => {
let scopes = [];
if(dataStore && dataStore.filterScopes){
scopes = dataStore.filterScopes;
}
MapUtil.filterMapByScopes(payload.data.mapConfig.map, scopes);
resolve(payload);
});
};
return new Promise(filterMapByScopesExecutor);
});
};
/**
@@ -1194,129 +1223,6 @@ define([
return connection;
};
/**
* make all systems appear visual on the map with its connections
* @param show
* @param callback
*/
$.fn.visualizeMap = function(show, callback){
let mapElement = $(this);
// start map update counter -> prevent map updates during animations
mapElement.getMapOverlay('timer').startMapUpdateCounter();
let systemElements = mapElement.find('.' + config.systemClass);
let endpointElements = mapElement.find('.jsplumb-endpoint');
let connectorElements = mapElement.find('.jsplumb-connector');
let overlayElements = mapElement.find('.jsplumb-overlay, .tooltip');
let hideElements = (elements) => {
if(elements.length > 0){
// disable transition for next opacity change
elements.addClass('pf-notransition');
// hide elements
elements.css('opacity', 0);
// Trigger a reflow, flushing the CSS changes
// -> http://stackoverflow.com/questions/11131875/what-is-the-cleanest-way-to-disable-css-transition-effects-temporarily
elements[0].offsetHeight; // jshint ignore:line
elements.removeClass('pf-notransition');
}
return elements;
};
// if map empty (no systems), execute callback and return
// no visual effects on larger maps
if(
systemElements.length === 0 ||
systemElements.length > 20 ||
endpointElements.length === 0
){
callback();
return;
}
// show nice animation
if(show === 'show'){
systemElements = hideElements(systemElements);
endpointElements = hideElements(endpointElements);
connectorElements = hideElements(connectorElements);
overlayElements = hideElements(overlayElements);
systemElements.velocity({
translateY: [ 0, -20],
opacity: [ 1, 0 ]
},{
duration: 300,
easing: 'easeOut',
complete: function(){
// show connections
endpointElements.velocity('transition.fadeIn', {
duration: 0
});
connectorElements.velocity('transition.fadeIn', {
stagger: 30,
duration: 120,
complete: function(){
callback();
}
});
// show overlay elements (if some exist)
if(overlayElements.length > 0){
overlayElements.delay(300).velocity('transition.fadeIn', {
stagger: 50,
duration: 180,
display: 'auto'
});
}
}
});
}else if(show === 'hide'){
$('.mCSB_container').velocity('callout.shake', {
stagger: 0,
drag: false,
duration: 180,
display: 'auto'
});
overlayElements.velocity('transition.fadeOut', {
stagger: 50,
drag: true,
duration: 180,
display: 'auto'
});
endpointElements.velocity('transition.fadeOut', {
duration: 0,
display: 'block',
complete: function(){
// show connections
connectorElements.velocity('transition.fadeOut', {
stagger: 0,
drag: true,
duration: 20,
display: 'block'
});
systemElements.delay(100).velocity({
translateY: [ -20, 0 ],
opacity: [ 0, 1 ]
},{
duration: 180,
display: 'block',
easing: 'easeOut',
complete: function(){
callback();
}
});
}
});
}
};
/**
* mark a system as source
* @param map
@@ -1619,7 +1525,7 @@ define([
// init system select live search - some delay until modal transition has finished
let selectElement = modalContent.find('.' + config.systemDialogSelectClass);
selectElement.delay(240).initSystemSelect({
key: 'systemId',
key: 'id',
disabledOptions: mapSystemIds
});
});
@@ -1666,6 +1572,9 @@ define([
});
headElement.on('shown', function(e, editable) {
// hide tooltip when xEditable is visible
system.toggleSystemTooltip('hide', {});
let inputElement = editable.input.$input.select();
// "fake" timeout until dom rendered
@@ -1674,6 +1583,15 @@ define([
input.select();
}, 0, inputElement);
});
headElement.on('hidden', function(e, editable) {
// show tooltip "again" on xEditable hidden
system.toggleSystemTooltip('show', {show: true});
// if system with changed (e.g. long alias) -> revalidate system
let map = MapUtil.getMapInstance(system.attr('data-mapid'));
map.revalidate(system.attr('id'));
});
};
/**
@@ -1963,104 +1881,106 @@ define([
/**
* get hidden menu entry options for a context menu
* @param component
* @returns {Array}
* @returns {Promise<any>}
*/
let getHiddenContextMenuOptions = function(component){
let hiddenOptions = [];
if(component instanceof jsPlumb.Connection){
// disable connection menu entries
let getHiddenContextMenuOptionsExecutor = (resolve, reject) => {
let hiddenOptions = [];
let scope = component.scope;
if(component instanceof jsPlumb.Connection){
// disable connection menu entries
let scope = component.scope;
if(scope === 'abyssal'){
hiddenOptions.push('frigate');
hiddenOptions.push('preserve_mass');
hiddenOptions.push('change_status');
if(scope === 'abyssal'){
hiddenOptions.push('frigate');
hiddenOptions.push('preserve_mass');
hiddenOptions.push('change_status');
hiddenOptions.push('change_scope');
hiddenOptions.push('separator');
}else if(scope === 'stargate'){
hiddenOptions.push('frigate');
hiddenOptions.push('preserve_mass');
hiddenOptions.push('change_status');
hiddenOptions.push('change_scope');
hiddenOptions.push('separator');
}else if(scope === 'stargate'){
hiddenOptions.push('frigate');
hiddenOptions.push('preserve_mass');
hiddenOptions.push('change_status');
hiddenOptions.push('scope_stargate');
}else if(scope === 'jumpbridge'){
hiddenOptions.push('frigate');
hiddenOptions.push('preserve_mass');
hiddenOptions.push('change_status');
hiddenOptions.push('scope_jumpbridge');
}else if(scope === 'wh'){
hiddenOptions.push('scope_wh');
hiddenOptions.push('scope_stargate');
}else if(scope === 'jumpbridge'){
hiddenOptions.push('frigate');
hiddenOptions.push('preserve_mass');
hiddenOptions.push('change_status');
hiddenOptions.push('scope_jumpbridge');
}else if(scope === 'wh'){
hiddenOptions.push('scope_wh');
}
}else if( component.hasClass(config.systemClass) ){
// disable system menu entries
if(component.data('locked') === true){
hiddenOptions.push('delete_system');
}
}
}else if( component.hasClass(config.systemClass) ){
// disable system menu entries
if(component.data('locked') === true){
hiddenOptions.push('delete_system');
}
}
resolve(hiddenOptions);
};
return hiddenOptions;
return new Promise(getHiddenContextMenuOptionsExecutor);
};
/**
* get active menu entry options for a context menu
* @param component
* @returns {Array}
* @returns {Promise<any>}
*/
let getActiveContextMenuOptions = function(component){
let activeOptions = [];
let getActiveContextMenuOptions = component => {
if(component instanceof jsPlumb.Connection){
let scope = component.scope;
let getActiveContextMenuOptionsExecutor = (resolve, reject) => {
let activeOptions = [];
if(component.hasType('wh_eol') === true){
activeOptions.push('wh_eol');
}
if(component instanceof jsPlumb.Connection){
let scope = component.scope;
if(component.hasType('frigate') === true){
activeOptions.push('frigate');
}
if(component.hasType('preserve_mass') === true){
activeOptions.push('preserve_mass');
}
if(component.hasType('wh_reduced') === true){
activeOptions.push('status_reduced');
}else if(component.hasType('wh_critical') === true){
activeOptions.push('status_critical');
}else{
// not reduced is default
activeOptions.push('status_fresh');
}
if(component.hasType('wh_eol') === true){
activeOptions.push('wh_eol');
}
}else if( component.hasClass(config.mapClass) ){
if(component.hasType('frigate') === true){
activeOptions.push('frigate');
}
if(component.hasType('preserve_mass') === true){
activeOptions.push('preserve_mass');
}
if(component.hasType('wh_reduced') === true){
activeOptions.push('status_reduced');
}else if(component.hasType('wh_critical') === true){
activeOptions.push('status_critical');
}else{
// not reduced is default
activeOptions.push('status_fresh');
}
// active map menu entries
if(component.data('filter_scope') === 'wh'){
activeOptions.push('filter_wh');
}
if(component.data('filter_scope') === 'stargate'){
activeOptions.push('filter_stargate');
}
if(component.data('filter_scope') === 'jumpbridge'){
activeOptions.push('filter_jumpbridge');
}
if(component.data('filter_scope') === 'abyssal'){
activeOptions.push('filter_abyssal');
}
}else if( component.hasClass(config.systemClass) ){
// active system menu entries
if(component.data('locked') === true){
activeOptions.push('lock_system');
}
if(component.data('rallyUpdated') > 0){
activeOptions.push('set_rally');
}
}
resolve(activeOptions);
}else if( component.hasClass(config.mapClass) ){
// active map menu entries
let promiseStore = MapUtil.getLocaleData('map', component.data('id'));
promiseStore.then(dataStore => {
if(dataStore && dataStore.filterScopes){
activeOptions = dataStore.filterScopes.map(scope => 'filter_' + scope);
}
resolve(activeOptions);
});
}else if( component.hasClass(config.systemClass) ){
// active system menu entries
if(component.data('locked') === true){
activeOptions.push('lock_system');
}
if(component.data('rallyUpdated') > 0){
activeOptions.push('set_rally');
}
return activeOptions;
resolve(activeOptions);
}
};
return new Promise(getActiveContextMenuOptionsExecutor);
};
/**
@@ -2172,17 +2092,14 @@ define([
}
// init system tooltips =======================================================================================
// TODO check this code:
/*
let systemTooltipOptions = {
toggle: 'tooltip',
placement: 'right',
container: 'body',
viewport: system.id
};
system.find('.fas').tooltip(systemTooltipOptions);
*/
// context menu ===============================================================================================
// trigger context menu
@@ -2192,12 +2109,11 @@ define([
let systemElement = $(this);
// hide all map contextmenu options
let hideOptions = getHiddenContextMenuOptions(systemElement);
// trigger menu "open
Promise.all([getHiddenContextMenuOptions(systemElement), getActiveContextMenuOptions(systemElement)]).then(payload => {
$(e.target).trigger('pf:openContextMenu', [e, this, payload[0], payload[1]]);
});
let activeOptions = getActiveContextMenuOptions(systemElement);
$(e.target).trigger('pf:openContextMenu', [e, this, hideOptions, activeOptions]);
return false;
});
@@ -2309,7 +2225,7 @@ define([
if(! system.hasClass('no-click')){
if(e.ctrlKey === true){
// select system
MapUtil.toggleSelectSystem(map, [system]);
MapUtil.toggleSystemsSelect(map, [system]);
}else{
MapUtil.showSystemInfo(map, system);
}
@@ -2367,14 +2283,17 @@ define([
let mapElement = $(this);
let map = getMapInstance(mapElement.data('id'));
let allSystems = mapElement.find('.' + config.systemClass + ':not(.' + config.systemSelectedClass + ')');
let allSystems = mapElement.find('.' + config.systemClass +
':not(.' + config.systemSelectedClass + ')' +
':not(.' + MapUtil.config.systemHiddenClass + ')'
);
// filter non-locked systems
allSystems = allSystems.filter(function(i, el){
return ( $(el).data('locked') !== true );
});
MapUtil.toggleSelectSystem(map, allSystems);
MapUtil.toggleSystemsSelect(map, allSystems);
Util.showNotify({title: allSystems.length + ' systems selected', type: 'success'});
@@ -2521,7 +2440,8 @@ define([
let connections = MapUtil.checkForConnection(newJsPlumbInstance, sourceId, targetId);
if(connections.length > 1){
bootbox.confirm('Connection already exists. Do you really want to add an additional one?', function(result) {
if(!result){
if(!result && connection._jsPlumb){
// connection._jsPlumb might be "undefined" in case connection was removed in the meantime
connection._jsPlumb.instance.detach(connection);
}
});
@@ -2570,7 +2490,7 @@ define([
*/
let setMapObserver = function(map){
// get map container
let mapContainer = $( map.getContainer() );
let mapContainer = $(map.getContainer());
mapContainer.bind('contextmenu', function(e){
e.preventDefault();
@@ -2580,11 +2500,10 @@ define([
if($(e.target).hasClass( config.mapClass )){
let mapElement = $(this);
let hideOptions = getHiddenContextMenuOptions(mapElement);
let activeOptions = getActiveContextMenuOptions(mapElement);
$(e.target).trigger('pf:openContextMenu', [e, mapElement, hideOptions, activeOptions]);
// trigger menu "open
Promise.all([getHiddenContextMenuOptions(mapElement), getActiveContextMenuOptions(mapElement)]).then(payload => {
$(e.target).trigger('pf:openContextMenu', [e, mapElement, payload[0], payload[1]]);
});
}
return false;
@@ -2640,52 +2559,32 @@ define([
case 'filter_abyssal':
// filter (show/hide)
let filterScope = action.split('_')[1];
let filterScopeLabel = MapUtil.getScopeInfoForConnection( filterScope, 'label');
// scope label
let filterScopeLabel = MapUtil.getScopeInfoForMap(filterScope, 'label');
let showScope = true;
if(
currentMapElement.data('filter_scope') &&
currentMapElement.data('filter_scope') === filterScope
){
// remove scope filter
currentMapElement.data('filter_scope', false);
showScope = false;
// hide map overlay filter info
currentMapElement.getMapOverlay('info').updateOverlayIcon('filter', 'hide');
}else{
// set scope filter
currentMapElement.data('filter_scope', filterScope);
// show map overlay filter info
currentMapElement.getMapOverlay('info').updateOverlayIcon('filter', 'show');
}
let filteredConnections = currentMap.getAllConnections(filterScope);
for(let i = 0; i < filteredConnections.length; i++){
let tempConnection = filteredConnections[i];
let tempEndpoints = tempConnection.endpoints;
let setVisible = true;
if(
showScope &&
tempConnection.scope !== filterScope
){
setVisible = false;
let promiseStore = MapUtil.getLocaleData('map', currentMapId);
promiseStore.then(data => {
let filterScopes = [];
if(data && data.filterScopes){
filterScopes = data.filterScopes;
}
// add or remove this scope from filter
let index = filterScopes.indexOf(filterScope);
if(index >= 0){
filterScopes.splice(index, 1);
}else{
filterScopes.push(filterScope);
// "all filters active" == "no filter"
if(filterScopes.length === Object.keys(Init.connectionScopes).length){
filterScopes = [];
}
}
// save filterScopes in IndexDB
MapUtil.storeLocalData('map', currentMapId, 'filterScopes', filterScopes);
MapUtil.filterMapByScopes(currentMap, filterScopes);
for(let j = 0; j < tempEndpoints.length; j++){
tempEndpoints[j].setVisible( setVisible );
}
}
Util.showNotify({title: 'Scope filter changed', text: filterScopeLabel, type: 'success'});
Util.showNotify({title: 'Scope filter changed', text: filterScopeLabel, type: 'success'});
});
break;
case 'delete_systems':
// delete all selected systems with its connections
@@ -2761,8 +2660,8 @@ define([
width: newWidth,
'min-width': minWidth + 'px'
},{
easing: 'easeInOutQuart',
duration: 120,
easing: 'easeOut',
duration: 60,
progress: function(){
// repaint connections of current system
map.revalidate(systemId);
@@ -2805,6 +2704,27 @@ define([
selector: '.' + config.systemClass + ' .' + config.systemHeadExpandClass
});
// system "active users" popover ------------------------------------------------------------------------------
mapContainer.hoverIntent({
over: function(e){
let counterElement = $(this);
let systemElement = counterElement.closest('.' + config.systemClass);
let mapId = systemElement.data('mapid');
let systemId = systemElement.data('systemId');
let userData = Util.getCurrentMapUserData(mapId);
let systemUserData = Util.getCharacterDataBySystemId(userData.data.systems, systemId);
counterElement.addSystemPilotTooltip(systemUserData, {
trigger: 'manual',
placement: 'right'
}).setPopoverSmall().popover('show');
},
out: function(e){
$(this).destroyPopover();
},
selector: '.' + config.systemHeadCounterClass
});
// system "effect" popover ------------------------------------------------------------------------------------
// -> event delegation to system elements, popup only if needed (hover)
mapContainer.hoverIntent({
@@ -3054,18 +2974,20 @@ define([
// container must exist! otherwise systems can not be updated
if(mapElement !== undefined){
mapElement = $(mapElement);
// get current character log data
let characterLogExists = false;
let currentCharacterLog = Util.getCurrentCharacterLog();
// check if map is frozen
if(mapElement.data('frozen') === true){
return returnStatus;
}
// compact/small system layout or not
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
// get current character log data
let characterLogExists = false;
let currentCharacterLog = Util.getCurrentCharacterLog();
// data for header update
let headerUpdateData = {
mapId: userData.config.id,
@@ -3133,7 +3055,7 @@ define([
}
}
system.updateSystemUserData(map, tempUserData, currentUserIsHere);
system.updateSystemUserData(map, tempUserData, currentUserIsHere, {compactView: compactView});
}
// users who are not in any map system --------------------------------------------------------------------
@@ -3288,6 +3210,8 @@ define([
systemData.rallyUpdated = system.data('rallyUpdated') || 0;
systemData.rallyPoke = system.data('rallyPoke') ? 1 : 0;
systemData.currentUser = system.data('currentUser'); // if user is currently in this system
systemData.planets = system.data('planets');
systemData.shattered = system.data('shattered') ? 1 : 0;
systemData.statics = system.data('statics');
systemData.updated = {
updated: parseInt( system.data('updated') )
@@ -3316,11 +3240,6 @@ define([
*/
let initMapOptions = (mapConfig, options) => {
/**
* init map options promise
* @param resolve
* @param reject
*/
let initMapOptionsExecutor = (resolve, reject) => {
let payload = {
action: 'initMapOptions',
@@ -3330,57 +3249,18 @@ define([
};
if(options.showAnimation){
/**
* callback after visualizeMap is done
* @param mapName
* @param mapContainer
*/
let switchTabCallback = (mapContainer, mapConfig) => {
Util.showNotify({title: 'Map initialized', text: mapConfig.name + ' - loaded', type: 'success'});
let mapWrapper = mapContainer.parents('.' + config.mapWrapperClass);
// auto scroll map to previous position -----------------------------------------------------------
let promiseStore = MapUtil.getLocaleData('map', mapContainer.data('id') );
promiseStore.then(data => {
// This code runs once the value has been loaded from offline storage
if(data && data.scrollOffset){
mapWrapper.scrollToPosition([data.scrollOffset.y, data.scrollOffset.x]);
}
});
// update main menu options based on the active map -----------------------------------------------
$(document).trigger('pf:updateMenuOptions', {
mapConfig: mapConfig
});
// init magnetizer --------------------------------------------------------------------------------
mapContainer.triggerMenuEvent('MapOption', {
option: 'mapMagnetizer',
toggle: false
});
// init grid snap ---------------------------------------------------------------------------------
mapContainer.triggerMenuEvent('MapOption', {
option: 'mapSnapToGrid',
toggle: false
});
// init endpoint overlay --------------------------------------------------------------------------
mapContainer.triggerMenuEvent('MapOption', {
option: 'mapEndpoint',
toggle: false
});
};
// show nice visualization effect ---------------------------------------------------------------------
let mapContainer = $(mapConfig.map.getContainer());
mapContainer.visualizeMap('show', function(){
switchTabCallback(mapContainer, mapConfig.config);
});
let mapElement = $(mapConfig.map.getContainer());
MapUtil.setMapDefaultOptions(mapElement, mapConfig.config)
.then(payload => MapUtil.visualizeMap(mapElement, 'show'))
.then(payload => MapUtil.scrollToDefaultPosition(mapElement))
.then(payload => {
Util.showNotify({title: 'Map initialized', text: mapConfig.config.name + ' - loaded', type: 'success'});
})
.then(() => resolve(payload));
}else{
// nothing to do here...
resolve(payload);
}
resolve(payload);
};
return new Promise(initMapOptionsExecutor);

View File

@@ -260,7 +260,7 @@ define([
let mapElement = $(this);
let map = getMapObjectFromMapElement(mapElement);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh', undefined, true);
// get connection signature information ---------------------------------------
getConnectionSignatureData(mapElement, connections, addConnectionsOverlay);
@@ -293,13 +293,21 @@ define([
title: 'active filter',
trigger: 'active',
class: 'pf-map-overlay-filter',
iconClass: ['fas', 'fa-fw', 'fa-filter']
iconClass: ['fas', 'fa-fw', 'fa-filter'],
onClick: function(e){
// clear all filter
let mapElement = Util.getMapElementFromOverlay(this);
let map = getMapObjectFromOverlayIcon(this);
MapUtil.storeLocalData('map', mapElement.data('id'), 'filterScopes', []);
MapUtil.filterMapByScopes(map, []);
}
},
mapSnapToGrid: {
title: 'active grid',
trigger: 'active',
class: 'pf-map-overlay-grid',
iconClass: ['glyphicon', 'glyphicon-th']
iconClass: ['fas', 'fa-fw', 'fa-th']
},
mapMagnetizer: {
title: 'active magnetizer',
@@ -352,6 +360,12 @@ define([
}
}
},
mapCompact: {
title: 'compact layout',
trigger: 'active',
class: 'pf-map-overlay-compact',
iconClass: ['fas', 'fa-fw', 'fa-compress']
},
connection: {
title: 'WH data',
trigger: 'hover',
@@ -639,8 +653,12 @@ define([
iconElement.data('visible', true);
}
}else if(viewType === 'hide'){
iconElement.removeClass('active').velocity('reverse');
iconElement.data('visible', false);
// check if icon is not already visible
// -> prevents unnecessary "hide" animation
if(iconElement.data('visible')){
iconElement.removeClass('active').velocity('reverse');
iconElement.data('visible', false);
}
// check if there is any visible icon remaining
let visibleIcons = mapOverlayInfo.find('i:visible');
@@ -704,6 +722,11 @@ define([
icon.hoverIntent(options[prop].hoverIntent);
}
// add "click" handler for some icons
if(options[prop].hasOwnProperty('onClick')){
icon.on('click', options[prop].onClick);
}
mapOverlayInfo.append(icon);
}
}

View File

@@ -21,9 +21,10 @@ define([
mapClass: 'pf-map', // class for all maps
popoverTriggerClass: 'pf-popover-trigger', // class for "popover" trigger elements
systemHeadInfoClass: 'pf-system-head-info', // class for system info
systemHeadInfoLeftClass: 'pf-system-head-info-left', // class for left system info
systemHeadInfoRightClass: 'pf-system-head-info-right', // class for right system info
systemActiveClass: 'pf-system-active', // class for an active system on a map
systemTooltipInnerIdPrefix: 'pf-system-tooltip-inner-', // id prefix for system tooltip content
systemTooltipInnerClass: 'pf-system-tooltip-inner', // class for system tooltip content
@@ -406,7 +407,7 @@ define([
* @param systems
*/
let removeSystems = (map, systems) => {
let removeSystemCallbak = function(deleteSystem){
let removeSystemCallbak = deleteSystem => {
map.remove(deleteSystem);
};
@@ -415,6 +416,7 @@ define([
// check if system is "active"
if( system.hasClass(config.systemActiveClass) ){
delete Init.currentSystemData;
// get parent Tab Content and fire clear modules event
let tabContentElement = MapUtil.getTabContentElementByMapElement( system );
$(tabContentElement).trigger('pf:removeSystemModules');
@@ -441,7 +443,7 @@ define([
* @param sourceSystem
* @returns {{x: *, y: *}}
*/
let calculateNewSystemPosition = function(sourceSystem){
let calculateNewSystemPosition = sourceSystem => {
let mapContainer = sourceSystem.parent();
let grid = [MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension];
@@ -490,24 +492,39 @@ define([
*/
let getHeadInfoElement = (data) => {
let headInfo = null;
let headInfoLeft = [];
let headInfoRight = [];
if(data.shattered){
headInfoLeft.push('<i class="fas fa-fw fa-skull ' + Util.getSecurityClassForSystem('SH') + '" title="shattered"></i>');
}
// check systemData if headInfo element is needed
if(data.statics && data.statics.length){
// format wh statics
let statics = [];
for(let staticData of data.statics){
statics.push(
for(let wormholeName of data.statics){
let staticData = Object.assign({}, Init.wormholes[wormholeName]);
headInfoRight.push(
'<span class="' +
Util.getSecurityClassForSystem(staticData.security) + ' ' +
config.popoverTriggerClass + '" data-name="' + staticData.name +
Util.config.popoverTriggerClass + '" data-name="' + staticData.name +
'">' + staticData.security + '</span>'
);
}
}
headInfo = $('<div>', {
if(headInfoLeft.length || headInfoRight.length){
headInfo = $('<div>', {
class: config.systemHeadInfoClass
}).append(
statics.join('&nbsp;&nbsp;')
$('<div>', {
class: config.systemHeadInfoLeftClass,
html: headInfoLeft.join('&nbsp;&nbsp;')
}),
$('<div>', {
class: config.systemHeadInfoRightClass,
html: headInfoRight.join('&nbsp;&nbsp;')
})
);
}

View File

@@ -19,13 +19,17 @@ define([
mapLocalStoragePrefix: 'map_', // prefix for map data local storage key
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
mapClass: 'pf-map', // class for all maps
mapGridClass: 'pf-grid-small', // class for map grid snapping
mapCompactClass: 'pf-compact', // class for map compact system UI
systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
systemActiveClass: 'pf-system-active', // class for an active system on a map
systemSelectedClass: 'pf-system-selected', // class for selected systems on on map
systemHiddenClass: 'pf-system-hidden', // class for hidden (filtered) systems
// dataTable
tableCellEllipsisClass: 'pf-table-cell-ellipsis',
@@ -52,6 +56,11 @@ define([
description: 'Endpoint overlay',
onEnable: 'showEndpointOverlays', // jQuery extension function
onDisable: 'hideEndpointOverlays' // jQuery extension function
},
mapCompact : {
buttonId: Util.config.menuButtonCompactId,
description: 'Compact system layout',
class: 'mapCompactClass'
}
};
@@ -453,6 +462,90 @@ define([
return activeConnections.length > 0;
};
/**
* filter map by scopes
* -> this effects visible systems and connections on UI
* @param map
* @param scopes
*/
let filterMapByScopes = (map, scopes) => {
if(map){
// TODO ^^sometimes map is undefined -> bug
let mapElement = $(map.getContainer());
let allSystems = mapElement.getSystems();
let allConnections = map.getAllConnections();
if(scopes && scopes.length){
// filter connections -------------------------------------------------------------------------------------
let visibleSystems = [];
let visibleConnections = searchConnectionsByScopeAndType(map, scopes);
for(let connection of allConnections){
if(visibleConnections.indexOf(connection) >= 0){
setConnectionVisible(connection, true);
// source/target system should always be visible -> even if filter scope not matches system type
if(visibleSystems.indexOf(connection.endpoints[0].element) < 0){
visibleSystems.push(connection.endpoints[0].element);
}
if(visibleSystems.indexOf(connection.endpoints[1].element) < 0){
visibleSystems.push(connection.endpoints[1].element);
}
}else{
setConnectionVisible(connection, false);
}
}
// filter systems -----------------------------------------------------------------------------------------
let visibleTypeIds = [];
if(scopes.indexOf('wh') >= 0){
visibleTypeIds.push(1);
}
if(scopes.indexOf('abyssal') >= 0){
visibleTypeIds.push(4);
}
for(let system of allSystems){
if(
visibleTypeIds.indexOf($(system).data('typeId')) >= 0 ||
visibleSystems.indexOf(system) >= 0
){
setSystemVisible(system, map, true);
}else{
setSystemVisible(system, map, false);
}
}
mapElement.getMapOverlay('info').updateOverlayIcon('filter', 'show');
}else{
// clear filter
for(let system of allSystems){
setSystemVisible(system, map, true);
}
for(let connection of allConnections){
setConnectionVisible(connection, true);
}
mapElement.getMapOverlay('info').updateOverlayIcon('filter', 'hide');
}
}
};
/**
* mark system as "selected" e.g. for dragging
* @param map
* @param system
* @param select
*/
let setSystemSelect = (map, system, select) => {
if(select){
system.addClass(config.systemSelectedClass);
map.addToDragSelection(system);
}else{
system.removeClass(config.systemSelectedClass);
map.removeFromDragSelection(system);
}
};
/**
* mark a system as "active"
* @param map
@@ -465,10 +558,32 @@ define([
// set current system active
system.addClass(config.systemActiveClass);
// collect all required data from map module to update the info element
// store them global and assessable for each module
Util.setCurrentSystemData({
systemData: system.getSystemData(),
mapId: parseInt( system.attr('data-mapid') )
});
};
/**
* set system visibility e.g. or filtered systems
* @param system
* @param visible
*/
let setSystemVisible = (system, map, visible) => {
system = $(system);
if(!visible){
// invisible systems should no longer be selected
setSystemSelect(map, system, false);
}
system.toggleClass(config.systemHiddenClass, !visible);
};
/**
* mark a connection as "active"
* @param map
* @param connections
*/
let setConnectionsActive = (map, connections) => {
@@ -482,22 +597,30 @@ define([
}
};
/**
* set connection visibility e.g. for filtered systems
* @param connection
* @param visible
*/
let setConnectionVisible = (connection, visible) => {
for(let endpoint of connection.endpoints){
endpoint.setVisible(visible);
}
};
/**
* toggle "selected" status of system
* @param map
* @param systems
*/
let toggleSelectSystem = (map, systems) => {
let toggleSystemsSelect = (map, systems) => {
for(let system of systems){
system = $(system);
if( system.data('locked') !== true ){
if( system.hasClass( config.systemSelectedClass ) ){
system.removeClass( config.systemSelectedClass );
map.removeFromDragSelection(system);
if(system.data('locked') !== true){
if(system.hasClass(config.systemSelectedClass)){
setSystemSelect(map, system, false);
}else{
system.addClass( config.systemSelectedClass );
map.addToDragSelection(system);
setSystemSelect(map, system, true);
}
}
}
@@ -532,16 +655,7 @@ define([
setSystemActive(map, system);
// get parent Tab Content and fire update event
let tabContentElement = getTabContentElementByMapElement( system );
// collect all required data from map module to update the info element
// store them global and assessable for each module
Util.setCurrentSystemData({
systemData: system.getSystemData(),
mapId: parseInt( system.attr('data-mapid') )
});
$(tabContentElement).trigger('pf:drawSystemModules');
getTabContentElementByMapElement(system).trigger('pf:drawSystemModules');
};
/**
@@ -604,17 +718,23 @@ define([
/**
* search connections by scope and/or type
* -> scope and target can be an array
* @param {Object} map - jsPlumb
* @param {string|string[]} scope
* @param {string|string[]} type
* @param map
* @param scope
* @param type
* @param noHidden
* @returns {Array}
*/
let searchConnectionsByScopeAndType = (map, scope, type) => {
let searchConnectionsByScopeAndType = (map, scope, type = undefined, noHidden = false) => {
let connections = [];
let scopeArray = (scope === undefined) ? ['*'] : ((Array.isArray(scope)) ? scope : [scope]);
let typeArray = (type === undefined) ? [] : ((Array.isArray(type)) ? type : [type]);
map.select({scope: scopeArray}).each(function(connection){
if(noHidden && !connection.isVisible()){
// exclude invisible connection
return;
}
if(typeArray.length > 0){
// filter by connection type as well...
for(let i = 0; i < typeArray.length; i++){
@@ -843,6 +963,185 @@ define([
}
};
/**
* show map animations when a new map gets visual
* @param mapElement
* @param show
* @returns {Promise<any>}
*/
let visualizeMap = (mapElement, show) => {
let visualizeMapExecutor = (resolve, reject) => {
// start map update counter -> prevent map updates during animations
mapElement.getMapOverlay('timer').startMapUpdateCounter();
let systemElements = mapElement.find('.' + config.systemClass);
let endpointElements = mapElement.find('.jsplumb-endpoint:visible');
let connectorElements = mapElement.find('.jsplumb-connector:visible');
let overlayElements = mapElement.find('.jsplumb-overlay:visible, .tooltip');
let hideElements = (elements) => {
if(elements.length > 0){
// disable transition for next opacity change
elements.addClass('pf-notransition');
// hide elements
elements.css('opacity', 0);
// Trigger a reflow, flushing the CSS changes
// -> http://stackoverflow.com/questions/11131875/what-is-the-cleanest-way-to-disable-css-transition-effects-temporarily
elements[0].offsetHeight; // jshint ignore:line
elements.removeClass('pf-notransition');
}
return elements;
};
let mapElements = systemElements.add(endpointElements).add(connectorElements);
// show nice animation
if(show === 'show'){
hideElements(systemElements);
hideElements(endpointElements);
hideElements(connectorElements);
hideElements(overlayElements);
overlayElements.velocity('transition.fadeIn', {
duration: 60,
display: 'auto'
});
if(mapElements.length){
mapElements.velocity({
translateY: [ 0, -20],
opacity: [ 1, 0 ]
}, {
duration: 150,
easing: 'easeOut',
complete: function(){
resolve({
action: 'visualizeMap',
data: false
});
}
});
}else{
// "complete" callback is not fired if no elements were animated
resolve({
action: 'visualizeMap',
data: false
});
}
}else if(show === 'hide'){
overlayElements.velocity('transition.fadeOut', {
duration: 60,
display: 'auto'
});
if(mapElements.length){
mapElements.velocity({
translateY: [ -20, 0 ],
opacity: [ 0, 1 ]
}, {
duration: 150,
easing: 'easeOut',
complete: function(){
resolve({
action: 'visualizeMap',
data: false
});
}
});
}else{
// "complete" callback is not fired if no elements were animated
resolve({
action: 'visualizeMap',
data: false
});
}
}
};
return new Promise(visualizeMapExecutor);
};
/**
* set default map Options (
* -> HINT: This function triggers Events! Promise is resolved before trigger completed
* @param mapElement
* @param mapConfig
* @returns {Promise<any>}
*/
let setMapDefaultOptions = (mapElement, mapConfig) => {
let setMapDefaultOptionsExecutor = (resolve, reject) => {
// update main menu options based on the active map -----------------------------------------------
$(document).trigger('pf:updateMenuOptions', {
mapConfig: mapConfig
});
// init compact system layout ---------------------------------------------------------------------
mapElement.triggerMenuEvent('MapOption', {
option: 'mapCompact',
toggle: false
});
// init magnetizer --------------------------------------------------------------------------------
mapElement.triggerMenuEvent('MapOption', {
option: 'mapMagnetizer',
toggle: false
});
// init grid snap ---------------------------------------------------------------------------------
mapElement.triggerMenuEvent('MapOption', {
option: 'mapSnapToGrid',
toggle: false
});
// init endpoint overlay --------------------------------------------------------------------------
mapElement.triggerMenuEvent('MapOption', {
option: 'mapEndpoint',
toggle: false
});
resolve({
action: 'setMapDefaultOptions',
data: false
});
};
return new Promise(setMapDefaultOptionsExecutor);
};
/**
* scroll map to default (stored) x/y coordinates
* @param mapElement
* @returns {Promise<any>}
*/
let scrollToDefaultPosition = (mapElement) => {
let scrollToDefaultPositionExecutor = (resolve, reject) => {
let mapWrapper = mapElement.parents('.' + config.mapWrapperClass);
// auto scroll map to previous stored position
let promiseStore = getLocaleData('map', mapElement.data('id'));
promiseStore.then(data => {
// This code runs once the value has been loaded from offline storage
if(data && data.scrollOffset){
mapWrapper.scrollToPosition([data.scrollOffset.y, data.scrollOffset.x]);
}
resolve({
action: 'scrollToDefaultPosition',
data: false
});
});
};
return new Promise(scrollToDefaultPositionExecutor);
};
/**
* delete local map configuration by key (IndexedDB)
* @param type
@@ -993,10 +1292,40 @@ define([
});
};
/**
* add system pilot tooltip
* @param systemUserData
* @param options
* @returns {*}
*/
$.fn.addSystemPilotTooltip = function(systemUserData, options){
let content = Util.getSystemPilotsTable(systemUserData);
let defaultOptions = {
placement: 'top',
html: true,
trigger: 'hover',
container: 'body',
title: 'Pilots',
content: content,
delay: {
show: 150,
hide: 0
},
};
options = $.extend({}, defaultOptions, options);
return this.each(function(){
$(this).popover(options);
});
};
/**
* add system effect tooltip
* @param security
* @param effect
* @param options
* @returns {*}
*/
$.fn.addSystemEffectTooltip = function(security, effect, options){
@@ -1029,6 +1358,36 @@ define([
});
};
/**
* add system planets tooltip
* @param planets
* @param options
* @returns {*}
*/
$.fn.addSystemPlanetsTooltip = function(planets, options){
let content = Util.getSystemPlanetsTable(planets);
let defaultOptions = {
placement: 'top',
html: true,
trigger: 'hover',
container: 'body',
title: 'Planets',
content: content,
delay: {
show: 150,
hide: 0
},
};
options = $.extend({}, defaultOptions, options);
return this.each(function(){
$(this).popover(options);
});
};
/**
* add a wormhole tooltip with wh specific data to elements
* @param tooltipData
@@ -1188,6 +1547,39 @@ define([
return url;
};
/**
* request system data
* @param requestData
* @param context
* @returns {Promise<any>}
*/
let requestSystemData = (requestData, context) => {
let requestSystemDataExecutor = (resolve, reject) => {
$.ajax({
url: Init.path.getSystemData,
type: 'POST',
dataType: 'json',
data: requestData,
context: context
}).done(function(data){
if(data.system){
resolve({
action: 'systemData',
context: this,
data: data.system
});
}else{
console.warn('Missing systemData in response!', requestData);
}
}).fail(function( jqXHR, status, error) {
console.warn('Fail request systemData!', requestData);
});
};
return new Promise(requestSystemDataExecutor);
};
return {
config: config,
mapOptions: mapOptions,
@@ -1204,8 +1596,9 @@ define([
getSystemData: getSystemData,
getSystemTypeInfo: getSystemTypeInfo,
getEffectInfoForSystem: getEffectInfoForSystem,
toggleSelectSystem: toggleSelectSystem,
toggleSystemsSelect: toggleSystemsSelect,
toggleConnectionActive: toggleConnectionActive,
setSystemActive: setSystemActive,
showSystemInfo: showSystemInfo,
showConnectionInfo: showConnectionInfo,
getConnectionsByType: getConnectionsByType,
@@ -1223,12 +1616,17 @@ define([
getEndpointOverlayContent: getEndpointOverlayContent,
getTabContentElementByMapElement: getTabContentElementByMapElement,
hasActiveConnection: hasActiveConnection,
filterMapByScopes: filterMapByScopes,
storeDefaultMapId: storeDefaultMapId,
getLocaleData: getLocaleData,
storeLocalData: storeLocalData,
deleteLocalData: deleteLocalData,
visualizeMap: visualizeMap,
setMapDefaultOptions: setMapDefaultOptions,
scrollToDefaultPosition: scrollToDefaultPosition,
getSystemId: getSystemId,
checkRight: checkRight,
getMapDeeplinkUrl: getMapDeeplinkUrl
getMapDeeplinkUrl: getMapDeeplinkUrl,
requestSystemData: requestSystemData
};
});

View File

@@ -35,6 +35,9 @@ define([
// set default select2 config
Util.initDefaultSelect2Config();
// set default xEditable config
Util.initDefaultEditableConfig();
// load page
// load info (maintenance) info panel (if scheduled)
$('body').loadPageStructure().setGlobalShortcuts();
@@ -254,12 +257,12 @@ define([
onGet: (MsgWorkerMessage) => {
switch(MsgWorkerMessage.task()){
case 'mapUpdate':
Util.updateCurrentMapData( MsgWorkerMessage.data() );
Util.updateCurrentMapData(MsgWorkerMessage.data());
ModuleMap.updateMapModule(mapModule);
break;
case 'mapAccess':
case 'mapDeleted':
Util.deleteCurrentMapData( MsgWorkerMessage.data() );
Util.deleteCurrentMapData(MsgWorkerMessage.data());
ModuleMap.updateMapModule(mapModule);
break;
case 'mapSubscriptions':
@@ -350,7 +353,7 @@ define([
// get updated map data
let updatedMapData = {
mapData: mapModule.getMapModuleDataForUpdate(),
mapData: ModuleMap.getMapModuleDataForUpdate(mapModule),
getUserData: Util.getCurrentUserData() ? 0 : 1
};
@@ -472,7 +475,7 @@ define([
// update system info panels
if(data.system){
mapModule.updateSystemModuleData(data.system);
ModuleMap.updateSystemModulesData(mapModule, data.system);
}
// store current map user data (cache)

View File

@@ -84,6 +84,7 @@ define([
* @param tabElement
*/
let setMapContentObserver = (tabElement) => {
tabElement.on('pf:drawSystemModules', '.' + config.mapTabContentClass, function(e){
drawSystemModules($(e.target));
});
@@ -98,7 +99,36 @@ define([
tabElement.on('pf:removeConnectionModules', '.' + config.mapTabContentClass, function(e){
removeConnectionModules($(e.target));
}) ;
});
tabElement.on('pf:updateSystemModules', '.' + config.mapTabContentClass, function(e, data){
updateSystemModules($(e.target), data);
});
};
/**
* update (multiple) modules
* @param tabContentElement
* @param modules
* @param data
*/
let updateModules = (tabContentElement, modules, data) => {
for(let Module of modules){
let moduleElement = tabContentElement.find('.' + Module.config.moduleTypeClass);
if(moduleElement.length > 0){
Module.updateModule(moduleElement, data);
}
}
};
/**
* update system modules with new data
* @param tabContentElement
* @param data
*/
let updateSystemModules = (tabContentElement, data) => {
let systemModules = [SystemInfoModule, SystemSignatureModule, SystemIntelModule];
updateModules(tabContentElement, systemModules, data);
};
/**
@@ -118,7 +148,7 @@ define([
* @param tabContentElement
*/
let removeSystemModules = (tabContentElement) => {
let systemModules = [SystemInfoModule, SystemGraphModule, SystemSignatureModule, SystemRouteModule, SystemKillboardModule];
let systemModules = [SystemInfoModule, SystemGraphModule, SystemSignatureModule, SystemRouteModule, SystemIntelModule, SystemKillboardModule];
removeModules(tabContentElement, systemModules);
};
@@ -168,90 +198,103 @@ define([
*/
let drawModule = (parentElement, Module, mapId, data) => {
/**
* show/render a Module
* @param parentElement
* @param Module
* @param mapId
* @param data
*/
let showPanel = (parentElement, Module, mapId, data) => {
let moduleElement = Module.getModule(parentElement, mapId, data);
if (moduleElement) {
// store Module object to DOM element for further access
moduleElement.data('module', Module);
moduleElement.data('data', data);
moduleElement.addClass([config.moduleClass, Module.config.moduleTypeClass].join(' '));
moduleElement.css({opacity: 0}); // will be animated
let drawModuleExecutor = (resolve, reject) => {
/**
* show/render a Module
* @param parentElement
* @param Module
* @param mapId
* @param data
*/
let showPanel = (parentElement, Module, mapId, data) => {
let moduleElement = Module.getModule(parentElement, mapId, data);
if (moduleElement) {
// store Module object to DOM element for further access
moduleElement.data('module', Module);
moduleElement.data('data', data);
moduleElement.addClass([config.moduleClass, Module.config.moduleTypeClass].join(' '));
moduleElement.css({opacity: 0}); // will be animated
// check module position from local storage
let promiseStore = MapUtil.getLocaleData('map', mapId);
promiseStore.then(function (dataStore) {
let Module = this.moduleElement.data('module');
let defaultPosition = Module.config.modulePosition || 0;
// check module position from local storage
let promiseStore = MapUtil.getLocaleData('map', mapId);
promiseStore.then(function (dataStore) {
let Module = this.moduleElement.data('module');
let defaultPosition = Module.config.modulePosition || 0;
// check for stored module order in indexDB (client) ----------------------------------------------
let key = 'modules_cell_' + this.parentElement.attr('data-position');
if (
dataStore &&
dataStore[key]
) {
let positionIndex = dataStore[key].indexOf(Module.config.moduleName);
if (positionIndex !== -1) {
// first index (0) => is position 1
defaultPosition = positionIndex + 1;
}
}
// find correct position for new moduleElement ----------------------------------------------------
let position = getModulePosition(this.parentElement, defaultPosition);
this.moduleElement.attr('data-position', defaultPosition);
this.moduleElement.attr('data-module', Module.config.moduleName);
// insert at correct position ---------------------------------------------------------------------
let prevModuleElement = this.parentElement.find('.' + config.moduleClass + ':nth-child(' + position + ')');
if (prevModuleElement.length) {
this.moduleElement.insertAfter(prevModuleElement);
} else {
this.parentElement.prepend(this.moduleElement);
}
if (typeof Module.beforeShow === 'function') {
Module.beforeShow(this.moduleElement, moduleElement.data('data'));
}
// show animation ---------------------------------------------------------------------------------
this.moduleElement.velocity({
opacity: [1, 0],
translateY: [0, +20]
}, {
duration: Init.animationSpeed.mapModule,
easing: 'easeOutSine',
complete: function (moduleElement) {
moduleElement = $(moduleElement);
let Module = $(moduleElement).data('module');
if (typeof Module.initModule === 'function') {
Module.initModule(moduleElement, mapId, moduleElement.data('data'));
// check for stored module order in indexDB (client) ----------------------------------------------
let key = 'modules_cell_' + this.parentElement.attr('data-position');
if (
dataStore &&
dataStore[key]
) {
let positionIndex = dataStore[key].indexOf(Module.config.moduleName);
if (positionIndex !== -1) {
// first index (0) => is position 1
defaultPosition = positionIndex + 1;
}
}
});
}.bind({
parentElement: parentElement,
moduleElement: moduleElement
}));
// find correct position for new moduleElement ----------------------------------------------------
let position = getModulePosition(this.parentElement, defaultPosition);
this.moduleElement.attr('data-position', defaultPosition);
this.moduleElement.attr('data-module', Module.config.moduleName);
// insert at correct position ---------------------------------------------------------------------
let prevModuleElement = this.parentElement.find('.' + config.moduleClass + ':nth-child(' + position + ')');
if (prevModuleElement.length) {
this.moduleElement.insertAfter(prevModuleElement);
} else {
this.parentElement.prepend(this.moduleElement);
}
if (typeof Module.beforeShow === 'function') {
Module.beforeShow(this.moduleElement, moduleElement.data('data'));
}
// show animation ---------------------------------------------------------------------------------
this.moduleElement.velocity({
opacity: [1, 0],
translateY: [0, +20]
}, {
duration: Init.animationSpeed.mapModule,
easing: 'easeOutSine',
complete: function (moduleElement) {
moduleElement = $(moduleElement);
let Module = $(moduleElement).data('module');
if (typeof Module.initModule === 'function') {
Module.initModule(moduleElement, mapId, moduleElement.data('data'));
}
resolve({
action: 'drawModule',
data: {
module: Module
}
});
}
});
}.bind({
parentElement: parentElement,
moduleElement: moduleElement
}));
}
};
// check if module already exists
let moduleElement = parentElement.find('.' + Module.config.moduleTypeClass);
if (moduleElement.length > 0) {
removeModule(moduleElement, Module, () => {
showPanel(parentElement, Module, mapId, data);
});
} else {
showPanel(parentElement, Module, mapId, data);
}
};
// check if module already exists
let moduleElement = parentElement.find('.' + Module.config.moduleTypeClass);
if (moduleElement.length > 0) {
removeModule(moduleElement, Module, () => {
showPanel(parentElement, Module, mapId, data);
});
} else {
showPanel(parentElement, Module, mapId, data);
}
return new Promise(drawModuleExecutor);
};
/**
@@ -259,30 +302,60 @@ define([
* @param tabContentElement
*/
let drawSystemModules = (tabContentElement) => {
require(['datatables.loader'], function(){
let currentSystemData = Util.getCurrentSystemData();
// get grid cells
let promiseDrawAll = [];
// request "additional" system data (e.g. Structures, Description)
// -> this is used to update some modules after initial draw
let promiseRequestData = MapUtil.requestSystemData({
mapId: currentSystemData.mapId,
systemId: currentSystemData.systemData.id
});
// draw modules -------------------------------------------------------------------------------------------
let firstCell = tabContentElement.find('.' + config.mapTabContentCellFirst);
let secondCell = tabContentElement.find('.' + config.mapTabContentCellSecond);
// draw system info module
drawModule(firstCell, SystemInfoModule, currentSystemData.mapId, currentSystemData.systemData);
let promiseInfo = drawModule(firstCell, SystemInfoModule, currentSystemData.mapId, currentSystemData.systemData);
// draw system graph module
drawModule(firstCell, SystemGraphModule, currentSystemData.mapId, currentSystemData.systemData);
// draw signature table module
drawModule(firstCell, SystemSignatureModule, currentSystemData.mapId, currentSystemData.systemData);
let promiseSignature = drawModule(firstCell, SystemSignatureModule, currentSystemData.mapId, currentSystemData.systemData);
// draw system routes module
drawModule(secondCell, SystemRouteModule, currentSystemData.mapId, currentSystemData.systemData);
// draw system intel module
drawModule(secondCell, SystemIntelModule, currentSystemData.mapId, currentSystemData.systemData);
let promiseIntel = drawModule(secondCell, SystemIntelModule, currentSystemData.mapId, currentSystemData.systemData);
// draw system killboard module
drawModule(secondCell, SystemKillboardModule, currentSystemData.mapId, currentSystemData.systemData);
// update some modules ------------------------------------------------------------------------------------
promiseDrawAll.push(promiseRequestData, promiseInfo, promiseSignature, promiseIntel);
// update "some" modules after draw AND additional system data was requested
Promise.all(promiseDrawAll).then(payload => {
// get systemData from first Promise (ajax call)
let responseData = payload.shift();
if(responseData.data){
let systemData = responseData.data;
// update all Modules
let modules = [];
for(let responseData of payload){
modules.push(responseData.data.module);
}
updateModules(tabContentElement, modules, systemData);
}
});
});
};
@@ -303,15 +376,15 @@ define([
};
/**
* updates current visible/active mapElement in mapModuleElement with user data
* @param mapModuleElement
* updates current visible/active mapElement in mapModule with user data
* @param mapModule
* @returns {Promise<any>}
*/
let updateActiveMapUserData = (mapModuleElement) => {
let updateActiveMapUserData = (mapModule) => {
let updateActiveMapModuleExecutor = (resolve, reject) => {
// get all active map elements for module
let mapElement = mapModuleElement.getActiveMap();
let mapElement = mapModule.getActiveMap();
updateMapUserData(mapElement).then(payload => resolve());
};
@@ -355,22 +428,22 @@ define([
};
/**
* update system info panels (below map)
* update active system modules (below map)
* @param mapModule
* @param systemData
*/
$.fn.updateSystemModuleData = function(systemData){
let mapModule = $(this);
let updateSystemModulesData = (mapModule, systemData) => {
if(systemData){
// check if current open system is still the requested info system
let currentSystemData = Util.getCurrentSystemData();
if(currentSystemData){
if(systemData.id === currentSystemData.systemData.id){
// trigger system update events
$(document).triggerHandler('pf:updateSystemInfoModule', [systemData]);
$(document).triggerHandler('pf:updateSystemSignatureModule', [systemData]);
}
if(
currentSystemData &&
systemData.id === currentSystemData.systemData.id
){
// trigger system update events
let tabContentElement = $( '#' + config.mapTabIdPrefix + systemData.mapId + '.' + config.mapTabContentClass);
tabContentElement.trigger('pf:updateSystemModules', [systemData]);
}
}
};
@@ -609,7 +682,7 @@ define([
mapElement.data('frozen', true);
// hide current map with animation
mapElement.visualizeMap('hide', function(){
MapUtil.visualizeMap(mapElement, 'hide').then(payload => {
// un-block map tabs
mapTabChangeBlocked = switchTabCallback(mapElement, tabLinkElement);
});
@@ -650,6 +723,12 @@ define([
let mapWrapperElement = mapElement.closest('.mCustomScrollbar');
mapWrapperElement.mCustomScrollbar('update');
// if there is an already an "active" system -> setCurrentSystemData for that again
let activeSystem = mapElement.find('.' + MapUtil.config.systemActiveClass + ':first');
if(activeSystem.length){
MapUtil.setSystemActive(mapConfig.map, activeSystem);
}
// change url to unique map URL
if (history.pushState) {
let mapUrl = MapUtil.getMapDeeplinkUrl(mapConfig.config.id);
@@ -668,11 +747,14 @@ define([
// skip "add button"
if(newMapId > 0){
// delete currentSystemData -> will be set for new map (if there is is an active system)
delete Init.currentSystemData;
let currentTabContentElement = $('#' + config.mapTabIdPrefix + oldMapId);
// disable scrollbar for map that will be hidden. "freeze" current state
let mapWrapperElement = currentTabContentElement.find('.' + config.mapWrapperClass);
$(mapWrapperElement).mCustomScrollbar('disable', false);
mapWrapperElement.mCustomScrollbar('disable', false);
}
});
@@ -946,15 +1028,15 @@ define([
/**
* clear all active maps
* @param mapModuleElement
* @param mapModule
* @returns {Promise<any>}
*/
let clearMapModule = (mapModuleElement) => {
let clearMapModule = (mapModule) => {
let promiseDeleteTab = [];
let tabMapElement = $('#' + config.mapTabElementId);
if(tabMapElement.length > 0){
let tabElements = mapModuleElement.getMapTabElements();
let tabElements = mapModule.getMapTabElements();
for(let i = 0; i < tabElements.length; i++){
let tabElement = $(tabElements[i]);
let mapId = tabElement.data('map-id');
@@ -1040,10 +1122,10 @@ define([
/**
* load/update map module into element (all maps)
* @param mapModuleElement
* @param mapModule
* @returns {Promise<any>}
*/
let updateMapModule = (mapModuleElement) => {
let updateMapModule = (mapModule) => {
// performance logging (time measurement)
let logKeyClientMapData = Init.performanceLogging.keyClientMapData;
Util.timeStart(logKeyClientMapData);
@@ -1060,7 +1142,7 @@ define([
if(tempMapData.length === 0){
// clear all existing maps ----------------------------------------------------------------------------
clearMapModule(mapModuleElement)
clearMapModule(mapModule)
.then(payload => {
// no map data available -> show "new map" dialog
$(document).trigger('pf:menuShowMapSettings', {tab: 'new'});
@@ -1082,7 +1164,7 @@ define([
};
// tab element already exists
let tabElements = mapModuleElement.getMapTabElements();
let tabElements = mapModule.getMapTabElements();
// mapIds that are currently active
let activeMapIds = [];
@@ -1148,7 +1230,7 @@ define([
};
tabMapElement = getMapTabElement(options, currentUserData);
mapModuleElement.prepend(tabMapElement);
mapModule.prepend(tabMapElement);
// add new tab for each map
for(let j = 0; j < tempMapData.length; j++){
@@ -1186,19 +1268,18 @@ define([
/**
* collect all data (systems/connections) for export/save from each active map in the map module
* if no change detected -> do not attach map data to return array
* @param mapModule
* @returns {Array}
*/
$.fn.getMapModuleDataForUpdate = function(){
let getMapModuleDataForUpdate = mapModule => {
// get all active map elements for module
let mapElements = $(this).getMaps();
let mapElements = mapModule.getMaps();
let data = [];
for(let i = 0; i < mapElements.length; i++){
// get all changed (system / connection) data from this map
let mapData = $(mapElements[i]).getMapDataFromClient({forceData: false, checkForChange: true});
if(mapData !== false){
if(
mapData.data.systems.length > 0 ||
mapData.data.connections.length > 0
@@ -1214,6 +1295,8 @@ define([
return {
updateTabData: updateTabData,
updateMapModule: updateMapModule,
updateActiveMapUserData: updateActiveMapUserData
updateActiveMapUserData: updateActiveMapUserData,
updateSystemModulesData: updateSystemModulesData,
getMapModuleDataForUpdate: getMapModuleDataForUpdate
};
});

View File

@@ -77,7 +77,6 @@ define([
* @param settings
*/
let showNotify = function(customConfig, settings){
customConfig = $.extend(true, {}, config, customConfig );
// desktop notification

View File

@@ -252,8 +252,7 @@ define([
id: Util.config.menuButtonFullScreenId
}).html('&nbsp;&nbsp;Full screen').prepend(
$('<i>',{
class: 'glyphicon glyphicon-fullscreen',
css: {width: '1.23em'}
class: 'fas fa-expand-arrows-alt fa-fw'
})
).on('click', function(){
let fullScreenElement = $('body');
@@ -345,9 +344,9 @@ define([
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonGridId
}).html('&nbsp;&nbsp;&nbsp;Grid snapping').prepend(
}).html('&nbsp;&nbsp;Grid snapping').prepend(
$('<i>',{
class: 'glyphicon glyphicon-th'
class: 'fas fa-th fa-fw'
})
).on('click', function(){
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
@@ -359,7 +358,7 @@ define([
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonMagnetizerId
}).html('&nbsp;&nbsp;&nbsp;Magnetizing').prepend(
}).html('&nbsp;&nbsp;Magnetizing').prepend(
$('<i>',{
class: 'fas fa-magnet fa-fw'
})
@@ -373,7 +372,7 @@ define([
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonEndpointId
}).html('&nbsp;&nbsp;&nbsp;Signatures').prepend(
}).html('&nbsp;&nbsp;Signatures').prepend(
$('<i>',{
class: 'fas fa-link fa-fw'
})
@@ -383,6 +382,25 @@ define([
toggle: true
});
})
).append(
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonCompactId
}).html('&nbsp;&nbsp;Compact').prepend(
$('<i>',{
class: 'fas fa-compress fa-fw'
})
).append(
$('<span>',{
class: 'badge bg-color bg-color-gray txt-color txt-color-warning',
text: 'beta'
})
).on('click', function(){
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
option: 'mapCompact',
toggle: true
});
})
).append(
getMenuHeadline('Help')
).append(
@@ -437,11 +455,7 @@ define([
* @param event
* @param data
*/
$.fn.triggerMenuEvent = function(event, data){
if(data === undefined){
data = {};
}
$.fn.triggerMenuEvent = function(event, data = {}){
$(this).trigger('pf:menu' + event, [data]);
};
@@ -710,12 +724,20 @@ define([
// END menu events =============================================================================
// global "popover" callback (for all popovers)
$('.' + Util.config.popoverTriggerClass).on('hide.bs.popover', function(e) {
let popoverElement = $(this).data('bs.popover').tip();
// destroy all active tooltips inside this popover
popoverElement.destroyTooltip(true);
});
// global "modal" callback (for all modals)
$('body').on('hide.bs.modal', '> .modal', function(a,b) {
$('body').on('hide.bs.modal', '> .modal', function(e) {
$(this).destroyTimestampCounter();
});
// disable memue links based on current map config
// disable menu links based on current map config
documentElement.on('pf:updateMenuOptions', function(e, data){
let hasRightMapDelete = MapUtil.checkRight('map_delete', data.mapConfig);
$('#' + Util.config.menuButtonMapDeleteId).toggleClass('disabled', !hasRightMapDelete);

View File

@@ -45,6 +45,16 @@ define([
}.bind({
Util: Util
}),
formatStatic: function(){
return function(value, render){
let isStatic = render(value) === 'true';
if(isStatic){
return '<i class="fas fa-check"></i>';
}else{
return '';
}
};
},
sigStrengthValue: function(){
return function(value, render){
let float = render(value);
@@ -94,6 +104,8 @@ define([
});
});
jumpDialog.initTooltips();
jumpDialog.modal('show');
});
};

View File

@@ -338,7 +338,7 @@ define([
// current position
if(tempSystemData.currentUser === true){
tempData.position = {
position: '<i class="fas fa-map-marker-alt fa-lg fa-fw"></i>',
position: '<i class="fas fa-map-marker-alt fa-fw"></i>',
position_sort: 1
};
}else{
@@ -379,8 +379,9 @@ define([
// static
let statics = [];
for(let j = 0; j < tempSystemData.statics.length; j++){
let security = tempSystemData.statics[j].security;
for(let wormholeName of tempSystemData.statics){
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
let security = wormholeData.security;
let secClass = Util.getSecurityClassForSystem(security);
statics.push('<span class="' + secClass + '">' + security + '</span>');
}
@@ -390,7 +391,7 @@ define([
let systemStatusClass = Util.getStatusInfoForSystem(tempSystemData.status.id, 'class');
if(systemStatusClass !== ''){
tempData.status = {
status: '<i class="far fa-square fa-lg fa-fw ' + systemStatusClass + '"></i>',
status: '<i class="far fa-square fa-fw ' + systemStatusClass + '"></i>',
status_sort: tempSystemData.status.id
};
}else{
@@ -404,7 +405,7 @@ define([
let systemEffectClass = MapUtil.getEffectInfoForSystem(tempSystemData.effect, 'class');
if(systemEffectClass !== ''){
tempData.effect = {
effect: '<i class="fas fa-square fa-lg fa-fw ' + systemEffectClass + '"></i>',
effect: '<i class="fas fa-square fa-fw ' + systemEffectClass + '"></i>',
effect_sort: tempSystemData.effect
};
}else{
@@ -428,10 +429,23 @@ define([
};
}
// shattered
if(tempSystemData.shattered){
tempData.shattered = {
shattered: '<i class="fas fa-skull fa-fw ' + Util.getSecurityClassForSystem('SH') + '"></i>',
shattered_sort: tempSystemData.shattered
};
}else{
tempData.shattered = {
shattered: '',
shattered_sort: 0
};
}
// locked
if(tempSystemData.locked === 1){
tempData.locked = {
locked: '<i class="fas fa-lock fa-lg fa-fw"></i>',
locked: '<i class="fas fa-lock fa-fw"></i>',
locked_sort: tempSystemData.locked
};
}else{
@@ -499,6 +513,16 @@ define([
_: 'trueSec',
sort: 'trueSec_sort'
}
},{
title: '<i class="fas fa-skull" title="shattered" data-toggle="tooltip"></i>',
width: '10px',
className: ['text-center', 'min-desktop'].join(' '),
searchable: false,
data: 'shattered',
render: {
_: 'shattered',
sort: 'shattered_sort'
}
},{
title: 'system',
data: 'name',
@@ -517,7 +541,8 @@ define([
data: 'region'
},{
title: '<i class="far fa-square" title="system&nbsp;status" data-toggle="tooltip"></i>',
width: '12px',
width: '10px',
className: 'text-center',
searchable: false,
data: 'status',
render: {
@@ -526,7 +551,7 @@ define([
}
},{
title: '<i class="fas fa-square" title="system&nbsp;effect" data-toggle="tooltip"></i>',
width: '12px',
width: '10px',
className: 'text-center',
searchable: false,
data: 'effect',
@@ -541,6 +566,7 @@ define([
},{
title: '<i class="fas fa-map-marker-alt" title="your&nbsp;position" data-toggle="tooltip"></i>',
width: '8px',
className: 'text-center',
searchable: false,
data: 'position',
render: {
@@ -556,6 +582,7 @@ define([
},{
title: '<i class="fas fa-lock" title="system&nbsp;locked" data-toggle="tooltip"></i>',
width: '10px',
className: 'text-center',
searchable: false,
data: 'locked',
render: {

View File

@@ -541,7 +541,9 @@ define([
filesCount === files.length &&
filesCountFail === 0
){
importMaps(importData);
importMaps(importData, () => {
mapInfoDialog.modal('hide');
});
}
};
@@ -651,7 +653,7 @@ define([
* import new map(s) data
* @param importData
*/
let importMaps = function(importData){
let importMaps = (importData, callback) => {
let importForm = $('#' + config.dialogMapImportFormId);
importForm.hideFormMessage('all');
@@ -675,6 +677,10 @@ define([
importForm.showFormMessage(responseData.warning);
}
if(callback){
callback();
}
Util.showNotify({title: 'Import finished', text: 'Map(s) imported', type: 'success'});
}
}).fail(function( jqXHR, status, error) {

View File

@@ -94,26 +94,30 @@ define([
};
options = $.extend({}, config, options);
let shatteredClass = Util.getSecurityClassForSystem('SH');
// format result data
function formatResultData (data) {
if(data.loading) return data.text;
if (data.loading){
return data.text;
}
// abyss system font
let systemNameClass = data.security === 'A' ? Util.config.fontTriglivianClass : '' ;
// show effect info just for wormholes
let hideEffectClass = '';
if(data.effect === ''){
hideEffectClass = 'hide';
}
let hideEffectClass = data.effect === null ? 'hide' : '';
let hideShatteredClass = !data.shattered ? 'hide' : '';
let markup = '<div class="clearfix">';
markup += '<div class="col-sm-5 pf-select-item-anchor">' + data.text + '</div>';
markup += '<div class="col-sm-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
markup += '<i class="fas fa-fw fa-square ' + hideEffectClass + '"></i>';
markup += '</div>';
markup += '<div class="col-sm-2 text-right ' + data.secClass + '">' + data.security + '</div>';
markup += '<div class="col-sm-3 text-right ' + data.trueSecClass + '">' + data.trueSec + '</div></div>';
markup += '<div class="col-sm-2 text-right ' + shatteredClass + '">';
markup += '<i class="fas fa-fw fa-skull ' + hideShatteredClass + '"></i>';
markup += '</div>';
markup += '<div class="col-sm-2 text-right ' + data.trueSecClass + '">' + data.trueSec + '</div></div>';
return markup;
}
@@ -123,22 +127,22 @@ define([
ajax: {
url: function(params){
// add params to URL
return Init.path.searchSystem + '/' + params.term.trim();
return Init.path.searchUniverseSystemData + '/' + params.term.trim();
},
dataType: 'json',
delay: 250,
timeout: 5000,
cache: true,
data: function(params) {
// no url params here
return;
data: function(params){
return {
page: params.page || 1
};
},
processResults: function(data) {
processResults: function(data, params) {
// parse the results into the format expected by Select2.
return {
results: data.map( function(item){
// "systemId" or "name"
results: data.results.map( function(item){
// "id" or "name"
let id = item[options.key];
let disabled = false;
let trueSec = parseFloat(item.trueSec);
@@ -167,16 +171,20 @@ define([
return {
id: id,
text: item.name,
systemId: parseInt(item.systemId),
// systemId: parseInt(item.systemId),
security: item.security,
secClass: secClass,
trueSec: trueSec.toFixed(1),
trueSecClass: trueSecClass,
effect: item.effect,
effectClass: effectClass,
shattered: item.shattered,
disabled: disabled
};
})
}),
pagination: {
more: data.pagination.more
}
};
},
error: function (jqXHR, status, error) {

View File

@@ -26,8 +26,9 @@ define([
// info table
systemInfoTableClass: 'pf-module-table', // class for system info table
systemInfoNameInfoClass: 'pf-system-info-name', // class for "name" information element
systemInfoEffectInfoClass: 'pf-system-info-effect', // class for "effect" information element
systemInfoNameClass: 'pf-system-info-name', // class for "name" information element
systemInfoEffectClass: 'pf-system-info-effect', // class for "effect" information element
systemInfoPlanetsClass: 'pf-system-info-planets', // class for "planets" information element
systemInfoStatusLabelClass: 'pf-system-info-status-label', // class for "status" information element
systemInfoStatusAttributeName: 'data-status', // attribute name for status label
systemInfoWormholeClass: 'pf-system-info-wormhole-', // class prefix for static wormhole element
@@ -45,8 +46,8 @@ define([
fontTriglivianClass: 'pf-triglivian' // class for "Triglivian" names (e.g. Abyssal systems)
};
// disable Module update temporary (until. some requests/animations) are finished
let disableModuleUpdate = true;
// disable Module update temporary (in case e.g. textarea is currently active)
let disableModuleUpdate = false;
// animation speed values
let animationSpeedToolbarAction = 200;
@@ -54,17 +55,6 @@ define([
// max character length for system description
let maxDescriptionLength = 512;
/**
* set module observer and look for relevant system data to update
*/
let setModuleObserver = (moduleElement) => {
$(document).off('pf:updateSystemInfoModule').on('pf:updateSystemInfoModule', function(e, data){
if(data){
moduleElement.updateSystemInfoModule(data);
}
});
};
/**
* shows the tool action element by animation
* @param toolsActionElement
@@ -94,47 +84,37 @@ define([
/**
* update trigger function for this module
* compare data and update module
* @param moduleElement
* @param systemData
*/
$.fn.updateSystemInfoModule = function(systemData){
// module update is disabled
if(disableModuleUpdate === true){
return;
}
let moduleElement = $(this);
let updateModule = (moduleElement, systemData) => {
let systemId = moduleElement.data('id');
if(systemId === systemData.id){
// update module
// system status =====================================================================================
// update system status -----------------------------------------------------------------------------------
let systemStatusLabelElement = moduleElement.find('.' + config.systemInfoStatusLabelClass);
let systemStatusId = parseInt( systemStatusLabelElement.attr( config.systemInfoStatusAttributeName ) );
if(systemStatusId !== systemData.status.id){
// status changed
let currentStatusClass = Util.getStatusInfoForSystem(systemStatusId, 'class');
let newStatusClass = Util.getStatusInfoForSystem(systemData.status.id, 'class');
let newStatusLabel = Util.getStatusInfoForSystem(systemData.status.id, 'label');
systemStatusLabelElement.removeClass(currentStatusClass).addClass(newStatusClass).text(newStatusLabel);
// set new status attribute
systemStatusLabelElement.attr( config.systemInfoStatusAttributeName, systemData.status.id);
}
// description textarea element ======================================================================
// update description textarea ----------------------------------------------------------------------------
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
let description = descriptionTextareaElement.editable('getValue', true);
if(description !== systemData.description){
if(
!disableModuleUpdate && // don´t update if field is active
description !== systemData.description
){
// description changed
// description button
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
// set new value
@@ -144,10 +124,8 @@ define([
if(systemData.description.length === 0){
// show/activate description field
// show button if value is empty
descriptionButton.show();
hideToolsActionElement(actionElement);
}else{
// hide/disable description field
@@ -157,9 +135,8 @@ define([
}
}
// created/updated tooltip ===========================================================================
let nameRowElement = $(moduleElement).find('.' + config.systemInfoNameInfoClass);
// created/updated tooltip --------------------------------------------------------------------------------
let nameRowElement = moduleElement.find('.' + config.systemInfoNameClass);
let tooltipData = {
created: systemData.created,
@@ -186,20 +163,17 @@ define([
// store systemId -> module can be updated with the correct data
moduleElement.data('id', systemData.id);
// shattered wormhole info data
let shatteredWormholeInfo = false;
// add security class for statics
// system "static" wh data
let staticsData = [];
if(
systemData.statics &&
systemData.statics.length > 0
){
for(let i = 0; i < systemData.statics.length; i++){
systemData.statics[i].class = Util.getSecurityClassForSystem( systemData.statics[i].security );
for(let wormholeName of systemData.statics){
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
wormholeData.class = Util.getSecurityClassForSystem(wormholeData.security);
staticsData.push(wormholeData);
}
}else if(systemData.type.id === 1){
// system type "wormhole" but no statics => "shattered wormhole"
shatteredWormholeInfo = true;
}
let effectName = MapUtil.getEffectInfoForSystem(systemData.effect, 'name');
@@ -233,7 +207,7 @@ define([
emptytext: '',
onblur: 'cancel',
showbuttons: true,
value: '', // value is set by trigger function updateSystemInfoModule()
value: '', // value is set by trigger function updateModule()
rows: 5,
name: 'description',
inputclass: config.descriptionTextareaElementClass,
@@ -280,7 +254,7 @@ define([
}
});
// on xEditable open -------------------------------------------------------------------------
// on xEditable open ------------------------------------------------------------------------------
descriptionTextareaElement.on('shown', function(e, editable){
let textarea = editable.input.$input;
@@ -301,7 +275,7 @@ define([
});
});
// on xEditable close ------------------------------------------------------------------------
// on xEditable close -----------------------------------------------------------------------------
descriptionTextareaElement.on('hidden', function(e){
let value = $(this).editable('getValue', true);
if(value.length === 0){
@@ -314,7 +288,7 @@ define([
disableModuleUpdate = false;
});
// enable xEditable field on Button click ----------------------------------------------------
// enable xEditable field on Button click ---------------------------------------------------------
descriptionButton.on('click', function(e){
e.stopPropagation();
let descriptionButton = $(this);
@@ -328,23 +302,23 @@ define([
showToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
});
// init tooltips -----------------------------------------------------------------------------
// init tooltips ----------------------------------------------------------------------------------
let tooltipElements = tempModuleElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip();
// init system effect popover ----------------------------------------------------------------
$(moduleElement).find('.' + config.systemInfoEffectInfoClass).addSystemEffectTooltip(systemData.security, systemData.effect);
// init system effect popover ---------------------------------------------------------------------
$(moduleElement).find('.' + config.systemInfoEffectClass).addSystemEffectTooltip(systemData.security, systemData.effect);
// init static wormhole information ----------------------------------------------------------
if(systemData.statics){
for(let i = 0; i < systemData.statics.length; i++){
let staticData = systemData.statics[i];
let staticRowElement = tempModuleElement.find('.' + config.systemInfoWormholeClass + staticData.name);
staticRowElement.addWormholeInfoTooltip(staticData);
}
// init planets popover ---------------------------------------------------------------------------
$(moduleElement).find('.' + config.systemInfoPlanetsClass).addSystemPlanetsTooltip(systemData.planets);
// init static wormhole information ---------------------------------------------------------------
for(let staticData of staticsData){
let staticRowElement = tempModuleElement.find('.' + config.systemInfoWormholeClass + staticData.name);
staticRowElement.addWormholeInfoTooltip(staticData);
}
// constellation popover ---------------------------------------------------------------------
// constellation popover --------------------------------------------------------------------------
tempModuleElement.find('a.popup-ajax').popover({
html: true,
trigger: 'hover',
@@ -363,7 +337,7 @@ define([
$.ajax({
url: popoverElement.data('url'),
success: function(data){
let systemEffectTable = Util.getSystemsInfoTable( data.systemData );
let systemEffectTable = Util.getSystemsInfoTable( data.systemsData );
popover.options.content = systemEffectTable;
// reopen popover (new content size)
popover.show();
@@ -378,9 +352,11 @@ define([
let moduleData = {
system: systemData,
static: staticsData,
tableClass: config.systemInfoTableClass,
nameInfoClass: config.systemInfoNameInfoClass,
effectInfoClass: config.systemInfoEffectInfoClass,
nameInfoClass: config.systemInfoNameClass,
effectInfoClass: config.systemInfoEffectClass,
planetsInfoClass: config.systemInfoPlanetsClass,
wormholePrefixClass: config.systemInfoWormholeClass,
statusInfoClass: config.systemInfoStatusLabelClass,
@@ -403,8 +379,12 @@ define([
return render(val) === 'A' ? config.fontTriglivianClass : '';
};
},
formatUrl: () => {
return (val, render) => render(val).replace(/ /g, '_');
},
planetCount: systemData.planets ? systemData.planets.length : 0,
shatteredWormholeInfo: shatteredWormholeInfo,
shatteredClass: Util.getSecurityClassForSystem('SH'),
ajaxConstellationInfoUrl: Init.path.getConstellationData,
@@ -419,20 +399,6 @@ define([
return moduleElement;
};
/**
* init callback
* @param moduleElement
* @param mapId
* @param systemData
*/
let initModule = (moduleElement, mapId, systemData) => {
// set module observer
setModuleObserver(moduleElement);
// enable auto update
disableModuleUpdate = false;
};
/**
* efore module destroy callback
* @param moduleElement
@@ -446,7 +412,7 @@ define([
return {
config: config,
getModule: getModule,
initModule: initModule,
updateModule: updateModule,
beforeDestroy: beforeDestroy
};
});

View File

@@ -104,19 +104,25 @@ define([
if(rowId){
// update row
let api = context.tableApi.row('#' + rowId).data(structureData);
api.nodes().to$().data('animationStatus', 'changed').destroyTimestampCounter();
let api = context.tableApi.row('#' + rowId);
let rowData = api.data();
// check for update
if(rowData.updated.updated !== structureData.updated.updated){
// row data changed -> update
api.data(structureData);
api.nodes().to$().data('animationStatus', 'changed').destroyTimestampCounter();
notificationCounter.changed++;
}
touchedRows.push(api.id());
notificationCounter.changed++;
}else{
// insert new row
//context.tableApi.row.add(structureData).nodes().to$().data('animationStatus', 'added');
let api = context.tableApi.row.add(structureData);
api.nodes().to$().data('animationStatus', 'added');
notificationCounter.added++;
touchedRows.push(api.id());
notificationCounter.added++;
}
}
}
@@ -125,7 +131,9 @@ define([
}
if(context.removeMissing){
notificationCounter.deleted += context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id)).remove().ids().count();
let api = context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id));
notificationCounter.deleted += api.ids().count();
api.remove();
}
context.tableApi.draw();
@@ -493,7 +501,9 @@ define([
_: function(data, type, row, meta){
let value = data;
if(type === 'display' && value){
value = '<img src="' + Init.url.ccpImageServer + '/Corporation/' + value + '_32.png" />';
value = '<a href="https://zkillboard.com/corporation/' + data + '/" target="_blank" rel="noopener">';
value += '<img src="' + Init.url.ccpImageServer + '/Corporation/' + data + '_32.png" />';
value += '</a>';
}
return value;
}
@@ -513,7 +523,7 @@ define([
},{
targets: 7,
title: 'updated',
width: 80,
width: 60,
className: ['text-right', config.tableCellCounterClass].join(' '),
data: 'updated.updated'
},{
@@ -632,7 +642,7 @@ define([
}
});
rows.to$().find('.' + config.tableCellCounterClass + ':not([data-counter])').initTimestampCounter();
rows.to$().find('.' + config.tableCellCounterClass + ':not([data-counter])').initTimestampCounter('d');
let animationRows = rows.to$().filter(function() {
return (
@@ -648,16 +658,10 @@ define([
}
},
initComplete: function(settings){
let tableApi = this.api();
// initial structure data request
getStructureData({
mapId: mapId,
systemId: systemData.id
},{
moduleElement: moduleElement,
tableApi: tableApi
}, callbackAddStructureRows);
// table data is load in updateModule() method
// -> no need to trigger additional ajax call here for data
// -> in case table update failed -> each if this initComplete() function finished before table updata
// e.g. return now promise in getModule() function
}
});
@@ -667,6 +671,8 @@ define([
container: 'body'
});
moduleElement.showLoadingAnimation();
return moduleElement;
};
@@ -740,6 +746,28 @@ define([
}
};
/**
* update trigger function for this module
* compare data and update module
* @param moduleElement
* @param systemData
*/
let updateModule = (moduleElement, systemData) => {
// update structure table data
let structureTableElement = moduleElement.find('.' + config.systemStructuresTableClass);
let tableApi = structureTableElement.DataTable();
let context = {
tableApi: tableApi,
removeMissing: true
};
callbackUpdateStructureRows(context, systemData);
moduleElement.hideLoadingAnimation();
};
/**
* init intel module
* @param moduleElement
@@ -785,7 +813,8 @@ define([
return {
config: config,
getModule: getModule,
initModule: initModule
initModule: initModule,
updateModule: updateModule
};
});

View File

@@ -24,6 +24,7 @@ define([
systemKillboardListClass: 'pf-system-killboard-list', // class for a list with kill entries
systemKillboardListEntryClass: 'pf-system-killboard-list-entry', // class for a list entry
systemKillboardListImgShip: 'pf-system-killboard-img-ship', // class for all ship images
systemKillboardListImgChar: 'pf-system-killboard-img-char', // class for all character logos
systemKillboardListImgAlly: 'pf-system-killboard-img-ally', // class for all alliance logos
systemKillboardListImgCorp: 'pf-system-killboard-img-corp' // class for all corp logos
};
@@ -60,125 +61,59 @@ define([
// change order (show right to left)
killboardData.tableData.reverse();
for(let i = 0; i < killboardData.tableData.length; i++){
let data = {
tableData: killboardData.tableData,
systemKillboardListClass: config.systemKillboardListClass,
systemKillboardListEntryClass: config.systemKillboardListEntryClass,
systemKillboardListImgShip: config.systemKillboardListImgShip,
systemKillboardListImgChar: config.systemKillboardListImgChar,
systemKillboardListImgAlly: config.systemKillboardListImgAlly,
systemKillboardListImgCorp: config.systemKillboardListImgCorp,
zKillboardUrl: 'https://zkillboard.com',
ccpImageServerUrl: Init.url.ccpImageServer,
// check if killMails exist in this hour
if(killboardData.tableData[i].killmails){
if(killMailCounter >= killMailCounterMax){
break;
}
moduleElement.append( $('<h5>').text( i ? i + 'h ago' : 'recent'));
let killMailData = killboardData.tableData[i].killmails;
let listeElement = $('<ul>', {
class: ['media-list', config.systemKillboardListClass].join(' ')
});
for(let j = 0; j < killMailData.length; j++){
dateFormat: () => {
return (val, render) => {
let killDate = Util.convertDateToUTC(new Date(render(val)));
return Util.convertDateToString(killDate);
};
},
iskFormat: () => {
return (val, render) => {
return Util.formatPrice(render(val));
};
},
checkRender : () => {
return (val, render) => {
if(killMailCounter < killMailCounterMax){
return render(val);
}
};
},
increaseCount : () => {
return (val, render) => {
killMailCounter++;
if(killMailCounter >= killMailCounterMax){
break;
}
};
}
};
let killData = killMailData[j];
requirejs(['text!templates/modules/killboard.html', 'mustache'], function(template, Mustache) {
let content = Mustache.render(template, data);
let linkUrl = '//zkillboard.com/kill/' + killData.killmail_id + '/';
let victimImageUrl = Init.url.ccpImageServer + '/Type/' + killData.victim.ship_type_id + '_64.png';
let killDate = Util.convertDateToUTC(new Date(killData.killmail_time));
let killDateString = Util.convertDateToString(killDate);
let killLossValue = Util.formatPrice( killData.zkb.totalValue );
moduleElement.append(content);
// check for ally
let victimAllyLogoUrl = '';
let displayAlly = 'none';
if(killData.victim.alliance_id > 0){
victimAllyLogoUrl = Init.url.ccpImageServer + '/Alliance/' + killData.victim.alliance_id + '_32.png';
displayAlly = 'block';
}
// check for corp
let victimCorpLogoUrl = '';
let displayCorp = 'none';
if(killData.victim.corporation_id > 0){
victimCorpLogoUrl = Init.url.ccpImageServer + '/Corporation/' + killData.victim.corporation_id + '_32.png';
displayCorp = 'inline';
}
let liElement = $('<li>', {
class: ['media', config.systemKillboardListEntryClass].join(' ')
}).append(
$('<a>', {
href: linkUrl,
target: '_blank'
}).append(
$('<img>', {
src: victimImageUrl,
class: ['media-object', 'pull-left', config.systemKillboardListImgShip].join(' ')
})
).append(
$('<img>', {
src: victimAllyLogoUrl,
title: killData.victim.allianceName,
class: ['pull-right', config.systemKillboardListImgAlly].join(' '),
css: {display: displayAlly}
}).attr('data-placement', 'left')
).append(
$('<div>', {
class: 'media-body'
}).append(
$('<h5>', {
class: 'media-heading',
text: killData.victim.characterName
}).prepend(
$('<small>', {
text: killDateString
})
).prepend(
$('<img>', {
src: victimCorpLogoUrl,
title: killData.victim.corporationName,
class: [config.systemKillboardListImgCorp].join(' '),
css: {display: displayCorp}
})
)
).append(
$('<h3>', {
class: ['media-heading'].join(' ')
}).append(
$('<small>', {
class: ['txt-color', 'txt-color-green', 'pull-right'].join(' '),
text: killLossValue
})
)
)
)
);
listeElement.append(liElement);
// animate kill li-elements
$('.' + config.systemKillboardListEntryClass).velocity('transition.expandIn', {
stagger: 50,
complete: function(){
// init tooltips
moduleElement.find('[title]').tooltip({
container: 'body'
});
}
moduleElement.append(listeElement);
}
}
// animate kill li-elements
$('.' + config.systemKillboardListEntryClass).velocity('transition.expandIn', {
stagger: 50,
complete: function(){
// init tooltips
moduleElement.find('[title]').tooltip({
container: 'body'
});
}
});
});
};
/**

View File

@@ -317,16 +317,16 @@ define([
mapIds: routeDialogData.mapIds,
systemFromData: dialogData.systemFromData,
systemToData: {
systemId: systemSelectData[0].systemId,
systemId: parseInt(systemSelectData[0].id),
name: systemSelectData[0].text
},
stargates: routeDialogData.hasOwnProperty('stargates') ? parseInt( routeDialogData.stargates ) : 0,
jumpbridges: routeDialogData.hasOwnProperty('jumpbridges') ? parseInt( routeDialogData.jumpbridges ) : 0,
wormholes: routeDialogData.hasOwnProperty('wormholes') ? parseInt( routeDialogData.wormholes ) : 0,
wormholesReduced: routeDialogData.hasOwnProperty('wormholesReduced') ? parseInt( routeDialogData.wormholesReduced ) : 0,
wormholesCritical: routeDialogData.hasOwnProperty('wormholesCritical') ? parseInt( routeDialogData.wormholesCritical ) : 0,
wormholesFrigate: routeDialogData.hasOwnProperty('wormholesFrigate') ? parseInt( routeDialogData.wormholesFrigate ) : 0,
wormholesEOL: routeDialogData.hasOwnProperty('wormholesEOL') ? parseInt( routeDialogData.wormholesEOL ) : 0
stargates: routeDialogData.hasOwnProperty('stargates') ? parseInt(routeDialogData.stargates) : 0,
jumpbridges: routeDialogData.hasOwnProperty('jumpbridges') ? parseInt(routeDialogData.jumpbridges) : 0,
wormholes: routeDialogData.hasOwnProperty('wormholes') ? parseInt(routeDialogData.wormholes) : 0,
wormholesReduced: routeDialogData.hasOwnProperty('wormholesReduced') ? parseInt(routeDialogData.wormholesReduced) : 0,
wormholesCritical: routeDialogData.hasOwnProperty('wormholesCritical') ? parseInt(routeDialogData.wormholesCritical) : 0,
wormholesFrigate: routeDialogData.hasOwnProperty('wormholesFrigate') ? parseInt(routeDialogData.wormholesFrigate) : 0,
wormholesEOL: routeDialogData.hasOwnProperty('wormholesEOL') ? parseInt(routeDialogData.wormholesEOL) : 0
}]
};
@@ -354,7 +354,7 @@ define([
// init system select live search ------------------------------------------------
// -> add some delay until modal transition has finished
let systemTargetSelect = $(this).find('.' + config.systemDialogSelectClass);
systemTargetSelect.delay(240).initSystemSelect({key: 'name'});
systemTargetSelect.delay(240).initSystemSelect({key: 'id'});
});
// show dialog
@@ -498,7 +498,7 @@ define([
// init default system select -----------------------------------------------------
// -> add some delay until modal transition has finished
let systemTargetSelect = $(this).find('.' + config.systemDialogSelectClass);
systemTargetSelect.delay(240).initSystemSelect({key: 'name', maxSelectionLength: maxSelectionLength});
systemTargetSelect.delay(240).initSystemSelect({key: 'id', maxSelectionLength: maxSelectionLength});
});
// show dialog
@@ -518,8 +518,8 @@ define([
let tmpData = data[i];
formattedData.push({
name: tmpData.id,
systemId: parseInt( tmpData.hasOwnProperty('systemId') ? tmpData.systemId : tmpData.element.getAttribute('data-systemid') )
systemId: parseInt(tmpData.id),
name: tmpData.text
});
}

View File

@@ -219,7 +219,7 @@ define([
* @param tableApi
* @returns {Array}
*/
let getTableData = function(tableApi){
let getTableData = tableApi => {
let tableData = [];
if(tableApi){
@@ -266,7 +266,7 @@ define([
* @param cellIndex
* @param data
*/
let updateSignatureCell = function(tableApi, rowElement, cellIndex, data){
let updateSignatureCell = (tableApi, rowElement, cellIndex, data) => {
let rowIndex = tableApi.row( rowElement ).index();
let updateCell = tableApi.cell( rowIndex, cellIndex );
let updateCellElement = updateCell.nodes().to$();
@@ -277,21 +277,36 @@ define([
}
// set new value
updateCell.data( data ).draw();
updateCell.data(data).draw();
if(cellIndex === 7){
updateCellElement.initTimestampCounter();
}
};
/**
* update trigger function for this module
* compare data and update module
* @param moduleElement
* @param systemData
*/
let updateModule = (moduleElement, systemData) => {
if(systemData.signatures){
updateSignatureTable(moduleElement, systemData.signatures, true);
}
moduleElement.hideLoadingAnimation();
};
/**
* Updates a signature table, changes all signatures where name matches
* add all new signatures as a row
*
* @param moduleElement
* @param signatureDataOrig
* @param deleteOutdatedSignatures -> set to "true" if signatures should be deleted that are not included in "signatureData"
*/
$.fn.updateSignatureTable = function(signatureDataOrig, deleteOutdatedSignatures){
let updateSignatureTable = (moduleElement, signatureDataOrig, deleteOutdatedSignatures) => {
// check if table update is allowed
if(disableTableUpdate === true){
return;
@@ -303,8 +318,6 @@ define([
// disable update until function is ready;
lockSignatureTable();
let moduleElement = $(this);
// get signature table API
let signatureTableApi = getDataTableInstanceByModuleElement(moduleElement, 'primary');
@@ -413,7 +426,7 @@ define([
/**
* lock system signature table for
*/
let lockSignatureTable = function(){
let lockSignatureTable = () => {
disableTableUpdate = true;
};
@@ -422,7 +435,7 @@ define([
* -> make table "update-able" again
* @param instant
*/
let unlockSignatureTable = function(instant){
let unlockSignatureTable = instant =>{
if(disableTableUpdate === true){
if(instant === true){
disableTableUpdate = false;
@@ -430,7 +443,6 @@ define([
// wait until add/remove animations are finished before enable table for auto update again
setTimeout(function(){ disableTableUpdate = false; }, 2000);
}
}
};
@@ -572,10 +584,10 @@ define([
moduleElement: moduleElement
}
}).done(function(responseData){
// unlock table for update
unlockSignatureTable(true);
// updates table with new/updated signature information
this.moduleElement.updateSignatureTable(responseData.signatures, false);
updateSignatureTable(this.moduleElement, responseData.signatures, false);
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': Update signatures', text: reason, type: 'warning'});
@@ -625,7 +637,7 @@ define([
* @param clipboard
* @returns {Array}
*/
let parseSignatureString = function(systemData, clipboard){
let parseSignatureString = (systemData, clipboard) => {
let signatureData = [];
if(clipboard.length){
@@ -698,7 +710,7 @@ define([
* @param options
* @returns {Array}
*/
let formatSignatureData = function(systemData, signatureData, options){
let formatSignatureData = (systemData, signatureData, options) => {
let formattedData = [];
@@ -850,7 +862,7 @@ define([
* @param options
* @returns {*|jQuery}
*/
let getLabeledButton = function(options){
let getLabeledButton = options => {
let buttonClasses = ['btn', 'btn-sm', 'btn-labeled'];
@@ -906,7 +918,7 @@ define([
* @param tableApi
* @returns {*}
*/
let getRows = function(tableApi){
let getRows = tableApi => {
let rows = tableApi.rows();
return rows;
};
@@ -916,7 +928,7 @@ define([
* @param tableApi
* @returns {*}
*/
let getSelectedRows = function(tableApi){
let getSelectedRows = tableApi => {
let selectedRows = tableApi.rows('.selected');
return selectedRows;
};
@@ -925,7 +937,7 @@ define([
* check the "delete signature" button. show/hide the button if a signature is selected
* @param moduleElement
*/
let checkDeleteSignaturesButton = function(moduleElement){
let checkDeleteSignaturesButton = moduleElement => {
moduleElement = $(moduleElement);
let signatureTableApi = getDataTableInstanceByModuleElement(moduleElement, 'primary');
@@ -967,11 +979,11 @@ define([
/**
* draw signature table toolbar (add signature button, scan progress bar
* @param moduleElement
* @param mapId
* @param systemData
*/
$.fn.drawSignatureTableToolbar = function(mapId, systemData){
let moduleElement = $(this);
let drawSignatureTableToolbar = (moduleElement, mapId, systemData) => {
// add toolbar buttons for table ------------------------------------------------------------------------------
let tableToolbar = $('<div>', {
@@ -1132,7 +1144,7 @@ define([
* @param element
* @param title
*/
let updateTooltip = function(element, title){
let updateTooltip = (element, title) => {
$(element).attr('data-container', 'body').attr('title', title.toUpperCase()).tooltip('fixTitle')
.tooltip('setContent');
};
@@ -1577,7 +1589,7 @@ define([
* @param groupId
* @returns {Array}
*/
let getAllSignatureNames = function(systemData, systemTypeId, areaId, groupId){
let getAllSignatureNames = (systemData, systemTypeId, areaId, groupId) => {
let newSelectOptions = [];
let cacheKey = [systemTypeId, areaId, groupId].join('_');
let newSelectOptionsCount = 0;
@@ -1666,8 +1678,9 @@ define([
// add static WH(s) for this system
if(systemData.statics){
let staticWHData = [];
for(let i = 0; i < systemData.statics.length; i++){
let staticWHName = systemData.statics[i].name + ' - ' + systemData.statics[i].security;
for(let wormholeName of systemData.statics) {
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
let staticWHName = wormholeData.name + ' - ' + wormholeData.security;
newSelectOptionsCount++;
staticWHData.push( {value: newSelectOptionsCount, text: staticWHName} );
@@ -1718,7 +1731,7 @@ define([
* @param obj
* @returns {number}
*/
let sumSignaturesRecursive = function(key, obj){
let sumSignaturesRecursive = (key, obj) => {
let sum = 0;
for (let prop in obj) {
@@ -1739,7 +1752,7 @@ define([
* @param systemTypeId
* @returns {{}}
*/
let getFrigateHolesBySystem = function(systemTypeId){
let getFrigateHolesBySystem = systemTypeId => {
let signatureNames = {};
if(Init.frigateWormholes[systemTypeId]){
@@ -1754,7 +1767,7 @@ define([
* @param tableApi
* @param rows
*/
let deleteSignatures = function(tableApi, rows){
let deleteSignatures = (tableApi, rows) => {
let deletedSignatures = 0;
let moduleElement = $('.' + config.moduleTypeClass);
@@ -1928,15 +1941,42 @@ define([
}
};
/**
* draw a signature table with data
* get unique column data from column object for select filter options
* @param column
* @returns {{}}
*/
let getColumnTableDataForFilter = column => {
// get all available options from column
let source = {};
column.data().unique().sort((a,b) => {
// sort alphabetically
let valA = a.filter.toLowerCase();
let valB = b.filter.toLowerCase();
if(valA < valB) return -1;
if(valA > valB) return 1;
return 0;
}).each(callData => {
if(callData.filter){
source[callData.filter] = callData.filter;
}
});
// add empty option
source[0] = '';
return source;
};
/**
* draw empty signature table
* @param moduleElement
* @param mapId
* @param signatureData
* @param systemData
*/
$.fn.drawSignatureTable = function(mapId, signatureData, systemData){
let moduleElement = $(this);
let drawSignatureTable = (moduleElement, mapId, systemData) => {
// setup filter select in footer
// column indexes that need a filter select
let filterColumnIndexes = [2];
@@ -1959,7 +1999,6 @@ define([
moduleElement.append(table);
let dataTableOptions = {
data: signatureData,
drawCallback: function(settings){
this.api().columns(filterColumnIndexes).every(function(){
let column = this;
@@ -2004,46 +2043,13 @@ define([
let signatureTable = table.dataTable(dataTableOptions);
let signatureTableApi = signatureTable.api();
setDataTableInstance(mapId, systemData.id, 'primary', signatureTableApi);
// make Table editable
signatureTable.makeEditable(signatureTableApi, systemData);
moduleElement.updateScannedSignaturesBar({showNotice: true});
};
/**
* get unique column data from column object for select filter options
* @param column
* @returns {{}}
*/
let getColumnTableDataForFilter = function(column){
// get all available options from column
let source = {};
column.data().unique().sort(function(a,b){
// sort alphabetically
let valA = a.filter.toLowerCase();
let valB = b.filter.toLowerCase();
if(valA < valB) return -1;
if(valA > valB) return 1;
return 0;
}).each(function(callData){
if(callData.filter){
source[callData.filter] = callData.filter;
}
});
// add empty option
source[0] = '';
return source;
};
/**
* setup dataTable options for all signatureTables
* @param systemData
*/
let initSignatureDataTable = function(systemData){
let initSignatureDataTable = systemData => {
$.extend( true, $.fn.dataTable.defaults, {
pageLength: -1,
@@ -2306,16 +2312,10 @@ define([
* @param moduleElement
* @param systemData
*/
let setModuleObserver = function(moduleElement, systemData){
let setModuleObserver = (moduleElement, systemData) => {
let tablePrimaryElement = moduleElement.find('.' + config.sigTablePrimaryClass);
let signatureTableApi = getDataTableInstanceByModuleElement(moduleElement, 'primary');
$(document).off('pf:updateSystemSignatureModule').on('pf:updateSystemSignatureModule', function(e, data){
if(data.signatures){
moduleElement.updateSignatureTable(data.signatures, true);
}
});
// set multi row select ---------------------------------------------------------------------------------------
tablePrimaryElement.on('click', 'tr', {moduleElement: moduleElement}, function(e){
if(e.ctrlKey) {
@@ -2355,7 +2355,7 @@ define([
* init callback
* @param moduleElement
* @param mapId
* @param connectionData
* @param systemData
*/
let initModule = (moduleElement, mapId, systemData) => {
unlockSignatureTable(true);
@@ -2386,41 +2386,19 @@ define([
moduleElement.data('mapId', mapId);
moduleElement.data('systemId', systemData.id);
moduleElement.showLoadingAnimation();
// init dataTables
initSignatureDataTable(systemData);
// draw "new signature" add table -----------------------------------------------------------------------------
// draw "new signature" add table
drawSignatureTableToolbar(moduleElement, mapId, systemData);
moduleElement.drawSignatureTableToolbar(mapId, systemData);
// draw signature table
drawSignatureTable(moduleElement, mapId, systemData);
// request signature data for system --------------------------------------------------------------------------
let requestData = {
systemIds: [systemData.id]
};
$.ajax({
type: 'POST',
url: Init.path.getSignatures,
data: requestData,
dataType: 'json',
context: {
mapId: mapId,
systemData: systemData
}
}).done(function(signatureData){
let signatureTableData = formatSignatureData(this.systemData, signatureData, fullSignatureOptions);
// draw signature table
moduleElement.drawSignatureTable(this.mapId, signatureTableData, this.systemData);
// set module observer
setModuleObserver(moduleElement, this.systemData);
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': Get signatures', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
});
// set module observer
setModuleObserver(moduleElement, systemData);
return moduleElement;
};
@@ -2450,6 +2428,7 @@ define([
getModule: getModule,
initModule: initModule,
beforeReDraw: beforeReDraw,
updateModule: updateModule,
beforeDestroy: beforeDestroy,
getAllSignatureNamesBySystem: getAllSignatureNamesBySystem
};

View File

@@ -41,6 +41,7 @@ define([
menuButtonMagnetizerId: 'pf-menu-button-magnetizer', // id for menu button "magnetizer"
menuButtonGridId: 'pf-menu-button-grid', // id for menu button "grid snap"
menuButtonEndpointId: 'pf-menu-button-endpoint', // id for menu button "endpoint" overlays
menuButtonCompactId: 'pf-menu-button-compact', // id for menu button "compact" UI map view
menuButtonMapDeleteId: 'pf-menu-button-map-delete', // id for menu button "delete map"
settingsMessageVelocityOptions: {
@@ -56,6 +57,9 @@ define([
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
mapClass: 'pf-map' , // class for all maps
// util
userStatusClass: 'pf-user-status', // class for player status
// select2
select2Class: 'pf-select2', // class for all "Select2" <select> elements
@@ -109,7 +113,7 @@ define([
class: [config.ajaxOverlayWrapperClass].join(' ')
}).append(
$('<i>', {
class: ['fas', 'fa-fw', iconSize, 'fa-sync', 'fa-spin'].join(' ')
class: ['fas', iconSize, 'fa-sync', 'fa-spin'].join(' ')
})
)
);
@@ -132,7 +136,6 @@ define([
return this.each(function(){
let loadingElement = $(this);
let overlay = loadingElement.find('.' + config.ajaxOverlayClass );
if(overlay.length){
// important: "stop" is required to stop "show" animation
// -> otherwise "complete" callback is not fired!
@@ -467,7 +470,6 @@ define([
* @returns {*}
*/
$.fn.initTooltips = function(options){
options = (typeof options === 'object') ? options : {};
let defaultOptions = {
@@ -482,6 +484,26 @@ define([
});
};
/**
* destroy popover elements
* @param recursive
* @returns {*}
*/
$.fn.destroyTooltip = function(recursive){
return this.each(function() {
let element = $(this);
let tooltipSelector = '[title]';
let tooltipElements = element.filter(tooltipSelector);
if(recursive){
tooltipElements = tooltipElements.add(element.find(tooltipSelector));
}
tooltipElements.each(function() {
$(this).tooltip('destroy');
});
});
};
/**
* adds a popup tooltip with character information (created/updated)
* @param tooltipData
@@ -585,7 +607,7 @@ define([
return elements.each(function() {
let element = $(this);
// check if tooltip already exists -> remove it
// check if popover already exists -> remove it
if(element.data('bs.popover') !== undefined){
element.off('click').popover('destroy');
}
@@ -658,6 +680,11 @@ define([
});
};
/**
* destroy popover elements
* @param recursive
* @returns {*}
*/
$.fn.destroyPopover = function(recursive){
return this.each(function() {
let element = $(this);
@@ -684,7 +711,6 @@ define([
$.fn.initPopoverClose = function(eventNamespace){
return this.each(function() {
$('body').off('click.' + eventNamespace).on('click.' + eventNamespace + ' contextmenu', function (e) {
$('.' + config.popoverTriggerClass).each(function () {
let popoverElement = $(this);
//the 'is' for buttons that trigger popups
@@ -938,6 +964,21 @@ define([
});
};
/**
* get hash from string
* @returns {number}
*/
String.prototype.hashCode = function() {
let hash = 0, i, chr;
if (this.length === 0) return hash;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
initPassiveEvents();
};
@@ -963,7 +1004,7 @@ define([
};
/**
* set default configuration for "Bootbox"
* set default configuration for "Bootbox"
*/
let initDefaultBootboxConfig = () => {
bootbox.setDefaults({
@@ -972,7 +1013,7 @@ define([
};
/**
* set default configuration for "Select2"
* set default configuration for "Select2"
*/
let initDefaultSelect2Config = () => {
$.fn.select2.defaults.set('theme', 'pathfinder');
@@ -999,6 +1040,15 @@ define([
autoHideScrollbar: false,
advanced: {
updateOnContentResize: true
},
callbacks: {
alwaysTriggerOffsets: false, // only trigger callback.onTotalScroll() once
onTotalScrollOffset: 300, // trigger callback.onTotalScroll() 100px before end
onTotalScroll: function(a){
// we want to "trigger" Select2´s 'scroll' event
// in order to make its "infinite scrolling" function working
this.mcs.content.find(':first-child').trigger('scroll');
}
}
});
};
@@ -1035,6 +1085,20 @@ define([
});
};
/**
* set default configuration for "xEditable"
*/
let initDefaultEditableConfig = () => {
// use fontAwesome buttons
$.fn.editableform.buttons =
'<button type="submit" class="btn btn-primary btn-sm editable-submit">'+
'<i class="fa fa-fw fa-check"></i>'+
'</button>'+
'<button type="button" class="btn btn-default btn-sm editable-cancel">'+
'<i class="fa fa-fw fa-times"></i>'+
'</button>';
};
/**
* get the current main trigger delay for the main trigger functions
* optional in/decrease the delay
@@ -1042,7 +1106,7 @@ define([
* @param value
* @returns {*}
*/
let getCurrentTriggerDelay = function( updateKey, value ){
let getCurrentTriggerDelay = (updateKey, value ) => {
// make sure the delay timer is valid!
// if this is called for the first time -> set CURRENT_DELAY
@@ -1068,7 +1132,7 @@ define([
* get date obj with current EVE Server Time.
* @returns {Date}
*/
let getServerTime = function(){
let getServerTime = () => {
// Server is running with GMT/UTC (EVE Time)
let localDate = new Date();
@@ -1090,7 +1154,7 @@ define([
* @param timestamp
* @returns {Date}
*/
let convertTimestampToServerTime = function(timestamp){
let convertTimestampToServerTime = timestamp => {
let currentTimeZoneOffsetInMinutes = new Date().getTimezoneOffset();
return new Date( (timestamp + (currentTimeZoneOffsetInMinutes * 60)) * 1000);
};
@@ -1101,7 +1165,7 @@ define([
* @param date2
* @returns {{}}
*/
let getTimeDiffParts = function(date1, date2){
let getTimeDiffParts = (date1, date2) => {
let parts = {};
let time1 = date1.getTime();
let time2 = date2.getTime();
@@ -1131,7 +1195,7 @@ define([
* start time measurement by a unique string identifier
* @param timerName
*/
let timeStart = function(timerName){
let timeStart = timerName => {
if(typeof performance === 'object'){
stopTimerCache[timerName] = performance.now();
@@ -1145,7 +1209,7 @@ define([
* @param timerName
* @returns {number}
*/
let timeStop = function(timerName){
let timeStop = timerName => {
let duration = 0;
@@ -1175,7 +1239,7 @@ define([
* @param charCounterElement
* @param maxCharLength
*/
let updateCounter = function(field, charCounterElement, maxCharLength){
let updateCounter = (field, charCounterElement, maxCharLength) => {
let value = field.val();
let inputLength = value.length;
@@ -1201,7 +1265,7 @@ define([
* @param logKey
* @param options
*/
let log = function(logKey, options){
let log = (logKey, options) => {
$(window).trigger('pf:log', [logKey, options]);
};
@@ -1210,8 +1274,8 @@ define([
* @param customConfig
* @param desktop
*/
let showNotify = function(customConfig, desktop){
requirejs(['notification'], function(Notification) {
let showNotify = (customConfig, desktop) => {
requirejs(['notification'], Notification => {
Notification.showNotify(customConfig, desktop);
});
};
@@ -1231,7 +1295,7 @@ define([
* @param option
* @returns {string}
*/
let getLogInfo = function(logType, option){
let getLogInfo = (logType, option) => {
let logInfo = '';
if(Init.classes.logTypes.hasOwnProperty(logType)){
@@ -1456,14 +1520,13 @@ define([
/**
* get all mapTabElements (<a> tags)
* or search for a specific tabElement within the
* mapModuleElement
* or search for a specific tabElement within mapModule
* @param mapId
* @returns {JQuery|*|{}|T}
*/
$.fn.getMapTabElements = function(mapId){
let mapModuleElement = $(this);
let mapTabElements = mapModuleElement.find('#' + config.mapTabBarId).find('a');
let mapModule = $(this);
let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a');
if(mapId){
// search for a specific tab element
@@ -1517,6 +1580,7 @@ define([
areaId = 12;
break;
case 'SH':
case 'C13':
areaId = 13;
break;
default:
@@ -1616,19 +1680,17 @@ define([
* @param data
* @returns {string}
*/
let getSystemEffectTable = function(data){
let getSystemEffectTable = effects => {
let table = '';
if(data.length > 0){
if(effects.length > 0){
table += '<table>';
for(let i = 0; i < data.length; i++){
for(let effect of effects){
table += '<tr>';
table += '<td>';
table += data[i].effect;
table += effect.effect;
table += '</td>';
table += '<td class="text-right">';
table += data[i].value;
table += effect.value;
table += '</td>';
table += '</tr>';
}
@@ -1638,13 +1700,85 @@ define([
return table;
};
/**
* get a HTML table with planet names
* e.g. for popover
* @param planets
* @returns {string}
*/
let getSystemPlanetsTable = planets => {
let table = '';
if(planets.length > 0){
table += '<table>';
for(let planet of planets){
table += '<tr>';
table += '<td>';
table += planet.name;
table += '</td>';
table += '<td class="text-right">';
table += planet.type.name;
table += '</td>';
table += '</tr>';
}
table += '</table>';
}
return table;
};
/**
* get a HTML table with pilots/ship names
* @param users
* @returns {string}
*/
let getSystemPilotsTable = users => {
let table = '';
if(users.length > 0){
let getRow = (statusClass, userName, shipName, shipTypeName, mass) => {
let row = '<tr>';
row += '<td class="text-right">';
row += '<small>';
row += statusClass !== null ? '<i class="fas fa-circle ' + config.userStatusClass + ' ' + statusClass + '">' : '';
row += '</small>';
row += '</td>';
row += '<td>';
row += userName;
row += '</td>';
row += '<td>';
row += shipName;
row += '</td>';
row += '<td class="text-right txt-color txt-color-orangeLight">';
row += shipTypeName;
row += '</td>';
row += '<td class="text-right">';
row += mass;
row += '</td>';
row += '</tr>';
return row;
};
let massAll = 0;
table += '<table>';
for(let user of users){
massAll += parseInt(user.log.ship.mass);
let statusClass = getStatusInfoForCharacter(user, 'class');
let mass = formatMassValue(user.log.ship.mass);
table += getRow(statusClass, user.name, user.log.ship.name, user.log.ship.typeName, mass);
}
table += getRow(null, '', '', '', formatMassValue(massAll));
table += '</table>';
}
return table;
};
/**
* get a HTML table with information for multiple systems
* e.g. for popover
* @param data
* @returns {string}
*/
let getSystemsInfoTable = function(data){
let getSystemsInfoTable = data => {
let table = '';
if(data.length > 0){
@@ -1678,7 +1812,7 @@ define([
* @param sec
* @returns {string}
*/
let getSecurityClassForSystem = (sec) => {
let getSecurityClassForSystem = sec => {
let secClass = '';
if( Init.classes.systemSecurity.hasOwnProperty(sec) ){
secClass = Init.classes.systemSecurity[sec]['class'];
@@ -2105,6 +2239,23 @@ define([
return nearBySystems;
};
/**
* get userData (pilots) from systemId
* @param userData
* @param systemId
* @returns {*}
*/
let getCharacterDataBySystemId = (userData, systemId) => {
if(userData && userData.length){
for(let i = 0; i < userData.length; i++){
if(userData[i].id === systemId){
return userData[i].user;
}
}
}
return [];
};
/**
* get current character data from all characters who are "nearby" the current user
* -> see getNearBySystemData()
@@ -2116,20 +2267,11 @@ define([
*/
let getNearByCharacterData = (nearBySystems, userData, jumps = 0, data = {}) => {
let getCharacterDataBySystemId = (systemId) => {
for(let i = 0; i < userData.length; i++){
if(userData[i].id === systemId){
return userData[i].user;
}
}
return [];
};
let filterFinalCharData = function(tmpFinalCharData){
return this.id !== tmpFinalCharData.id;
};
let characterData = getCharacterDataBySystemId(nearBySystems.systemData.systemId);
let characterData = getCharacterDataBySystemId(userData, nearBySystems.systemData.systemId);
if(characterData.length){
// filter (remove) characterData for "already" added chars
@@ -2568,6 +2710,7 @@ define([
initPrototypes: initPrototypes,
initDefaultBootboxConfig: initDefaultBootboxConfig,
initDefaultSelect2Config: initDefaultSelect2Config,
initDefaultEditableConfig: initDefaultEditableConfig,
getCurrentTriggerDelay: getCurrentTriggerDelay,
getServerTime: getServerTime,
convertTimestampToServerTime: convertTimestampToServerTime,
@@ -2588,6 +2731,8 @@ define([
getMapModule: getMapModule,
getSystemEffectData: getSystemEffectData,
getSystemEffectTable: getSystemEffectTable,
getSystemPlanetsTable: getSystemPlanetsTable,
getSystemPilotsTable: getSystemPilotsTable,
getSystemsInfoTable: getSystemsInfoTable,
getStatusInfoForCharacter: getStatusInfoForCharacter,
getSecurityClassForSystem: getSecurityClassForSystem,
@@ -2614,6 +2759,7 @@ define([
getCurrentUserInfo: getCurrentUserInfo,
getCurrentCharacterLog: getCurrentCharacterLog,
flattenXEditableSelectArray: flattenXEditableSelectArray,
getCharacterDataBySystemId: getCharacterDataBySystemId,
getNearBySystemData: getNearBySystemData,
getNearByCharacterData: getNearByCharacterData,
setDestination: setDestination,

File diff suppressed because one or more lines are too long

2
js/lib/jquery-3.3.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -51,19 +51,20 @@ $.fn.dragToSelect = function (conf) {
// Config
var config = $.extend({
className: 'pf-map-drag-to-select',
activeClass: 'active',
disabledClass: 'disabled',
selectedClass: 'pf-system-selected',
ignoredClass: 'pf-system-locked', // do not select locked systems
scrollTH: 10,
percentCovered: 25,
selectables: false,
autoScroll: false,
selectOnMove: false,
onShow: function () {return true;},
onHide: function () {return true;},
onRefresh: function () {return true;}
className: 'pf-map-drag-to-select',
activeClass: 'active',
disabledClass: 'disabled',
selectedClass: 'pf-system-selected',
ignoreLockedClass: 'pf-system-locked', // do not select locked systems
ignoreVisibleClass: 'pf-system-hidden', // do not select invisible systems
scrollTH: 10,
percentCovered: 25,
selectables: false,
autoScroll: false,
selectOnMove: false,
onShow: function () {return true;},
onHide: function () {return true;},
onRefresh: function () {return true;}
}, c);
var realParent = $(this);
@@ -248,7 +249,7 @@ $.fn.dragToSelect = function (conf) {
return;
}
var selectables = realParent.find(config.selectables + ':not(.' + config.ignoredClass + ')');
var selectables = realParent.find(config.selectables + ':not(.' + config.ignoreLockedClass + ')'+ ':not(.' + config.ignoreVisibleClass + ')');
var selectBoxOffset = selectBox.offset();
var selectBoxDim = {
left: selectBoxOffset.left,

View File

@@ -1,176 +1,164 @@
// Buttons
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.buttons', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.buttons', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
}
}(typeof window !== "undefined" ? window : this, function($, PNotify){
PNotify.prototype.options.buttons = {
// Provide a button for the user to manually close the notice.
closer: true,
// Only show the closer button on hover.
closer_hover: true,
// Provide a button for the user to manually stick the notice.
sticker: true,
// Only show the sticker button on hover.
sticker_hover: true,
// Show the buttons even when the nonblock module is in use.
show_on_nonblock: false,
// The various displayed text, helps facilitating internationalization.
labels: {
close: "Close",
stick: "Stick",
unstick: "Unstick"
},
// The classes to use for button icons. Leave them null to use the classes from the styling you're using.
classes: {
closer: null,
pin_up: null,
pin_down: null
}
}(this, function($, PNotify){
PNotify.prototype.options.buttons = {
// Provide a button for the user to manually close the notice.
closer: true,
// Only show the closer button on hover.
closer_hover: true,
// Provide a button for the user to manually stick the notice.
sticker: true,
// Only show the sticker button on hover.
sticker_hover: true,
// Show the buttons even when the nonblock module is in use.
show_on_nonblock: false,
// The various displayed text, helps facilitating internationalization.
labels: {
close: "Close",
stick: "Stick",
unstick: "Unstick"
};
PNotify.prototype.modules.buttons = {
init: function(notice, options){
var that = this;
notice.elem.on({
"mouseenter": function(e){
// Show the buttons.
if (that.options.sticker && (!(notice.options.nonblock && notice.options.nonblock.nonblock) || that.options.show_on_nonblock)) {
that.sticker.trigger("pnotify:buttons:toggleStick").css("visibility", "visible");
}
if (that.options.closer && (!(notice.options.nonblock && notice.options.nonblock.nonblock) || that.options.show_on_nonblock)) {
that.closer.css("visibility", "visible");
}
},
// The classes to use for button icons. Leave them null to use the classes from the styling you're using.
classes: {
closer: null,
pin_up: null,
pin_down: null
"mouseleave": function(e){
// Hide the buttons.
if (that.options.sticker_hover) {
that.sticker.css("visibility", "hidden");
}
if (that.options.closer_hover) {
that.closer.css("visibility", "hidden");
}
}
};
PNotify.prototype.modules.buttons = {
closer: null,
sticker: null,
});
init: function(notice, options){
var that = this;
notice.elem.on({
"mouseenter": function(e){
// Show the buttons.
if (that.options.sticker && (!(notice.options.nonblock && notice.options.nonblock.nonblock) || that.options.show_on_nonblock)) {
that.sticker.trigger("pnotify:buttons:toggleStick").css("visibility", "visible");
}
if (that.options.closer && (!(notice.options.nonblock && notice.options.nonblock.nonblock) || that.options.show_on_nonblock)) {
that.closer.css("visibility", "visible");
}
},
"mouseleave": function(e){
// Hide the buttons.
if (that.options.sticker_hover) {
that.sticker.css("visibility", "hidden");
}
if (that.options.closer_hover) {
that.closer.css("visibility", "hidden");
}
}
});
// Provide a button to stick the notice.
this.sticker = $("<div />", {
"class": "ui-pnotify-sticker",
"aria-role": "button",
"aria-pressed": notice.options.hide ? "false" : "true",
"tabindex": "0",
"title": notice.options.hide ? options.labels.stick : options.labels.unstick,
"css": {
"cursor": "pointer",
"visibility": options.sticker_hover ? "hidden" : "visible"
},
"click": function(){
notice.options.hide = !notice.options.hide;
if (notice.options.hide) {
notice.queueRemove();
} else {
notice.cancelRemove();
}
$(this).trigger("pnotify:buttons:toggleStick");
}
})
.bind("pnotify:buttons:toggleStick", function(){
var pin_up = that.options.classes.pin_up === null ? notice.styles.pin_up : that.options.classes.pin_up;
var pin_down = that.options.classes.pin_down === null ? notice.styles.pin_down : that.options.classes.pin_down;
$(this)
.attr("title", notice.options.hide ? that.options.labels.stick : that.options.labels.unstick)
.children()
.attr("class", "")
.addClass(notice.options.hide ? pin_up : pin_down)
.attr("aria-pressed", notice.options.hide ? "false" : "true");
})
.append("<span />")
.trigger("pnotify:buttons:toggleStick")
.prependTo(notice.container);
if (!options.sticker || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.sticker.css("display", "none");
}
// Provide a button to close the notice.
this.closer = $("<div />", {
"class": "ui-pnotify-closer",
"aria-role": "button",
"tabindex": "0",
"title": options.labels.close,
"css": {"cursor": "pointer", "visibility": options.closer_hover ? "hidden" : "visible"},
"click": function(){
notice.remove(false);
that.sticker.css("visibility", "hidden");
that.closer.css("visibility", "hidden");
}
})
.append($("<span />", {"class": options.classes.closer === null ? notice.styles.closer : options.classes.closer}))
.prependTo(notice.container);
if (!options.closer || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.closer.css("display", "none");
}
// Provide a button to stick the notice.
this.sticker = $("<div />", {
"class": "ui-pnotify-sticker",
"aria-role": "button",
"aria-pressed": notice.options.hide ? "false" : "true",
"tabindex": "0",
"title": notice.options.hide ? options.labels.stick : options.labels.unstick,
"css": {
"cursor": "pointer",
"visibility": options.sticker_hover ? "hidden" : "visible"
},
update: function(notice, options){
// Update the sticker and closer buttons.
if (!options.closer || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.closer.css("display", "none");
} else if (options.closer) {
this.closer.css("display", "block");
}
if (!options.sticker || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.sticker.css("display", "none");
} else if (options.sticker) {
this.sticker.css("display", "block");
}
// Update the sticker icon.
this.sticker.trigger("pnotify:buttons:toggleStick");
// Update the close icon.
this.closer.find("span").attr("class", "").addClass(options.classes.closer === null ? notice.styles.closer : options.classes.closer);
// Update the hover status of the buttons.
if (options.sticker_hover) {
this.sticker.css("visibility", "hidden");
} else if (!(notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.sticker.css("visibility", "visible");
}
if (options.closer_hover) {
this.closer.css("visibility", "hidden");
} else if (!(notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.closer.css("visibility", "visible");
}
"click": function(){
notice.options.hide = !notice.options.hide;
if (notice.options.hide) {
notice.queueRemove();
} else {
notice.cancelRemove();
}
$(this).trigger("pnotify:buttons:toggleStick");
}
};
$.extend(PNotify.styling.brighttheme, {
closer: "brighttheme-icon-closer",
pin_up: "brighttheme-icon-sticker",
pin_down: "brighttheme-icon-sticker brighttheme-icon-stuck"
});
$.extend(PNotify.styling.jqueryui, {
closer: "ui-icon ui-icon-close",
pin_up: "ui-icon ui-icon-pin-w",
pin_down: "ui-icon ui-icon-pin-s"
});
$.extend(PNotify.styling.bootstrap2, {
closer: "icon-remove",
pin_up: "icon-pause",
pin_down: "icon-play"
});
$.extend(PNotify.styling.bootstrap3, {
closer: "glyphicon glyphicon-remove",
pin_up: "glyphicon glyphicon-pause",
pin_down: "glyphicon glyphicon-play"
});
$.extend(PNotify.styling.fontawesome, {
closer: "fas fa-times",
pin_up: "fas fa-pause",
pin_down: "fas fa-play"
});
})
.bind("pnotify:buttons:toggleStick", function(){
var pin_up = that.options.classes.pin_up === null ? notice.styles.pin_up : that.options.classes.pin_up;
var pin_down = that.options.classes.pin_down === null ? notice.styles.pin_down : that.options.classes.pin_down;
$(this)
.attr("title", notice.options.hide ? that.options.labels.stick : that.options.labels.unstick)
.children()
.attr("class", "")
.addClass(notice.options.hide ? pin_up : pin_down)
.attr("aria-pressed", notice.options.hide ? "false" : "true");
})
.append("<span />")
.trigger("pnotify:buttons:toggleStick")
.prependTo(notice.container);
if (!options.sticker || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.sticker.css("display", "none");
}
// Provide a button to close the notice.
this.closer = $("<div />", {
"class": "ui-pnotify-closer",
"aria-role": "button",
"tabindex": "0",
"title": options.labels.close,
"css": {"cursor": "pointer", "visibility": options.closer_hover ? "hidden" : "visible"},
"click": function(){
notice.remove(false);
that.sticker.css("visibility", "hidden");
that.closer.css("visibility", "hidden");
}
})
.append($("<span />", {"class": options.classes.closer === null ? notice.styles.closer : options.classes.closer}))
.prependTo(notice.container);
if (!options.closer || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.closer.css("display", "none");
}
},
update: function(notice, options){
// Update the sticker and closer buttons.
if (!options.closer || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.closer.css("display", "none");
} else if (options.closer) {
this.closer.css("display", "block");
}
if (!options.sticker || (notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.sticker.css("display", "none");
} else if (options.sticker) {
this.sticker.css("display", "block");
}
// Update the sticker icon.
this.sticker.trigger("pnotify:buttons:toggleStick");
// Update the close icon.
this.closer.find("span").attr("class", "").addClass(options.classes.closer === null ? notice.styles.closer : options.classes.closer);
// Update the hover status of the buttons.
if (options.sticker_hover) {
this.sticker.css("visibility", "hidden");
} else if (!(notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.sticker.css("visibility", "visible");
}
if (options.closer_hover) {
this.closer.css("visibility", "hidden");
} else if (!(notice.options.nonblock && notice.options.nonblock.nonblock && !options.show_on_nonblock)) {
this.closer.css("visibility", "visible");
}
}
};
$.extend(PNotify.styling.brighttheme, {
closer: "brighttheme-icon-closer",
pin_up: "brighttheme-icon-sticker",
pin_down: "brighttheme-icon-sticker brighttheme-icon-stuck"
});
$.extend(PNotify.styling.bootstrap3, {
closer: "glyphicon glyphicon-remove",
pin_up: "glyphicon glyphicon-pause",
pin_down: "glyphicon glyphicon-play"
});
$.extend(PNotify.styling.fontawesome, {
closer: "fa fa-times",
pin_up: "fa fa-pause",
pin_down: "fa fa-play"
});
return PNotify;
}));

View File

@@ -1,50 +1,51 @@
// Callbacks
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.callbacks', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
}
}(this, function($, PNotify){
var _init = PNotify.prototype.init,
_open = PNotify.prototype.open,
_remove = PNotify.prototype.remove;
PNotify.prototype.init = function(){
if (this.options.before_init) {
this.options.before_init(this.options);
}
_init.apply(this, arguments);
if (this.options.after_init) {
this.options.after_init(this);
}
};
PNotify.prototype.open = function(){
var ret;
if (this.options.before_open) {
ret = this.options.before_open(this);
}
if (ret !== false) {
_open.apply(this, arguments);
if (this.options.after_open) {
this.options.after_open(this);
}
}
};
PNotify.prototype.remove = function(timer_hide){
var ret;
if (this.options.before_close) {
ret = this.options.before_close(this, timer_hide);
}
if (ret !== false) {
_remove.apply(this, arguments);
if (this.options.after_close) {
this.options.after_close(this, timer_hide);
}
}
};
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.callbacks', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
}
}(typeof window !== "undefined" ? window : this, function($, PNotify){
var _init = PNotify.prototype.init,
_open = PNotify.prototype.open,
_remove = PNotify.prototype.remove;
PNotify.prototype.init = function(){
if (this.options.before_init) {
this.options.before_init(this.options);
}
_init.apply(this, arguments);
if (this.options.after_init) {
this.options.after_init(this);
}
};
PNotify.prototype.open = function(){
var ret;
if (this.options.before_open) {
ret = this.options.before_open(this);
}
if (ret !== false) {
_open.apply(this, arguments);
if (this.options.after_open) {
this.options.after_open(this);
}
}
};
PNotify.prototype.remove = function(timer_hide){
var ret;
if (this.options.before_close) {
ret = this.options.before_close(this, timer_hide);
}
if (ret !== false) {
_remove.apply(this, arguments);
if (this.options.after_close) {
this.options.after_close(this, timer_hide);
}
}
};
return PNotify;
}));

View File

@@ -1,154 +1,157 @@
// Desktop
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.desktop', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
}
}(this, function($, PNotify){
var permission;
var notify = function(title, options){
// Memoize based on feature detection.
if ("Notification" in window) {
notify = function (title, options) {
return new Notification(title, options);
};
} else if ("mozNotification" in navigator) {
notify = function (title, options) {
// Gecko < 22
return navigator.mozNotification
.createNotification(title, options.body, options.icon)
.show();
};
} else if ("webkitNotifications" in window) {
notify = function (title, options) {
return window.webkitNotifications.createNotification(
options.icon,
title,
options.body
);
};
} else {
notify = function (title, options) {
return null;
};
}
return notify(title, options);
};
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.desktop', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
}
}(typeof window !== "undefined" ? window : this, function($, PNotify){
var permission;
var notify = function(title, options){
// Memoize based on feature detection.
if ("Notification" in window) {
notify = function (title, options) {
return new Notification(title, options);
};
} else if ("mozNotification" in navigator) {
notify = function (title, options) {
// Gecko < 22
return navigator.mozNotification
.createNotification(title, options.body, options.icon)
.show();
};
} else if ("webkitNotifications" in window) {
notify = function (title, options) {
return window.webkitNotifications.createNotification(
options.icon,
title,
options.body
);
};
} else {
notify = function (title, options) {
return null;
};
}
return notify(title, options);
};
PNotify.prototype.options.desktop = {
// Display the notification as a desktop notification.
desktop: false,
// If desktop notifications are not supported or allowed, fall back to a regular notice.
fallback: true,
// The URL of the icon to display. If false, no icon will show. If null, a default icon will show.
icon: null,
// Using a tag lets you update an existing notice, or keep from duplicating notices between tabs.
// If you leave tag null, one will be generated, facilitating the "update" function.
// see: http://www.w3.org/TR/notifications/#tags-example
tag: null
};
PNotify.prototype.modules.desktop = {
tag: null,
icon: null,
genNotice: function(notice, options){
if (options.icon === null) {
this.icon = "http://sciactive.com/pnotify/includes/desktop/"+notice.options.type+".png";
} else if (options.icon === false) {
this.icon = null;
} else {
this.icon = options.icon;
}
if (this.tag === null || options.tag !== null) {
this.tag = options.tag === null ? "PNotify-"+Math.round(Math.random() * 1000000) : options.tag;
}
notice.desktop = notify(notice.options.title, {
icon: this.icon,
body: options.text || notice.options.text,
tag: this.tag
});
if (!("close" in notice.desktop) && ("cancel" in notice.desktop)) {
notice.desktop.close = function(){
notice.desktop.cancel();
};
}
notice.desktop.onclick = function(){
notice.elem.trigger("click");
};
notice.desktop.onclose = function(){
if (notice.state !== "closing" && notice.state !== "closed") {
notice.remove();
}
};
},
init: function(notice, options){
if (!options.desktop)
return;
permission = PNotify.desktop.checkPermission();
if (permission !== 0) {
// Keep the notice from opening if fallback is false.
if (!options.fallback) {
notice.options.auto_display = false;
}
return;
}
this.genNotice(notice, options);
},
update: function(notice, options, oldOpts){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
this.genNotice(notice, options);
},
beforeOpen: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
},
afterOpen: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
if ("show" in notice.desktop) {
notice.desktop.show();
}
},
beforeClose: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
},
afterClose: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
if ("close" in notice.desktop) {
notice.desktop.close();
}
}
};
PNotify.desktop = {
permission: function(){
if (typeof Notification !== "undefined" && "requestPermission" in Notification) {
Notification.requestPermission();
} else if ("webkitNotifications" in window) {
window.webkitNotifications.requestPermission();
}
},
checkPermission: function(){
if (typeof Notification !== "undefined" && "permission" in Notification) {
return (Notification.permission === "granted" ? 0 : 1);
} else if ("webkitNotifications" in window) {
return window.webkitNotifications.checkPermission() == 0 ? 0 : 1;
} else {
return 1;
}
}
};
permission = PNotify.desktop.checkPermission();
PNotify.prototype.options.desktop = {
// Display the notification as a desktop notification.
desktop: false,
// If desktop notifications are not supported or allowed, fall back to a regular notice.
fallback: true,
// The URL of the icon to display. If false, no icon will show. If null, a default icon will show.
icon: null,
// Using a tag lets you update an existing notice, or keep from duplicating notices between tabs.
// If you leave tag null, one will be generated, facilitating the "update" function.
// see: http://www.w3.org/TR/notifications/#tags-example
tag: null,
// Optionally display a different title for the desktop.
title: null,
// Optionally display different text for the desktop.
text: null
};
PNotify.prototype.modules.desktop = {
genNotice: function(notice, options){
if (options.icon === null) {
this.icon = "http://sciactive.com/pnotify/includes/desktop/"+notice.options.type+".png";
} else if (options.icon === false) {
this.icon = null;
} else {
this.icon = options.icon;
}
if (this.tag === null || options.tag !== null) {
this.tag = options.tag === null ? "PNotify-"+Math.round(Math.random() * 1000000) : options.tag;
}
notice.desktop = notify(options.title || notice.options.title, {
icon: this.icon,
body: options.text || notice.options.text,
tag: this.tag
});
if (!("close" in notice.desktop) && ("cancel" in notice.desktop)) {
notice.desktop.close = function(){
notice.desktop.cancel();
};
}
notice.desktop.onclick = function(){
notice.elem.trigger("click");
};
notice.desktop.onclose = function(){
if (notice.state !== "closing" && notice.state !== "closed") {
notice.remove();
}
};
},
init: function(notice, options){
if (!options.desktop)
return;
permission = PNotify.desktop.checkPermission();
if (permission !== 0) {
// Keep the notice from opening if fallback is false.
if (!options.fallback) {
notice.options.auto_display = false;
}
return;
}
this.genNotice(notice, options);
},
update: function(notice, options, oldOpts){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
this.genNotice(notice, options);
},
beforeOpen: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
},
afterOpen: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
if ("show" in notice.desktop) {
notice.desktop.show();
}
},
beforeClose: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
},
afterClose: function(notice, options){
if ((permission !== 0 && options.fallback) || !options.desktop)
return;
notice.elem.css({'left': '-10000px'}).removeClass('ui-pnotify-in');
if ("close" in notice.desktop) {
notice.desktop.close();
}
}
};
PNotify.desktop = {
permission: function(){
if (typeof Notification !== "undefined" && "requestPermission" in Notification) {
Notification.requestPermission();
} else if ("webkitNotifications" in window) {
window.webkitNotifications.requestPermission();
}
},
checkPermission: function(){
if (typeof Notification !== "undefined" && "permission" in Notification) {
return (Notification.permission === "granted" ? 0 : 1);
} else if ("webkitNotifications" in window) {
return window.webkitNotifications.checkPermission() == 0 ? 0 : 1;
} else {
return 1;
}
}
};
permission = PNotify.desktop.checkPermission();
return PNotify;
}));

File diff suppressed because it is too large Load Diff

View File

@@ -1,156 +1,157 @@
// Nonblock
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.nonblock', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
}
}(this, function($, PNotify){
// Some useful regexes.
var re_on = /^on/,
re_mouse_events = /^(dbl)?click$|^mouse(move|down|up|over|out|enter|leave)$|^contextmenu$/,
re_ui_events = /^(focus|blur|select|change|reset)$|^key(press|down|up)$/,
re_html_events = /^(scroll|resize|(un)?load|abort|error)$/;
// Fire a DOM event.
var dom_event = function(e, orig_e){
var event_object;
e = e.toLowerCase();
if (document.createEvent && this.dispatchEvent) {
// FireFox, Opera, Safari, Chrome
e = e.replace(re_on, '');
if (e.match(re_mouse_events)) {
// This allows the click event to fire on the notice. There is
// probably a much better way to do it.
$(this).offset();
event_object = document.createEvent("MouseEvents");
event_object.initMouseEvent(
e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail,
orig_e.screenX, orig_e.screenY, orig_e.clientX, orig_e.clientY,
orig_e.ctrlKey, orig_e.altKey, orig_e.shiftKey, orig_e.metaKey, orig_e.button, orig_e.relatedTarget
);
} else if (e.match(re_ui_events)) {
event_object = document.createEvent("UIEvents");
event_object.initUIEvent(e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail);
} else if (e.match(re_html_events)) {
event_object = document.createEvent("HTMLEvents");
event_object.initEvent(e, orig_e.bubbles, orig_e.cancelable);
}
if (!event_object) return;
this.dispatchEvent(event_object);
} else {
// Internet Explorer
if (!e.match(re_on)) e = "on"+e;
event_object = document.createEventObject(orig_e);
this.fireEvent(e, event_object);
}
};
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module.
define('pnotify.nonblock', ['jquery', 'pnotify'], factory);
} else if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory(require('jquery'), require('./pnotify'));
} else {
// Browser globals
factory(root.jQuery, root.PNotify);
}
}(typeof window !== "undefined" ? window : this, function($, PNotify){
// Some useful regexes.
var re_on = /^on/,
re_mouse_events = /^(dbl)?click$|^mouse(move|down|up|over|out|enter|leave)$|^contextmenu$/,
re_ui_events = /^(focus|blur|select|change|reset)$|^key(press|down|up)$/,
re_html_events = /^(scroll|resize|(un)?load|abort|error)$/;
// Fire a DOM event.
var dom_event = function(e, orig_e){
var event_object;
e = e.toLowerCase();
if (document.createEvent && this.dispatchEvent) {
// FireFox, Opera, Safari, Chrome
e = e.replace(re_on, '');
if (e.match(re_mouse_events)) {
// This allows the click event to fire on the notice. There is
// probably a much better way to do it.
$(this).offset();
event_object = document.createEvent("MouseEvents");
event_object.initMouseEvent(
e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail,
orig_e.screenX, orig_e.screenY, orig_e.clientX, orig_e.clientY,
orig_e.ctrlKey, orig_e.altKey, orig_e.shiftKey, orig_e.metaKey, orig_e.button, orig_e.relatedTarget
);
} else if (e.match(re_ui_events)) {
event_object = document.createEvent("UIEvents");
event_object.initUIEvent(e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail);
} else if (e.match(re_html_events)) {
event_object = document.createEvent("HTMLEvents");
event_object.initEvent(e, orig_e.bubbles, orig_e.cancelable);
}
if (!event_object) return;
this.dispatchEvent(event_object);
} else {
// Internet Explorer
if (!e.match(re_on)) e = "on"+e;
event_object = document.createEventObject(orig_e);
this.fireEvent(e, event_object);
}
};
// This keeps track of the last element the mouse was over, so
// mouseleave, mouseenter, etc can be called.
var nonblock_last_elem;
// This is used to pass events through the notice if it is non-blocking.
var nonblock_pass = function(notice, e, e_name){
notice.elem.addClass("ui-pnotify-nonblock-hide");
var element_below = document.elementFromPoint(e.clientX, e.clientY);
notice.elem.removeClass("ui-pnotify-nonblock-hide");
var jelement_below = $(element_below);
var cursor_style = jelement_below.css("cursor");
if (cursor_style === "auto" && element_below.tagName === "A") {
cursor_style = "pointer";
}
notice.elem.css("cursor", cursor_style !== "auto" ? cursor_style : "default");
// If the element changed, call mouseenter, mouseleave, etc.
if (!nonblock_last_elem || nonblock_last_elem.get(0) != element_below) {
if (nonblock_last_elem) {
dom_event.call(nonblock_last_elem.get(0), "mouseleave", e.originalEvent);
dom_event.call(nonblock_last_elem.get(0), "mouseout", e.originalEvent);
}
dom_event.call(element_below, "mouseenter", e.originalEvent);
dom_event.call(element_below, "mouseover", e.originalEvent);
}
dom_event.call(element_below, e_name, e.originalEvent);
// Remember the latest element the mouse was over.
nonblock_last_elem = jelement_below;
};
// This keeps track of the last element the mouse was over, so
// mouseleave, mouseenter, etc can be called.
var nonblock_last_elem;
// This is used to pass events through the notice if it is non-blocking.
var nonblock_pass = function(notice, e, e_name){
notice.elem.addClass("ui-pnotify-nonblock-hide");
var element_below = document.elementFromPoint(e.clientX, e.clientY);
notice.elem.removeClass("ui-pnotify-nonblock-hide");
var jelement_below = $(element_below);
var cursor_style = jelement_below.css("cursor");
if (cursor_style === "auto" && element_below.tagName === "A") {
cursor_style = "pointer";
}
notice.elem.css("cursor", cursor_style !== "auto" ? cursor_style : "default");
// If the element changed, call mouseenter, mouseleave, etc.
if (!nonblock_last_elem || nonblock_last_elem.get(0) != element_below) {
if (nonblock_last_elem) {
dom_event.call(nonblock_last_elem.get(0), "mouseleave", e.originalEvent);
dom_event.call(nonblock_last_elem.get(0), "mouseout", e.originalEvent);
}
dom_event.call(element_below, "mouseenter", e.originalEvent);
dom_event.call(element_below, "mouseover", e.originalEvent);
}
dom_event.call(element_below, e_name, e.originalEvent);
// Remember the latest element the mouse was over.
nonblock_last_elem = jelement_below;
};
PNotify.prototype.options.nonblock = {
// Create a non-blocking notice. It lets the user click elements underneath it.
nonblock: false
};
PNotify.prototype.modules.nonblock = {
init: function(notice, options){
var that = this;
notice.elem.on({
"mouseenter": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
if (that.options.nonblock) {
// If it's non-blocking, animate to the other opacity.
notice.elem.addClass("ui-pnotify-nonblock-fade");
}
},
"mouseleave": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
nonblock_last_elem = null;
notice.elem.css("cursor", "auto");
// Animate back to the normal opacity.
if (that.options.nonblock && notice.animating !== "out") {
notice.elem.removeClass("ui-pnotify-nonblock-fade");
}
},
"mouseover": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
},
"mouseout": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
},
"mousemove": function(e){
if (that.options.nonblock) {
e.stopPropagation();
nonblock_pass(notice, e, "onmousemove");
}
},
"mousedown": function(e){
if (that.options.nonblock) {
e.stopPropagation();
e.preventDefault();
nonblock_pass(notice, e, "onmousedown");
}
},
"mouseup": function(e){
if (that.options.nonblock) {
e.stopPropagation();
e.preventDefault();
nonblock_pass(notice, e, "onmouseup");
}
},
"click": function(e){
if (that.options.nonblock) {
e.stopPropagation();
nonblock_pass(notice, e, "onclick");
}
},
"dblclick": function(e){
if (that.options.nonblock) {
e.stopPropagation();
nonblock_pass(notice, e, "ondblclick");
}
}
});
}
};
PNotify.prototype.options.nonblock = {
// Create a non-blocking notice. It lets the user click elements underneath it.
nonblock: false
};
PNotify.prototype.modules.nonblock = {
init: function(notice, options){
var that = this;
notice.elem.on({
"mouseenter": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
if (that.options.nonblock) {
// If it's non-blocking, animate to the other opacity.
notice.elem.addClass("ui-pnotify-nonblock-fade");
}
},
"mouseleave": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
nonblock_last_elem = null;
notice.elem.css("cursor", "auto");
// Animate back to the normal opacity.
if (that.options.nonblock && notice.animating !== "out") {
notice.elem.removeClass("ui-pnotify-nonblock-fade");
}
},
"mouseover": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
},
"mouseout": function(e){
if (that.options.nonblock) {
e.stopPropagation();
}
},
"mousemove": function(e){
if (that.options.nonblock) {
e.stopPropagation();
nonblock_pass(notice, e, "onmousemove");
}
},
"mousedown": function(e){
if (that.options.nonblock) {
e.stopPropagation();
e.preventDefault();
nonblock_pass(notice, e, "onmousedown");
}
},
"mouseup": function(e){
if (that.options.nonblock) {
e.stopPropagation();
e.preventDefault();
nonblock_pass(notice, e, "onmouseup");
}
},
"click": function(e){
if (that.options.nonblock) {
e.stopPropagation();
nonblock_pass(notice, e, "onclick");
}
},
"dblclick": function(e){
if (that.options.nonblock) {
e.stopPropagation();
nonblock_pass(notice, e, "ondblclick");
}
}
});
}
};
return PNotify;
}));

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 493 KiB

After

Width:  |  Height:  |  Size: 586 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.0.2 by @fontawesome - http://fontawesome.com
License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
Font Awesome Free 5.0.13 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
@@ -15,10 +15,10 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
<missing-glyph horiz-adv-x="0" />
<glyph glyph-name="address-book"
unicode="&#xF2B9;"
horiz-adv-x="448" d=" M320 128V56C320 42.745 309.255 32 296 32H152C138.745 32 128 42.745 128 56V128C128 149.431 142.207 168.266 162.813 174.153L180.877 179.314C193.629 172.116 208.342 168 224 168S254.371 172.116 267.122 179.314L285.1860000000001 174.153C305.793 168.266 320 149.431 320 128zM224 192C259.346 192 288 220.654 288 256S259.346 320 224 320S160 291.346 160 256S188.654 192 224 192zM416 288V224H436C442.627 224 448 218.627 448 212V172C448 165.373 442.627 160 436 160H416V96H436C442.627 96 448 90.627 448 84V44C448 37.373 442.627 32 436 32H416V-16C416 -42.51 394.51 -64 368 -64H80C53.49 -64 32 -42.51 32 -16V400C32 426.51 53.49 448 80 448H368C394.51 448 416 426.51 416 400V352H436C442.627 352 448 346.627 448 340V300C448 293.373 442.627 288 436 288H416zM368 -10V394A6 6 0 0 1 362 400H86A6 6 0 0 1 80 394V-10A6 6 0 0 1 86 -16H362A6 6 0 0 1 368 -10z" />
horiz-adv-x="448" d=" M436 288C442.6 288 448 293.4 448 300V340C448 346.6 442.6 352 436 352H416V400C416 426.5 394.5 448 368 448H48C21.5 448 0 426.5 0 400V-16C0 -42.5 21.5 -64 48 -64H368C394.5 -64 416 -42.5 416 -16V32H436C442.6 32 448 37.4 448 44V84C448 90.6 442.6 96 436 96H416V160H436C442.6 160 448 165.4 448 172V212C448 218.6 442.6 224 436 224H416V288H436zM368 -16H48V400H368V-16zM208 192C243.3 192 272 220.7 272 256S243.3 320 208 320S144 291.3 144 256S172.7 192 208 192zM118.4 64H297.6C310 64 320 72.6 320 83.2V102.4C320 134.2 289.9 160 252.8 160C242 160 234.1 152 208 152C181.1 152 174.6 160 163.2 160C126.1 160 96 134.2 96 102.4V83.2C96 72.6 106 64 118.4 64z" />
<glyph glyph-name="address-card"
unicode="&#xF2BB;"
horiz-adv-x="512" d=" M464 384H48C21.49 384 0 362.51 0 336V48C0 21.49 21.49 0 48 0H464C490.51 0 512 21.49 512 48V336C512 362.51 490.51 384 464 384zM458 48H54A6 6 0 0 0 48 54V330A6 6 0 0 0 54 336H458A6 6 0 0 0 464 330V54A6 6 0 0 0 458 48zM404 224H300C293.373 224 288 229.373 288 236V260C288 266.627 293.373 272 300 272H404C410.627 272 416 266.627 416 260V236C416 229.373 410.627 224 404 224zM404 144H300C293.373 144 288 149.373 288 156V180C288 186.627 293.373 192 300 192H404C410.627 192 416 186.627 416 180V156C416 149.373 410.627 144 404 144zM120 240C120 270.928 145.072 296 176 296S232 270.928 232 240S206.928 184 176 184S120 209.072 120 240zM256 150.143V108C256 101.373 250.627 96 244 96H108C101.373 96 96 101.373 96 108V150.143A24 24 0 0 0 113.104 173.131L126.568 177.17C140.186 166.432 157.351 160 176 160S211.814 166.432 225.433 177.17L238.897 173.131A24 24 0 0 0 256 150.143z" />
horiz-adv-x="576" d=" M528 416H48C21.5 416 0 394.5 0 368V16C0 -10.5 21.5 -32 48 -32H528C554.5 -32 576 -10.5 576 16V368C576 394.5 554.5 416 528 416zM528 16H48V368H528V16zM208 192C243.3 192 272 220.7 272 256S243.3 320 208 320S144 291.3 144 256S172.7 192 208 192zM118.4 64H297.6C310 64 320 72.6 320 83.2V102.4C320 134.2 289.9 160 252.8 160C242 160 234.1 152 208 152C181.1 152 174.6 160 163.2 160C126.1 160 96 134.2 96 102.4V83.2C96 72.6 106 64 118.4 64zM360 128H472C476.4 128 480 131.6 480 136V152C480 156.4 476.4 160 472 160H360C355.6 160 352 156.4 352 152V136C352 131.6 355.6 128 360 128zM360 192H472C476.4 192 480 195.6 480 200V216C480 220.4 476.4 224 472 224H360C355.6 224 352 220.4 352 216V200C352 195.6 355.6 192 360 192zM360 256H472C476.4 256 480 259.6 480 264V280C480 284.4 476.4 288 472 288H360C355.6 288 352 284.4 352 280V264C352 259.6 355.6 256 360 256z" />
<glyph glyph-name="arrow-alt-circle-down"
unicode="&#xF358;"
horiz-adv-x="512" d=" M256 440C119 440 8 329 8 192S119 -56 256 -56S504 55 504 192S393 440 256 440zM256 -8C145.5 -8 56 81.5 56 192S145.5 392 256 392S456 302.5 456 192S366.5 -8 256 -8zM224 308V192H157C146.3 192 141 179.1 148.5 171.5L247.5 72.5C252.2 67.8 259.8 67.8 264.5 72.5L363.5 171.5C371.1 179.1 365.7 192 355 192H288V308C288 314.6 282.6 320 276 320H236C229.4 320 224 314.6 224 308z" />
@@ -99,13 +99,16 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
horiz-adv-x="512" d=" M464 384H48C21.5 384 0 362.5 0 336V48C0 21.5 21.5 0 48 0H464C490.5 0 512 21.5 512 48V336C512 362.5 490.5 384 464 384zM458 48H54C50.7 48 48 50.7 48 54V330C48 333.3 50.7 336 54 336H458C461.3 336 464 333.3 464 330V54C464 50.7 461.3 48 458 48zM246.9 133.7C248.6 131.3 248.4 128.1 246.4 126C192.8 69.2 73.6 93.9 73.6 193.9C73.6 291.2 195.3 313.4 246.1 264C248.2 262 248.6 260.8 247.1 258.3L229.6 227.8C227.7 224.7 223.4 223.8 220.5 226.1C179.7 258.1 125.9 241.0000000000001 125.9 194.9C125.9 146.9 176.9 124.4 218.1 162.3C220.9 164.8 225.2 164.4 227.3 161.4L246.9 133.7000000000001zM437.3 133.7C439 131.3 438.8 128.1 436.8 126C383.2 69.1 264 93.9 264 193.9C264 291.2 385.7 313.4 436.5 264C438.6 262 439 260.8 437.5 258.3L420 227.8C418.1 224.7 413.8 223.8 410.9 226.1C370.1 258.1 316.3 241.0000000000001 316.3 194.9C316.3 146.9 367.3 124.4 408.5 162.3C411.3 164.8 415.6 164.4 417.7 161.4L437.3 133.7000000000001z" />
<glyph glyph-name="comment-alt"
unicode="&#xF27A;"
horiz-adv-x="576" d=" M288 416C129 416 0 322.9 0 208C0 158.7 23.7 113.5 63.3 77.8C54.6 54.5 41.2 45.1 26.2 34.7C15.1 27 -6 15 1.6 -8.5C6.7 -23.9 22.5 -33.2 39.7 -31.8C97.4 -27.2 150.9 -12.6 196.7 10.7C225.4 3.8 256.1 0 287.9 0C447 0 575.9 93 575.9 208C576 322.9 447.1 416 288 416zM288 48C255.5 48 222.6 52.4 190.7 62C158.4 43 112 16 56 8C88 32 112.8 69.6 117.2 96.4C79.1 122.4 48 161.3 48 208C48 278.9 134.3 368 288 368S528 278.9 528 208C528 137 441.7 48 288 48zM224 208C224 181.5 202.5 160 176 160S128 181.5 128 208S149.5 256 176 256S224 234.5 224 208zM336 208C336 181.5 314.5 160 288 160S240 181.5 240 208S261.5 256 288 256S336 234.5 336 208zM448 208C448 181.5 426.5 160 400 160S352 181.5 352 208S373.5 256 400 256S448 234.5 448 208z" />
horiz-adv-x="512" d=" M448 448H64C28.7 448 0 419.3 0 384V96C0 60.7 28.7 32 64 32H160V-52C160 -59.1 165.8 -64 172 -64C174.4 -64 176.9 -63.3 179.1 -61.6L304 32H448C483.3 32 512 60.7 512 96V384C512 419.3 483.3 448 448 448zM464 96C464 87.2 456.8 80 448 80H288L275.2 70.4L208 20V80H64C55.2 80 48 87.2 48 96V384C48 392.8 55.2 400 64 400H448C456.8 400 464 392.8 464 384V96z" />
<glyph glyph-name="comment-dots"
unicode="&#xF4AD;"
horiz-adv-x="512" d=" M144 240C126.3 240 112 225.7 112 208S126.3 176 144 176S176 190.3 176 208S161.7 240 144 240zM256 240C238.3 240 224 225.7 224 208S238.3 176 256 176S288 190.3 288 208S273.7 240 256 240zM368 240C350.3 240 336 225.7 336 208S350.3 176 368 176S400 190.3 400 208S385.7 240 368 240zM256 416C114.6 416 0 322.9 0 208C0 160.4 19.9 116.8 52.9 81.7C38 42.3 7 8.9 6.5 8.5C-0.1 1.5 -1.9 -8.7 1.9 -17.5S14.4 -32 24 -32C85.5 -32 134 -6.3 163.1 14.3C192 5.2 223.2 0 256 0C397.4 0 512 93.1 512 208S397.4 416 256 416zM256 48C229.3 48 202.9 52.1 177.6 60.1L154.9 67.3L135.4 53.5C121.1 43.4 101.5 32.1 77.9 24.5C85.2 36.6 92.3 50.2 97.8 64.7L108.4 92.8L87.8 114.6C69.7 133.9 48 165.8 48 208C48 296.2 141.3 368 256 368S464 296.2 464 208S370.7 48 256 48z" />
<glyph glyph-name="comment"
unicode="&#xF075;"
horiz-adv-x="576" d=" M288 416C129 416 0 322.9 0 208C0 158.7 23.7 113.5 63.3 77.8C54.6 54.5 41.2 45.1 26.2 34.7C15.1 27 -6 15 1.6 -8.5C6.7 -23.9 22.5 -33.2 39.7 -31.8C97.4 -27.2 150.9 -12.6 196.7 10.7C225.4 3.8 256.1 0 287.9 0C447 0 575.9 93 575.9 208C576 322.9 447.1 416 288 416zM288 48C255.5 48 222.6 52.4 190.7 62C158.4 43 112 16 56 8C88 32 112.8 69.6 117.2 96.4C79.1 122.4 48 161.3 48 208C48 278.9 134.3 368 288 368S528 278.9 528 208C528 137 441.7 48 288 48z" />
horiz-adv-x="512" d=" M256 416C114.6 416 0 322.9 0 208C0 160.4 19.9 116.8 52.9 81.7C38 42.3 7 8.9 6.5 8.5C-0.1 1.5 -1.9 -8.7 1.9 -17.5S14.4 -32 24 -32C85.5 -32 134 -6.3 163.1 14.3C192 5.2 223.2 0 256 0C397.4 0 512 93.1 512 208S397.4 416 256 416zM256 48C229.3 48 202.9 52.1 177.6 60.1L154.9 67.3L135.4 53.5C121.1 43.4 101.5 32.1 77.9 24.5C85.2 36.6 92.3 50.2 97.8 64.7L108.4 92.8L87.8 114.6C69.7 133.9 48 165.8 48 208C48 296.2 141.3 368 256 368S464 296.2 464 208S370.7 48 256 48z" />
<glyph glyph-name="comments"
unicode="&#xF086;"
horiz-adv-x="576" d=" M574.507 4.14C569.0859999999999 -17.121 549.9369999999999 -32 527.996 -32C495.75 -32 461.485 -22.01 425.896 -2.266C375.256 -13.892 316.745 -10.143 267.9359999999999 11.171C309.08 14.09 348.2969999999999 23.51 384.267 39.876C400.589 41.096 416.9409999999999 44.196 432.8979999999999 49.469C454.404 35.635 490.663 16 527.996 16C495.996 33.455 484.777 54.958 481.837 74.502C507.28 93.35 527.996 121.685 527.996 155.637C527.996 166.132 525.6129999999999 177.173 520.9549999999999 188.104C528.3599999999999 214.034 529.6109999999999 238.298 526.1399999999999 262.042C558.3039999999999 231.581 575.9959999999999 192.914 575.9959999999999 155.637C575.9959999999999 121.7439999999999 563.0829999999999 90.5899999999999 541.0199999999999 64.5179999999999C543.6729999999999 62.4799999999999 546.9439999999998 60.3419999999999 550.9819999999999 58.1399999999999C570.2429999999998 47.632 579.9289999999999 25.401 574.5069999999998 4.1399999999999zM240.002 368C117.068 368 48.004 295.123 48.004 237.091C48.004 198.895 72.863 167.019 103.395 145.815C99.868 123.827 86.404 99.636 48.004 80C92.804 80 136.314 102.089 162.123 117.653C187.643 109.747 214.006 106.182 240.002 106.182C362.998 106.182 432 179.024 432 237.091C432 295.118 362.943 368 240.002 368M240.002 416C390.193 416 480 321.974 480 237.091C480 214.346 473.494 190.697 461.184 168.7C449.3060000000001 147.474 432.6450000000001 128.406 411.661 112.026C390.068 95.169 364.863 81.981 336.748 72.829C306.893 63.11 274.343 58.183 240.002 58.183C215.553 58.183 191.662 60.87 168.71 66.187C126.311 43.488 85.785 32 48.004 32C25.824 32 6.532 47.197 1.339 68.761C-3.855 90.324 6.403 112.639 26.15 122.737C33.813 126.655 39.474 130.4740000000001 43.669 134.031C36.276 141.86 29.717 150.155 24.035 158.875C8.09 183.345 0.005 209.661 0.005 237.091C0.005 321.741 89.508 416 240.002 416z" />
horiz-adv-x="576" d=" M532 61.8C559.5 88.9 576 122.9 576 160C576 240 499.5 306.1 399.8 317.9C368.3 375.5 294.3 416 208 416C93.1 416 0 344.4 0 256C0 219 16.5 185 44 157.8C28.7 127.1 6.7 103.3 6.3 102.9C0 96.2000000000001 -1.8 86.4 1.9 77.9C5.5 69.4 13.9 63.9 23.1 63.9C76.6 63.9 119.8 84.1 148.3 102.7000000000001C157.5 100.6 167 99.0000000000001 176.7 97.8000000000001C208.1 40.4 281.8 0 368 0C388.8 0 408.8 2.4 427.8 6.8C456.3 -11.7 499.4 -32 553 -32C562.2 -32 570.5 -26.5 574.2 -18C577.8000000000001 -9.5 576.1 0.3 569.8000000000001 7C569.4000000000001 7.3 547.3000000000001 31.1 532.0000000000001 61.8zM139.2 154.1L122.1 143C108 133.9 93.6 126.7 79 121.6C81.7 126.3 84.4 131.3 87 136.4L102.5 167.5000000000001L77.7 192C64.2 205.4 48 227.3 48 256C48 316.7 121.3 368 208 368S368 316.7 368 256S294.7 144 208 144C191.5 144 175 145.9 159 149.6L139.2 154.1zM498.3 96L473.6 71.6L489.1 40.5C491.7 35.4 494.4 30.4 497.1 25.7C482.5 30.8 468.1 38 454 47.1L436.9 58.2L417 53.6C401 49.9 384.5 47.9999999999999 368 47.9999999999999C314 47.9999999999999 265.8 68.1 236.7 97.6999999999999C338 108.5 416 175.1 416 256C416 259.4 415.6 262.7 415.3 266C479.7 251.5 528 209.2 528 160C528 131.3 511.8 109.4 498.3 96z" />
<glyph glyph-name="compass"
unicode="&#xF14E;"
horiz-adv-x="512" d=" M256 440C119.033 440 8 328.967 8 192S119.033 -56 256 -56S504 55.033 504 192S392.967 440 256 440zM256 -8C145.468 -8 56 81.451 56 192C56 302.531 145.451 392 256 392C366.532 392 456 302.549 456 192C456 81.468 366.549 -8 256 -8zM347.326 304.131L313.9670000000001 166.352A24.005 24.005 0 0 0 307.1950000000001 154.623L204.5550000000001 56.844C187.4510000000001 40.551 158.9950000000001 56.41 164.6750000000001 79.868L198.0340000000001 217.647A23.997 23.997 0 0 0 204.8060000000001 229.376L307.4480000000001 327.155C324.7330000000001 343.625 352.9420000000001 327.33 347.3260000000001 304.131zM256 224C238.327 224 224 209.673 224 192S238.327 160 256 160S288 174.327 288 192S273.673 224 256 224z" />
@@ -133,6 +136,9 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
<glyph glyph-name="eye-slash"
unicode="&#xF070;"
horiz-adv-x="576" d=" M272.702 88.861C192.219 97.872 136.49 175.747 155.772 255.903L272.702 88.861zM288 56C185.444 56 95.908 110.701 48 192C69.755 228.917 100.1 260.342 136.344 283.658L108.803 323.0010000000001C67.001 295.766 31.921 259.259 6.646 216.369A47.999 47.999 0 0 1 6.646 167.63C63.004 71.994 168.14 8 288 8A332.89 332.89 0 0 1 327.648 10.367L295.627 56.111A284.16 284.16 0 0 0 288 56zM569.354 167.631C536.1220000000001 111.237 485.933 65.889 425.8000000000001 38.139L473.9160000000001 -30.601C477.717 -36.03 476.3960000000001 -43.513 470.967 -47.313L450.23 -61.83C444.8010000000001 -65.631 437.3180000000001 -64.3099999999999 433.5180000000001 -58.881L102.084 414.601C98.283 420.03 99.604 427.513 105.033 431.313L125.77 445.83C131.199 449.631 138.682 448.31 142.482 442.881L198.008 363.556C226.612 371.657 256.808 376 288 376C407.86 376 512.996 312.006 569.354 216.369A48.00200000000001 48.00200000000001 0 0 0 569.354 167.631zM528 192C483.843 266.933 404.323 319.27 311.838 327.007C302.042 316.9220000000001 296 303.17 296 288C296 257.072 321.072 232 352 232S408 257.072 408 288L407.999 288.0420000000001C438.6310000000001 230.765 424.738 157.7820000000001 371.0710000000001 116.323L397.766 78.188C452.626 101.449 498.308 141.614 528 192z" />
<glyph glyph-name="eye"
unicode="&#xF06E;"
horiz-adv-x="576" d=" M569.354 216.369C512.97 312.051 407.81 376 288 376C168.14 376 63.004 312.006 6.646 216.369A47.999 47.999 0 0 1 6.646 167.63C63.031 71.949 168.19 8 288 8C407.86 8 512.996 71.994 569.354 167.631A47.997 47.997 0 0 1 569.354 216.369zM288 56C185.444 56 95.909 110.701 48 192C92.157 266.933 171.677 319.27 264.1620000000001 327.007C273.9580000000001 316.9220000000001 280 303.17 280 288C280 257.072 254.928 232 224 232S168 257.072 168 288L168.001 288.0420000000001C157.794 268.957 152 247.156 152 224C152 148.889 212.889 88 288 88S424 148.889 424 224C424 255.031 413.6 283.629 396.105 306.515C451.704 283.362 498.009 242.894 528 192C480.092 110.701 390.5560000000001 56 288 56z" />
<glyph glyph-name="file-alt"
unicode="&#xF15C;"
horiz-adv-x="384" d=" M288 200V172C288 165.4 282.6 160 276 160H108C101.4 160 96 165.4 96 172V200C96 206.6 101.4 212 108 212H276C282.6 212 288 206.6 288 200zM276 128H108C101.4 128 96 122.6 96 116V88C96 81.4 101.4 76 108 76H276C282.6 76 288 81.4 288 88V116C288 122.6 282.6 128 276 128zM384 316.1V-16C384 -42.5 362.5 -64 336 -64H48C21.5 -64 0 -42.5 0 -16V400C0 426.5 21.5 448 48 448H252.1C264.8 448 277 442.9 286 433.9L369.9 350C378.9 341.1 384 328.8 384 316.1zM256 396.1V320H332.1L256 396.1zM336 -16V272H232C218.7 272 208 282.7 208 296V400H48V-16H336z" />
@@ -177,10 +183,10 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
horiz-adv-x="512" d=" M464 320H272L208 384H48C21.49 384 0 362.51 0 336V48C0 21.49 21.49 0 48 0H464C490.51 0 512 21.49 512 48V272C512 298.51 490.51 320 464 320zM458 48H54C50.686 48 48 50.678 48 53.992V330.008A5.993 5.993 0 0 0 54 336H188.118L252.118 272H458A6 6 0 0 0 464 266V54A6 6 0 0 0 458 48z" />
<glyph glyph-name="frown"
unicode="&#xF119;"
horiz-adv-x="512" d=" M256 392C366.532 392 456 302.549 456 192C456 81.468 366.549 -8 256 -8C145.468 -8 56 81.451 56 192C56 302.532 145.451 392 256 392M256 440C119.033 440 8 328.967 8 192S119.033 -56 256 -56S504 55.033 504 192S392.967 440 256 440zM320 304C310.465 304 301.488 301.6140000000001 293.63 297.411H293.647C306.382 297.411 316.706 287.087 316.706 274.352C316.706 261.617 306.382 251.293 293.647 251.293S270.588 261.617 270.588 274.352V274.3690000000001C266.386 266.512 264 257.535 264 248C264 217.072 289.072 192 320 192S376 217.072 376 248S350.928 304 320 304zM192 304C182.465 304 173.488 301.6140000000001 165.63 297.411H165.647C178.382 297.411 188.706 287.087 188.706 274.352C188.706 261.617 178.382 251.293 165.647 251.293C152.912 251.293 142.588 261.617 142.588 274.352V274.3690000000001C138.386 266.512 136 257.535 136 248C136 217.072 161.072 192 192 192S248 217.072 248 248S222.928 304 192 304zM363.5470000000001 102.218C306.952 179.182 205.164 179.283 148.4900000000001 102.2189999999999C129.6700000000001 76.6259999999999 168.3480000000001 48.2009999999999 187.16 73.781C224.671 124.791 287.5250000000001 124.577 324.8770000000001 73.7819999999999C343.3860000000001 48.6099999999999 382.6980000000001 76.1769999999999 363.5470000000001 102.2179999999999z" />
horiz-adv-x="496" d=" M248 440C111 440 0 329 0 192S111 -56 248 -56S496 55 496 192S385 440 248 440zM248 -8C137.7 -8 48 81.7 48 192S137.7 392 248 392S448 302.3 448 192S358.3 -8 248 -8zM168 208C185.7 208 200 222.3 200 240S185.7 272 168 272S136 257.7 136 240S150.3 208 168 208zM328 272C310.3 272 296 257.7 296 240S310.3 208 328 208S360 222.3 360 240S345.7 272 328 272zM248 144C207.8 144 170 126.3 144.2 95.4C135.7 85.2 137.1 70.1 147.3 61.6C157.5 53.1 172.6 54.4999999999999 181.1 64.7C197.7 84.6 222.1 96.1 248 96.1S298.3 84.7 314.9 64.7C319.7 59 326.5 56.1 333.4 56.1C338.8 56.1 344.3 57.9 348.8 61.7C359 70.2 360.3 85.3 351.9 95.5C326 126.3 288.2 144 248 144z" />
<glyph glyph-name="futbol"
unicode="&#xF1E3;"
horiz-adv-x="512" d=" M207.898 122.429L178.004 213.741L256 270.2680000000001L333.996 213.741L304.374 122.429H207.898zM504 192C504 55.033 392.967 -56 256 -56S8 55.033 8 192S119.033 440 256 440S504 328.967 504 192zM48.002 192.19L48 192C48 147.3 62.015 104.758 87.95 69.374L95.932 104.492L184.527 93.621L222.302 12.636L191.324 -5.791C233.156 -19.422 278.922 -19.397 320.678 -5.791L289.7 12.636L327.475 93.621L416.069 104.492L424.051 69.374C449.985 104.758 464 147.3 464 192L463.998 192.19L436.995 168.629L371.772 229.504L388.894 317.283L424.432 314.1C399.216 348.73 363.1230000000001 376.153 319.855 390.0510000000001L333.9980000000001 356.9600000000001L256 313.75L178.004 356.9600000000001L192.148 390.051C148.868 376.149 112.782 348.723 87.57 314.1L123.38 317.283L140.229 229.504L75.006 168.629L48.002 192.19z" />
horiz-adv-x="496" d=" M483.8 268.6C449.8 373.4 352.6 440 248.1 440C222.7 440 196.9 436.1 171.4 427.8C41.2 385.5 -30.1 245.6 12.2 115.4C46.2 10.6 143.4 -56 247.9 -56C273.3 -56 299.1 -52.1 324.6 -43.8C454.8 -1.5 526.1 138.4 483.8 268.6zM409.3 74.9L357.1 68.5L313.4000000000001 129.4L337.8 204.6L408.9 226.7L447.8 190.3C447.6 159.6 440.4 129.1999999999999 426.1 101.1C421.4 91.8 415.4 83.3 409.3 74.9zM409.3 310.3L398.9000000000001 257.2L328.2000000000001 235.2L264.0000000000001 281.7V355.5L311.4000000000001 381.7C350.6 368.7 384.8000000000001 343.7 409.3000000000001 310.3zM184.9 381.6L232 355.5V281.7L167.8 235.2L97.2 257.2L87.1 309.7C111.4 343.1 145 368.3 184.9 381.6zM139 68.5L85.9 75C71.5 95.1 48.6 134.6 48.1 190.3L87.1 226.7L158.2 204.5L182.5 130.2000000000001L139 68.5000000000001zM187.2 1.5L164.8 49.6L208.4 111.3H287L331.3 49.6L308.9000000000001 1.5C302.7000000000001 -0.3 251.3000000000001 -18.9 187.2000000000001 1.5z" />
<glyph glyph-name="gem"
unicode="&#xF3A5;"
horiz-adv-x="576" d=" M464 448H112C108 448 104.2 446 102 442.6L2 295.4C-0.9 291 -0.6 285.2000000000001 2.7 281.2000000000001L278.7 -59.6C283.5 -65.5 292.5 -65.5 297.3 -59.6L573.3 281.2C576.5999999999999 285.3 576.9 291 574 295.4L474.1 442.6C471.8 446 468.1 448 464 448zM444.7 400L508 304H439.6L387.9000000000001 400H444.7000000000001zM242.6 400H333.3L385 304H191L242.6 400zM131.3 400H188.1L136.4 304H68L131.3 400zM88.3 256H139.7L208 96L88.3 256zM191.2 256H384.8L288 12.7L191.2 256zM368 96L436.2 256H487.6L368 96z" />
@@ -219,13 +225,13 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
horiz-adv-x="512" d=" M21.096 66.21L150.188 -55.303A32 32 0 0 1 172.12 -64.001H409.7200000000001C423.8900000000001 -64.001 436.3730000000001 -54.682 440.4000000000001 -41.097L472.215 66.216A115.955 115.955 0 0 1 477 99.189V136.028C477 140.079 477.476 144.132 478.414 148.073L510.144 281.4830000000001C520.243 323.8950000000001 487.828 364.221 444.6 364.0080000000001C440.456 388.8640000000001 422.057 411.1730000000001 394.75 418.0000000000001C358.947 426.9520000000001 322.523 405.3450000000001 313.5 369.25L296.599 264L274.924 395.99C266.638 432.06 230.621 454.562 194.62 446.286C165.004 439.4820000000001 144.482 413.897 142.738 384.991C100.101 384.16 69.283 344.428 78.667 303.147L109.707 166.639C82.513 189.154 42.423 186.631 18.225 160.917C-7.151 133.956 -5.873 91.592 21.096 66.21zM53.164 128.021L53.166 128.0219999999999C60.385 135.694 72.407 136.002 80.022 128.8349999999999L133.034 78.9409999999999C143.225 69.351 160 76.6 160 90.594V160.073C160 161.266 159.866 162.456 159.603 163.619L125.473 313.791C119.877 338.408 156.975 346.651 162.527 322.212L192.926 188.4549999999999A16 16 0 0 1 208.529 176.0009999999999H217.1330000000001C227.4090000000001 176.0009999999999 235.0270000000001 185.5679999999999 232.7270000000001 195.5839999999999L191.107 376.7369999999999C185.484 401.2059999999999 222.497 409.813 228.142 385.2449999999999L273.362 188.4169999999999A16 16 0 0 1 288.956 176H302.173A16 16 0 0 1 317.695 188.119L360.067 357.6090000000001C366.171 382.0310000000001 403.029 372.7680000000001 396.932 348.3920000000001L358.805 195.88C356.284 185.792 363.92 176 374.327 176H384.021A16 16 0 0 1 399.586 188.295L426.509 301.4C432.3300000000001 325.848 469.306 317.087 463.475 292.598L431.7200000000001 159.19A100.094 100.094 0 0 1 429 136.028V99.189C429 92.641 428.057 86.138 426.195 79.8610000000001L397.775 -16H178.465L53.978 101.164C46.349 108.344 45.984 120.393 53.164 128.021z" />
<glyph glyph-name="handshake"
unicode="&#xF2B5;"
horiz-adv-x="640" d=" M616 352H568C560.893 352 554.51 348.909 550.116 344H526.59L495.46 380.3L495.3 380.48A103.974 103.974 0 0 1 417.03 416H370.48C352.73 416 335.58 411.06 320.79 401.99C304.33 411.07 285.67 416 266.62 416H234.51C205.607 416 176.911 404.781 155.31 383.2L116.12 344H89.884C85.49 348.909 79.107 352 72 352H24C10.745 352 0 341.255 0 328V88C0 74.745 10.745 64 24 64H72C82.449 64 91.334 70.68 94.629 80H113.43L188.78 12.43C214.322 -14.02 248.705 -32 285.36 -32C301.75 -32 317.64 -28.15 331.4600000000001 -21.07C356.396 -21.566 382.5610000000001 -10.702 400.5300000000001 10.34C420.2140000000001 15.919 438.033 27.766 451.25 44.9400000000001C472.239 49.3410000000001 491.978 61.4320000000001 504.67 80.0000000000001H545.371C548.6659999999999 70.6800000000001 557.5509999999999 64.0000000000001 568 64.0000000000001H616C629.255 64.0000000000001 640 74.7450000000001 640 88.0000000000001V328C640 341.255 629.255 352 616 352zM48 96C39.163 96 32 103.163 32 112S39.163 128 48 128S64 120.837 64 112S56.837 96 48 96zM460.52 101.76C445.17 87.465 423.636 90.432 420.57 93.76C421.984 80.378 402.313 52.717 371.49 54.88C365.949 36.357 343.272 21.054 320 29.13C311.11 20.24 297.54 16 285.36 16C260.4100000000001 16 237.59 30.54 222.22 46.91L140.92 119.8200000000001A31.975999999999996 31.975999999999996 0 0 1 119.56 128.0000000000001H96V296H122.75C131.23 296 139.37 299.37 145.37 305.37L189.25 349.25A64.004 64.004 0 0 0 234.51 368H266.62C272.42 368 278.13 367.21 283.62 365.7L240.35 315.2100000000001C216.79 287.73 216.51 247.59 239.69 219.77C272.078 180.904 331.068 180.542 364.17 217.79L390.1500000000001 247.87L462.59 152C476.03 137.4 473.54 113.87 460.52 101.76zM544 128H519.542C519.6460000000001 148.261 512.743 167.33 499.78 182.4L421.7 285.7200000000001C426.21 295.23 424.04 306.95 415.69 314.17C405.615 322.861 390.46 321.669 381.83 311.69L328.2 249.57C314.372 234.16 289.977 234.425 276.56 250.5A25.856999999999996 25.856999999999996 0 0 0 276.79 283.9700000000001L334.7100000000001 351.55A47.09 47.09 0 0 0 370.48 368H417.0300000000001C433.1400000000001 368 448.4700000000001 361.06 459.1 348.9600000000001L504.52 296H544V128zM592 96C583.163 96 576 103.163 576 112S583.163 128 592 128S608 120.837 608 112S600.837 96 592 96z" />
horiz-adv-x="640" d=" M519.2 320.1L471.6 367.7A56.252 56.252 0 0 1 432 384H205.2C190.4 384 176.1 378.1 165.6 367.7L118 320.1H0V64.4H64C81.6 64.4 95.8 78.6 95.9 96.1H105L189.6 19.6999999999999C220.5 -5.4000000000001 263.4 -6.0000000000001 295.2 15.8999999999999C307.7 5.0999999999999 321.2 -1e-13 336.3 -1e-13C354.5 -1e-13 371.6 7.3999999999999 385.1 23.9999999999999C407.2000000000001 15.3 433.3 21.3999999999999 449.1 40.8L475.3 73.1C480.9 79.9999999999999 484.4 87.9 486.2 96.1H544.1C544.2 78.6 558.5 64.4 576 64.4H640V320.1H519.2zM48 96.4C39.2 96.4 32 103.6 32 112.4S39.2 128.4 48 128.4S64 121.2 64 112.4C64 103.5 56.8 96.4 48 96.4zM438 103.3L411.9 71.1C409.1 67.7 404.1 67.1 400.6 69.9L376.7 89.3L346.7 52.8C340.7 45.4999999999999 331.7 47.9999999999999 328.7 50.4L291.9 81.9L276.3 62.7C262.4 45.6 237.1 43 221 56.1L123.7 144.1H96V272.2H137.9L199.6 333.8C201.6 334.6 203.3 335.3 205.3 336.1H262L223.3 300.6C193.9 273.7 192.2 228.3 218.9 199.3C233.7 183.1 280.1 158.1 320.4 194.9L328.6 202.4L436.8 114.6C440.2 111.8 440.7 106.7 438 103.3zM544 144.1H474.8C472.5 146.9 469.9 149.5 467.1 151.8L364.4000000000001 235.2L376.9000000000001 246.6C383.4000000000001 252.6 383.9000000000001 262.7 377.9000000000001 269.2L367 280.9C361 287.4 350.9 287.8 344.4 281.9L289.2 231.3C279.7 222.6 263.5 221.9 254.6 231.3C245.3 241.2 246.1 256.4 255.8 265.2000000000001L321.4 325.3C328.8 332.1 338.4 335.8 348.4 335.8L432.1 336C434.2 336 436.2 335.2000000000001 437.6 333.7000000000001L499.3 272.1H544V144.1zM592 96.4C583.2 96.4 576 103.6 576 112.4S583.2 128.4 592 128.4S608 121.2 608 112.4C608 103.5 600.8 96.4 592 96.4z" />
<glyph glyph-name="hdd"
unicode="&#xF0A0;"
horiz-adv-x="576" d=" M567.403 212.358L462.323 363.411A48 48 0 0 1 422.919 384H153.081A48 48 0 0 1 113.677 363.411L8.597 212.358A48.001 48.001 0 0 1 0 184.946V48C0 21.49 21.49 0 48 0H528C554.51 0 576 21.49 576 48V184.946C576 194.747 573 204.312 567.403 212.358zM153.081 336H422.919L500.832 224H75.168L153.081 336zM528 48H48V176H528V48zM496 112C496 94.327 481.673 80 464 80S432 94.327 432 112S446.327 144 464 144S496 129.673 496 112zM400 112C400 94.327 385.673 80 368 80S336 94.327 336 112S350.327 144 368 144S400 129.673 400 112z" />
<glyph glyph-name="heart"
unicode="&#xF004;"
horiz-adv-x="576" d=" M257.3 -27.4L92.5 134.4C85.4 141 24 199.9 24 273.2C24 363.9 80.8 424 176 424C217.4 424 256.6 401.2 288 374.2C319.3 401.2 358.6 424 400 424C491.7 424 552 367.5 552 273.2C552 221.2 520.2 169.7 483.9 134.5L483.5 134.1L318.7 -27.4A43.7 43.7 0 0 0 257.3 -27.4zM125.9 168.9L288 9.7L449.8 168.4C477.1 195.4 504 234.7 504 273.2C504 340.1 465.8 376 400 376C352.8 376 307.2 326.7 288 307.6C271 324.6 224 376 176 376C110.1 376 72 340.1 72 273.2C72 235.9 98.7 194.3 125.9 168.9z" />
horiz-adv-x="512" d=" M458.4 383.7C400.6 432.3 311.3 425 256 368.7C200.7 425 111.4 432.4 53.6 383.7C-21.6 320.4 -10.6 217.2 43 162.5L218.4 -16.2C228.4 -26.4 241.8 -32.1 256 -32.1C270.3 -32.1 283.6 -26.4999999999999 293.6 -16.3L469 162.4C522.5 217.1 533.7 320.3 458.4 383.7zM434.8 196.2L259.4 17.5C257 15.1 255 15.1 252.6 17.5L77.2 196.2C40.7 233.4 33.3 303.8 84.5 346.9C123.4 379.6 183.4 374.7 221 336.4L256 300.7L291 336.4C328.8 374.9 388.8 379.6 427.5 347C478.6 303.9 471 233.1 434.8 196.2z" />
<glyph glyph-name="hospital"
unicode="&#xF0F8;"
horiz-adv-x="448" d=" M128 204V244C128 250.627 133.373 256 140 256H180C186.627 256 192 250.627 192 244V204C192 197.373 186.627 192 180 192H140C133.373 192 128 197.373 128 204zM268 192H308C314.627 192 320 197.373 320 204V244C320 250.627 314.627 256 308 256H268C261.373 256 256 250.627 256 244V204C256 197.373 261.373 192 268 192zM192 108V148C192 154.627 186.627 160 180 160H140C133.373 160 128 154.627 128 148V108C128 101.373 133.373 96 140 96H180C186.627 96 192 101.373 192 108zM268 96H308C314.627 96 320 101.373 320 108V148C320 154.627 314.627 160 308 160H268C261.373 160 256 154.627 256 148V108C256 101.373 261.373 96 268 96zM448 -28V-64H0V-28C0 -21.373 5.373 -16 12 -16H31.5V362.9650000000001C31.5 374.582 42.245 384 55.5 384H144V424C144 437.255 154.745 448 168 448H280C293.255 448 304 437.255 304 424V384H392.5C405.755 384 416.5 374.582 416.5 362.9650000000001V-16H436C442.627 -16 448 -21.373 448 -28zM79.5 -15H192V52C192 58.627 197.373 64 204 64H244C250.627 64 256 58.627 256 52V-15H368.5V336H304V312C304 298.745 293.255 288 280 288H168C154.745 288 144 298.745 144 312V336H79.5V-15zM266 384H240V410A6 6 0 0 1 234 416H214A6 6 0 0 1 208 410V384H182A6 6 0 0 1 176 378V358A6 6 0 0 1 182 352H208V326A6 6 0 0 1 214 320H234A6 6 0 0 1 240 326V352H266A6 6 0 0 1 272 358V378A6 6 0 0 1 266 384z" />
@@ -234,10 +240,10 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
horiz-adv-x="384" d=" M368 400H372C378.627 400 384 405.373 384 412V436C384 442.627 378.627 448 372 448H12C5.373 448 0 442.627 0 436V412C0 405.373 5.373 400 12 400H16C16 319.4360000000001 48.188 234.193 113.18 192C47.899 149.619 16 64.1 16 -16H12C5.373 -16 0 -21.373 0 -28V-52C0 -58.627 5.373 -64 12 -64H372C378.627 -64 384 -58.627 384 -52V-28C384 -21.373 378.627 -16 372 -16H368C368 64.564 335.812 149.807 270.82 192C336.102 234.381 368 319.9 368 400zM64 400H320C320 298.38 262.693 216 192 216S64 298.379 64 400zM320 -16H64C64 85.62 121.308 168 192 168S320 85.62 320 -16z" />
<glyph glyph-name="id-badge"
unicode="&#xF2C1;"
horiz-adv-x="384" d=" M192 320C227.346 320 256 291.346 256 256S227.346 192 192 192S128 220.654 128 256S156.654 320 192 320M253.187 174.153L235.123 179.314C222.371 172.116 207.658 168 192 168S161.629 172.116 148.878 179.314L130.814 174.153C110.207 168.266 96 149.431 96 128V56C96 42.745 106.745 32 120 32H264C277.255 32 288 42.745 288 56V128C288 149.431 273.793 168.266 253.187 174.153zM0 400V-16C0 -42.51 21.49 -64 48 -64H336C362.51 -64 384 -42.51 384 -16V400C384 426.51 362.51 448 336 448H48C21.49 448 0 426.51 0 400zM336 368V-10A6 6 0 0 0 330 -16H54A6 6 0 0 0 48 -10V368H336z" />
horiz-adv-x="384" d=" M336 448H48C21.5 448 0 426.5 0 400V-16C0 -42.5 21.5 -64 48 -64H336C362.5 -64 384 -42.5 384 -16V400C384 426.5 362.5 448 336 448zM336 -16H48V400H336V-16zM144 336H240C248.8 336 256 343.2 256 352S248.8 368 240 368H144C135.2 368 128 360.8 128 352S135.2 336 144 336zM192 160C227.3 160 256 188.7 256 224S227.3 288 192 288S128 259.3 128 224S156.7 160 192 160zM102.4 32H281.6C294 32 304 40.6 304 51.2V70.4C304 102.2 273.9 128 236.8 128C226 128 218.1 120 192 120C165.1 120 158.6 128 147.2 128C110.1 128 80 102.2 80 70.4V51.2C80 40.6 90 32 102.4 32z" />
<glyph glyph-name="id-card"
unicode="&#xF2C2;"
horiz-adv-x="512" d=" M404 192H300C293.373 192 288 197.373 288 204V228C288 234.627 293.373 240 300 240H404C410.627 240 416 234.627 416 228V204C416 197.373 410.627 192 404 192zM416 124V148C416 154.627 410.627 160 404 160H300C293.373 160 288 154.627 288 148V124C288 117.373 293.373 112 300 112H404C410.627 112 416 117.373 416 124zM512 336V48C512 21.49 490.51 0 464 0H48C21.49 0 0 21.49 0 48V336C0 362.51 21.49 384 48 384H464C490.51 384 512 362.51 512 336zM464 54V304H48V54A6 6 0 0 1 54 48H458A6 6 0 0 1 464 54zM176 152C206.928 152 232 177.072 232 208S206.928 264 176 264S120 238.928 120 208S145.072 152 176 152zM238.896 141.131L225.432 145.17C211.814 134.432 194.649 128 176 128S140.186 134.432 126.567 145.17L113.103 141.131A24 24 0 0 1 96 118.143V76C96 69.373 101.373 64 108 64H244C250.627 64 256 69.373 256 76V118.143A24 24 0 0 1 238.896 141.131z" />
horiz-adv-x="576" d=" M528 416H48C21.5 416 0 394.5 0 368V16C0 -10.5 21.5 -32 48 -32H528C554.5 -32 576 -10.5 576 16V368C576 394.5 554.5 416 528 416zM528 16H303.2C304.1 20.5 304 12.4 304 38.4C304 70.2 273.9 96 236.8 96C226 96 218.1 88 192 88C165.1 88 158.6 96 147.2 96C110.1 96 80 70.2 80 38.4C80 12.4 79.8 20.5 80.8 16H48V304H528V16zM360 96H472C476.4 96 480 99.6 480 104V120C480 124.4 476.4 128 472 128H360C355.6 128 352 124.4 352 120V104C352 99.6 355.6 96 360 96zM360 160H472C476.4 160 480 163.6 480 168V184C480 188.4 476.4 192 472 192H360C355.6 192 352 188.4 352 184V168C352 163.6 355.6 160 360 160zM360 224H472C476.4 224 480 227.6 480 232V248C480 252.4 476.4 256 472 256H360C355.6 256 352 252.4 352 248V232C352 227.6 355.6 224 360 224zM192 128C227.3 128 256 156.7 256 192S227.3 256 192 256S128 227.3 128 192S156.7 128 192 128z" />
<glyph glyph-name="image"
unicode="&#xF03E;"
horiz-adv-x="512" d=" M464 384H48C21.49 384 0 362.51 0 336V48C0 21.49 21.49 0 48 0H464C490.51 0 512 21.49 512 48V336C512 362.51 490.51 384 464 384zM458 48H54A6 6 0 0 0 48 54V330A6 6 0 0 0 54 336H458A6 6 0 0 0 464 330V54A6 6 0 0 0 458 48zM128 296C105.909 296 88 278.091 88 256S105.909 216 128 216S168 233.909 168 256S150.091 296 128 296zM96 96H416V176L328.485 263.515C323.7990000000001 268.201 316.201 268.201 311.514 263.515L192 144L152.485 183.515C147.799 188.201 140.201 188.201 135.514 183.515L96 144V96z" />
@@ -264,13 +270,13 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
horiz-adv-x="576" d=" M508.505 411.83L381.517 355.424L207.179 413.537A47.992 47.992 0 0 1 172.505 411.863L28.505 347.863A48 48 0 0 1 0 304V16.033C0 -18.905 35.991 -41.831 67.495 -27.83L194.483 28.576L368.822 -29.537A47.992 47.992 0 0 1 403.496 -27.863L547.496 36.137A48 48 0 0 1 576 80V367.967C576 402.905 540.009 425.831 508.505 411.83zM360 24L216 72V360L360 312V24zM48 16V304L168 357.333V69.333L48 16zM528 80L408 26.667V314.6670000000001L528 368V80z" />
<glyph glyph-name="meh"
unicode="&#xF11A;"
horiz-adv-x="512" d=" M256 392C366.532 392 456 302.549 456 192C456 81.468 366.549 -8 256 -8C145.468 -8 56 81.451 56 192C56 302.532 145.451 392 256 392M256 440C119.033 440 8 328.967 8 192S119.033 -56 256 -56S504 55.033 504 192S392.967 440 256 440zM320 304C310.465 304 301.488 301.6140000000001 293.63 297.411H293.647C306.382 297.411 316.706 287.087 316.706 274.352C316.706 261.617 306.382 251.293 293.647 251.293S270.588 261.617 270.588 274.352V274.3690000000001C266.386 266.512 264 257.535 264 248C264 217.072 289.072 192 320 192S376 217.072 376 248S350.928 304 320 304zM192 304C182.465 304 173.488 301.6140000000001 165.63 297.411H165.647C178.382 297.411 188.706 287.087 188.706 274.352C188.706 261.617 178.382 251.293 165.647 251.293C152.912 251.293 142.588 261.617 142.588 274.352V274.3690000000001C138.386 266.512 136 257.535 136 248C136 217.072 161.072 192 192 192S248 217.072 248 248S222.928 304 192 304zM328 120H184C152.224 120 152.251 72 184 72H328C359.776 72 359.749 120 328 120z" />
horiz-adv-x="496" d=" M248 440C111 440 0 329 0 192S111 -56 248 -56S496 55 496 192S385 440 248 440zM248 -8C137.7 -8 48 81.7 48 192S137.7 392 248 392S448 302.3 448 192S358.3 -8 248 -8zM168 208C185.7 208 200 222.3 200 240S185.7 272 168 272S136 257.7 136 240S150.3 208 168 208zM328 272C310.3 272 296 257.7 296 240S310.3 208 328 208S360 222.3 360 240S345.7 272 328 272zM336 128H160C146.8 128 136 117.2 136 104S146.8 80 160 80H336C349.2 80 360 90.8 360 104S349.2 128 336 128z" />
<glyph glyph-name="minus-square"
unicode="&#xF146;"
horiz-adv-x="448" d=" M108 164C101.4 164 96 169.4 96 176V208C96 214.6 101.4 220 108 220H340C346.6 220 352 214.6 352 208V176C352 169.4 346.6 164 340 164H108zM448 368V16C448 -10.5 426.5 -32 400 -32H48C21.5 -32 0 -10.5 0 16V368C0 394.5 21.5 416 48 416H400C426.5 416 448 394.5 448 368zM400 22V362C400 365.3 397.3 368 394 368H54C50.7 368 48 365.3 48 362V22C48 18.7 50.7 16 54 16H394C397.3 16 400 18.7 400 22z" />
<glyph glyph-name="money-bill-alt"
unicode="&#xF3D1;"
horiz-adv-x="640" d=" M320 304C266.979 304 224 253.857 224 192C224 130.153 266.977 80 320 80C373 80 416 130.13 416 192C416 253.857 373.021 304 320 304zM368 139.572C368 132.095 364.0830000000001 128 356.428 128H289.135C281.479 128 277.562 132.095 277.562 139.572V148.473C277.562 155.95 281.479 160.045 289.135 160.045H304.266V199.923C304.266 205.086 304.8 210.426 304.8 210.426H304.444S302.665 207.756 301.596 206.688C297.1449999999999 202.415 291.092 202.237 285.93 207.756L280.412 213.987C275.07 219.328 275.428 225.203 280.946 230.366L302.666 250.305C307.115 254.4 311.032 256.002 317.086 256.002H329.191C336.847 256.002 340.941 252.086 340.941 244.43V160.046H356.429C364.084 160.046 368.001 155.952 368.001 148.474V139.572zM616 384H24C10.745 384 0 373.255 0 360V25C0 11.745 10.745 1 24 1H616C629.255 1 640 11.745 640 25V360C640 373.255 629.255 384 616 384zM512 48H128C128 92.183 92.183 128 48 128V256C92.183 256 128 291.817 128 336H512C512 291.817 547.817 256 592 256V128C547.817 128 512 92.183 512 48z" />
horiz-adv-x="640" d=" M320 304C266.98 304 224 253.86 224 192C224 130.15 266.98 80 320 80C373 80 416 130.13 416 192C416 253.86 373.02 304 320 304zM360 136C360 131.58 356.42 128 352 128H288C283.58 128 280 131.58 280 136V152C280 156.42 283.58 160 288 160H304V215.44L303.53 215.13A7.991999999999999 7.991999999999999 0 0 0 292.44 217.35L283.56 230.66A7.991999999999999 7.991999999999999 0 0 0 285.7800000000001 241.75L301.11 251.97A23.99 23.99 0 0 0 314.42 256H328C332.42 256 336 252.42 336 248V160H352C356.42 160 360 156.42 360 152V136zM608 384H32C14.33 384 0 369.67 0 352V32C0 14.33 14.33 0 32 0H608C625.67 0 640 14.33 640 32V352C640 369.67 625.67 384 608 384zM592 112C556.65 112 528 83.35 528 48H112C112 83.35 83.35 112 48 112V272C83.35 272 112 300.65 112 336H528C528 300.65 556.65 272 592 272V112z" />
<glyph glyph-name="moon"
unicode="&#xF186;"
horiz-adv-x="512" d=" M279.135 -64C357.891 -64 430.117 -28.196 477.979 30.775C506.249 65.606 475.421 116.497 431.73 108.176C349.382 92.493 273.458 155.444 273.458 238.968C273.458 287.392 299.518 331.26 340.892 354.804C379.637 376.854 369.891 435.592 325.87 443.723A257.936 257.936 0 0 1 279.135 448C137.775 448 23.135 333.425 23.135 192C23.135 50.64 137.711 -64 279.135 -64zM279.135 400C292.12 400 304.824 398.799 317.151 396.522C262.391 365.359 225.4580000000001 306.48 225.4580000000001 238.968C225.4580000000001 125.12 329.0990000000001 39.768 440.7100000000001 61.024C402.574 14.036 344.366 -16 279.135 -16C164.26 -16 71.135 77.125 71.135 192S164.26 400 279.135 400z" />
@@ -309,7 +315,7 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
horiz-adv-x="576" d=" M561.938 289.94L417.94 433.908C387.926 463.922 336 442.903 336 399.968V342.77C293.55 340.89 251.97 336.2200000000001 215.24 324.7800000000001C180.07 313.8300000000001 152.17 297.2000000000001 132.33 275.36C108.22 248.8 96 215.4 96 176.06C96 114.363 129.178 63.605 180.87 31.3C218.416 7.792 266.118 43.951 251.89 87.04C236.375 134.159 234.734 157.963 336 165.8V112C336 69.007 387.968 48.087 417.94 78.06L561.938 222.06C580.688 240.8 580.688 271.2 561.938 289.94zM384 112V215.84C255.309 213.918 166.492 192.65 206.31 72C176.79 90.45 144 123.92 144 176.06C144 285.394 273.14 295.007 384 295.91V400L528 256L384 112zM408.74 27.507A82.658 82.658 0 0 1 429.714 36.81C437.69 41.762 448 35.984 448 26.596V-16C448 -42.51 426.51 -64 400 -64H48C21.49 -64 0 -42.51 0 -16V336C0 362.51 21.49 384 48 384H180C186.627 384 192 378.627 192 372V367.514C192 362.597 189.013 358.145 184.431 356.362C170.729 351.031 158.035 344.825 146.381 337.777A12.138 12.138 0 0 0 140.101 336H54A6 6 0 0 1 48 330V-10A6 6 0 0 1 54 -16H394A6 6 0 0 1 400 -10V15.966C400 21.336 403.579 26.025 408.74 27.507z" />
<glyph glyph-name="smile"
unicode="&#xF118;"
horiz-adv-x="512" d=" M256 392C366.532 392 456 302.549 456 192C456 81.468 366.549 -8 256 -8C145.468 -8 56 81.451 56 192C56 302.532 145.451 392 256 392M256 440C119.033 440 8 328.967 8 192S119.033 -56 256 -56S504 55.033 504 192S392.967 440 256 440zM320 304C310.465 304 301.488 301.6140000000001 293.63 297.411H293.647C306.382 297.411 316.706 287.087 316.706 274.352C316.706 261.617 306.382 251.293 293.647 251.293S270.588 261.617 270.588 274.352V274.3690000000001C266.386 266.512 264 257.535 264 248C264 217.072 289.072 192 320 192S376 217.072 376 248S350.928 304 320 304zM192 304C182.465 304 173.488 301.6140000000001 165.63 297.411H165.647C178.382 297.411 188.706 287.087 188.706 274.352C188.706 261.617 178.382 251.293 165.647 251.293C152.912 251.293 142.588 261.617 142.588 274.352V274.3690000000001C138.386 266.512 136 257.535 136 248C136 217.072 161.072 192 192 192S248 217.072 248 248S222.928 304 192 304zM387.372 121.781C406.1910000000001 147.373 367.516 175.798 348.702 150.219C298.567 82.042 213.473 82.039 163.335 150.219C144.507 175.82 105.857 147.358 124.665 121.781C193.963 27.55 317.988 27.43 387.372 121.781z" />
horiz-adv-x="496" d=" M248 440C111 440 0 329 0 192S111 -56 248 -56S496 55 496 192S385 440 248 440zM248 -8C137.7 -8 48 81.7 48 192S137.7 392 248 392S448 302.3 448 192S358.3 -8 248 -8zM332 135.4C311.2 110.4 280.5 96 248 96S184.8 110.3 164 135.4C155.5 145.6 140.4 146.9 130.2 138.5C120 130 118.7 114.9 127.1 104.7C157.1 68.7 201.2 48.1 248 48.1S338.9 68.7 368.9 104.7C377.4 114.9 376 130 365.8 138.5C355.6 146.9 340.5 145.6 332 135.4zM168 208C185.7 208 200 222.3 200 240S185.7 272 168 272S136 257.7 136 240S150.3 208 168 208zM328 208C345.7 208 360 222.3 360 240S345.7 272 328 272S296 257.7 296 240S310.3 208 328 208z" />
<glyph glyph-name="snowflake"
unicode="&#xF2DC;"
horiz-adv-x="448" d=" M438.237 92.073L371.663 130.613L431.111 140.94C436.957 142.315 441.72 146.123 444.569 151.07C447.0490000000001 155.377 448.075 160.548 447.093 165.721C444.983 176.836 434.4070000000001 183.76 423.4720000000001 181.188L338.0490000000001 150.073L255.914 192L338.05 233.926L423.473 202.811C434.409 200.239 444.985 207.163 447.094 218.278C449.205 229.393 442.048 240.487 431.113 243.059L371.665 253.386L438.238 291.926C447.778 297.449 450.853 310.018 445.105 320C439.357 329.982 426.965 333.596 417.425 328.074L350.851 289.534L371.656 346.3210000000001C374.902 357.103 368.898 368.863 358.243 372.589C347.589 376.314 336.3209999999999 370.592 333.075 359.81L317.2369999999999 270.075L244.8139999999999 228.149V312L314.3989999999999 370.621C322.0879999999999 378.831 321.3959999999999 391.4770000000001 312.8509999999999 398.866C304.3059999999999 406.257 291.1459999999999 405.589 283.4569999999999 397.38L244.8129999999999 350.92V428C244.8129999999999 439.046 235.4949999999999 448 223.9999999999999 448S203.1869999999999 439.046 203.1869999999999 428V350.92L164.5429999999999 397.38C156.8539999999999 405.5900000000001 143.6939999999999 406.256 135.1489999999999 398.866C126.6049999999999 391.477 125.9129999999999 378.831 133.6019999999999 370.621L203.187 312V228.147L130.764 270.073L114.926 359.809C111.679 370.591 100.411 376.313 89.757 372.588C79.101 368.863 73.098 357.102 76.344 346.32L97.149 289.533L30.576 328.073C21.036 333.596 8.643 329.981 2.896 319.999S0.223 297.448 9.763 291.925L76.337 253.385L16.888 243.057C5.953 240.485 -1.202 229.391 0.907 218.276C3.017 207.162 13.593 200.238 24.529 202.81L109.951 233.925L192.086 192L109.95 150.074L24.527 181.189C13.591 183.761 3.016 176.8370000000001 0.905 165.723C-1.204 154.61 5.951 143.514 16.886 140.942L76.335 130.614L9.761 92.074C0.223 86.551 -2.852 73.982 2.896 64S21.036 50.403 30.576 55.926L97.15 94.466L76.345 37.68C74.61 31.916 75.517 25.875 78.365 20.929C80.845 16.622 84.798 13.145 89.757 11.412C100.412 7.687 111.68 13.409 114.926 24.191L130.764 113.927L203.187 155.853V72L133.602 13.379C125.912 5.169 126.605 -7.476 135.149 -14.866C143.693 -22.254 156.854 -21.589 164.543 -13.379L203.187 33.081V-44C203.187 -55.046 212.505 -64 224 -64S244.813 -55.046 244.813 -44V33.081L283.457 -13.379C287.568 -17.768 293.2389999999999 -19.9999999999999 298.935 -19.9999999999999C303.8949999999999 -19.9999999999999 308.874 -18.3059999999999 312.851 -14.8659999999999C321.396 -7.4759999999999 322.088 5.1690000000001 314.399 13.3790000000001L244.813 72V155.853L317.236 113.927L333.074 24.191C336.32 13.409 347.588 7.687 358.242 11.412C368.8950000000001 15.138 374.901 26.8990000000001 371.654 37.6800000000001L350.849 94.467L417.423 55.927C426.963 50.404 439.356 54.019 445.103 64.001C450.852 73.982 447.778 86.5510000000001 438.237 92.073z" />
@@ -345,16 +351,19 @@ License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1,
horiz-adv-x="448" d=" M192 260V44C192 37.373 186.627 32 180 32H156C149.373 32 144 37.373 144 44V260C144 266.627 149.373 272 156 272H180C186.627 272 192 266.627 192 260zM292 272H268C261.373 272 256 266.627 256 260V44C256 37.373 261.373 32 268 32H292C298.627 32 304 37.373 304 44V260C304 266.627 298.627 272 292 272zM424 368C437.255 368 448 357.255 448 344V332C448 325.373 442.627 320 436 320H416V-16C416 -42.51 394.51 -64 368 -64H80C53.49 -64 32 -42.51 32 -16V320H12C5.373 320 0 325.373 0 332V344C0 357.255 10.745 368 24 368H98.411L132.429 424.6960000000001A48 48 0 0 0 173.589 448H274.412A48 48 0 0 0 315.572 424.6960000000001L349.589 368H424zM154.389 368H293.612L276.1600000000001 397.087A6 6 0 0 1 271.015 400H176.987A6 6 0 0 1 171.842 397.087L154.389 368zM368 320H80V-10A6 6 0 0 1 86 -16H362A6 6 0 0 1 368 -10V320z" />
<glyph glyph-name="user-circle"
unicode="&#xF2BD;"
horiz-adv-x="512" d=" M256 440C119.033 440 8 328.967 8 192S119.033 -56 256 -56S504 55.033 504 192S392.967 440 256 440zM256 392C366.532 392 456 302.549 456 192C456 157.52 447.294 125.091 431.96 96.787C418.557 123.1800000000001 394.435 144.3290000000001 364.576 153.359C378.19 174.191 385.5 198.532 385.5 224C385.5 295.569 327.581 353.5 256 353.5C184.431 353.5 126.5 295.581 126.5 224C126.5 198.532 133.81 174.191 147.424 153.359C117.603 144.341 93.462 123.217 80.039 96.787C64.706 125.089 56 157.518 56 192C56 302.531 145.451 392 256 392zM176 224C176 268.183 211.817 304 256 304S336 268.183 336 224S300.183 144 256 144S176 179.817 176 224zM116.073 49.057C117.592 83.055 145.627 110.154 180 110.154H194.171C232.508 89.265 279.508 89.273 317.83 110.154H332C366.373 110.154 394.408 83.055 395.927 49.057C318.1810000000001 -27.057 193.771 -27.008 116.073 49.057z" />
horiz-adv-x="496" d=" M248 344C195 344 152 301 152 248S195 152 248 152S344 195 344 248S301 344 248 344zM248 200C221.5 200 200 221.5 200 248S221.5 296 248 296S296 274.5 296 248S274.5 200 248 200zM248 440C111 440 0 329 0 192S111 -56 248 -56S496 55 496 192S385 440 248 440zM248 -8C198.3 -8 152.9 10.3 117.9 40.4C132.8 63.4 158.3 79 187.5 79.9C208.3 73.5 228.1 70.3 248 70.3S287.7 73.4 308.5 79.9C337.7 78.9 363.2 63.4 378.1 40.4C343.1 10.3 297.7000000000001 -8 248.0000000000001 -8zM410.7 76.1C386.3 107.5 348.6 128 305.6 128C295.4000000000001 128 279.6 118.4 248.0000000000001 118.4C216.5 118.4 200.6 128 190.4 128C147.5 128 109.8 107.5 85.3 76.1C61.9 108.8 48 148.8 48 192C48 302.3 137.7 392 248 392S448 302.3 448 192C448 148.8 434.1 108.8 410.7 76.1z" />
<glyph glyph-name="user"
unicode="&#xF007;"
horiz-adv-x="512" d=" M399.326 159.092C422.188 189.114 436 226.915 436 268C436 367.409 355.414 448 256 448C156.591 448 76 367.414 76 268C76 226.927 89.806 189.122 112.674 159.092C50.028 151.664 0 98.349 0 32V3.5C0 -33.72 30.28 -64 67.5 -64H444.5C481.72 -64 512 -33.72 512 3.5V32C512 98.374 461.948 151.667 399.326 159.092zM256 400C328.902 400 388 340.902 388 268S328.902 136 256 136S124 195.098 124 268S183.098 400 256 400zM464 3.5C464 -7.27 455.27 -16 444.5 -16H67.5C56.73 -16 48 -7.27 48 3.5V32C48 76.183 83.817 112 128 112H166.14C221.626 80.032 290.166 79.913 345.86 112H384C428.183 112 464 76.183 464 32V3.5z" />
horiz-adv-x="448" d=" M313.6 144C284.9000000000001 144 271.1 128 224 128C176.9 128 163.2000000000001 144 134.4 144C60.2 144 0 83.8 0 9.6V-16C0 -42.5 21.5 -64 48 -64H400C426.5 -64 448 -42.5 448 -16V9.6C448 83.8 387.8 144 313.6 144zM400 -16H48V9.6C48 57.2000000000001 86.8 96 134.4 96C149 96 172.7 80 224 80C275.7 80 298.9 96 313.6 96C361.2000000000001 96 400 57.2 400 9.6V-16zM224 160C303.5 160 368 224.5 368 304S303.5 448 224 448S80 383.5 80 304S144.5 160 224 160zM224 400C276.9 400 320 356.9 320 304S276.9 208 224 208S128 251.1 128 304S171.1 400 224 400z" />
<glyph glyph-name="window-close"
unicode="&#xF410;"
horiz-adv-x="512" d=" M464 416H48C21.5 416 0 394.5 0 368V16C0 -10.5 21.5 -32 48 -32H464C490.5 -32 512 -10.5 512 16V368C512 394.5 490.5 416 464 416zM464 22C464 18.7 461.3 16 458 16H54C50.7 16 48 18.7 48 22V362C48 365.3 50.7 368 54 368H458C461.3 368 464 365.3 464 362V22zM356.5 253.4L295.1 192L356.5 130.6C361.1 126 361.1 118.5 356.5 113.8L334.2 91.5C329.6 86.9 322.1 86.9 317.4 91.5L256 152.9L194.6 91.5C190 86.9 182.5 86.9 177.8 91.5L155.5 113.8C150.9 118.4 150.9 125.9 155.5 130.6L216.9 192L155.5 253.4000000000001C150.9 258 150.9 265.5 155.5 270.2000000000001L177.8 292.5000000000001C182.4 297.1 189.9 297.1 194.6 292.5000000000001L256 231.1000000000001L317.4 292.5000000000001C322 297.1 329.5 297.1 334.2 292.5000000000001L356.5 270.2000000000001C361.2 265.6 361.2 258.1 356.5 253.4000000000001z" />
<glyph glyph-name="window-maximize"
unicode="&#xF2D0;"
horiz-adv-x="512" d=" M464 416H48C21.5 416 0 394.5 0 368V16C0 -10.5 21.5 -32 48 -32H464C490.5 -32 512 -10.5 512 16V368C512 394.5 490.5 416 464 416zM464 22C464 18.7 461.3 16 458 16H54C50.7 16 48 18.7 48 22V256H464V22z" />
<glyph glyph-name="window-minimize"
unicode="&#xF2D1;"
horiz-adv-x="512" d=" M480 -32H32C14.3 -32 0 -17.7 0 0S14.3 32 32 32H480C497.7 32 512 17.7 512 0S497.7 -32 480 -32z" />
<glyph glyph-name="window-restore"
unicode="&#xF2D2;"
horiz-adv-x="512" d=" M464 448H144C117.5 448 96 426.5 96 400V352H48C21.5 352 0 330.5 0 304V-16C0 -42.5 21.5 -64 48 -64H368C394.5 -64 416 -42.5 416 -16V32H464C490.5 32 512 53.5 512 80V400C512 426.5 490.5 448 464 448zM368 -16H48V192H368V-16zM464 80H416V304C416 330.5 394.5 352 368 352H144V400H464V80z" />

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More