62 changed files with 7089 additions and 3136 deletions
@ -0,0 +1,105 @@ |
|||
package runtime |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
log "github.com/sirupsen/logrus" |
|||
|
|||
"github.com/FreifunkBremen/freifunkmanager/ssh" |
|||
) |
|||
|
|||
func (n *Node) SSHUpdate(sshmgmt *ssh.Manager, iface string, oldnode *Node) { |
|||
addr := n.GetAddress(iface) |
|||
client, err := sshmgmt.ConnectTo(addr) |
|||
if err != nil { |
|||
return |
|||
} |
|||
defer client.Close() |
|||
|
|||
if oldnode == nil || n.Hostname != oldnode.Hostname { |
|||
ssh.Execute(n.Address.String(), client, fmt.Sprintf(` |
|||
uci set system.@system[0].hostname='%s'; |
|||
uci set wireless.priv_radio0.ssid="offline-$(uci get system.@system[0].hostname)"; |
|||
uci set wireless.priv_radio1.ssid="offline-$(uci get system.@system[0].hostname)"; |
|||
uci commit; echo $(uci get system.@system[0].hostname) > /proc/sys/kernel/hostname;`, |
|||
n.Hostname)) |
|||
} |
|||
if oldnode == nil || n.Owner != oldnode.Owner { |
|||
ssh.Execute(n.Address.String(), client, fmt.Sprintf(` |
|||
uci set gluon-node-info.@owner[0].contact='%s'; |
|||
uci commit gluon-node-info;`, |
|||
n.Owner)) |
|||
} |
|||
if oldnode == nil || !locationEqual(n.Location, oldnode.Location) { |
|||
ssh.Execute(n.Address.String(), client, fmt.Sprintf(` |
|||
uci set gluon-node-info.@location[0].latitude='%f'; |
|||
uci set gluon-node-info.@location[0].longitude='%f'; |
|||
uci set gluon-node-info.@location[0].share_location=1; |
|||
uci commit gluon-node-info;`, |
|||
n.Location.Latitude, n.Location.Longitude)) |
|||
|
|||
} |
|||
runWifi := false |
|||
defer func() { |
|||
if runWifi { |
|||
ssh.Execute(n.Address.String(), client, "wifi") |
|||
// send warning for running wifi, because it kicks clients from node
|
|||
log.Warn("[cmd] wifi ", n.NodeID) |
|||
} |
|||
}() |
|||
|
|||
result, err := ssh.Run(n.Address.String(), client, ` |
|||
if [ "$(uci get wireless.radio0.hwmode | grep -c g)" -ne 0 ]; then |
|||
echo "radio0"; |
|||
elif [ "$(uci get wireless.radio1.hwmode | grep -c g)" -ne 0 ]; then |
|||
echo "radio1"; |
|||
fi;`) |
|||
if err != nil { |
|||
return |
|||
} |
|||
radio := ssh.SSHResultToString(result) |
|||
if radio != "" { |
|||
if oldnode == nil || n.Wireless.TxPower24 != oldnode.Wireless.TxPower24 { |
|||
ssh.Execute(n.Address.String(), client, fmt.Sprintf(` |
|||
uci set wireless.%s.txpower='%d'; |
|||
uci commit wireless;`, |
|||
radio, n.Wireless.TxPower24)) |
|||
runWifi = true |
|||
} |
|||
if oldnode == nil || n.Wireless.Channel24 != oldnode.Wireless.Channel24 { |
|||
ssh.Execute(n.Address.String(), client, fmt.Sprintf(` |
|||
uci set wireless.%s.channel='%d'; |
|||
uci commit wireless;`, |
|||
radio, n.Wireless.Channel24)) |
|||
runWifi = true |
|||
} |
|||
} |
|||
result, err = ssh.Run(n.Address.String(), client, ` |
|||
if [ "$(uci get wireless.radio0.hwmode | grep -c a)" -ne 0 ]; then |
|||
echo "radio0"; |
|||
elif [ "$(uci get wireless.radio1.hwmode | grep -c a)" -ne 0 ]; then |
|||
echo "radio1"; |
|||
fi;`) |
|||
if err != nil { |
|||
return |
|||
} |
|||
radio = ssh.SSHResultToString(result) |
|||
if radio != "" { |
|||
if oldnode == nil || n.Wireless.TxPower5 != oldnode.Wireless.TxPower5 { |
|||
ssh.Execute(n.Address.String(), client, fmt.Sprintf(` |
|||
uci set wireless.%s.txpower='%d'; |
|||
uci commit wireless;`, |
|||
radio, n.Wireless.TxPower5)) |
|||
runWifi = true |
|||
} |
|||
if oldnode == nil || n.Wireless.Channel5 != oldnode.Wireless.Channel5 { |
|||
ssh.Execute(n.Address.String(), client, fmt.Sprintf(` |
|||
uci set wireless.%s.channel='%d'; |
|||
uci commit wireless;`, |
|||
radio, n.Wireless.Channel5)) |
|||
runWifi = true |
|||
} |
|||
} |
|||
|
|||
oldnode = n |
|||
} |
@ -0,0 +1,3 @@ |
|||
{ |
|||
"presets": ["env"] |
|||
} |
@ -0,0 +1,6 @@ |
|||
node_modules |
|||
data |
|||
app.js |
|||
app.js.map |
|||
styles.css |
|||
styles.css.map |
@ -0,0 +1,16 @@ |
|||
nav .login { |
|||
float: right; |
|||
display: inline-block; |
|||
cursor: pointer; |
|||
text-decoration: none !important; |
|||
text-align: center; |
|||
box-sizing: border-box; |
|||
padding: 1em .5em; |
|||
height: 50px; |
|||
color: #fff; |
|||
|
|||
a { |
|||
color: #fff; |
|||
padding-left: 2px; |
|||
} |
|||
} |
@ -0,0 +1,61 @@ |
|||
|
|||
header { |
|||
width: 100%; |
|||
height: 50px; |
|||
|
|||
> div { |
|||
display: inline-block; |
|||
} |
|||
} |
|||
nav { |
|||
background-color: #373636; |
|||
position: fixed; |
|||
display: inline-block; |
|||
font-weight: 700; |
|||
width: 100%; |
|||
height: 50px; |
|||
|
|||
ul { |
|||
padding: 0; |
|||
margin: 0; |
|||
list-style-type: none; |
|||
} |
|||
|
|||
ul > li { |
|||
float:left; |
|||
display: inline-block; |
|||
|
|||
a, |
|||
span { |
|||
display: inline-block; |
|||
cursor: pointer; |
|||
text-decoration: none !important; |
|||
text-align: center; |
|||
text-transform: uppercase; |
|||
color: inherit; |
|||
box-sizing: border-box; |
|||
padding: 1.1em .5em; |
|||
height: 50px; |
|||
} |
|||
|
|||
&:hover, |
|||
&.active { |
|||
background: rgba(255, 255, 255, 0.2); |
|||
} |
|||
|
|||
&.item-1 { |
|||
background: #ffb400; |
|||
color: #000; |
|||
} |
|||
|
|||
&.item-2 { |
|||
background: #dc0067; |
|||
color: #fff; |
|||
} |
|||
|
|||
&.item-3 { |
|||
background: #ccc; |
|||
color: #000; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
.notifications { |
|||
position: absolute; |
|||
right: 1em; |
|||
} |
|||
|
|||
.notify { |
|||
position: relative; |
|||
min-height: 1em; |
|||
margin: 1em 0; |
|||
padding: 1em 1.5em; |
|||
color: rgba(0,0,0,.87); |
|||
-webkit-transition: opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease; |
|||
transition: opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease; |
|||
box-shadow: 0 0 0 1px rgba(34,36,38,.22) inset, 0 0 0 0 transparent; |
|||
background: #ccc; |
|||
color: #000; |
|||
} |
|||
.notify.success { |
|||
background: #009ee0; |
|||
color: #fff; |
|||
} |
|||
.notify.warn { |
|||
background: #ffb400; |
|||
color: #000; |
|||
} |
|||
.notify.error { |
|||
background: #dc0067; |
|||
color: #fff; |
|||
} |
@ -0,0 +1,25 @@ |
|||
nav .status { |
|||
float: right; |
|||
background-color: #009ee0; |
|||
color: white; |
|||
width: 50px; |
|||
height: 50px; |
|||
|
|||
&.connecting, |
|||
&.running { |
|||
background-color: #ffb400; |
|||
animation: blinkDot 2s infinite; |
|||
} |
|||
&.offline, |
|||
&.failed { |
|||
background-color: #dc0067; |
|||
animation: blinkDot 1s infinite; |
|||
} |
|||
|
|||
|
|||
@keyframes blinkDot { |
|||
50% { |
|||
background-color: rgba(255, 255, 255, 0.25); |
|||
} |
|||
} |
|||
} |
@ -1,62 +0,0 @@ |
|||
.prompt { |
|||
position: fixed; |
|||
bottom: 0px; |
|||
background-color: #ccc; |
|||
width: 100%; |
|||
} |
|||
.prompt .btn { |
|||
width: 10%; |
|||
} |
|||
.prompt input { |
|||
width: 85%; |
|||
margin-left: 2%; |
|||
} |
|||
.console { |
|||
font-family: monospace; |
|||
white-space: pre; |
|||
font-size: 14px; |
|||
} |
|||
.console { |
|||
width: 100%; |
|||
border-spacing: 0px; |
|||
} |
|||
.console > tr { |
|||
clear: both; |
|||
border-spacing: 0px; |
|||
|
|||
} |
|||
.console > tr > td { |
|||
width: 100%; |
|||
padding: 0px; |
|||
border-spacing: 0px; |
|||
height: 18px; |
|||
} |
|||
.console > tr.cmd > td { |
|||
margin-top: 3px; |
|||
} |
|||
.console > tr:not(.cmd) > td { |
|||
margin-top: 0px; |
|||
} |
|||
.console table, |
|||
.console table tr, |
|||
.console table td { |
|||
width: 100%; |
|||
padding: 0px; |
|||
margin: 0px; |
|||
border-collapse: collapse; |
|||
} |
|||
.console .time, .console .host{ |
|||
color: #009ee0; |
|||
width: 1%; |
|||
} |
|||
.console .status { |
|||
text-align: right; |
|||
height: 18px; |
|||
} |
|||
|
|||
.console table { |
|||
background-color: #ccc; |
|||
} |
|||
.console table .status { |
|||
width: 18px; |
|||
} |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 696 B |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 618 B |
@ -1,624 +0,0 @@ |
|||
/* required styles */ |
|||
|
|||
.leaflet-pane, |
|||
.leaflet-tile, |
|||
.leaflet-marker-icon, |
|||
.leaflet-marker-shadow, |
|||
.leaflet-tile-container, |
|||
.leaflet-pane > svg, |
|||
.leaflet-pane > canvas, |
|||
.leaflet-zoom-box, |
|||
.leaflet-image-layer, |
|||
.leaflet-layer { |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
.leaflet-container { |
|||
overflow: hidden; |
|||
} |
|||
.leaflet-tile, |
|||
.leaflet-marker-icon, |
|||
.leaflet-marker-shadow { |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
user-select: none; |
|||
-webkit-user-drag: none; |
|||
} |
|||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ |
|||
.leaflet-safari .leaflet-tile { |
|||
image-rendering: -webkit-optimize-contrast; |
|||
} |
|||
/* hack that prevents hw layers "stretching" when loading new tiles */ |
|||
.leaflet-safari .leaflet-tile-container { |
|||
width: 1600px; |
|||
height: 1600px; |
|||
-webkit-transform-origin: 0 0; |
|||
} |
|||
.leaflet-marker-icon, |
|||
.leaflet-marker-shadow { |
|||
display: block; |
|||
} |
|||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ |
|||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ |
|||
.leaflet-container .leaflet-overlay-pane svg, |
|||
.leaflet-container .leaflet-marker-pane img, |
|||
.leaflet-container .leaflet-shadow-pane img, |
|||
.leaflet-container .leaflet-tile-pane img, |
|||
.leaflet-container img.leaflet-image-layer { |
|||
max-width: none !important; |
|||
} |
|||
|
|||
.leaflet-container.leaflet-touch-zoom { |
|||
-ms-touch-action: pan-x pan-y; |
|||
touch-action: pan-x pan-y; |
|||
} |
|||
.leaflet-container.leaflet-touch-drag { |
|||
-ms-touch-action: pinch-zoom; |
|||
} |
|||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { |
|||
-ms-touch-action: none; |
|||
touch-action: none; |
|||
} |
|||
.leaflet-tile { |
|||
filter: inherit; |
|||
visibility: hidden; |
|||
} |
|||
.leaflet-tile-loaded { |
|||
visibility: inherit; |
|||
} |
|||
.leaflet-zoom-box { |
|||
width: 0; |
|||
height: 0; |
|||
-moz-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
z-index: 800; |
|||
} |
|||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ |
|||
.leaflet-overlay-pane svg { |
|||
-moz-user-select: none; |
|||
} |
|||
|
|||
.leaflet-pane { z-index: 400; } |
|||
|
|||
.leaflet-tile-pane { z-index: 200; } |
|||
.leaflet-overlay-pane { z-index: 400; } |
|||
.leaflet-shadow-pane { z-index: 500; } |
|||
.leaflet-marker-pane { z-index: 600; } |
|||
.leaflet-tooltip-pane { z-index: 650; } |
|||
.leaflet-popup-pane { z-index: 700; } |
|||
|
|||
.leaflet-map-pane canvas { z-index: 100; } |
|||
.leaflet-map-pane svg { z-index: 200; } |
|||
|
|||
.leaflet-vml-shape { |
|||
width: 1px; |
|||
height: 1px; |
|||
} |
|||
.lvml { |
|||
behavior: url(#default#VML); |
|||
display: inline-block; |
|||
position: absolute; |
|||
} |
|||
|
|||
|
|||
/* control positioning */ |
|||
|
|||
.leaflet-control { |
|||
position: relative; |
|||
z-index: 800; |
|||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ |
|||
pointer-events: auto; |
|||
} |
|||
.leaflet-top, |
|||
.leaflet-bottom { |
|||
position: absolute; |
|||
z-index: 1000; |
|||
pointer-events: none; |
|||
} |
|||
.leaflet-top { |
|||
top: 0; |
|||
} |
|||
.leaflet-right { |
|||
right: 0; |
|||
} |
|||
.leaflet-bottom { |
|||
bottom: 0; |
|||
} |
|||
.leaflet-left { |
|||
left: 0; |
|||
} |
|||
.leaflet-control { |
|||
float: left; |
|||
clear: both; |
|||
} |
|||
.leaflet-right .leaflet-control { |
|||
float: right; |
|||
} |
|||
.leaflet-top .leaflet-control { |
|||
margin-top: 10px; |
|||
} |
|||
.leaflet-bottom .leaflet-control { |
|||
margin-bottom: 10px; |
|||
} |
|||
.leaflet-left .leaflet-control { |
|||
margin-left: 10px; |
|||
} |
|||
.leaflet-right .leaflet-control { |
|||
margin-right: 10px; |
|||
} |
|||
|
|||
|
|||
/* zoom and fade animations */ |
|||
|
|||
.leaflet-fade-anim .leaflet-tile { |
|||
will-change: opacity; |
|||
} |
|||
.leaflet-fade-anim .leaflet-popup { |
|||
opacity: 0; |
|||
-webkit-transition: opacity 0.2s linear; |
|||
-moz-transition: opacity 0.2s linear; |
|||
-o-transition: opacity 0.2s linear; |
|||
transition: opacity 0.2s linear; |
|||
} |
|||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { |
|||
opacity: 1; |
|||
} |
|||
.leaflet-zoom-animated { |
|||
-webkit-transform-origin: 0 0; |
|||
-ms-transform-origin: 0 0; |
|||
transform-origin: 0 0; |
|||
} |
|||
.leaflet-zoom-anim .leaflet-zoom-animated { |
|||
will-change: transform; |
|||
} |
|||
.leaflet-zoom-anim .leaflet-zoom-animated { |
|||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); |
|||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); |
|||
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1); |
|||
transition: transform 0.25s cubic-bezier(0,0,0.25,1); |
|||
} |
|||
.leaflet-zoom-anim .leaflet-tile, |
|||
.leaflet-pan-anim .leaflet-tile { |
|||
-webkit-transition: none; |
|||
-moz-transition: none; |
|||
-o-transition: none; |
|||
transition: none; |
|||
} |
|||
|
|||
.leaflet-zoom-anim .leaflet-zoom-hide { |
|||
visibility: hidden; |
|||
} |
|||
|
|||
|
|||
/* cursors */ |
|||
|
|||
.leaflet-interactive { |
|||
cursor: pointer; |
|||
} |
|||
.leaflet-grab { |
|||
cursor: -webkit-grab; |
|||
cursor: -moz-grab; |
|||
} |
|||
.leaflet-crosshair, |
|||
.leaflet-crosshair .leaflet-interactive { |
|||
cursor: crosshair; |
|||
} |
|||
.leaflet-popup-pane, |
|||
.leaflet-control { |
|||
cursor: auto; |
|||
} |
|||
.leaflet-dragging .leaflet-grab, |
|||
.leaflet-dragging .leaflet-grab .leaflet-interactive, |
|||
.leaflet-dragging .leaflet-marker-draggable { |
|||
cursor: move; |
|||
cursor: -webkit-grabbing; |
|||
cursor: -moz-grabbing; |
|||
} |
|||
|
|||
/* marker & overlays interactivity */ |
|||
.leaflet-marker-icon, |
|||
.leaflet-marker-shadow, |
|||
.leaflet-image-layer, |
|||
.leaflet-pane > svg path, |
|||
.leaflet-tile-container { |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.leaflet-marker-icon.leaflet-interactive, |
|||
.leaflet-image-layer.leaflet-interactive, |
|||
.leaflet-pane > svg path.leaflet-interactive { |
|||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ |
|||
pointer-events: auto; |
|||
} |
|||
|
|||
/* visual tweaks */ |
|||
|
|||
.leaflet-container { |
|||
background: #ddd; |
|||
outline: 0; |
|||
} |
|||
.leaflet-container a { |
|||
color: #0078A8; |
|||
} |
|||
.leaflet-container a.leaflet-active { |
|||
outline: 2px solid orange; |
|||
} |
|||
.leaflet-zoom-box { |
|||
border: 2px dotted #38f; |
|||
background: rgba(255,255,255,0.5); |
|||
} |
|||
|
|||
|
|||
/* general typography */ |
|||
.leaflet-container { |
|||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; |
|||
} |
|||
|
|||
|
|||
/* general toolbar styles */ |
|||
|
|||
.leaflet-bar { |
|||
box-shadow: 0 1px 5px rgba(0,0,0,0.65); |
|||
border-radius: 4px; |
|||
} |
|||
.leaflet-bar a, |
|||
.leaflet-bar a:hover { |
|||
background-color: #fff; |
|||
border-bottom: 1px solid #ccc; |
|||
width: 26px; |
|||
height: 26px; |
|||
line-height: 26px; |
|||
display: block; |
|||
text-align: center; |
|||
text-decoration: none; |
|||
color: black; |
|||
} |
|||
.leaflet-bar a, |
|||
.leaflet-control-layers-toggle { |
|||
background-position: 50% 50%; |
|||
background-repeat: no-repeat; |
|||
display: block; |
|||
} |
|||
.leaflet-bar a:hover { |
|||
background-color: #f4f4f4; |
|||
} |
|||
.leaflet-bar a:first-child { |
|||
border-top-left-radius: 4px; |
|||
border-top-right-radius: 4px; |
|||
} |
|||
.leaflet-bar a:last-child { |
|||
border-bottom-left-radius: 4px; |
|||
border-bottom-right-radius: 4px; |
|||
border-bottom: none; |
|||
} |
|||
.leaflet-bar a.leaflet-disabled { |
|||
cursor: default; |
|||
background-color: #f4f4f4; |
|||
color: #bbb; |
|||
} |
|||
|
|||
.leaflet-touch .leaflet-bar a { |
|||
width: 30px; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
} |
|||
|
|||
|
|||
/* zoom control */ |
|||
|
|||
.leaflet-control-zoom-in, |
|||
.leaflet-control-zoom-out { |
|||
font: bold 18px 'Lucida Console', Monaco, monospace; |
|||
text-indent: 1px; |
|||
} |
|||
.leaflet-control-zoom-out { |
|||
font-size: 20px; |
|||
} |
|||
|
|||
.leaflet-touch .leaflet-control-zoom-in { |
|||
font-size: 22px; |
|||
} |
|||
.leaflet-touch .leaflet-control-zoom-out { |
|||
font-size: 24px; |
|||
} |
|||
|
|||
|
|||
/* layers control */ |
|||
|
|||
.leaflet-control-layers { |
|||
box-shadow: 0 1px 5px rgba(0,0,0,0.4); |
|||
background: #fff; |
|||
border-radius: 5px; |
|||
} |
|||
.leaflet-control-layers-toggle { |
|||
background-image: url(images/layers.png); |
|||
width: 36px; |
|||
height: 36px; |
|||
} |
|||
.leaflet-retina .leaflet-control-layers-toggle { |
|||
background-image: url(images/layers-2x.png); |
|||
background-size: 26px 26px; |
|||
} |
|||
.leaflet-touch .leaflet-control-layers-toggle { |
|||
width: 44px; |
|||
height: 44px; |
|||
} |
|||
.leaflet-control-layers .leaflet-control-layers-list, |
|||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle { |
|||
display: none; |
|||
} |
|||
.leaflet-control-layers-expanded .leaflet-control-layers-list { |
|||
display: block; |
|||
position: relative; |
|||
} |
|||
.leaflet-control-layers-expanded { |
|||
padding: 6px 10px 6px 6px; |
|||
color: #333; |
|||
background: #fff; |
|||
} |
|||
.leaflet-control-layers-scrollbar { |
|||
overflow-y: scroll; |
|||
padding-right: 5px; |
|||
} |
|||
.leaflet-control-layers-selector { |
|||
margin-top: 2px; |
|||
position: relative; |
|||
top: 1px; |
|||
} |
|||
.leaflet-control-layers label { |
|||
display: block; |
|||
} |
|||
.leaflet-control-layers-separator { |
|||
height: 0; |
|||
border-top: 1px solid #ddd; |
|||
margin: 5px -10px 5px -6px; |
|||
} |
|||
|
|||
/* Default icon URLs */ |
|||
.leaflet-default-icon-path { |
|||
background-image: url(images/marker-icon.png); |
|||
} |
|||
|
|||
|
|||
/* attribution and scale controls */ |
|||
|
|||
.leaflet-container .leaflet-control-attribution { |
|||
background: #fff; |
|||
background: rgba(255, 255, 255, 0.7); |
|||
margin: 0; |
|||
} |
|||
.leaflet-control-attribution, |
|||
.leaflet-control-scale-line { |
|||
padding: 0 5px; |
|||
color: #333; |
|||
} |
|||
.leaflet-control-attribution a { |
|||
text-decoration: none; |
|||
} |
|||
.leaflet-control-attribution a:hover { |
|||
text-decoration: underline; |
|||
} |
|||
.leaflet-container .leaflet-control-attribution, |
|||
.leaflet-container .leaflet-control-scale { |
|||
font-size: 11px; |
|||
} |
|||
.leaflet-left .leaflet-control-scale { |
|||
margin-left: 5px; |
|||
} |
|||
.leaflet-bottom .leaflet-control-scale { |
|||
margin-bottom: 5px; |
|||
} |
|||
.leaflet-control-scale-line { |
|||
border: 2px solid #777; |
|||
border-top: none; |
|||
line-height: 1.1; |
|||
padding: 2px 5px 1px; |
|||
font-size: 11px; |
|||
white-space: nowrap; |
|||
overflow: hidden; |
|||
-moz-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
|
|||
background: #fff; |
|||
background: rgba(255, 255, 255, 0.5); |
|||
} |
|||
.leaflet-control-scale-line:not(:first-child) { |
|||
border-top: 2px solid #777; |
|||
border-bottom: none; |
|||
margin-top: -2px; |
|||
} |
|||
.leaflet-control-scale-line:not(:first-child):not(:last-child) { |
|||
border-bottom: 2px solid #777; |
|||
} |
|||
|
|||
.leaflet-touch .leaflet-control-attribution, |
|||
.leaflet-touch .leaflet-control-layers, |
|||
.leaflet-touch .leaflet-bar { |
|||
box-shadow: none; |
|||
} |
|||
.leaflet-touch .leaflet-control-layers, |
|||
.leaflet-touch .leaflet-bar { |
|||
border: 2px solid rgba(0,0,0,0.2); |
|||
background-clip: padding-box; |
|||
} |
|||
|
|||
|
|||
/* popup */ |
|||
|
|||
.leaflet-popup { |
|||
position: absolute; |
|||
text-align: center; |
|||
margin-bottom: 20px; |
|||
} |
|||
.leaflet-popup-content-wrapper { |
|||
padding: 1px; |
|||
text-align: left; |
|||
border-radius: 12px; |
|||
} |
|||
.leaflet-popup-content { |
|||
margin: 13px 19px; |
|||
line-height: 1.4; |
|||
} |
|||
.leaflet-popup-content p { |
|||
margin: 18px 0; |
|||
} |
|||
.leaflet-popup-tip-container { |
|||
width: 40px; |
|||
height: 20px; |
|||
position: absolute; |
|||
left: 50%; |
|||
margin-left: -20px; |
|||
overflow: hidden; |
|||
pointer-events: none; |
|||
} |
|||
.leaflet-popup-tip { |
|||
width: 17px; |
|||
height: 17px; |
|||
padding: 1px; |
|||
|
|||
margin: -10px auto 0; |
|||
|
|||
-webkit-transform: rotate(45deg); |
|||
-moz-transform: rotate(45deg); |
|||
-ms-transform: rotate(45deg); |
|||
-o-transform: rotate(45deg); |
|||
transform: rotate(45deg); |
|||
} |
|||
.leaflet-popup-content-wrapper, |
|||
.leaflet-popup-tip { |
|||
background: white; |
|||
color: #333; |
|||
box-shadow: 0 3px 14px rgba(0,0,0,0.4); |
|||
} |
|||
.leaflet-container a.leaflet-popup-close-button { |
|||
position: absolute; |
|||
top: 0; |
|||
right: 0; |
|||
padding: 4px 4px 0 0; |
|||
border: none; |
|||
text-align: center; |
|||
width: 18px; |
|||
height: 14px; |
|||
font: 16px/14px Tahoma, Verdana, sans-serif; |
|||
color: #c3c3c3; |
|||
text-decoration: none; |
|||
font-weight: bold; |
|||
background: transparent; |
|||
} |
|||
.leaflet-container a.leaflet-popup-close-button:hover { |
|||
color: #999; |
|||
} |
|||
.leaflet-popup-scrolled { |
|||
overflow: auto; |
|||
border-bottom: 1px solid #ddd; |
|||
border-top: 1px solid #ddd; |
|||
} |
|||
|
|||
.leaflet-oldie .leaflet-popup-content-wrapper { |
|||
zoom: 1; |
|||
} |
|||
.leaflet-oldie .leaflet-popup-tip { |
|||
width: 24px; |
|||
margin: 0 auto; |
|||
|
|||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; |
|||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); |
|||
} |
|||
.leaflet-oldie .leaflet-popup-tip-container { |
|||
margin-top: -1px; |
|||
} |
|||
|
|||
.leaflet-oldie .leaflet-control-zoom, |
|||
.leaflet-oldie .leaflet-control-layers, |
|||
.leaflet-oldie .leaflet-popup-content-wrapper, |
|||
.leaflet-oldie .leaflet-popup-tip { |
|||
border: 1px solid #999; |
|||
} |
|||
|
|||
|
|||
/* div icon */ |
|||
|
|||
.leaflet-div-icon { |
|||
background: #fff; |
|||
border: 1px solid #666; |
|||
} |
|||
|
|||
|
|||
/* Tooltip */ |
|||
/* Base styles for the element that has a tooltip */ |
|||
.leaflet-tooltip { |
|||
position: absolute; |
|||
padding: 6px; |
|||
background-color: #fff; |
|||
border: 1px solid #fff; |
|||
border-radius: 3px; |
|||
color: #222; |
|||
white-space: nowrap; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
pointer-events: none; |
|||
box-shadow: 0 1px 3px rgba(0,0,0,0.4); |
|||
} |
|||
.leaflet-tooltip.leaflet-clickable { |
|||
cursor: pointer; |
|||
pointer-events: auto; |
|||
} |
|||
.leaflet-tooltip-top:before, |
|||
.leaflet-tooltip-bottom:before, |
|||
.leaflet-tooltip-left:before, |
|||
.leaflet-tooltip-right:before { |
|||
position: absolute; |
|||
pointer-events: none; |
|||
border: 6px solid transparent; |
|||
background: transparent; |
|||
content: ""; |
|||
} |
|||
|
|||
/* Directions */ |
|||
|
|||
.leaflet-tooltip-bottom { |
|||
margin-top: 6px; |
|||
} |
|||
.leaflet-tooltip-top { |
|||
margin-top: -6px; |
|||
} |
|||
.leaflet-tooltip-bottom:before, |
|||
.leaflet-tooltip-top:before { |
|||
left: 50%; |
|||
margin-left: -6px; |
|||
} |
|||
.leaflet-tooltip-top:before { |
|||
bottom: 0; |
|||
margin-bottom: -12px; |
|||
border-top-color: #fff; |
|||
} |
|||
.leaflet-tooltip-bottom:before { |
|||
top: 0; |
|||
margin-top: -12px; |
|||
margin-left: -6px; |
|||
border-bottom-color: #fff; |
|||
} |
|||
.leaflet-tooltip-left { |
|||
margin-left: -6px; |
|||
} |
|||
.leaflet-tooltip-right { |
|||
margin-left: 6px; |
|||
} |
|||
.leaflet-tooltip-left:before, |
|||
.leaflet-tooltip-right:before { |
|||
top: 50%; |
|||
margin-top: -6px; |
|||
} |
|||
.leaflet-tooltip-left:before { |
|||
right: 0; |
|||
margin-right: -12px; |
|||
border-left-color: #fff; |
|||
} |
|||
.leaflet-tooltip-right:before { |
|||
left: 0; |
|||
margin-left: -12px; |
|||
border-right-color: #fff; |
|||
} |
@ -0,0 +1,94 @@ |
|||
import browserSync from 'browser-sync'; |
|||
import browserify from 'browserify'; |
|||
import buffer from 'vinyl-buffer'; |
|||
import gulp from 'gulp'; |
|||
import gulpLoadPlugins from 'gulp-load-plugins'; |
|||
import source from 'vinyl-source-stream'; |
|||
import sourcemaps from 'gulp-sourcemaps'; |
|||
import watchify from 'watchify'; |
|||
|
|||
const gulpPlugins = gulpLoadPlugins(); |
|||
|
|||
function bundle (watching = false) { |
|||
const browserifyConf = { |
|||
'debug': true, |
|||
'entries': ['js/index.js'], |
|||
'transform': ['babelify']}; |
|||
|
|||
if (watching) { |
|||
browserifyConf.plugin = [watchify]; |
|||
} |
|||
|
|||
const browser = browserify(browserifyConf); |
|||
|
|||
function bundler () { |
|||
return browser.bundle(). |
|||
on('error', (err) => { |
|||
console.log(err.message); |
|||
}). |
|||
pipe(source('app.js')). |
|||
pipe(buffer()). |
|||
pipe(sourcemaps.init({'loadMaps': true})). |
|||
pipe(gulpPlugins.uglify({ |
|||
'mangle': {'reserved': ['moment']} |
|||
})). |
|||
pipe(sourcemaps.write('./')). |
|||
pipe(gulp.dest('./')); |
|||
} |
|||
|
|||
browser.on('update', () => { |
|||
bundler(); |
|||
console.log('scripts rebuild'); |
|||
}); |
|||
|
|||
return bundler(); |
|||
} |
|||
|
|||
gulp.task('scripts', () => { |
|||
bundle(); |
|||
}); |
|||
|
|||
gulp.task('styles', () => { |
|||
gulp.src('css/styles.less'). |
|||
pipe(gulpPlugins.plumber()). |
|||
pipe(sourcemaps.init()). |
|||
pipe(gulpPlugins.less({ |
|||
'includePaths': ['.'] |
|||
})). |
|||
pipe(gulpPlugins.autoprefixer()). |
|||
pipe(sourcemaps.write('./')). |
|||
pipe(gulp.dest('./')); |
|||
}); |
|||
|
|||
gulp.task('build', [ |
|||
'scripts', |
|||
'styles' |
|||
]); |
|||
|
|||
gulp.task('watch', () => { |
|||
bundle(true); |
|||
gulp.watch('css/**/*.less', ['styles']); |
|||
}); |
|||
|
|||
gulp.task('serve', ['watch'], () => { |
|||
browserSync({ |
|||
'notify': false, |
|||
'port': 9000, |
|||
// Proxy: 'example.com',
|
|||
'server': { |
|||
'baseDir': '.' |
|||
} |
|||
}); |
|||
|
|||
gulp.watch([ |
|||
'**/*.html', |
|||
'**/*.php', |
|||
'styles.css', |
|||
'app.js' |
|||
]).on('change', browserSync.reload); |
|||
}); |
|||
|
|||
gulp.task('default', [ |
|||
'build', |
|||
'serve' |
|||
]); |