New settings panel & &subscription
This commit is contained in:
1 parent
7a03fa94ab
commit
13a9155634
20 files changed
+790
-144
No files matched your search
@@ -0,0 +1,14 @@
|
|||||||
|
CREATE TABLE `users` (
|
||||||
|
`id_user` int(10) UNSIGNED auto_increment,
|
||||||
|
`name` VARCHAR(100),
|
||||||
|
`email` VARCHAR(320),
|
||||||
|
`language` VARCHAR(2),
|
||||||
|
`active` BOOLEAN,
|
||||||
|
`led` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`id_user`),
|
||||||
|
UNIQUE KEY `uni_email` (`email`)
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE posts ADD COLUMN id_user int(10) UNSIGNED AFTER id_project;
|
||||||
|
ALTER TABLE posts ADD INDEX(`id_user`);
|
||||||
|
ALTER TABLE posts ADD FOREIGN KEY (`id_user`) REFERENCES users(`id_user`);
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Email extends PhpObject {
|
||||||
|
|
||||||
|
private $sServName;
|
||||||
|
private $sTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var Translator[]
|
||||||
|
*/
|
||||||
|
private $asTranslators;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var Mask[]
|
||||||
|
*/
|
||||||
|
private $asTemplates;
|
||||||
|
|
||||||
|
private $asDests;
|
||||||
|
|
||||||
|
public function __construct($sServName, $sTemplate='') {
|
||||||
|
$this->sServName = $sServName;
|
||||||
|
$this->setTemplate($sTemplate);
|
||||||
|
$this->asDests = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTemplate($sTemplate) {
|
||||||
|
$this->sTemplate = $sTemplate;
|
||||||
|
$this->asTranslators = array();
|
||||||
|
$this->asTemplates = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTemplate($sLanguage) {
|
||||||
|
if(!array_key_exists($sLanguage, $this->asTemplates)) {
|
||||||
|
$this->asTranslators[$sLanguage] = new Translator($sLanguage);
|
||||||
|
$this->buildTemplate($sLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array('subject'=>$this->asTranslators[$sLanguage]->getTranslation('conf_subject'), 'email'=>$this->asTemplates[$sLanguage]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildTemplate($sLanguage) {
|
||||||
|
$oTemplate = new Mask($this->sTemplate, $this->asTranslators[$sLanguage]);
|
||||||
|
|
||||||
|
switch($this->sTemplate) {
|
||||||
|
case 'confirmation':
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->asTemplates[$sLanguage] = $oTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Target User Info
|
||||||
|
* @param array $asDests Contains: id_user, name, email, language, active
|
||||||
|
*/
|
||||||
|
public function setDestInfo($asDests) {
|
||||||
|
if(array_key_exists('email', $asDests)) $asDests = array($asDests);
|
||||||
|
$this->asDests = $asDests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send() {
|
||||||
|
$sEOL = "\r\n";
|
||||||
|
foreach($this->asDests as $asDest) {
|
||||||
|
//Message
|
||||||
|
$asTemplate = $this->getTemplate($asDest['language']);
|
||||||
|
$oEmail = $asTemplate['email'];
|
||||||
|
|
||||||
|
//Unsubscribe Link
|
||||||
|
$sUnsubLink = $this->sServName.'?a=unsubscribe_email&id='.$asDest['id_user'];
|
||||||
|
$oEmail->setTag('unsubscribe_link', $sUnsubLink);
|
||||||
|
|
||||||
|
//Email Content
|
||||||
|
$sHtmlMessage = $oEmail->getMask();
|
||||||
|
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
||||||
|
|
||||||
|
//Email
|
||||||
|
$iBoundary = uniqid("HTMLEMAIL");
|
||||||
|
$sHeaders =
|
||||||
|
'From: Spotty <spot@lutran.fr>'.$sEOL.
|
||||||
|
'Reply-To: Spotty <spot@lutran.fr>'.$sEOL.
|
||||||
|
'List-Unsubscribe: <mailto:unsubscribe@'.parse_url($this->sServName)['host'].'?subject=unsubscribe>, <'.$sUnsubLink.'>'.$sEOL.
|
||||||
|
'List-Unsubscribe-Post: List-Unsubscribe=One-Click'.$sEOL.
|
||||||
|
'MIME-Version: 1.0'.$sEOL.
|
||||||
|
'Content-Type: multipart/alternative; boundary="'.$iBoundary.'"'.$sEOL;
|
||||||
|
|
||||||
|
$sBody =
|
||||||
|
'--'.$iBoundary.$sEOL. //Plain Message
|
||||||
|
'Content-Type: text/plain; charset=UTF-8'.$sEOL.
|
||||||
|
'Content-Transfer-Encoding: base64'.$sEOL.
|
||||||
|
chunk_split(base64_encode($sPlainMessage)).$sEOL.
|
||||||
|
|
||||||
|
'--'.$iBoundary.$sEOL. //HTML Message
|
||||||
|
'Content-Type: text/html; charset=UTF-8'.$sEOL.
|
||||||
|
'Content-Transfer-Encoding: base64'.$sEOL.
|
||||||
|
chunk_split(base64_encode($sHtmlMessage)).$sEOL.
|
||||||
|
'--'.$iBoundary.'--';
|
||||||
|
|
||||||
|
//Send
|
||||||
|
if(!mail($asDest['email'], $asTemplate['subject'], $sBody, $sHeaders)) $this->addError('Could not send '.$this->sTemplate.' email to '.$asDest['email']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -101,7 +101,7 @@ class Feed extends PhpObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function checkUpdateFeed($sProjectMode) {
|
public function checkUpdateFeed($sProjectMode) {
|
||||||
//Feed updated once a day in Blog Mode
|
//Feed updated once every hour in Blog Mode
|
||||||
if($sProjectMode == Project::MODE_BLOG && date('Y-m-d-H', $this->iLastUpdate) != date('Y-m-d-H')) $this->updateFeed();
|
if($sProjectMode == Project::MODE_BLOG && date('Y-m-d-H', $this->iLastUpdate) != date('Y-m-d-H')) $this->updateFeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+70
-14
@@ -21,6 +21,8 @@ class Spot extends Main
|
|||||||
|
|
||||||
const FEED_CHUNK_SIZE = 15;
|
const FEED_CHUNK_SIZE = 15;
|
||||||
|
|
||||||
|
const DEFAULT_LANG = 'en';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Active Project
|
* Active Project
|
||||||
* @var Project
|
* @var Project
|
||||||
@@ -33,18 +35,27 @@ class Spot extends Main
|
|||||||
*/
|
*/
|
||||||
private $oMedia;
|
private $oMedia;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User
|
||||||
|
* @var User
|
||||||
|
*/
|
||||||
|
private $oUser;
|
||||||
|
|
||||||
public function __construct($oClassManagement, $sProcessPage, $sTimezone)
|
public function __construct($oClassManagement, $sProcessPage, $sTimezone)
|
||||||
{
|
{
|
||||||
$asClasses = array(
|
$asClasses = array(
|
||||||
array('name'=>'feed', 'project'=>true),
|
array('name'=>'feed', 'project'=>true),
|
||||||
array('name'=>'project', 'project'=>true),
|
array('name'=>'project', 'project'=>true),
|
||||||
array('name'=>'media', 'project'=>true),
|
array('name'=>'media', 'project'=>true),
|
||||||
array('name'=>'converter', 'project'=>true)
|
array('name'=>'converter', 'project'=>true),
|
||||||
|
array('name'=>'user', 'project'=>true)
|
||||||
);
|
);
|
||||||
parent::__construct($oClassManagement, $sProcessPage, $asClasses, true, __FILE__, $sTimezone);
|
parent::__construct($oClassManagement, $sProcessPage, $asClasses, true, __FILE__, $sTimezone);
|
||||||
|
|
||||||
|
$this->oUser = new User($this->oDb);
|
||||||
|
|
||||||
$this->oClassManagement->incClass('translator');
|
$this->oClassManagement->incClass('translator');
|
||||||
$this->oLang = new Translator('', 'en');
|
$this->oLang = new Translator($this->oUser->getLang(), self::DEFAULT_LANG);
|
||||||
|
|
||||||
$this->oProject = new Project($this->oDb);
|
$this->oProject = new Project($this->oDb);
|
||||||
$this->oMedia = new Media($this->oDb, $this->oProject);
|
$this->oMedia = new Media($this->oDb, $this->oProject);
|
||||||
@@ -66,8 +77,9 @@ class Spot extends Main
|
|||||||
Feed::FEED_TABLE => array('ref_feed_id', Db::getId(Feed::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'),
|
Feed::FEED_TABLE => array('ref_feed_id', Db::getId(Feed::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'),
|
||||||
Feed::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
|
Feed::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
|
||||||
Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to', 'timezone'),
|
Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to', 'timezone'),
|
||||||
self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), 'name', 'content', 'site_time'),
|
self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), Db::getId(User::USER_TABLE), 'name', 'content', 'site_time'),
|
||||||
Media::MEDIA_TABLE => array(Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'rotate', 'comment')
|
Media::MEDIA_TABLE => array(Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'rotate', 'comment'),
|
||||||
|
User::USER_TABLE => array('name', 'email', 'language', 'active')
|
||||||
),
|
),
|
||||||
'types' => array
|
'types' => array
|
||||||
(
|
(
|
||||||
@@ -95,7 +107,10 @@ class Spot extends Main
|
|||||||
'taken_on' => "TIMESTAMP DEFAULT 0",
|
'taken_on' => "TIMESTAMP DEFAULT 0",
|
||||||
'posted_on' => "TIMESTAMP DEFAULT 0",
|
'posted_on' => "TIMESTAMP DEFAULT 0",
|
||||||
'rotate' => "SMALLINT",
|
'rotate' => "SMALLINT",
|
||||||
'comment' => "LONGTEXT"
|
'comment' => "LONGTEXT",
|
||||||
|
'email' => "VARCHAR(320)",
|
||||||
|
'language' => "VARCHAR(2)",
|
||||||
|
'active' => "BOOLEAN"
|
||||||
),
|
),
|
||||||
'constraints' => array
|
'constraints' => array
|
||||||
(
|
(
|
||||||
@@ -103,7 +118,8 @@ class Spot extends Main
|
|||||||
Feed::FEED_TABLE => array("UNIQUE KEY `uni_ref_feed_id` (`ref_feed_id`)", "INDEX(`ref_feed_id`)"),
|
Feed::FEED_TABLE => array("UNIQUE KEY `uni_ref_feed_id` (`ref_feed_id`)", "INDEX(`ref_feed_id`)"),
|
||||||
Feed::SPOT_TABLE => array("UNIQUE KEY `uni_ref_spot_id` (`ref_spot_id`)", "INDEX(`ref_spot_id`)"),
|
Feed::SPOT_TABLE => array("UNIQUE KEY `uni_ref_spot_id` (`ref_spot_id`)", "INDEX(`ref_spot_id`)"),
|
||||||
Project::PROJ_TABLE => "UNIQUE KEY `uni_proj_name` (`codename`)",
|
Project::PROJ_TABLE => "UNIQUE KEY `uni_proj_name` (`codename`)",
|
||||||
Media::MEDIA_TABLE => "UNIQUE KEY `uni_file_name` (`filename`)"
|
Media::MEDIA_TABLE => "UNIQUE KEY `uni_file_name` (`filename`)",
|
||||||
|
User::USER_TABLE => "UNIQUE KEY `uni_email` (`email`)"
|
||||||
),
|
),
|
||||||
'cascading_delete' => array
|
'cascading_delete' => array
|
||||||
(
|
(
|
||||||
@@ -119,7 +135,8 @@ class Spot extends Main
|
|||||||
'vars' => array(
|
'vars' => array(
|
||||||
'chunk_size' => self::FEED_CHUNK_SIZE,
|
'chunk_size' => self::FEED_CHUNK_SIZE,
|
||||||
'default_project_codename' => $this->oProject->getProjectCodeName(),
|
'default_project_codename' => $this->oProject->getProjectCodeName(),
|
||||||
'projects' => $this->oProject->getProjects()
|
'projects' => $this->oProject->getProjects(),
|
||||||
|
'user' => $this->oUser->getUserInfo()
|
||||||
),
|
),
|
||||||
'consts' => array(
|
'consts' => array(
|
||||||
'geo_server' => Settings::GEO_SERVER,
|
'geo_server' => Settings::GEO_SERVER,
|
||||||
@@ -155,7 +172,7 @@ class Spot extends Main
|
|||||||
public function getMarkers()
|
public function getMarkers()
|
||||||
{
|
{
|
||||||
$asMessages = $this->getSpotMessages();
|
$asMessages = $this->getSpotMessages();
|
||||||
$bSuccess = !empty($asMessages);
|
$bSuccess = !empty($this->getMedias('posted_on') + $asMessages + $this->getPosts());
|
||||||
$sDesc = $bSuccess?'':self::NO_DATA;
|
$sDesc = $bSuccess?'':self::NO_DATA;
|
||||||
|
|
||||||
//Add medias
|
//Add medias
|
||||||
@@ -183,6 +200,35 @@ class Spot extends Main
|
|||||||
return self::getJsonResult($bSuccess, $sDesc, $asMessages);
|
return self::getJsonResult($bSuccess, $sDesc, $asMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function subscribe($sEmail) {
|
||||||
|
$asResult = $this->oUser->addUser($sEmail, $this->oLang->getLanguage());
|
||||||
|
|
||||||
|
//Send Confirmation Email
|
||||||
|
if($asResult['result']) {
|
||||||
|
$this->oClassManagement->incClass('email', true);
|
||||||
|
$oConfEmail = new Email($this->asContext['serv_name'],'email_confirmation');
|
||||||
|
$oConfEmail->setDestInfo($this->oUser->getUserInfo());
|
||||||
|
$oConfEmail->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unsubscribe() {
|
||||||
|
$asResult = $this->oUser->removeUser();
|
||||||
|
return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unsubscribeFromEmail($iUserId) {
|
||||||
|
$this->oUser->setUserId($iUserId);
|
||||||
|
$this->oLang->setLanguage($this->oUser->getLang(), self::DEFAULT_LANG);
|
||||||
|
$asResult = $this->oUser->removeUser();
|
||||||
|
|
||||||
|
$sDesc = $asResult['desc'];
|
||||||
|
if($sDesc=='') $sDesc = $this->oLang->getTranslation('nl_unsubscribed');
|
||||||
|
return $sDesc;
|
||||||
|
}
|
||||||
|
|
||||||
private function getSpotMessages()
|
private function getSpotMessages()
|
||||||
{
|
{
|
||||||
$asMessages = array();
|
$asMessages = array();
|
||||||
@@ -192,20 +238,22 @@ class Spot extends Main
|
|||||||
foreach($asFeeds as $iFeedId) {
|
foreach($asFeeds as $iFeedId) {
|
||||||
$oFeed = new Feed($this->oDb, $iFeedId);
|
$oFeed = new Feed($this->oDb, $iFeedId);
|
||||||
$asMessages = $oFeed->getMessages($this->oProject->getActivePeriod());
|
$asMessages = $oFeed->getMessages($this->oProject->getActivePeriod());
|
||||||
foreach($asMessages as $iIndex=>&$asMessage)
|
foreach($asMessages as &$asMessage)
|
||||||
{
|
{
|
||||||
$asMessage['latitude'] = floatval($asMessage['latitude']);
|
$asMessage['latitude'] = floatval($asMessage['latitude']);
|
||||||
$asMessage['longitude'] = floatval($asMessage['longitude']);
|
$asMessage['longitude'] = floatval($asMessage['longitude']);
|
||||||
$asMessage['lat_dms'] = self::decToDms($asMessage['latitude'], 'lat');
|
$asMessage['lat_dms'] = self::decToDms($asMessage['latitude'], 'lat');
|
||||||
$asMessage['lon_dms'] = self::decToDms($asMessage['longitude'], 'lon');
|
$asMessage['lon_dms'] = self::decToDms($asMessage['longitude'], 'lon');
|
||||||
$asMessage['displayed_id'] = $iIndex + 1;
|
|
||||||
|
|
||||||
$this->addTimeStamp($asMessage, $asMessage['unix_time']);
|
$this->addTimeStamp($asMessage, $asMessage['unix_time']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usort($asMessages, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
|
usort($asMessages, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
|
||||||
|
|
||||||
return $asMessages;
|
$asSortedMessages = array_values($asMessages);
|
||||||
|
foreach($asSortedMessages as $iIndex=>&$asSortedMessage) $asSortedMessage['displayed_id'] = $iIndex + 1;
|
||||||
|
|
||||||
|
return $asSortedMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,20 +267,23 @@ class Spot extends Main
|
|||||||
{
|
{
|
||||||
$asMedias = $this->oMedia->getMediasInfo();
|
$asMedias = $this->oMedia->getMediasInfo();
|
||||||
$asValidMedias = array();
|
$asValidMedias = array();
|
||||||
foreach($asMedias as $iIndex=>$asMedia) {
|
foreach($asMedias as $asMedia) {
|
||||||
$sTimeRef = $asMedia[$sTimeRefField];
|
$sTimeRef = $asMedia[$sTimeRefField];
|
||||||
if($sTimeRef >= $this->oProject->getActivePeriod('from') && $sTimeRef <= $this->oProject->getActivePeriod('to')) {
|
if($sTimeRef >= $this->oProject->getActivePeriod('from') && $sTimeRef <= $this->oProject->getActivePeriod('to')) {
|
||||||
$asMedia['taken_on_formatted'] = $this->getTimeFormat(strtotime($asMedia['taken_on']));
|
$asMedia['taken_on_formatted'] = $this->getTimeFormat(strtotime($asMedia['taken_on']));
|
||||||
$asMedia['posted_on_formatted'] = $this->getTimeFormat(strtotime($asMedia['posted_on']));
|
$asMedia['posted_on_formatted'] = $this->getTimeFormat(strtotime($asMedia['posted_on']));
|
||||||
$asMedia['displayed_id'] = $iIndex + 1;
|
|
||||||
|
|
||||||
$this->addTimeStamp($asMedia, strtotime($sTimeRef));
|
$this->addTimeStamp($asMedia, strtotime($sTimeRef));
|
||||||
$asValidMedias[] = $asMedia;
|
$asValidMedias[] = $asMedia;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usort($asValidMedias, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
|
usort($asValidMedias, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
|
||||||
|
|
||||||
return $asValidMedias;
|
$asSortedMedias = array_values($asValidMedias);
|
||||||
|
foreach($asSortedMedias as $iIndex=>&$asSortedMedia) $asSortedMedia['displayed_id'] = $iIndex + 1;
|
||||||
|
|
||||||
|
return $asSortedMedias;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPosts()
|
private function getPosts()
|
||||||
@@ -251,6 +302,7 @@ class Spot extends Main
|
|||||||
foreach($asPosts as &$asPost) {
|
foreach($asPosts as &$asPost) {
|
||||||
$iUnixTimeStamp = strtotime($asPost['site_time']); //assumes site timezone (Settings::TIMEZONE)
|
$iUnixTimeStamp = strtotime($asPost['site_time']); //assumes site timezone (Settings::TIMEZONE)
|
||||||
$asPost['formatted_name'] = Toolbox::mb_ucwords($asPost['name']);
|
$asPost['formatted_name'] = Toolbox::mb_ucwords($asPost['name']);
|
||||||
|
unset($asPost[Db::getId(User::USER_TABLE)]);
|
||||||
|
|
||||||
$this->addTimeStamp($asPost, $iUnixTimeStamp);
|
$this->addTimeStamp($asPost, $iUnixTimeStamp);
|
||||||
}
|
}
|
||||||
@@ -315,11 +367,15 @@ class Spot extends Main
|
|||||||
{
|
{
|
||||||
$asData = array(
|
$asData = array(
|
||||||
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
||||||
|
Db::getId(User::USER_TABLE) => $this->oUser->getUserId(),
|
||||||
'name' => mb_strtolower(trim($sName)),
|
'name' => mb_strtolower(trim($sName)),
|
||||||
'content' => trim($sPost),
|
'content' => trim($sPost),
|
||||||
'site_time' => date(Db::TIMESTAMP_FORMAT) //site time (Settings::TIMEZONE)
|
'site_time' => date(Db::TIMESTAMP_FORMAT) //site time (Settings::TIMEZONE)
|
||||||
);
|
);
|
||||||
$iPostId = $this->oDb->insertRow(self::POST_TABLE, $asData);
|
$iPostId = $this->oDb->insertRow(self::POST_TABLE, $asData);
|
||||||
|
|
||||||
|
$this->oUser->updateNickname($sName);
|
||||||
|
|
||||||
return self::getJsonResult(($iPostId > 0), '');
|
return self::getJsonResult(($iPostId > 0), '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class User extends PhpObject {
|
||||||
|
|
||||||
|
//DB Tables
|
||||||
|
const USER_TABLE = 'users';
|
||||||
|
|
||||||
|
//Cookie
|
||||||
|
const COOKIE_ID_USER = 'subscriber';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Handle
|
||||||
|
* @var Db
|
||||||
|
*/
|
||||||
|
private $oDb;
|
||||||
|
|
||||||
|
//User Info
|
||||||
|
private $iUserId;
|
||||||
|
private $asUserInfo;
|
||||||
|
|
||||||
|
public function __construct(Db &$oDb) {
|
||||||
|
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||||
|
$this->oDb = &$oDb;
|
||||||
|
$this->iUserId = 0;
|
||||||
|
$this->asUserInfo = array('name'=>'', 'email'=>'', 'language'=>'', 'active'=>0);
|
||||||
|
$this->checkUserCookie();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLang() {
|
||||||
|
return $this->asUserInfo['language'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addUser($sEmail, $sLang) {
|
||||||
|
$bSuccess = false;
|
||||||
|
$sDesc = '';
|
||||||
|
$sEmail = trim($sEmail);
|
||||||
|
|
||||||
|
//Check Email availability
|
||||||
|
$iUserId = $this->oDb->selectValue(self::USER_TABLE, Db::getId(self::USER_TABLE), array('email'=>$sEmail, 'active'=>true));
|
||||||
|
|
||||||
|
if($iUserId > 0) $sDesc = 'lang:nl_email_exists';
|
||||||
|
else {
|
||||||
|
//Add/Reactivate user
|
||||||
|
$iUserId = $this->oDb->insertUpdateRow(self::USER_TABLE, array('email'=>$sEmail, 'language'=>$sLang, 'active'=>true), array('email'));
|
||||||
|
if($iUserId==0) $sDesc = 'lang:error_commit_db';
|
||||||
|
else $bSuccess = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set Cookie (valid 1 year)
|
||||||
|
if($iUserId > 0) {
|
||||||
|
$this->setUserId($iUserId);
|
||||||
|
$this->updateCookie();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Spot::getResult($bSuccess, $sDesc, $this->getUserInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeUser() {
|
||||||
|
$bSuccess = false;
|
||||||
|
$sDesc = '';
|
||||||
|
|
||||||
|
if($this->iUserId > 0) {
|
||||||
|
$iUserId = $this->oDb->updateRow(self::USER_TABLE, $this->iUserId, array('active'=>false));
|
||||||
|
if($iUserId==0) $sDesc = 'lang:error_commit_db';
|
||||||
|
else $bSuccess = true;
|
||||||
|
}
|
||||||
|
else $sDesc = 'lang:nl_unknown_email';
|
||||||
|
|
||||||
|
return Spot::getResult($bSuccess, $sDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateNickname($sNickname) {
|
||||||
|
if($this->iUserId > 0 && $sNickname!='') $this->oDb->updateRow(self::USER_TABLE, $this->iUserId, array('name'=>$sNickname));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkUserCookie() {
|
||||||
|
if(isset($_COOKIE[self::COOKIE_ID_USER])){
|
||||||
|
$this->setUserId($_COOKIE[self::COOKIE_ID_USER]);
|
||||||
|
|
||||||
|
//Extend cookie life
|
||||||
|
if($this->iUserId > 0) $this->updateCookie();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserId() {
|
||||||
|
return $this->iUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserInfo() {
|
||||||
|
$asUserInfo = $this->asUserInfo;
|
||||||
|
$asUserInfo[Db::getId(self::USER_TABLE)] = $this->iUserId;
|
||||||
|
return $asUserInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUserId($iUserId) {
|
||||||
|
$this->iUserId = 0;
|
||||||
|
|
||||||
|
$asUser = $this->oDb->selectRow(self::USER_TABLE, array(Db::getId(self::USER_TABLE)=>$iUserId, 'active'=>true), array_keys($this->asUserInfo));
|
||||||
|
if(!empty($asUser)) {
|
||||||
|
$this->iUserId = $iUserId;
|
||||||
|
$this->asUserInfo = $asUser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateCookie() {
|
||||||
|
setcookie(self::COOKIE_ID_USER, $this->iUserId, time() + 60 * 60 * 24 * 365);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ $sField = isset($_REQUEST['field'])?$_REQUEST['field']:'';
|
|||||||
$oValue = isset($_REQUEST['value'])?$_REQUEST['value']:'';
|
$oValue = isset($_REQUEST['value'])?$_REQUEST['value']:'';
|
||||||
$iId = isset($_REQUEST['id'])?$_REQUEST['id']:0;
|
$iId = isset($_REQUEST['id'])?$_REQUEST['id']:0;
|
||||||
$sType = isset($_REQUEST['type'])?$_REQUEST['type']:'';
|
$sType = isset($_REQUEST['type'])?$_REQUEST['type']:'';
|
||||||
|
$sEmail = isset($_REQUEST['email'])?$_REQUEST['email']:'';
|
||||||
|
|
||||||
//Initiate class
|
//Initiate class
|
||||||
$oSpot = new Spot($oClassManagement, __FILE__, $sTimezone);
|
$oSpot = new Spot($oClassManagement, __FILE__, $sTimezone);
|
||||||
@@ -65,6 +66,15 @@ if($sAction!='')
|
|||||||
case 'build_geojson':
|
case 'build_geojson':
|
||||||
$sResult = $oSpot->convertGpxToGeojson($sName);
|
$sResult = $oSpot->convertGpxToGeojson($sName);
|
||||||
break;
|
break;
|
||||||
|
case 'subscribe':
|
||||||
|
$sResult = $oSpot->subscribe($sEmail);
|
||||||
|
break;
|
||||||
|
case 'unsubscribe':
|
||||||
|
$sResult = $oSpot->unsubscribe();
|
||||||
|
break;
|
||||||
|
case 'unsubscribe_email':
|
||||||
|
$sResult = $oSpot->unsubscribeFromEmail($iId);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$sResult = Main::getJsonResult(false, Main::NOT_FOUND);
|
$sResult = Main::getJsonResult(false, Main::NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ admin_save_success = Saved
|
|||||||
track_main = Main track
|
track_main = Main track
|
||||||
track_offtrack = Off-track
|
track_offtrack = Off-track
|
||||||
track_hitchhiking = Hitchhiking
|
track_hitchhiking = Hitchhiking
|
||||||
|
track_download = Download GPX Track
|
||||||
|
|
||||||
upload_title = Picture & Video Uploads
|
upload_title = Picture & Video Uploads
|
||||||
upload_wrong_mode = Project "$0" is not in blog mode. No upload allowed
|
upload_wrong_mode = Project "$0" is not in blog mode. No upload allowed
|
||||||
@@ -20,6 +21,7 @@ post_new_message = New message
|
|||||||
and = and
|
and = and
|
||||||
counter = #$0
|
counter = #$0
|
||||||
|
|
||||||
|
maps = Base Maps
|
||||||
map_satellite = Satellite
|
map_satellite = Satellite
|
||||||
map_otm = Open Topo Map
|
map_otm = Open Topo Map
|
||||||
map_ign_france = IGN (France)
|
map_ign_france = IGN (France)
|
||||||
@@ -38,11 +40,13 @@ click_zoom = Click to zoom
|
|||||||
media_count = Media $0 / $1
|
media_count = Media $0 / $1
|
||||||
media_no_id = Missing Media ID in request
|
media_no_id = Missing Media ID in request
|
||||||
media_comment_update= Comment of media "$0" updated
|
media_comment_update= Comment of media "$0" updated
|
||||||
|
see_on_google = See on Google Maps
|
||||||
|
|
||||||
city_time = $0 Time
|
city_time = $0 Time
|
||||||
|
|
||||||
project_id = Project ID
|
project_id = Project ID
|
||||||
project = Project
|
project = Project
|
||||||
|
projects = Projects
|
||||||
mode = Mode
|
mode = Mode
|
||||||
code_name = Code name
|
code_name = Code name
|
||||||
start = Start
|
start = Start
|
||||||
@@ -62,3 +66,25 @@ time_zone = Time zone
|
|||||||
unit_day = day
|
unit_day = day
|
||||||
unit_days = days
|
unit_days = days
|
||||||
unit_hour = h
|
unit_hour = h
|
||||||
|
|
||||||
|
newsletter = Keep in touch!
|
||||||
|
nl_email_placeholder= my@email.com
|
||||||
|
nl_subscribed_desc = You're all set. We'll send you updates as soon as we get them
|
||||||
|
nl_unsubscribed_desc= Write down your email address and we'll send you François' position as soon as we get it :)
|
||||||
|
nl_email_exists = This email is already subscribed
|
||||||
|
nl_subscribe = Subscribe
|
||||||
|
nl_subscribed = Thanks! You'll receive a confirmation email shortly
|
||||||
|
nl_unsubscribe = Unsubscribe
|
||||||
|
nl_unsubscribed = Done. No more junk mail from us
|
||||||
|
nl_unknown_email = Unknown email address
|
||||||
|
|
||||||
|
conf_subject = Successful Registration
|
||||||
|
conf_preheader = Thanks for keeping in touch!
|
||||||
|
conf_thanks_sub = You're all set!
|
||||||
|
conf_body_para_1 = Thank you for checking in on my wanderings :). I'll make sure to keep you posted on my progress along the trail.
|
||||||
|
conf_body_para_2 = I usually check-in once a day, plus sometimes on special events, like successful peak ascents. I am using a GPS-based device (PLB) which does not require phone reception to work. Thus the messages should be pretty frequent, but, being awestruck by the beauty of nature, I could also just forget to send a signal once in a while. So do not worry if you don't receive anything for a couple of days.
|
||||||
|
conf_body_para_3 = If I've posted some pictures recently, you should also get them in this email.
|
||||||
|
conf_body_conclusion= Happy Trails!
|
||||||
|
conf_signature = --François
|
||||||
|
conf_unsubscribe = PS: Changed your mind?
|
||||||
|
conf_unsubscribe_btn= Unsubscribe
|
||||||
@@ -8,6 +8,7 @@ admin_save_success = Sauvegardé
|
|||||||
track_main = Trajet principal
|
track_main = Trajet principal
|
||||||
track_offtrack = Variante
|
track_offtrack = Variante
|
||||||
track_hitchhiking = Hors rando
|
track_hitchhiking = Hors rando
|
||||||
|
track_download = Télécharger la trace GPX
|
||||||
|
|
||||||
upload_title = Uploader photos & vidéos
|
upload_title = Uploader photos & vidéos
|
||||||
upload_wrong_mode = Le projet "$0" n'est pas en mode blog. Aucun upload possible
|
upload_wrong_mode = Le projet "$0" n'est pas en mode blog. Aucun upload possible
|
||||||
@@ -20,6 +21,7 @@ post_new_message = Nouveau message
|
|||||||
and = et
|
and = et
|
||||||
counter = N° $0
|
counter = N° $0
|
||||||
|
|
||||||
|
maps = Fonds de carte
|
||||||
map_satellite = Satellite
|
map_satellite = Satellite
|
||||||
map_otm = Open Topo Map
|
map_otm = Open Topo Map
|
||||||
map_ign_france = IGN (France)
|
map_ign_france = IGN (France)
|
||||||
@@ -38,11 +40,13 @@ click_zoom = Click pour zoomer
|
|||||||
media_count = Média $0 sur $1
|
media_count = Média $0 sur $1
|
||||||
media_no_id = ID du média manquant
|
media_no_id = ID du média manquant
|
||||||
media_comment_update= Commentaire du media "$0" mis-à-jour
|
media_comment_update= Commentaire du media "$0" mis-à-jour
|
||||||
|
see_on_google = Voir la position sur Google Maps
|
||||||
|
|
||||||
city_time = heure de $0
|
city_time = heure de $0
|
||||||
|
|
||||||
project_id = ID projet
|
project_id = ID projet
|
||||||
project = Projet
|
project = Projet
|
||||||
|
projects = Projets
|
||||||
mode = Mode
|
mode = Mode
|
||||||
code_name = Nom de code
|
code_name = Nom de code
|
||||||
start = Départ
|
start = Départ
|
||||||
@@ -62,3 +66,25 @@ time_zone = Fuseau horaire
|
|||||||
unit_day = jour
|
unit_day = jour
|
||||||
unit_days = jours
|
unit_days = jours
|
||||||
unit_hour = h
|
unit_hour = h
|
||||||
|
|
||||||
|
newsletter = Rester en contact
|
||||||
|
nl_email_placeholder= mon@email.com
|
||||||
|
nl_subscribed_desc = C'est tout bon. On t'enverra les nouvelles posititions dès qu'on les reçoit
|
||||||
|
nl_unsubscribed_desc= Ajoute ton adresse email et on t'enverra la nouvelle position de François dès qu'on la reçoit :)
|
||||||
|
nl_email_exists = Cette adresse email est déjà enregistrée
|
||||||
|
nl_subscribe = S'abonner
|
||||||
|
nl_subscribed = Merci ! Tu vas recevoir un email de confirmation très bientôt
|
||||||
|
nl_unsubscribe = Se désinscrire
|
||||||
|
nl_unsubscribed = C'est fait. Fini le spam!
|
||||||
|
nl_unknown_email = Adresse email inconnue
|
||||||
|
|
||||||
|
conf_subject = Confirmation
|
||||||
|
conf_preheader = Merci de rester en contact !
|
||||||
|
conf_thanks_sub = C'est tout bon !
|
||||||
|
conf_body_para_1 = C'est gentil de venir voir où j'en suis. Promis, je vous tiendrais au courant de mon avancée.
|
||||||
|
conf_body_para_2 = En général, j'envoie un message une fois par jour. Lorsque je passe à des endroits sympas, j'en envoie un supplémentaire (ascension de sommets, ce genre de choses). J'utilise une balise GPS pour envoyer le signal, je n'ai donc pas besoin de réseau téléphonique pour que cela fonctionne. Cependant, il peut m'arriver d'appuyer sur le bouton. Donc pas de raison de s'inquiéter si vous ne recevez pas de messages pendant une journée ou deux.
|
||||||
|
conf_body_para_3 = If I've posted some pictures recently, you should also get them in this email.
|
||||||
|
conf_body_conclusion= A bientôt sur les chemins !
|
||||||
|
conf_signature = --François
|
||||||
|
conf_unsubscribe = PS: Trop d'emails ?
|
||||||
|
conf_unsubscribe_btn= Se désinscrire
|
||||||
+1
-1
@@ -48,7 +48,7 @@
|
|||||||
<tbody></tbody>
|
<tbody></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id="feedback"></div>
|
<div id="feedback" class="feedback"></div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
oSpot.pageInit = function(asHash) {
|
oSpot.pageInit = function(asHash) {
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||||
|
<title>[#]lang:conf_subject[#]</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span style="color: transparent; display: none !important; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">[#]lang:conf_preheader[#]</span>
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="width:100%;max-width:600px;">
|
||||||
|
<tr>
|
||||||
|
<td width="20%"><img src="https://spot.lutran.fr/images/icons/mstile-144x144.png" width="90%" border="0" alt="logo" /></td>
|
||||||
|
<td><h1>[#]lang:conf_thanks_sub[#]</h1></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<p align="justify">[#]lang:conf_body_para_1[#]</p>
|
||||||
|
<p align="justify">[#]lang:conf_body_para_2[#]</p>
|
||||||
|
<p align="justify">[#]lang:conf_body_para_3[#]</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<p>[#]lang:conf_body_conclusion[#]<br />[#]lang:conf_signature[#]</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<p>[#]lang:conf_unsubscribe[#] <a href="[#]unsubscribe_link[#]" target="_blank">[#]lang:conf_unsubscribe_btn[#]</a></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+181
-49
@@ -3,6 +3,24 @@
|
|||||||
<div class="loader fa fa-fw fa-map flicker" id="map_loading"></div>
|
<div class="loader fa fa-fw fa-map flicker" id="map_loading"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
|
<div id="settings">
|
||||||
|
<div id="settings-sections">
|
||||||
|
<div class="settings-section">
|
||||||
|
<h1><i class="fa fa-fw push fa-map"></i>[#]lang:maps[#]</h1>
|
||||||
|
<div id="layers"></div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-section newsletter">
|
||||||
|
<h1><i class="fa fa-fw push fa-newsletter"></i>[#]lang:newsletter[#]</h1>
|
||||||
|
<input type="email" name="email" id="email" placeholder="[#]lang:nl_email_placeholder[#]" /><button id="nl_btn"><span><i class="fa"></i></span></button>
|
||||||
|
<div id="settings-feedback" class="feedback"></div>
|
||||||
|
<div id="nl_desc"></div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-section">
|
||||||
|
<h1><i class="fa fa-fw push fa-project"></i>[#]lang:projects[#]</h1>
|
||||||
|
<div id="settings-projects"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="feed">
|
<div id="feed">
|
||||||
<div id="posts">
|
<div id="posts">
|
||||||
<div id="poster"></div>
|
<div id="poster"></div>
|
||||||
@@ -11,6 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="elems">
|
<div id="elems">
|
||||||
|
<div id="settings-button"><i class="fa fa-menu fa-fw"></i></div>
|
||||||
<div id="post-button"><i class="fa fa-fw"></i></div>
|
<div id="post-button"><i class="fa fa-fw"></i></div>
|
||||||
<div id="legend" class="leaflet-control-layers leaflet-control leaflet-control-layers-expanded">
|
<div id="legend" class="leaflet-control-layers leaflet-control leaflet-control-layers-expanded">
|
||||||
<div class="track"><span class="line main"></span><span class="desc">[#]lang:track_main[#]</span></div>
|
<div class="track"><span class="line main"></span><span class="desc">[#]lang:track_main[#]</span></div>
|
||||||
@@ -40,7 +59,6 @@ oSpot.pageInit = function(asHash) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
oSpot.onResize = function() {
|
oSpot.onResize = function() {
|
||||||
self.tmp('mobile', $('#mobile').is(':visible'));
|
|
||||||
self.tmp('feed_width', self.tmp('with_feed')?$('#feed').outerWidth(true):0);
|
self.tmp('feed_width', self.tmp('with_feed')?$('#feed').outerWidth(true):0);
|
||||||
self.tmp('map_offset', -1 * self.tmp('feed_width') / $('body').outerWidth(true));
|
self.tmp('map_offset', -1 * self.tmp('feed_width') / $('body').outerWidth(true));
|
||||||
|
|
||||||
@@ -64,7 +82,7 @@ oSpot.onKeydown = function(oEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleFeedPanel(bShow, bAutoPan) {
|
function toggleFeedPanel(bShow, sMapAction) {
|
||||||
var $Container = $('#projects');
|
var $Container = $('#projects');
|
||||||
if(typeof bShow === 'undefined') $Container.toggleClass('with-feed');
|
if(typeof bShow === 'undefined') $Container.toggleClass('with-feed');
|
||||||
else $Container.toggleClass('with-feed', bShow);
|
else $Container.toggleClass('with-feed', bShow);
|
||||||
@@ -72,17 +90,36 @@ function toggleFeedPanel(bShow, bAutoPan) {
|
|||||||
oSpot.tmp('with_feed', $Container.hasClass('with-feed'));
|
oSpot.tmp('with_feed', $Container.hasClass('with-feed'));
|
||||||
oSpot.onResize();
|
oSpot.onResize();
|
||||||
|
|
||||||
if(typeof bAutoPan === 'undefined') bAutoPan = true;
|
if(isMobile()) $('#settings-button').toggle(!oSpot.tmp('with_feed'));
|
||||||
if(bAutoPan && typeof oSpot.tmp('map') != 'undefined') {
|
|
||||||
oSpot.tmp('map').panBy([(oSpot.tmp('with_feed')?1:-1)*$('#feed').outerWidth(true)/2, 0], {
|
sMapAction = sMapAction || 'panTo';
|
||||||
duration: 0.5
|
switch(sMapAction) {
|
||||||
});
|
case 'none': break;
|
||||||
|
case 'panTo': oSpot.tmp('map').panBy([(oSpot.tmp('with_feed')?1:-1)*$('#feed').outerWidth(true)/2, 0], {duration: 0.5}); break;
|
||||||
|
case 'panToInstant': oSpot.tmp('map').panBy([(oSpot.tmp('with_feed')?1:-1)*$('#feed').outerWidth(true)/2, 0]); break;
|
||||||
|
case 'fitBounds': oSpot.tmp('map').fitBounds(self.tmp('track').getBounds(), {paddingTopLeft: L.point(5, self.tmp('marker_size').height + 5), paddingBottomRight: L.point(self.tmp('feed_width') + 5, 5)}); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleSettingsPanel(bShow) {
|
||||||
|
var $Container = $('#projects');
|
||||||
|
if(typeof bShow === 'undefined') $Container.toggleClass('with-settings');
|
||||||
|
else $Container.toggleClass('with-settings', bShow);
|
||||||
|
|
||||||
|
var bWithSettings = isSettingsPanelOpen();
|
||||||
|
oSpot.onResize();
|
||||||
|
|
||||||
|
if(isMobile()) $('#post-button').toggle(!bWithSettings);
|
||||||
|
|
||||||
|
oSpot.tmp('map').panBy([(bWithSettings?-1:1)*$('#settings').outerWidth(true)/2, 0], {duration: 0.5});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSettingsPanelOpen() {
|
||||||
|
return $('#projects').hasClass('with-settings');
|
||||||
|
}
|
||||||
|
|
||||||
function isMobile() {
|
function isMobile() {
|
||||||
self.tmp('mobile', $('#mobile').is(':visible'));
|
return $('#mobile').is(':visible');
|
||||||
return self.tmp('mobile');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPage(asHash) {
|
function initPage(asHash) {
|
||||||
@@ -97,8 +134,7 @@ function initPage(asHash) {
|
|||||||
self.tmp('trail-markers', 'object');
|
self.tmp('trail-markers', 'object');
|
||||||
self.tmp('marker_size', {width: 32, height: 32});
|
self.tmp('marker_size', {width: 32, height: 32});
|
||||||
|
|
||||||
toggleFeedPanel(!isMobile(), false);
|
toggleFeedPanel(false, 'none');
|
||||||
oSpot.onResize();
|
|
||||||
|
|
||||||
//Lightbox options
|
//Lightbox options
|
||||||
lightbox.option({
|
lightbox.option({
|
||||||
@@ -119,6 +155,7 @@ function initPage(asHash) {
|
|||||||
self.tmp(['track-type-styles', sTrackType], {weight: parseInt($Legend.css('height')), color: $Legend.css('background-color'), opacity: 1});
|
self.tmp(['track-type-styles', sTrackType], {weight: parseInt($Legend.css('height')), color: $Legend.css('background-color'), opacity: 1});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Post Panel one-off init (see initPosts for project related init)
|
||||||
//Scrollbar
|
//Scrollbar
|
||||||
self.tmp('simple-bar', new SimpleBar($('#posts')[0]));
|
self.tmp('simple-bar', new SimpleBar($('#posts')[0]));
|
||||||
self.tmp('simple-bar').getScrollElement().addEventListener('scroll', onFeedScroll);
|
self.tmp('simple-bar').getScrollElement().addEventListener('scroll', onFeedScroll);
|
||||||
@@ -131,6 +168,12 @@ function initPage(asHash) {
|
|||||||
if(aiDelta.x > self.tmp('feed_width')/3 && aiDelta.x > Math.abs(aiDelta.y)) toggleFeedPanel(false);
|
if(aiDelta.x > self.tmp('feed_width')/3 && aiDelta.x > Math.abs(aiDelta.y)) toggleFeedPanel(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Feed Panel
|
||||||
|
initPosts();
|
||||||
|
|
||||||
|
//Settings Panel
|
||||||
|
initSettings();
|
||||||
|
|
||||||
//project Bootstrap
|
//project Bootstrap
|
||||||
initProject(asHash.items[0]);
|
initProject(asHash.items[0]);
|
||||||
}
|
}
|
||||||
@@ -163,34 +206,36 @@ function initProject(sProjectCodeName){
|
|||||||
mimeType: 'application/json'
|
mimeType: 'application/json'
|
||||||
})
|
})
|
||||||
).done(function(aoMessages, aoTracks) {
|
).done(function(aoMessages, aoTracks) {
|
||||||
initSpotMessages(aoMessages[0]['data'] || [], aoTracks[0]);
|
initSpotMessages(aoMessages[0]['data'] || [], aoTracks[0], aoMessages[0]['desc']=='No Data');
|
||||||
});
|
});
|
||||||
|
|
||||||
//Posts
|
//Show/Hide Poster Panel
|
||||||
initPosts();
|
var bHistoMode = (self.vars(['project', 'mode']) == self.consts.modes.histo);
|
||||||
|
$('#poster').toggle(!bHistoMode);
|
||||||
|
|
||||||
|
//Feed auto-update
|
||||||
|
self.tmp('simple-bar').getScrollElement().scrollTop = 0;
|
||||||
|
if(!bHistoMode) onAutoUpdate(true);
|
||||||
|
else updateFeed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPosts() {
|
function initPosts() {
|
||||||
var $Poster = $('#poster').empty();
|
|
||||||
if(self.vars(['project', 'mode'])==self.consts.modes.histo) $Poster.hide();
|
|
||||||
else {
|
|
||||||
var asPoster = {
|
var asPoster = {
|
||||||
type: 'poster',
|
type: 'poster',
|
||||||
formatted_time: '',
|
formatted_time: '',
|
||||||
relative_time: oSpot.lang('post_new_message')
|
relative_time: oSpot.lang('post_new_message')
|
||||||
};
|
};
|
||||||
getPost(asPoster).appendTo($Poster.show());
|
getPost(asPoster).appendTo($('#poster'));
|
||||||
|
|
||||||
autosize($('#post'));
|
autosize($('#post'));
|
||||||
|
|
||||||
$('#submit').click(function(){
|
$('#submit').click(function(){
|
||||||
if($Poster.checkForm())
|
if($('#poster').checkForm())
|
||||||
{
|
{
|
||||||
self.get(
|
self.get(
|
||||||
'add_post',
|
'add_post',
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
$('#name').val('');
|
|
||||||
$('#post').val('');
|
$('#post').val('');
|
||||||
updateFeed(true);
|
updateFeed(true);
|
||||||
},
|
},
|
||||||
@@ -204,10 +249,71 @@ function initPosts() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Feed auto-update
|
function initSettings(){
|
||||||
self.tmp('simple-bar').getScrollElement().scrollTop = 0;
|
//Scrollbar
|
||||||
if(self.vars(['project', 'mode']) != self.consts.modes.histo) onAutoUpdate(true);
|
new SimpleBar($('#settings-sections')[0]);
|
||||||
else updateFeed(true);
|
|
||||||
|
//Feedback display function
|
||||||
|
var settingsFeedback = function(sType, sMsg){
|
||||||
|
$('<p>', {'class': sType})
|
||||||
|
.append($('<i>', {'class':'fa push fa-'+sType}))
|
||||||
|
.append(sMsg)
|
||||||
|
.appendTo($('#settings-feedback'))
|
||||||
|
.slideDown('fast')
|
||||||
|
.delay(5000)
|
||||||
|
.slideUp('fast', function(){$(this).remove();});
|
||||||
|
};
|
||||||
|
|
||||||
|
//Newsletter Subscription
|
||||||
|
$('#nl_btn').click(function(){
|
||||||
|
var sAction = $(this).prop('name');
|
||||||
|
var sEmail = $('#email').val();
|
||||||
|
var regexEmail = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
if(!regexEmail.test(sEmail)) settingsFeedback('error', 'this is not an email');
|
||||||
|
else {
|
||||||
|
oSpot.get(
|
||||||
|
sAction,
|
||||||
|
function(asData) {
|
||||||
|
settingsFeedback('success', oSpot.lang('nl_'+sAction+'d'));
|
||||||
|
oSpot.vars('user', asData);
|
||||||
|
setUserInterface();
|
||||||
|
},
|
||||||
|
{'email': sEmail},
|
||||||
|
function(sDesc) {settingsFeedback('error', sDesc);},
|
||||||
|
function(sState) {
|
||||||
|
var bLoading = (sState=='start');
|
||||||
|
$('#nl_btn')
|
||||||
|
.prop('disabled', bLoading)
|
||||||
|
.toggleClass('loading', bLoading);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Twink interface with user data
|
||||||
|
setUserInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUserInterface() {
|
||||||
|
var asUserInfo = oSpot.vars('user');
|
||||||
|
if(asUserInfo.id_user) { //Subscribed User
|
||||||
|
$('#email').val(asUserInfo.email).prop('disabled', true);
|
||||||
|
$('#nl_btn').attr({name: 'unsubscribe', title: oSpot.lang('nl_unsubscribe'), 'class':'unsubscribe'});
|
||||||
|
$('#nl_desc').text(oSpot.lang('nl_subscribed_desc'));
|
||||||
|
|
||||||
|
//Populate nickname
|
||||||
|
if(asUserInfo.name) $('#name').val(asUserInfo.name);
|
||||||
|
}
|
||||||
|
else { //Unsubscribed User
|
||||||
|
//Switch to subcribe mode
|
||||||
|
$('#email').val('').prop('disabled', false);
|
||||||
|
$('#nl_btn').attr({name: 'subscribe', title: oSpot.lang('nl_subscribe'), 'class':'subscribe'});
|
||||||
|
$('#nl_desc').text(oSpot.lang('nl_unsubscribed_desc'));
|
||||||
|
|
||||||
|
//Reset nickname
|
||||||
|
$('#name').val('');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAutoUpdate(bFirstExec) {
|
function onAutoUpdate(bFirstExec) {
|
||||||
@@ -218,11 +324,17 @@ function onAutoUpdate(bFirstExec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getElevWidth() {
|
function getElevWidth() {
|
||||||
// Page widthFeed Panel Legend width (bottom left) Elevation right margin (from page side)
|
var
|
||||||
return $('#projects').width() - oSpot.tmp('feed_width') - $('.leaflet-bottom.leaflet-left > .leaflet-control-layers').outerWidth(true) - parseInt($('.leaflet-bottom.leaflet-right > .leaflet-control-scale').css('margin-right').slice(0, -2));
|
iPageWidth = $('#projects').width(),
|
||||||
|
iFeedPanelWidth = oSpot.tmp('feed_width'),
|
||||||
|
iSettingsPanelWidth = isSettingsPanelOpen()?$('#settings').outerWidth(true):0,
|
||||||
|
iLegendWidth = $('.leaflet-bottom.leaflet-left > .leaflet-control-layers').outerWidth(true),
|
||||||
|
oElevRightMarging = parseInt($('.leaflet-bottom.leaflet-right > .leaflet-control-scale').css('margin-right').slice(0, -2));
|
||||||
|
|
||||||
|
return iPageWidth - iFeedPanelWidth - iSettingsPanelWidth - iLegendWidth - oElevRightMarging;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSpotMessages(aoMessages, aoTracks) {
|
function initSpotMessages(aoMessages, aoTracks, bNoFeed) {
|
||||||
|
|
||||||
//Tile layers
|
//Tile layers
|
||||||
aoLayers = {};
|
aoLayers = {};
|
||||||
@@ -241,6 +353,13 @@ function initSpotMessages(aoMessages, aoTracks) {
|
|||||||
});
|
});
|
||||||
self.tmp('map', oMap);
|
self.tmp('map', oMap);
|
||||||
|
|
||||||
|
//Controls: Settings Panel
|
||||||
|
var oSettingsPanel = L.control({position: 'topleft'});
|
||||||
|
var $SettingsButton = $('#settings-button').clone();
|
||||||
|
$SettingsButton.click(toggleSettingsPanel);
|
||||||
|
oSettingsPanel.onAdd = function(oMap) {return $SettingsButton[0];};
|
||||||
|
oSettingsPanel.addTo(oMap);
|
||||||
|
|
||||||
//Controls: Feed Panel
|
//Controls: Feed Panel
|
||||||
var oFeedPanel = L.control({position: 'topright'});
|
var oFeedPanel = L.control({position: 'topright'});
|
||||||
var $PostButton = $('#post-button').clone();
|
var $PostButton = $('#post-button').clone();
|
||||||
@@ -254,27 +373,23 @@ function initSpotMessages(aoMessages, aoTracks) {
|
|||||||
oLegend.addTo(oMap);
|
oLegend.addTo(oMap);
|
||||||
|
|
||||||
//Controls: Projects
|
//Controls: Projects
|
||||||
var oProjects = L.control({position: 'bottomleft'});
|
|
||||||
oProjects.onAdd = function(oMap) {
|
|
||||||
var $Labels = $('<div>', {'class': 'leaflet-control-layers-base'});
|
var $Labels = $('<div>', {'class': 'leaflet-control-layers-base'});
|
||||||
$.each(self.vars('projects'), function(sCodeName, asProject){
|
$.each(self.vars('projects'), function(sCodeName, asProject){
|
||||||
var asRadioAttrs = {'type': 'radio', 'class': 'leaflet-control-layers-selector', 'name':'project', 'value': sCodeName};
|
var asRadioAttrs = {'type': 'radio', 'class': 'leaflet-control-layers-selector', 'name':'project', 'value': sCodeName};
|
||||||
if(asProject.id == self.vars(['project', 'id'])) asRadioAttrs.checked = 'checked';
|
if(asProject.id == self.vars(['project', 'id'])) asRadioAttrs.checked = 'checked';
|
||||||
var $Radio =$('<input>', asRadioAttrs).change(function(){
|
var $Radio =$('<input>', asRadioAttrs).change(function(){
|
||||||
|
toggleSettingsPanel(false);
|
||||||
self.setHash(self.vars('page'), [$(this).val()]);
|
self.setHash(self.vars('page'), [$(this).val()]);
|
||||||
});
|
});
|
||||||
|
|
||||||
var $Label = $('<label>').append($('<div>')
|
var $Label = $('<label>').append($('<div>')
|
||||||
.append($Radio)
|
.append($Radio)
|
||||||
.append($('<span>').text(' '+asProject.name))
|
.append($('<span>').text(' '+asProject.name))
|
||||||
.append($('<a>', {'class':'fa fa-download push-left', href:asProject.gpxfilepath}).click(function(e){e.stopPropagation();}))
|
.append($('<a>', {'class':'fa fa-download push-left', href:asProject.gpxfilepath, title:oSpot.lang('track_download')}).click(function(e){e.stopPropagation();}))
|
||||||
);
|
);
|
||||||
$Labels.append($Label);
|
$Labels.append($Label);
|
||||||
});
|
});
|
||||||
|
$('#settings-projects').empty().append($Labels);
|
||||||
return $('<div>', {'class':'leaflet-control-layers leaflet-control leaflet-control-layers-expanded'}).append($('<section>').append($Labels))[0];
|
|
||||||
};
|
|
||||||
oProjects.addTo(oMap);
|
|
||||||
|
|
||||||
//Controls: Scale
|
//Controls: Scale
|
||||||
oScale = L.control.scale({imperial: false, 'position':'bottomright'}).addTo(oMap);
|
oScale = L.control.scale({imperial: false, 'position':'bottomright'}).addTo(oMap);
|
||||||
@@ -295,8 +410,9 @@ function initSpotMessages(aoMessages, aoTracks) {
|
|||||||
}).addTo(oMap);
|
}).addTo(oMap);
|
||||||
self.tmp('elev', oElev);
|
self.tmp('elev', oElev);
|
||||||
|
|
||||||
//Controls: Tiles (layers)
|
//Controls: Tiles (layers): Add & Move to Settings Panel
|
||||||
L.control.layers(aoLayers, null, {position: 'topleft'}).addTo(oMap);
|
L.control.layers(aoLayers, null, {position: 'topleft'}).addTo(oMap);
|
||||||
|
$('#layers').empty().append($('.leaflet-control-layers-list .leaflet-control-layers-base'));
|
||||||
|
|
||||||
//Tracks, colors & popup
|
//Tracks, colors & popup
|
||||||
var oActualTracks = L.geoJson(aoTracks, {
|
var oActualTracks = L.geoJson(aoTracks, {
|
||||||
@@ -305,7 +421,7 @@ function initSpotMessages(aoMessages, aoTracks) {
|
|||||||
}
|
}
|
||||||
}).addTo(oMap);
|
}).addTo(oMap);
|
||||||
|
|
||||||
var oTracks = L.geoJson(aoTracks, {
|
self.tmp('track', L.geoJson(aoTracks, {
|
||||||
style: {weight: 20, opacity: 0},
|
style: {weight: 20, opacity: 0},
|
||||||
onEachFeature: function(feature, oLayer) {
|
onEachFeature: function(feature, oLayer) {
|
||||||
var asProperties = feature.properties;
|
var asProperties = feature.properties;
|
||||||
@@ -392,19 +508,18 @@ function initSpotMessages(aoMessages, aoTracks) {
|
|||||||
(oElev.addData.bind(oElev))(feature, oLayer);
|
(oElev.addData.bind(oElev))(feature, oLayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).addTo(oMap);
|
}).addTo(oMap));
|
||||||
|
|
||||||
//Centering map
|
//Centering map
|
||||||
|
var bWithFeedPanel = (!bNoFeed && !isMobile());
|
||||||
if(self.vars(['project', 'mode'])==self.consts.modes.blog && aoMessages.length > 0)
|
if(self.vars(['project', 'mode'])==self.consts.modes.blog && aoMessages.length > 0)
|
||||||
{
|
{
|
||||||
//Zoom on last message
|
//Zoom on last message
|
||||||
var oLastMsg = aoMessages[aoMessages.length-1];
|
var oLastMsg = aoMessages[aoMessages.length-1];
|
||||||
oMap.setView(L.latLng(oLastMsg.latitude, oLastMsg.longitude), 15);
|
oMap.setView(L.latLng(oLastMsg.latitude, oLastMsg.longitude), 15);
|
||||||
|
oMap.panBy([(bWithFeedPanel?1:0)*$('#feed').outerWidth(true)/2, 0]);
|
||||||
//Recenter map to be at the center of 70% (map_offset) of the page, 30% being used by posts
|
|
||||||
oMap.setOffsetView(self.tmp('map_offset'));
|
|
||||||
}
|
}
|
||||||
else oMap.fitBounds(oTracks.getBounds(), {paddingTopLeft: L.point(5, self.tmp('marker_size').height + 5), paddingBottomRight: L.point(self.tmp('feed_width') + 5, 5)});
|
else oMap.fitBounds(self.tmp('track').getBounds(), {paddingTopLeft: L.point(5, self.tmp('marker_size').height + 5), paddingBottomRight: L.point(5 + parseInt(bWithFeedPanel?$('#feed').outerWidth(true):0), 5)});
|
||||||
|
|
||||||
//Spot Messages
|
//Spot Messages
|
||||||
$.each(aoMessages, function(iKey, oMsg){
|
$.each(aoMessages, function(iKey, oMsg){
|
||||||
@@ -426,7 +541,7 @@ function initSpotMessages(aoMessages, aoTracks) {
|
|||||||
.append(oMsg.formatted_time+(self.vars(['project', 'mode'])==self.consts.modes.blog?' ('+oMsg.relative_time+')':'')+self.tmp('site_tz_notice')))
|
.append(oMsg.formatted_time+(self.vars(['project', 'mode'])==self.consts.modes.blog?' ('+oMsg.relative_time+')':'')+self.tmp('site_tz_notice')))
|
||||||
.append($('<p>', {'class':'coordinates'})
|
.append($('<p>', {'class':'coordinates'})
|
||||||
.addIcon('fa-coords fa-fw fa-lg', false)
|
.addIcon('fa-coords fa-fw fa-lg', false)
|
||||||
.append('Lat : '+oMsg.latitude+', Lng : '+oMsg.longitude));
|
.append(getGoogleMapsLink(oMsg)));
|
||||||
|
|
||||||
//Tooltip medias
|
//Tooltip medias
|
||||||
if(oMsg.medias) {
|
if(oMsg.medias) {
|
||||||
@@ -440,14 +555,14 @@ function initSpotMessages(aoMessages, aoTracks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
oMarker.bindPopup($Tooltip[0], {
|
oMarker.bindPopup($Tooltip[0], {
|
||||||
maxWidth: 1000,
|
maxWidth: $('#projects').width(),
|
||||||
autoPan: false,
|
autoPan: false,
|
||||||
closeOnClick: true,
|
closeOnClick: true,
|
||||||
offset: new L.Point(0, -30)
|
offset: new L.Point(0, -30)
|
||||||
});
|
});
|
||||||
|
|
||||||
//Open tooltip on latest message in mobile mode
|
//Open tooltip on latest message in mobile mode
|
||||||
if(iKey === (aoMessages.length - 1) && self.vars(['project', 'mode']) == self.consts.modes.blog && (!oMsg.medias || oMsg.medias.length < 3) && self.tmp('mobile')) oMarker.openPopup();
|
if(iKey === (aoMessages.length - 1) && self.vars(['project', 'mode']) == self.consts.modes.blog && (!oMsg.medias || oMsg.medias.length < 3) && isMobile()) oMarker.openPopup();
|
||||||
|
|
||||||
oSpot.tmp(['markers', oMsg.id_message], oMarker);
|
oSpot.tmp(['markers', oMsg.id_message], oMarker);
|
||||||
});
|
});
|
||||||
@@ -498,7 +613,7 @@ function updateFeed(bFirstChunk, bDiscrete) {
|
|||||||
|
|
||||||
self.tmp('updatable', true);
|
self.tmp('updatable', true);
|
||||||
|
|
||||||
if(bFirstChunk && !self.tmp('mobile') && !$.isEmptyObject(asData)) toggleFeedPanel(true, false);
|
if(bFirstChunk && !isMobile() && !$.isEmptyObject(asData)) toggleFeedPanel(true, 'none');
|
||||||
}, {
|
}, {
|
||||||
'project_id': self.vars(['project', 'id']),
|
'project_id': self.vars(['project', 'id']),
|
||||||
'chunk': self.tmp('news_chunk')
|
'chunk': self.tmp('news_chunk')
|
||||||
@@ -517,7 +632,7 @@ function setFeedUpdateTimer(iSeconds, fCallback) {
|
|||||||
function getPost(asPost) {
|
function getPost(asPost) {
|
||||||
asPost.headerless = asPost.headerless || false;
|
asPost.headerless = asPost.headerless || false;
|
||||||
var $Post = $('<div>', {'class':'post '+asPost.type+(asPost.headerless?' headerless':'')});
|
var $Post = $('<div>', {'class':'post '+asPost.type+(asPost.headerless?' headerless':'')});
|
||||||
var sRelTime = (asPost.relative_time!='')?((self.vars(['project', 'mode'])==self.consts.modes.histo)?asPost.formatted_time.substr(0, 10):asPost.relative_time):'';
|
var sRelTime = (asPost.relative_time!='')?((self.vars('project') && self.vars(['project', 'mode'])==self.consts.modes.histo)?asPost.formatted_time.substr(0, 10):asPost.relative_time):'';
|
||||||
var sAbsTime = asPost.formatted_time;
|
var sAbsTime = asPost.formatted_time;
|
||||||
var sType = asPost.subtype || asPost.type;
|
var sType = asPost.subtype || asPost.type;
|
||||||
var $Body = {};
|
var $Body = {};
|
||||||
@@ -526,7 +641,7 @@ function getPost(asPost) {
|
|||||||
case 'message':
|
case 'message':
|
||||||
$Body = $('<div>')
|
$Body = $('<div>')
|
||||||
.data('id', asPost.id_message)
|
.data('id', asPost.id_message)
|
||||||
.append($('<p>').addIcon('fa-coords', true).append(asPost.lat_dms+' '+asPost.lon_dms))
|
.append($('<p>').addIcon('fa-coords', true).append(getGoogleMapsLink(asPost)))
|
||||||
.append($('<p>').addIcon('fa-time', true).append(sAbsTime+self.tmp('site_tz_notice')))
|
.append($('<p>').addIcon('fa-time', true).append(sAbsTime+self.tmp('site_tz_notice')))
|
||||||
.append($('<a>', {'class':'drill'})
|
.append($('<a>', {'class':'drill'})
|
||||||
.append($('<img>', {'class':'staticmap', title: oSpot.lang('click_zoom'), src: getWmtsApiUrl('static', asPost.latitude, asPost.longitude, 13)}))
|
.append($('<img>', {'class':'staticmap', title: oSpot.lang('click_zoom'), src: getWmtsApiUrl('static', asPost.latitude, asPost.longitude, 13)}))
|
||||||
@@ -536,9 +651,17 @@ function getPost(asPost) {
|
|||||||
)
|
)
|
||||||
.click(function(){
|
.click(function(){
|
||||||
var oMarker = oSpot.tmp(['markers', $(this).parent().data('id')]);
|
var oMarker = oSpot.tmp(['markers', $(this).parent().data('id')]);
|
||||||
self.tmp('map').setOffsetView(self.tmp('map_offset'), oMarker.getLatLng(), 13);
|
if(isMobile()) {
|
||||||
|
toggleFeedPanel(false, 'panToInstant');
|
||||||
|
self.tmp('map').setView(oMarker.getLatLng(), 15);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var iOffset = $('#feed').outerWidth(true)/2 - ($('#projects').hasClass('with-settings')?1:-1)*$('#settings').outerWidth(true)/2;
|
||||||
|
var iRatio = -1 * iOffset / $('body').outerWidth(true);
|
||||||
|
self.tmp('map').setOffsetView(iRatio, oMarker.getLatLng(), 15);
|
||||||
|
}
|
||||||
|
|
||||||
if(!oMarker.isPopupOpen()) oMarker.openPopup();
|
if(!oMarker.isPopupOpen()) oMarker.openPopup();
|
||||||
if(self.tmp('mobile')) toggleFeedPanel(false);
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.hover(
|
.hover(
|
||||||
@@ -615,4 +738,13 @@ function getMediaLink(asData, sType) {
|
|||||||
|
|
||||||
return $Link;
|
return $Link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGoogleMapsLink(asInfo) {
|
||||||
|
return $('<a>', {
|
||||||
|
href:'https://www.google.com/maps/place/'+asInfo.lat_dms+'+'+asInfo.lon_dms+'/@'+asInfo.latitude+','+asInfo.longitude+',10z',
|
||||||
|
title: oSpot.lang('see_on_google'),
|
||||||
|
target: '_blank',
|
||||||
|
rel: 'noreferrer'
|
||||||
|
}).text(asInfo.lat_dms+' '+asInfo.lon_dms);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -13,3 +13,4 @@
|
|||||||
* Reset zoom on image closing (lightbox)
|
* Reset zoom on image closing (lightbox)
|
||||||
* Fix video fullscreen button on ios
|
* Fix video fullscreen button on ios
|
||||||
* Fix lightbox portrait mode: push text under
|
* Fix lightbox portrait mode: push text under
|
||||||
|
* Subscribe to message feed
|
||||||
+7
-10
@@ -65,12 +65,12 @@ function Spot(asGlobals)
|
|||||||
|
|
||||||
/* Interface with server */
|
/* Interface with server */
|
||||||
|
|
||||||
this.get = function(sAction, fOnSuccess, oVars, fOnError, bProcessIcon)
|
this.get = function(sAction, fOnSuccess, oVars, fOnError, fonProgress)
|
||||||
{
|
{
|
||||||
if(!oVars) oVars = {};
|
if(!oVars) oVars = {};
|
||||||
fOnError = fOnError || function(sError) {console.log(sError);};
|
fOnError = fOnError || function(sError) {console.log(sError);};
|
||||||
bProcessIcon = bProcessIcon || false;
|
fonProgress = fonProgress || function(sState){};
|
||||||
//if(bProcessIcon) self.addBufferIcon();
|
fonProgress('start');
|
||||||
|
|
||||||
oVars['a'] = sAction;
|
oVars['a'] = sAction;
|
||||||
oVars['t'] = self.consts.timezone;
|
oVars['t'] = self.consts.timezone;
|
||||||
@@ -82,18 +82,15 @@ function Spot(asGlobals)
|
|||||||
})
|
})
|
||||||
.done(function(oData)
|
.done(function(oData)
|
||||||
{
|
{
|
||||||
|
fonProgress('done');
|
||||||
if(oData.desc.substr(0, self.consts.lang_prefix.length)==self.consts.lang_prefix) oData.desc = self.lang(oData.desc.substr(5));
|
if(oData.desc.substr(0, self.consts.lang_prefix.length)==self.consts.lang_prefix) oData.desc = self.lang(oData.desc.substr(5));
|
||||||
|
|
||||||
if(oData.result==self.consts.error) fOnError(oData.desc);
|
if(oData.result==self.consts.error) fOnError(oData.desc);
|
||||||
else
|
else fOnSuccess(oData.data);
|
||||||
{
|
|
||||||
//if(bProcessIcon) self.resetIcon();
|
|
||||||
fOnSuccess(oData.data);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.fail(function(jqXHR, textStatus, errorThrown)
|
.fail(function(jqXHR, textStatus, errorThrown)
|
||||||
{
|
{
|
||||||
//if(bProcessIcon) self.resetIcon();
|
fonProgress('fail');
|
||||||
fOnError(textStatus+' '+errorThrown);
|
fOnError(textStatus+' '+errorThrown);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -171,7 +168,7 @@ function Spot(asGlobals)
|
|||||||
self.onSamePageMove = function(asHash){return false};
|
self.onSamePageMove = function(asHash){return false};
|
||||||
self.onQuitPage = function(){return true};
|
self.onQuitPage = function(){return true};
|
||||||
self.onResize = function(){};
|
self.onResize = function(){};
|
||||||
self.onFeedback = function(sType, sMsg){feedback(sType, sMsg);};
|
self.onFeedback = function(sType, sMsg){};
|
||||||
self.onKeydown = function(oEvent){};
|
self.onKeydown = function(oEvent){};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -57,3 +57,26 @@ button {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input, textarea, button {
|
||||||
|
border: none;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Feedback */
|
||||||
|
|
||||||
|
.feedback {
|
||||||
|
p {
|
||||||
|
margin: 0 0 1em 0;
|
||||||
|
&.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
&.warning {
|
||||||
|
color: orange;
|
||||||
|
}
|
||||||
|
&.success {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-2
@@ -16,10 +16,10 @@ $fa-css-prefix: fa;
|
|||||||
@extend .fas;
|
@extend .fas;
|
||||||
|
|
||||||
&.push {
|
&.push {
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5rem;
|
||||||
}
|
}
|
||||||
&.push-left {
|
&.push-left {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +47,15 @@ $fa-css-prefix: fa;
|
|||||||
.#{$fa-css-prefix}-elev-gain:before { content: fa-content($fa-var-arrow-circle-up); }
|
.#{$fa-css-prefix}-elev-gain:before { content: fa-content($fa-var-arrow-circle-up); }
|
||||||
.#{$fa-css-prefix}-download:before { content: fa-content($fa-var-file-download); }
|
.#{$fa-css-prefix}-download:before { content: fa-content($fa-var-file-download); }
|
||||||
|
|
||||||
|
/* Settings */
|
||||||
|
.#{$fa-css-prefix}-menu:before { content: fa-content($fa-var-bars); }
|
||||||
|
.#{$fa-css-prefix}-newsletter:before { content: fa-content($fa-var-wifi); }
|
||||||
|
.#{$fa-css-prefix}-project:before { content: fa-content($fa-var-hiking); }
|
||||||
|
.#{$fa-css-prefix}-error:before { content: fa-content($fa-var-exclamation-square); }
|
||||||
|
.#{$fa-css-prefix}-warning:before { content: fa-content($fa-var-exclamation-triangle); }
|
||||||
|
.#{$fa-css-prefix}-success:before { content: fa-content($fa-var-check-circle); }
|
||||||
|
.#{$fa-css-prefix}-unsubscribe:before { content: fa-content($fa-var-times); }
|
||||||
|
|
||||||
/* Feed */
|
/* Feed */
|
||||||
.#{$fa-css-prefix}-post:before { content: fa-content($fa-var-comment); }
|
.#{$fa-css-prefix}-post:before { content: fa-content($fa-var-comment); }
|
||||||
.#{$fa-css-prefix}-media:before { content: fa-content($fa-var-photo-video); }
|
.#{$fa-css-prefix}-media:before { content: fa-content($fa-var-photo-video); }
|
||||||
|
|||||||
@@ -26,14 +26,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#feedback {
|
|
||||||
.error {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.success {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+166
-50
@@ -1,34 +1,34 @@
|
|||||||
//Feed width
|
//Feed width
|
||||||
$block-spacing: 1rem;
|
$block-spacing: 1rem;
|
||||||
$feed-width: 30%;
|
$panel-width: 30%;
|
||||||
$feed-width-max: "400px + 3 * #{$block-spacing}";
|
$panel-width-max: "400px + 3 * #{$block-spacing}";
|
||||||
|
|
||||||
//Feed colors
|
//Feed colors
|
||||||
$post-input-bg: #d9deff;
|
$post-input-bg: #ffffff; //#d9deff;
|
||||||
$post-color: #323268;
|
$post-color: #333; //#323268;
|
||||||
$post-bg: #B4BDFF;
|
$post-bg: rgba(255,255,255,.8); //#B4BDFF;
|
||||||
$message-color: #326526;
|
$message-color: #326526;
|
||||||
$message-bg: #6DFF58;
|
$message-bg: #6DFF58;
|
||||||
$media-color: #635C28;
|
$media-color: #333; //#635C28;
|
||||||
$media-bg: #F3EC9F;
|
$media-bg: rgba(255,255,255,.8); //#F3EC9F;
|
||||||
|
|
||||||
//Legend colors
|
//Legend colors
|
||||||
$track-main-color: #00ff78;
|
$track-main-color: #00ff78;
|
||||||
$track-off-track-color: #0000ff;
|
$track-off-track-color: #0000ff;
|
||||||
$track-hitchhiking-color: #FF7814;
|
$track-hitchhiking-color: #FF7814;
|
||||||
$legend-color: #222;
|
$legend-color: $post-color;
|
||||||
|
|
||||||
#projects {
|
#projects {
|
||||||
|
|
||||||
&.with-feed {
|
&.with-feed {
|
||||||
#submap {
|
#submap {
|
||||||
width: calc(100% - #{$feed-width});
|
width: calc(100% - #{$panel-width});
|
||||||
min-width: calc(100% - #{$feed-width-max});
|
min-width: calc(100% - #{$panel-width-max});
|
||||||
}
|
}
|
||||||
|
|
||||||
.leaflet-right {
|
.leaflet-right {
|
||||||
width: calc(#{$feed-width});
|
width: calc(#{$panel-width});
|
||||||
max-width: calc(#{$feed-width-max});
|
max-width: calc(#{$panel-width-max});
|
||||||
}
|
}
|
||||||
|
|
||||||
#feed {
|
#feed {
|
||||||
@@ -47,6 +47,39 @@ $legend-color: #222;
|
|||||||
right: -100%;
|
right: -100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.with-settings {
|
||||||
|
#submap {
|
||||||
|
width: calc(100% - #{$panel-width});
|
||||||
|
min-width: calc(100% - #{$panel-width-max});
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-left {
|
||||||
|
width: calc(#{$panel-width});
|
||||||
|
max-width: calc(#{$panel-width-max});
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings {
|
||||||
|
z-index: 999;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-button {
|
||||||
|
.fa {
|
||||||
|
@extend .fa-prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:not(.with-settings) {
|
||||||
|
#settings #settings-sections {
|
||||||
|
left: -100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.with-feed.with-settings {
|
||||||
|
#submap {
|
||||||
|
width: calc(100% - #{$panel-width} * 2);
|
||||||
|
min-width: calc(100% - #{$panel-width-max} * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#submap {
|
#submap {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -103,19 +136,6 @@ $legend-color: #222;
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.leaflet-control-layers-expanded {
|
|
||||||
color: $legend-color;
|
|
||||||
width: calc(100% - 2em - 16px);
|
|
||||||
|
|
||||||
a.fa-download {
|
|
||||||
color: $legend-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #0078A8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.leaflet-control-scale {
|
&.leaflet-control-scale {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
|
||||||
@@ -125,30 +145,27 @@ $legend-color: #222;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pull right controls by $feed-width % */
|
/* Pull right/left controls by $panel-width */
|
||||||
.leaflet-right {
|
.leaflet-right, .leaflet-left {
|
||||||
transition: all 0.5s;
|
transition: all 0.5s;
|
||||||
width: 0;
|
width: 0;
|
||||||
max-width: 0;
|
max-width: 0;
|
||||||
|
}
|
||||||
.leaflet-control {
|
.leaflet-right .leaflet-control {
|
||||||
left: -100%;
|
left: -100%;
|
||||||
}
|
}
|
||||||
|
.leaflet-left .leaflet-control {
|
||||||
|
right: -100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace Layers image with font awesome icon */
|
/* Hide default layer control */
|
||||||
.leaflet-control-layers-toggle {
|
.leaflet-top.leaflet-left .leaflet-control-layers {
|
||||||
@extend .control-icon;
|
|
||||||
@extend .fa-layers;
|
|
||||||
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#legend {
|
#legend {
|
||||||
.track {
|
.track {
|
||||||
|
white-space: nowrap;
|
||||||
.line {
|
.line {
|
||||||
width: 2em;
|
width: 2em;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
@@ -175,7 +192,7 @@ $legend-color: #222;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#post-button {
|
#post-button, #settings-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-shadow: 0px 1px 1px rgba(0,0,0,0.8);
|
text-shadow: 0px 1px 1px rgba(0,0,0,0.8);
|
||||||
width: 44px;
|
width: 44px;
|
||||||
@@ -188,8 +205,13 @@ $legend-color: #222;
|
|||||||
.fa {
|
.fa {
|
||||||
color: #CCC;
|
color: #CCC;
|
||||||
@extend .control-icon;
|
@extend .control-icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#post-button .fa {
|
||||||
@extend .fa-post;
|
@extend .fa-post;
|
||||||
}
|
}
|
||||||
|
#settings-button .fa {
|
||||||
|
@extend .fa-menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drill & Map icons */
|
/* Drill & Map icons */
|
||||||
@@ -235,25 +257,21 @@ $legend-color: #222;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Feed Panel */
|
/* Feed/Settings Panel */
|
||||||
|
|
||||||
#feed {
|
#feed, #settings {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: calc(#{$feed-width});
|
width: calc(#{$panel-width});
|
||||||
max-width: calc(#{$feed-width-max});
|
max-width: calc(#{$panel-width-max});
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
transition-property: z-index;
|
transition-property: z-index;
|
||||||
transition-duration: 0.1s;
|
transition-duration: 0.1s;
|
||||||
transition-delay: 0.5s;
|
transition-delay: 0.5s;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
input, textarea, button {
|
input, textarea {
|
||||||
border: none;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
border-radius: 3px;
|
|
||||||
background-color: $post-input-bg;
|
background-color: $post-input-bg;
|
||||||
color: $post-color;
|
color: $post-color;
|
||||||
}
|
}
|
||||||
@@ -267,6 +285,9 @@ $legend-color: #222;
|
|||||||
color: $post-color;
|
color: $post-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#feed {
|
||||||
|
right: 0;
|
||||||
|
|
||||||
#posts {
|
#posts {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -391,6 +412,10 @@ $legend-color: #222;
|
|||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $message-color;
|
||||||
|
}
|
||||||
|
|
||||||
a.drill {
|
a.drill {
|
||||||
.drill-icon {
|
.drill-icon {
|
||||||
transform: translate(-16px, -32px);
|
transform: translate(-16px, -32px);
|
||||||
@@ -432,13 +457,94 @@ $legend-color: #222;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#settings {
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
#settings-sections {
|
||||||
|
width: calc(100% - 3rem);
|
||||||
|
margin: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: 2px 2px 3px 0px rgba(0,0,0,.5);
|
||||||
|
position: absolute;
|
||||||
|
transition: all 0.5s;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
color: $post-color;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
|
||||||
|
.settings-section {
|
||||||
|
h1 {
|
||||||
|
margin: 1.5rem 0 1rem;
|
||||||
|
}
|
||||||
|
&:first-child h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-bottom: .3em;
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.newsletter {
|
||||||
|
input#email {
|
||||||
|
width: calc(100% - 6em);
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
color: #999;
|
||||||
|
background: rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button#nl_btn {
|
||||||
|
margin-left: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
|
||||||
|
&.subscribe .fa {
|
||||||
|
@extend .fa-send;
|
||||||
|
}
|
||||||
|
&.unsubscribe .fa {
|
||||||
|
@extend .fa-unsubscribe;
|
||||||
|
}
|
||||||
|
&.loading {
|
||||||
|
background-color: $message-color;
|
||||||
|
color: white;
|
||||||
|
span {
|
||||||
|
@extend .flicker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-projects {
|
||||||
|
a.fa-download {
|
||||||
|
color: $legend-color;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #0078A8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Info Window */
|
/* Info Window */
|
||||||
|
|
||||||
|
.leaflet-popup-content {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
.info-window {
|
.info-window {
|
||||||
|
margin: 1rem;
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
margin: 1em 0;
|
margin: 1em 0 1.2em;
|
||||||
|
|
||||||
|
i {
|
||||||
|
margin-right: 0.3125em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@@ -448,15 +554,24 @@ $legend-color: #222;
|
|||||||
i {
|
i {
|
||||||
padding-right: 0.5em;
|
padding-right: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $post-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.medias {
|
.medias {
|
||||||
margin-top: 0.5em;
|
margin-top: -0.5rem;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 15px;
|
|
||||||
|
margin-right: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&.drill {
|
&.drill {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
@@ -486,6 +601,7 @@ $legend-color: #222;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#elems {
|
#elems {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
+3
-4
@@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
#projects {
|
#projects {
|
||||||
|
|
||||||
&.with-feed {
|
&.with-feed, &.with-settings {
|
||||||
#submap {
|
#submap {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.leaflet-right {
|
.leaflet-right, .leaflet-left {
|
||||||
width: calc(100% - 44px - 2 * #{$block-spacing});
|
width: calc(100% - 44px - 2 * #{$block-spacing});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,14 +20,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.leaflet-control-container {
|
.leaflet-control-container {
|
||||||
.leaflet-top.leaflet-left,
|
|
||||||
.leaflet-bottom.leaflet-left,
|
.leaflet-bottom.leaflet-left,
|
||||||
.leaflet-bottom.leaflet-right .leaflet-control.elevation {
|
.leaflet-bottom.leaflet-right .leaflet-control.elevation {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#feed {
|
#feed, #settings {
|
||||||
width: calc(100% - 44px - 2 * #{$block-spacing});
|
width: calc(100% - 44px - 2 * #{$block-spacing});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKcg72j00.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKew72j00.woff2) format("woff2");unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKcw72j00.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKfA72j00.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKcQ72j00.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(fonts/4iCs6KVjbNBYlgoKfw72.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjvWyNL4U.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjtGyNL4U.woff2) format("woff2");unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjvGyNL4U.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjs2yNL4U.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjvmyNL4U.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(fonts/4iCv6KVjbNBYlgoCxCvjsGyN.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@-webkit-keyframes fadeIn{from{opacity:.3}}@-moz-keyframes fadeIn{from{opacity:.3}}@-ms-keyframes fadeIn{from{opacity:.3}}@-o-keyframes fadeIn{from{opacity:.3}}@keyframes fadeIn{from{opacity:.3}}.flicker,.lightbox .lb-cancel{-webkit-animation:fadeIn .5s infinite alternate;-moz-animation:fadeIn .5s infinite alternate;-ms-animation:fadeIn .5s infinite alternate;-o-animation:fadeIn .5s infinite alternate;animation:fadeIn .5s infinite alternate}body,textarea,input,button{font-size:14px;font-family:"Ubuntu",sans-serif;margin:0}textarea{resize:none}button{cursor:pointer;font-weight:bold}/*!
|
@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKcg72j00.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKew72j00.woff2) format("woff2");unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKcw72j00.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKfA72j00.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCs6KVjbNBYlgoKcQ72j00.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:400;src:local("Ubuntu Regular"),local("Ubuntu-Regular"),url(fonts/4iCs6KVjbNBYlgoKfw72.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjvWyNL4U.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjtGyNL4U.woff2) format("woff2");unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjvGyNL4U.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjs2yNL4U.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(https://fonts.gstatic.com/s/ubuntu/v13/4iCv6KVjbNBYlgoCxCvjvmyNL4U.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Ubuntu";font-style:normal;font-weight:700;src:local("Ubuntu Bold"),local("Ubuntu-Bold"),url(fonts/4iCv6KVjbNBYlgoCxCvjsGyN.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@-webkit-keyframes fadeIn{from{opacity:.3}}@-moz-keyframes fadeIn{from{opacity:.3}}@-ms-keyframes fadeIn{from{opacity:.3}}@-o-keyframes fadeIn{from{opacity:.3}}@keyframes fadeIn{from{opacity:.3}}.flicker,#projects #settings #settings-sections .settings-section.newsletter button#nl_btn.loading span,.lightbox .lb-cancel{-webkit-animation:fadeIn .5s infinite alternate;-moz-animation:fadeIn .5s infinite alternate;-ms-animation:fadeIn .5s infinite alternate;-o-animation:fadeIn .5s infinite alternate;animation:fadeIn .5s infinite alternate}body,textarea,input,button{font-size:14px;font-family:"Ubuntu",sans-serif;margin:0}textarea{resize:none}button{cursor:pointer;font-weight:bold}input,textarea,button{border:none;padding:.5em 1em;border-radius:3px}.feedback p{margin:0 0 1em 0}.feedback p.error{color:red}.feedback p.warning{color:orange}.feedback p.success{color:green}/*!
|
||||||
* Font Awesome Pro 5.11.2 by @fontawesome - https://fontawesome.com
|
* Font Awesome Pro 5.11.2 by @fontawesome - https://fontawesome.com
|
||||||
* License - https://fontawesome.com/license (Commercial License)
|
* License - https://fontawesome.com/license (Commercial License)
|
||||||
*/@font-face{font-family:"Font Awesome 5 Pro";font-style:normal;font-weight:900;font-display:auto;src:url("fa/fonts/fa-solid-900.eot");src:url("fa/fonts/fa-solid-900.eot?#iefix") format("embedded-opentype"),url("fa/fonts/fa-solid-900.woff2") format("woff2"),url("fa/fonts/fa-solid-900.woff") format("woff"),url("fa/fonts/fa-solid-900.ttf") format("truetype"),url("fa/fonts/fa-solid-900.svg#fontawesome") format("svg")}.fa,.lightbox .lb-cancel,.lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.control-icon,#projects #post-button .fa,#projects #post-button .control-icon,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-prev,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-next,#projects #post-button .lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-dataContainer .lb-data .lb-closeContainer #projects #post-button .lb-close,#projects #post-button .lightbox .lb-cancel,.lightbox #projects #post-button .lb-cancel,#projects #post-button .spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.spot-theme.leaflet-control.elevation-collapsed #projects #post-button .elevation-toggle,#projects #post-button .leaflet-control-layers-toggle,#projects .leaflet-control-layers-toggle,.spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.fas{font-family:"Font Awesome 5 Pro";font-weight:900}.fa,.lightbox .lb-cancel,.lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.control-icon,#projects #post-button .fa,#projects #post-button .control-icon,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-prev,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-next,#projects #post-button .lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-dataContainer .lb-data .lb-closeContainer #projects #post-button .lb-close,#projects #post-button .lightbox .lb-cancel,.lightbox #projects #post-button .lb-cancel,#projects #post-button .spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.spot-theme.leaflet-control.elevation-collapsed #projects #post-button .elevation-toggle,#projects #post-button .leaflet-control-layers-toggle,#projects .leaflet-control-layers-toggle,.spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.fas,.far,.fal,.fad,.fab{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-0.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.lightbox .fa-pull-left.lb-cancel,.lightbox .lb-dataContainer .lb-data .lb-closeContainer .fa-pull-left.lb-close,.lightbox .lb-outerContainer .lb-container .lb-nav a.fa-pull-left.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav a.fa-pull-left.lb-prev,.fa-pull-left.control-icon,#projects #post-button .fa-pull-left.fa,#projects #post-button .fa-pull-left.control-icon,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.fa-pull-left.lb-prev,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.fa-pull-left.lb-prev,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.fa-pull-left.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.fa-pull-left.lb-next,#projects #post-button .lightbox .lb-dataContainer .lb-data .lb-closeContainer .fa-pull-left.lb-close,.lightbox .lb-dataContainer .lb-data .lb-closeContainer #projects #post-button .fa-pull-left.lb-close,#projects #post-button .lightbox .fa-pull-left.lb-cancel,.lightbox #projects #post-button .fa-pull-left.lb-cancel,#projects #post-button .spot-theme.leaflet-control.elevation-collapsed .fa-pull-left.elevation-toggLine truncated
|
*/@font-face{font-family:"Font Awesome 5 Pro";font-style:normal;font-weight:900;font-display:auto;src:url("fa/fonts/fa-solid-900.eot");src:url("fa/fonts/fa-solid-900.eot?#iefix") format("embedded-opentype"),url("fa/fonts/fa-solid-900.woff2") format("woff2"),url("fa/fonts/fa-solid-900.woff") format("woff"),url("fa/fonts/fa-solid-900.ttf") format("truetype"),url("fa/fonts/fa-solid-900.svg#fontawesome") format("svg")}.fa,.lightbox .lb-cancel,.lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.control-icon,#projects #post-button .fa,#projects #post-button .control-icon,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-prev,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-next,#projects #post-button .lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-dataContainer .lb-data .lb-closeContainer #projects #post-button .lb-close,#projects #post-button .lightbox .lb-cancel,.lightbox #projects #post-button .lb-cancel,#projects #post-button .spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.spot-theme.leaflet-control.elevation-collapsed #projects #post-button .elevation-toggle,#projects #settings-button .fa,#projects #settings-button .control-icon,#projects #settings-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #settings-button a.lb-prev,#projects #settings-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #settings-button a.lb-next,#projects #settings-button .lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-dataContainer .lb-data .lb-closeContainer #projects #settings-button .lb-close,#projects #settings-button .lightbox .lb-cancel,.lightbox #projects #settings-button .lb-cancel,#projects #settings-button .spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.spot-theme.leaflet-control.elevation-collapsed #projects #settings-button .elevation-toggle,#projects #post-button #settings-button .fa,#projects #settings-button #post-button .fa,#projects #post-button #settings-button .control-icon,#projects #settings-button #post-button .control-icon,.spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.fas{font-family:"Font Awesome 5 Pro";font-weight:900}.fa,.lightbox .lb-cancel,.lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.control-icon,#projects #post-button .fa,#projects #post-button .control-icon,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-prev,#projects #post-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #post-button a.lb-next,#projects #post-button .lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-dataContainer .lb-data .lb-closeContainer #projects #post-button .lb-close,#projects #post-button .lightbox .lb-cancel,.lightbox #projects #post-button .lb-cancel,#projects #post-button .spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.spot-theme.leaflet-control.elevation-collapsed #projects #post-button .elevation-toggle,#projects #settings-button .fa,#projects #settings-button .control-icon,#projects #settings-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-prev,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #settings-button a.lb-prev,#projects #settings-button .lightbox .lb-outerContainer .lb-container .lb-nav a.lb-next,.lightbox .lb-outerContainer .lb-container .lb-nav #projects #settings-button a.lb-next,#projects #settings-button .lightbox .lb-dataContainer .lb-data .lb-closeContainer .lb-close,.lightbox .lb-dataContainer .lb-data .lb-closeContainer #projects #settings-button .lb-close,#projects #settings-button .lightbox .lb-cancel,.lightbox #projects #settings-button .lb-cancel,#projects #settings-button .spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.spot-theme.leaflet-control.elevation-collapsed #projects #settings-button .elevation-toggle,#projects #post-button #settings-button .fa,#projects #settings-button #post-button .fa,#projects #post-button #settings-button .control-icon,#projects #settings-button #post-button .control-icon,.spot-theme.leaflet-control.elevation-collapsed .elevation-toggle,.fas,.far,.fal,.fad,.fab{-moz-osx-font-smoothing:grayscale;-webkit-font-smooLine truncated
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["_fonts.scss","_common.scss","fa/solid.scss","fa/_variables.scss","fa/_core.scss","fa/_larger.scss","fa/_fixed-width.scss","fa/_list.scss","fa/_bordered-pulled.scss","fa/_animated.scss","fa/_rotated-flipped.scss","fa/_mixins.scss","fa/_stacked.scss","_fa.scss","lightbox/_lightbox.scss","_lightbox.scss","_simplebar.scss","leaflet/_leaflet.scss","leaflet/_leaflet_elevation.scss","_leaflet.scss","_mask_project.scss","_mask_upload.scss","_mask_admin.scss","_mobile.scss"],"names":[],"mappings":"CAGA,WACE,qBACA,kBACA,gBACA,8IACA,iFAGF,WACE,qBACA,kBACA,gBACA,8IACA,yDAGF,WACE,qBACA,kBACA,gBACA,8IACA,0BAGF,WACE,qBACA,kBACA,gBACA,8IACA,0BAGF,WACE,qBACA,kBACA,gBACA,8IACA,2GAGF,WACE,qBACA,kBACA,gBACA,0GACA,yJAGF,WACE,qBACA,kBACA,gBACA,4IACA,iFAGF,WACE,qBACA,kBACA,gBACA,4IACA,yDAGF,WACE,qBACA,kBACA,gBACA,4IACA,0BAGF,WACE,qBACA,kBACA,gBACA,4IACA,0BAGF,WACE,qBACA,kBACA,gBACA,4IACA,2GAGF,WACE,qBACA,kBACA,gBACA,wGACA,yJC9FF,0BACE,iBAEF,uBACE,iBAEF,sBACE,iBAEF,qBACE,iBAEF,kBACE,iBAWF,8BAPC,kBAQoB,8BAPpB,eAOoB,8BANpB,cAMoB,8BALpB,aAKoB,8BAJpB,UAIoB,8BAkBrB,2BACC,eACA,gCACA,SAGD,SACC,YAGD,OACC,eACA,iBCzDD;AAAA;AAAA;AAAA,GAMA,WACE,iCACA,kBACA,gBACA,aCLqB,KDMrB,qCACA,2RAOF,qtCAEE,iCACA,gBEnBF,yuCAME,kCACA,mCACA,qBACA,kBACA,oBACA,oBACA,cCXF,OACE,yBACA,kBACA,yBAGF,OACE,gBAGF,OACE,iBAIA,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,QACE,eClBJ,OACE,kBACA,MHOqB,OIRvB,OACE,qBACA,kBACA,eAEA,4BAGF,OACE,UACA,kBACA,kBACA,MJLqB,IIMrB,oBCbF,WACE,wBACA,mBACA,yBAGF,yBACA,2BAOE,2jDACA,mlDCfF,SACE,qCAGF,UACE,uCAGF,mBACE,GACE,uBAGF,KACE,0BCdJ,cCWE,sEACA,wBDXF,eCUE,sEACA,yBDVF,eCSE,sEACA,yBDRF,oBCYE,gFACA,uBDZF,kBCWE,gFACA,uBDXF,mDCUE,gFACA,wBDLA,oIAME,YElBJ,UACE,qBACA,WACA,gBACA,kBACA,sBACA,YAGF,0BAEE,OACA,kBACA,kBACA,WAGF,aACE,oBAGF,aACE,cAGF,YACE,MTpBqB,KUQtB,yzCACC,kBAED,k6CACC,iBAIF,2/BACC,eACA,kBACA,iBACA,qBACA,WACA,gBAKD,2BACA,uCACA,kCACA,yCACA,mCACA,iCACA,8EACA,2GACA,gCACA,iCACA,iCACA,gCAGA,y/BACA,6BACA,6BACA,6BACA,+BACA,kCACA,4BACA,8BACA,mCACA,qCACA,2GACA,8BACA,kCACA,kCAGA,8BACA,4BAGA,0DACA,gGACA,+rCACA,sGCzEA,0BACE,gBAGF,iBACE,kBACA,MACA,OACA,aACA,sBACA,2DACA,WACA,aAGF,UACE,kBACA,OACA,WACA,cACA,kBACA,cACA,mBACA,aAGF,oBACE,cACA,YACA,kBACA,gBACA,kBAGA,sBAIF,oBACE,uBAEF,gCACC,yBAID,gBACE,YAGF,mBACE,kBACA,QACA,YACA,aACA,cACA,kBAIA,sBAGF,yBACE,WACA,cACA,WAGF,WACE,kBACA,QACA,OACA,WACA,WACA,kBACA,cAGF,WACE,cACA,WACA,YACA,cACA,gDAGF,QACE,kBACA,MACA,OACA,YACA,WACA,WAGF,mBACE,OAGF,UACE,aACA,2GAGF,kBACE,YACA,eACA,cAGF,kBACE,UACA,OACA,WACA,sDACA,0DACA,UACA,+BACA,4BACA,0BACA,uBAGF,wBACE,4DACA,UAGF,kBACE,UACA,QACA,YACA,uDACA,0DACA,UACA,+BACA,4BACA,0BACA,uBAGF,wBACE,4DACA,UAGF,kBACE,cACA,gBACA,QACA,WACA,8BACA,+BAGF,wBACE,WACA,cACA,WAGF,SACE,cACA,WAGF,qBACE,UACA,WACA,gBACA,kBAGF,qBACE,eACA,iBACA,gBAGF,uBACE,WAGF,oBACE,cACA,WACA,mBACA,eACA,WAGF,mBACE,cACA,YACA,WACA,YACA,wDACA,iBACA,aACA,2DACA,WACA,+BACA,4BACA,0BACA,uBAGF,yBACE,eACA,4DACA,UC1MF,iBACC,SACA,QAGD,UACC,aACA,mBACA,uBACA,WACA,YAGA,6BACC,SACA,gBACA,sCAEA,2CACC,gBAEA,qDACC,6BACA,YACA,iBACA,iBACA,WAEA,UACC,2FAMD,0HACC,WACA,qBAEA,wIACC,kBACA,oBAIF,6DAnDH,gBACA,cAoDI,oEACC,SAIF,6DA1DH,gBACA,cA2DI,oEACC,UAOL,4BACC,SACA,UACA,qBACA,mBACA,YACA,eACA,cACA,gBAEA,qCACC,oBAEA,iDACC,WAEA,kEACC,eACA,cACA,eAGD,8EACC,aAGD,4DACC,UACA,eAGF,wDACC,wBACA,eAEA,kEAvGH,gBACA,cAwGI,WAMJ,qBA/GA,gBACA,cAiHC,WCrHF,iBACE,kBACA,sBACA,eACA,2BACA,yBACA,uBAGF,mBACE,gBACA,cACA,eACA,kBACA,mBAGF,gBACE,kBACA,kBACA,gBACA,UACA,SACA,OACA,MACA,SACA,QACA,sBACA,uBACA,UAGF,kBACE,6BACA,8BACA,uBACA,kBACA,MACA,OACA,SACA,QACA,UACA,SACA,iCAGF,2BACE,kBACA,iCACA,kBACA,cACA,YACA,WACA,mBACA,eACA,gBACA,qBACA,wBAGF,2FAEE,QACA,SAGF,mDAEE,YACA,cAGF,uBACE,gBACA,eACA,WACA,oBAGF,wCACE,8BACA,YACA,WACA,cACA,kBACA,WACA,eACA,gBACA,WACA,UACA,SACA,oBACA,kBACA,cACA,aAGF,gCACE,mBACA,cACA,UACA,kBACA,MACA,OACA,aACA,YACA,eACA,cACA,gBACA,oBACA,WAGF,iBACE,UACA,kBACA,QACA,SACA,oBACA,gBAGF,uDACE,oBACA,iBACA,yBAGF,qDACE,mBAGF,qBACE,kBACA,UACA,UACA,gBAGF,4BACE,kBACA,WACA,gBACA,kBACA,OACA,QACA,UACA,8BAGF,8CAEE,WACA,6BAGF,oCACE,MACA,WAGF,gEACE,QACA,WAGF,sCACE,OACA,YAGF,kEACE,YACA,SACA,UAGF,2DACE,WACA,OACA,QACA,WACA,aACA,eACA,WAIF,mEACE,WACA,OAGF,yBACE,cACA,eACA,UACA,kBACA,aACA,YACA,kBACA,kBAGF,0BACE,eACA,OACA,kBACA,kBACA,qBACA,wBChNF,6LAUC,kBACA,OACA,MAED,mBACC,gBAED,0DAGC,yBACG,sBACK,iBACN,uBAGH,yBACC,uBAGD,8BACC,0CAGD,wCACC,aACA,cACA,6BAED,4CAEC,cAID,2PAMC,0BACA,2BAGD,sCACC,6BACA,yBAED,sCACC,4BAEA,kBACA,wBAED,yDACC,sBACA,kBAED,mBACC,wCAED,qBACC,gDAED,cACC,eACA,kBAED,qBACC,mBAED,kBACC,QACA,SACA,2BACK,sBACL,YAGD,0BACC,sBAGD,0BAEA,+BACA,kCACA,iCACA,iCACA,kCACA,gCAEA,qCACA,kCAEA,mBACC,UACA,WAED,MACC,2BACA,qBACA,kBAMD,iBACC,kBACA,YACA,8BACA,oBAED,6BAEC,kBACA,aACA,oBAED,aACC,MAED,eACC,QAED,gBACC,SAED,cACC,OAED,iBACC,WACA,WAED,gCACC,YAED,8BACC,gBAED,iCACC,mBAED,+BACC,iBAED,gCACC,kBAMD,iCACC,oBAED,kCACC,UACA,sCACG,mCACK,8BAET,oDACC,UAED,uBACC,6BACI,yBACI,qBAET,0CACC,sBAED,0CACC,sEACG,gEACK,sDAET,iEAEC,wBACG,qBACK,gBAGT,sCACC,kBAMD,qBACC,eAED,cACC,oBACA,iBACA,YAED,2DAEC,iBAED,qCAEC,YAED,iIAGC,YACLine truncated
|
{"version":3,"sourceRoot":"","sources":["_fonts.scss","_common.scss","fa/solid.scss","fa/_variables.scss","fa/_core.scss","fa/_larger.scss","fa/_fixed-width.scss","fa/_list.scss","fa/_bordered-pulled.scss","fa/_animated.scss","fa/_rotated-flipped.scss","fa/_mixins.scss","fa/_stacked.scss","_fa.scss","lightbox/_lightbox.scss","_lightbox.scss","_simplebar.scss","leaflet/_leaflet.scss","leaflet/_leaflet_elevation.scss","_leaflet.scss","_mask_project.scss","_mask_upload.scss","_mask_admin.scss","_mobile.scss"],"names":[],"mappings":"CAGA,WACE,qBACA,kBACA,gBACA,8IACA,iFAGF,WACE,qBACA,kBACA,gBACA,8IACA,yDAGF,WACE,qBACA,kBACA,gBACA,8IACA,0BAGF,WACE,qBACA,kBACA,gBACA,8IACA,0BAGF,WACE,qBACA,kBACA,gBACA,8IACA,2GAGF,WACE,qBACA,kBACA,gBACA,0GACA,yJAGF,WACE,qBACA,kBACA,gBACA,4IACA,iFAGF,WACE,qBACA,kBACA,gBACA,4IACA,yDAGF,WACE,qBACA,kBACA,gBACA,4IACA,0BAGF,WACE,qBACA,kBACA,gBACA,4IACA,0BAGF,WACE,qBACA,kBACA,gBACA,4IACA,2GAGF,WACE,qBACA,kBACA,gBACA,wGACA,yJC9FF,0BACE,iBAEF,uBACE,iBAEF,sBACE,iBAEF,qBACE,iBAEF,kBACE,iBAWF,6HAPC,kBAQoB,8BAPpB,eAOoB,8BANpB,cAMoB,8BALpB,aAKoB,8BAJpB,UAIoB,8BAkBrB,2BACC,eACA,gCACA,SAGD,SACC,YAGD,OACC,eACA,iBAGD,sBACC,YACA,iBACA,kBAMA,YACC,iBACA,kBACC,UAED,oBACC,aAED,oBACC,YC9EH;AAAA;AAAA;AAAA,GAMA,WACE,iCACA,kBACA,gBACA,aCLqB,KDMrB,qCACA,2RAOF,srEAEE,iCACA,gBEnBF,0sEAME,kCACA,mCACA,qBACA,kBACA,oBACA,oBACA,cCXF,OACE,yBACA,kBACA,yBAGF,OACE,gBAGF,OACE,iBAIA,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,OACE,cADF,QACE,eClBJ,OACE,kBACA,MHOqB,OIRvB,OACE,qBACA,kBACA,eAEA,4BAGF,OACE,UACA,kBACA,kBACA,MJLqB,IIMrB,oBCbF,WACE,wBACA,mBACA,yBAGF,yBACA,2BAOE,09EACA,4/ECfF,SACE,qCAGF,UACE,uCAGF,mBACE,GACE,uBAGF,KACE,0BCdJ,cCWE,sEACA,wBDXF,eCUE,sEACA,yBDVF,eCSE,sEACA,yBDRF,oBCYE,gFACA,uBDZF,kBCWE,gFACA,uBDXF,mDCUE,gFACA,wBDLA,oIAME,YElBJ,UACE,qBACA,WACA,gBACA,kBACA,sBACA,YAGF,0BAEE,OACA,kBACA,kBACA,WAGF,aACE,oBAGF,aACE,cAGF,YACE,MTpBqB,KUQtB,woEACC,mBAED,myEACC,kBAIF,49DACC,eACA,kBACA,iBACA,qBACA,WACA,gBAKD,2BACA,uCACA,kCACA,yCACA,mCACA,iCACA,8BACA,2GACA,gCACA,iCACA,iCACA,gCAGA,0sDACA,kCACA,+BACA,6BACA,+BACA,+BACA,q8GAGA,0pDACA,6BACA,6BACA,6BACA,+BACA,kCACA,4BACA,8BACA,mCACA,qCACA,2GACA,8BACA,kCACA,kCAGA,8BACA,k5GAGA,0DACA,4xDACA,wqDACA,sGClFA,0BACE,gBAGF,iBACE,kBACA,MACA,OACA,aACA,sBACA,2DACA,WACA,aAGF,UACE,kBACA,OACA,WACA,cACA,kBACA,cACA,mBACA,aAGF,oBACE,cACA,YACA,kBACA,gBACA,kBAGA,sBAIF,oBACE,uBAEF,gCACC,yBAID,gBACE,YAGF,mBACE,kBACA,QACA,YACA,aACA,cACA,kBAIA,sBAGF,yBACE,WACA,cACA,WAGF,WACE,kBACA,QACA,OACA,WACA,WACA,kBACA,cAGF,WACE,cACA,WACA,YACA,cACA,gDAGF,QACE,kBACA,MACA,OACA,YACA,WACA,WAGF,mBACE,OAGF,UACE,aACA,2GAGF,kBACE,YACA,eACA,cAGF,kBACE,UACA,OACA,WACA,sDACA,0DACA,UACA,+BACA,4BACA,0BACA,uBAGF,wBACE,4DACA,UAGF,kBACE,UACA,QACA,YACA,uDACA,0DACA,UACA,+BACA,4BACA,0BACA,uBAGF,wBACE,4DACA,UAGF,kBACE,cACA,gBACA,QACA,WACA,8BACA,+BAGF,wBACE,WACA,cACA,WAGF,SACE,cACA,WAGF,qBACE,UACA,WACA,gBACA,kBAGF,qBACE,eACA,iBACA,gBAGF,uBACE,WAGF,oBACE,cACA,WACA,mBACA,eACA,WAGF,mBACE,cACA,YACA,WACA,YACA,wDACA,iBACA,aACA,2DACA,WACA,+BACA,4BACA,0BACA,uBAGF,yBACE,eACA,4DACA,UC1MF,iBACC,SACA,QAGD,UACC,aACA,mBACA,uBACA,WACA,YAGA,6BACC,SACA,gBACA,sCAEA,2CACC,gBAEA,qDACC,6BACA,YACA,iBACA,iBACA,WAEA,UACC,2FAMD,0HACC,WACA,qBAEA,wIACC,kBACA,oBAIF,6DAnDH,gBACA,cAoDI,oEACC,SAIF,6DA1DH,gBACA,cA2DI,oEACC,UAOL,4BACC,SACA,UACA,qBACA,mBACA,YACA,eACA,cACA,gBAEA,qCACC,oBAEA,iDACC,WAEA,kEACC,eACA,cACA,eAGD,8EACC,aAGD,4DACC,UACA,eAGF,wDACC,wBACA,eAEA,kEAvGH,gBACA,cAwGI,WAMJ,qBA/GA,gBACA,cAiHC,WCrHF,iBACE,kBACA,sBACA,eACA,2BACA,yBACA,uBAGF,mBACE,gBACA,cACA,eACA,kBACA,mBAGF,gBACE,kBACA,kBACA,gBACA,UACA,SACA,OACA,MACA,SACA,QACA,sBACA,uBACA,UAGF,kBACE,6BACA,8BACA,uBACA,kBACA,MACA,OACA,SACA,QACA,UACA,SACA,iCAGF,2BACE,kBACA,iCACA,kBACA,cACA,YACA,WACA,mBACA,eACA,gBACA,qBACA,wBAGF,2FAEE,QACA,SAGF,mDAEE,YACA,cAGF,uBACE,gBACA,eACA,WACA,oBAGF,wCACE,8BACA,YACA,WACA,cACA,kBACA,WACA,eACA,gBACA,WACA,UACA,SACA,oBACA,kBACA,cACA,aAGF,gCACE,mBACA,cACA,UACA,kBACA,MACA,OACA,aACA,YACA,eACA,cACA,gBACA,oBACA,WAGF,iBACE,UACA,kBACA,QACA,SACA,oBACA,gBAGF,uDACE,oBACA,iBACA,yBAGF,qDACE,mBAGF,qBACE,kBACA,UACA,UACA,gBAGF,4BACE,kBACA,WACA,gBACA,kBACA,OACA,QACA,UACA,8BAGF,8CAEE,WACA,6BAGF,oCACE,MACA,WAGF,gEACE,QACA,WAGF,sCACE,OACA,YAGF,kEACE,YACA,SACA,UAGF,2DACE,WACA,OACA,QACA,WACA,aACA,eACA,WAIF,mEACE,WACA,OAGF,yBACE,cACA,eACA,UACA,kBACA,aACA,YACA,kBACA,kBAGF,0BACE,eACA,OACA,kBACA,kBACA,qBACA,wBChNF,6LAUC,kBACA,OACA,MAED,mBACC,gBAED,0DAGC,yBACG,sBACK,iBACN,uBAGH,yBACC,uBAGD,8BACC,0CAGD,wCACC,aACA,cACA,6BAED,4CAEC,cAID,2PAMC,0BACA,2BAGD,sCACC,6BACA,yBAED,sCACC,4BAEA,kBACA,wBAED,yDACC,sBACA,kBAED,mBACC,wCAED,qBACC,gDAED,cACC,eACA,kBAED,qBACC,mBAED,kBACC,QACA,SACA,2BACK,sBACL,YAGD,0BACC,sBAGD,0BAEA,+BACA,kCACA,iCACA,iCACA,kCACA,gCAEA,qCACA,kCAEA,mBACC,UACA,WAED,MACC,2BACA,qBACA,kBAMD,iBACC,kBACA,YACA,8BACA,oBAED,6BAEC,kBACA,aACA,oBAED,aACC,MAED,eACC,QAED,gBACC,SAED,cACC,OAED,iBACC,WACA,WAED,gCACC,YAED,8BACC,gBAED,iCACC,mBAED,+BACC,iBAED,gCACC,kBAMD,iCACC,oBAED,kCACC,UACA,sCACG,mCACK,8BAET,oDACC,UAED,uBACC,6BACI,yBACI,qBAET,0CACC,sBAED,0CACC,sEACG,Line truncated
|
||||||
Reference in new issue
Block a user