Merge remote-tracking branch 'upstream/gh-pages' into gh-pages
Conflicts: style.css
This commit is contained in:
commit
ece492f1ca
@ -81,6 +81,7 @@ Contributors
|
||||
[JasonMillward](https://github.com/JasonMillward),
|
||||
[mledoze](https://github.com/mledoze),
|
||||
[OshiHidra](https://github.com/OshiHidra),
|
||||
[Pirozek](https://github.com/Pirozek),
|
||||
[Scrool](https://github.com/Scrool),
|
||||
[sorgo](https://github.com/sorgo),
|
||||
[Xelio](https://github.com/Xelio),
|
||||
|
6
build.py
6
build.py
@ -1,10 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import glob
|
||||
import time
|
||||
|
||||
def readfile(fn):
|
||||
with open(fn, 'Ur') as f:
|
||||
with open(fn, 'Ur', encoding='utf8') as f:
|
||||
return f.read()
|
||||
|
||||
c = '\n\n'.join(map(readfile, glob.glob('code/*')))
|
||||
@ -14,7 +14,7 @@ m = m.split('@@INJECTHERE@@')
|
||||
m.insert(1, c)
|
||||
t = '\n\n'.join(m)
|
||||
|
||||
with open('total-conversion-build.user.js', 'w') as f:
|
||||
with open('total-conversion-build.user.js', 'w', encoding='utf8') as f:
|
||||
f.write(t)
|
||||
|
||||
# vim: ai si ts=4 sw=4 sts=4 et
|
||||
|
17
code/boot.js
17
code/boot.js
@ -27,17 +27,17 @@ window.setupLargeImagePreview = function() {
|
||||
|
||||
window.setupStyles = function() {
|
||||
$('head').append('<style>' +
|
||||
[ '#map { margin-right: '+(SIDEBAR_WIDTH+2)+'px } ',
|
||||
'#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
||||
[ '#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
||||
'#largepreview.res img { border:2px solid '+COLORS[TEAM_RES]+'; } ',
|
||||
'#largepreview.none img { border:2px solid '+COLORS[TEAM_NONE]+'; } ',
|
||||
'#chatcontrols { bottom: '+(CHAT_SHRINKED+24)+'px; }',
|
||||
'#chat { height: '+CHAT_SHRINKED+'px; } ',
|
||||
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4)+'px; } ',
|
||||
'#sidebar { width:'+(SIDEBAR_WIDTH + HIDDEN_SCROLLBAR_ASSUMED_WIDTH + 2 /*border*/)+'px; } ',
|
||||
'.leaflet-right { margin-right: '+(SIDEBAR_WIDTH+1)+'px } ',
|
||||
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4+1)+'px; } ',
|
||||
'#sidebar { width:'+(SIDEBAR_WIDTH + HIDDEN_SCROLLBAR_ASSUMED_WIDTH + 1 /*border*/)+'px; } ',
|
||||
'#sidebartoggle { right:'+SIDEBAR_WIDTH+'px; } ',
|
||||
'#scrollwrapper { width:'+(SIDEBAR_WIDTH + 2*HIDDEN_SCROLLBAR_ASSUMED_WIDTH)+'px; right:-'+(2*HIDDEN_SCROLLBAR_ASSUMED_WIDTH-2)+'px } ',
|
||||
'#sidebar input, h2, #updatestatus { width:'+(SIDEBAR_WIDTH - 2*4)+'px !important } ',
|
||||
'#sidebar input, h2 { width:'+(SIDEBAR_WIDTH - 2*4)+'px !important } ',
|
||||
'#sidebar > *, #gamestat span, .imgpreview img { width:'+SIDEBAR_WIDTH+'px; }'].join("\n")
|
||||
+ '</style>');
|
||||
}
|
||||
@ -176,16 +176,15 @@ window.setupSidebarToggle = function() {
|
||||
var sidebar = $('#sidebar');
|
||||
if(sidebar.is(':visible')) {
|
||||
sidebar.hide();
|
||||
$('#map').css('margin-right','0');
|
||||
$('.leaflet-right').css('margin-right','0');
|
||||
toggle.html('◢<br>◥');
|
||||
toggle.css('right', '0');
|
||||
} else {
|
||||
sidebar.show();
|
||||
$('#map').css('margin-right', SIDEBAR_WIDTH+2+'px');
|
||||
$('.leaflet-right').css('margin-right', SIDEBAR_WIDTH+1+'px');
|
||||
toggle.html('◣<br>◤');
|
||||
toggle.css('right', SIDEBAR_WIDTH+'px');
|
||||
toggle.css('right', SIDEBAR_WIDTH+1+'px');
|
||||
}
|
||||
window.map.invalidateSize(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -216,9 +216,17 @@ window.renderPortal = function(ent) {
|
||||
var team = getTeam(ent[2]);
|
||||
|
||||
// do nothing if portal did not change
|
||||
var old = window.portals[ent[0]];
|
||||
if(old && old.options.level === portalLevel && old.options.team === team)
|
||||
return;
|
||||
var layerGroup = portalsLayers[parseInt(portalLevel)];
|
||||
var old = findEntityInLeaflet(layerGroup, window.portals, ent[0]);
|
||||
if(old) {
|
||||
var oo = old.options;
|
||||
var u = oo.team !== team;
|
||||
u = u || oo.level !== portalLevel;
|
||||
// nothing for the portal changed, so don’t update. Let resonators
|
||||
// manage themselves if they want to be updated.
|
||||
if(!u) return renderResonators(ent);
|
||||
removeByGuid(ent[0]);
|
||||
}
|
||||
|
||||
// there were changes, remove old portal
|
||||
removeByGuid(ent[0]);
|
||||
@ -245,7 +253,7 @@ window.renderPortal = function(ent) {
|
||||
details: ent[2],
|
||||
guid: ent[0]});
|
||||
|
||||
p.on('remove', function() {
|
||||
p.on('remove', function() {
|
||||
var portalGuid = this.options.guid
|
||||
|
||||
// remove attached resonators, skip if
|
||||
@ -261,13 +269,17 @@ window.renderPortal = function(ent) {
|
||||
window.portalAccessIndicator = null;
|
||||
}
|
||||
});
|
||||
p.on('add', function() {
|
||||
|
||||
p.on('add', function() {
|
||||
// enable for debugging
|
||||
if(window.portals[this.options.guid]) throw('duplicate portal detected');
|
||||
window.portals[this.options.guid] = this;
|
||||
// handles the case where a selected portal gets removed from the
|
||||
// map by hiding all portals with said level
|
||||
if(window.selectedPortal != this.options.guid)
|
||||
window.portalResetColor(this);
|
||||
});
|
||||
|
||||
p.on('click', function() { window.renderPortalDetails(ent[0]); });
|
||||
p.on('dblclick', function() {
|
||||
window.renderPortalDetails(ent[0]);
|
||||
@ -279,11 +291,10 @@ window.renderPortal = function(ent) {
|
||||
window.runHooks('portalAdded', {portal: p});
|
||||
|
||||
// portalLevel contains a float, need to round down
|
||||
p.addTo(portalsLayers[parseInt(portalLevel)]);
|
||||
p.addTo(layerGroup);
|
||||
}
|
||||
|
||||
window.renderResonators = function(ent) {
|
||||
|
||||
var portalLevel = getPortalLevel(ent[2]);
|
||||
if(portalLevel < getMinPortalLevel() && ent[0] != selectedPortal) return;
|
||||
|
||||
@ -344,8 +355,12 @@ window.portalResetColor = function(portal) {
|
||||
|
||||
// renders a link on the map from the given entity
|
||||
window.renderLink = function(ent) {
|
||||
removeByGuid(ent[0]);
|
||||
if(Object.keys(links).length >= MAX_DRAWN_LINKS) return;
|
||||
if(Object.keys(links).length >= MAX_DRAWN_LINKS)
|
||||
return removeByGuid(ent[0]);
|
||||
|
||||
// assume that links never change. If they do, they will have a
|
||||
// different ID.
|
||||
if(findEntityInLeaflet(linksLayer, links, ent[0])) return;
|
||||
|
||||
var team = getTeam(ent[2]);
|
||||
var edge = ent[2].edge;
|
||||
@ -366,6 +381,8 @@ window.renderLink = function(ent) {
|
||||
|
||||
poly.on('remove', function() { delete window.links[this.options.guid]; });
|
||||
poly.on('add', function() {
|
||||
// enable for debugging
|
||||
if(window.links[this.options.guid]) throw('duplicate link detected');
|
||||
window.links[this.options.guid] = this;
|
||||
this.bringToBack();
|
||||
});
|
||||
@ -374,8 +391,12 @@ window.renderLink = function(ent) {
|
||||
|
||||
// renders a field on the map from a given entity
|
||||
window.renderField = function(ent) {
|
||||
window.removeByGuid(ent[0]);
|
||||
if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return;
|
||||
if(Object.keys(fields).length >= MAX_DRAWN_FIELDS)
|
||||
return window.removeByGuid(ent[0]);
|
||||
|
||||
// assume that fields never change. If they do, they will have a
|
||||
// different ID.
|
||||
if(findEntityInLeaflet(fieldsLayer, fields, ent[0])) return;
|
||||
|
||||
var team = getTeam(ent[2]);
|
||||
var reg = ent[2].capturedRegion;
|
||||
@ -391,14 +412,37 @@ window.renderField = function(ent) {
|
||||
clickable: false,
|
||||
smoothFactor: 10,
|
||||
vertices: ent[2].capturedRegion,
|
||||
lastUpdate: ent[1],
|
||||
guid: ent[0]});
|
||||
|
||||
if(!getPaddedBounds().intersects(poly.getBounds())) return;
|
||||
|
||||
poly.on('remove', function() { delete window.fields[this.options.guid]; });
|
||||
poly.on('add', function() {
|
||||
// enable for debugging
|
||||
if(window.fields[this.options.guid]) console.warn('duplicate field detected');
|
||||
window.fields[this.options.guid] = this;
|
||||
this.bringToBack();
|
||||
});
|
||||
poly.addTo(fieldsLayer);
|
||||
}
|
||||
|
||||
|
||||
// looks for the GUID in either the layerGroup or entityHash, depending
|
||||
// on which is faster. Will either return the Leaflet entity or null, if
|
||||
// it does not exist.
|
||||
// For example, to find a field use the function like this:
|
||||
// field = findEntityInLeaflet(fieldsLayer, fields, 'asdasdasd');
|
||||
window.findEntityInLeaflet = function(layerGroup, entityHash, guid) {
|
||||
// fast way
|
||||
if(map.hasLayer(layerGroup)) return entityHash[guid] || null;
|
||||
|
||||
// slow way in case the layer is currently hidden
|
||||
var ent = null;
|
||||
layerGroup.eachLayer(function(entity) {
|
||||
if(entity.options.guid !== guid) return true;
|
||||
ent = entity;
|
||||
return false;
|
||||
});
|
||||
return ent;
|
||||
}
|
||||
|
@ -19,24 +19,23 @@ window.renderPortalDetails = function(guid) {
|
||||
links[link.isOrigin ? 'outgoing' : 'incoming']++;
|
||||
});
|
||||
function linkExpl(t) { return '<tt title="↳ incoming links\n↴ outgoing links\n• is meant to be the portal.">'+t+'</tt>'; }
|
||||
var linksText = linkExpl('links')+':'+linkExpl(' ↳ ' + links.incoming+' • '+links.outgoing+' ↴');
|
||||
var linksText = [linkExpl('links'), linkExpl(' ↳ ' + links.incoming+' • '+links.outgoing+' ↴')];
|
||||
|
||||
var player = d.captured && d.captured.capturingPlayerId
|
||||
? getPlayerName(d.captured.capturingPlayerId)
|
||||
: null;
|
||||
var playerText = player ? 'owner: ' + player : null;
|
||||
var playerText = player ? ['owner', player] : null;
|
||||
|
||||
var time = d.captured ? unixTimeToString(d.captured.capturedTime) : null;
|
||||
var sinceText = time ? 'since: ' + time : null;
|
||||
var sinceText = time ? ['since', time] : null;
|
||||
|
||||
var linkedFields = 'fields: ' + d.portalV2.linkedFields.length;
|
||||
var linkedFields = ['fields', d.portalV2.linkedFields.length];
|
||||
|
||||
// collect and html-ify random data
|
||||
var randDetails = [playerText, sinceText, getRangeText(d), getEnergyText(d), linksText, getAvgResoDistText(d), linkedFields];
|
||||
var randDetails = [playerText, sinceText, getRangeText(d), getEnergyText(d), linksText, getAvgResoDistText(d), linkedFields, getDestroyAP(d)];
|
||||
randDetails = randDetails.map(function(detail) {
|
||||
if(!detail) return '';
|
||||
detail = detail.split(':');
|
||||
detail = '<aside>'+detail.shift()+'<span>'+detail.join(':')+'</span></aside>';
|
||||
detail = '<aside>'+detail[0]+'<span>'+detail[1]+'</span></aside>';
|
||||
return detail;
|
||||
}).join('\n');
|
||||
|
||||
|
@ -6,12 +6,12 @@
|
||||
// returns displayable text+link about portal range
|
||||
window.getRangeText = function(d) {
|
||||
var range = getPortalRange(d);
|
||||
return 'range: '
|
||||
return ['range',
|
||||
+ '<a onclick="window.rangeLinkClick()">'
|
||||
+ (range > 1000
|
||||
? Math.round(range/1000) + ' km'
|
||||
: Math.round(range) + ' m')
|
||||
+ '</a>';
|
||||
+ '</a>'];
|
||||
}
|
||||
|
||||
// generates description text from details for portal
|
||||
@ -69,17 +69,15 @@ window.getEnergyText = function(d) {
|
||||
var totalNrg = getTotalPortalEnergy(d);
|
||||
var inf = currentNrg + ' / ' + totalNrg;
|
||||
var fill = prettyEnergy(currentNrg) + ' / ' + prettyEnergy(totalNrg)
|
||||
var meter = 'energy: <tt title="'+inf+'">' + fill + '</tt>';
|
||||
return meter;
|
||||
return ['energy', '<tt title="'+inf+'">' + fill + '</tt>'];
|
||||
}
|
||||
|
||||
window.getAvgResoDistText = function(d) {
|
||||
var avgDist = Math.round(10*getAvgResoDist(d))/10;
|
||||
return '⌀ res dist: ' + avgDist + ' m';
|
||||
return ['⌀ res dist', avgDist + ' m'];
|
||||
}
|
||||
|
||||
window.getResonatorDetails = function(d) {
|
||||
console.log('rendering reso details');
|
||||
var resoDetails = '';
|
||||
// octant=slot: 0=E, 1=NE, 2=N, 3=NW, 4=W, 5=SW, 6=S, SE=7
|
||||
// resos in the display should be ordered like this:
|
||||
@ -139,3 +137,33 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick, isLeft) {
|
||||
var text = '<span class="meter-text '+cls+'">'+(nick||'')+'</span>';
|
||||
return (isLeft ? text+meter : meter+text) + '<br/>';
|
||||
}
|
||||
|
||||
// calculate AP gain from destroying portal
|
||||
// so far it counts only resonators + links
|
||||
window.getDestroyAP = function(d) {
|
||||
var resoCount = 0;
|
||||
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(!reso) return true;
|
||||
resoCount += 1;
|
||||
});
|
||||
|
||||
var linkCount = d.portalV2.linkedEdges ? d.portalV2.linkedEdges.length : 0;
|
||||
var fieldCount = d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0;
|
||||
|
||||
var resoAp = resoCount * DESTROY_RESONATOR;
|
||||
var linkAp = linkCount * DESTROY_LINK;
|
||||
var fieldAp = fieldCount * DESTROY_FIELD;
|
||||
var sum = resoAp + linkAp + fieldAp;
|
||||
|
||||
function tt(text) {
|
||||
var t = 'Destroy:\n';
|
||||
t += resoCount + '×\tResonators\t= ' + digits(resoAp) + '\n';
|
||||
t += linkCount + '×\tLinks\t\t= ' + digits(linkAp) + '\n';
|
||||
t += fieldCount + '×\tFields\t\t= ' + digits(fieldAp) + '\n';
|
||||
t += 'Sum: ' + digits(sum) + ' AP';
|
||||
return '<tt title="'+t+'">' + digits(text) + '</tt>';
|
||||
}
|
||||
|
||||
return [tt('AP Gain'), tt(sum)];
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ window.renderUpdateStatus = function() {
|
||||
t += ' <span style="color:red" class="help" title="Can only render so much before it gets unbearably slow. Not all entities are shown. Zoom in or increase the limit (search for MAX_DRAWN_*).">RENDER LIMIT</span> '
|
||||
|
||||
if(window.failedRequestCount > 0)
|
||||
t += ' <span style="color:red">' + window.failedRequestCount + ' requests failed</span>.'
|
||||
t += ' <span style="color:red">' + window.failedRequestCount + ' failed</span>.'
|
||||
|
||||
t += '<br/>(';
|
||||
var minlvl = getMinPortalLevel();
|
||||
|
@ -160,6 +160,10 @@ window.getTypeByGuid = function(guid) {
|
||||
// .c == player/creator
|
||||
// .d == chat messages
|
||||
//
|
||||
// others, not used in web:
|
||||
// .5 == resources (burster/resonator)
|
||||
// .6 == XM
|
||||
// .4 == media items, maybe all droppped resources (?)
|
||||
// resonator guid is [portal guid]-resonator-[slot]
|
||||
switch(guid.slice(33)) {
|
||||
case '11':
|
||||
|
10
main.js
10
main.js
@ -49,7 +49,6 @@ for(var i = 0; i < d.length; i++) {
|
||||
// player information is now available in a hash like this:
|
||||
// window.PLAYER = {"ap": "123", "energy": 123, "available_invites": 123, "nickname": "somenick", "team": "ALIENS||RESISTANCE"};
|
||||
|
||||
|
||||
// remove complete page. We only wanted the user-data and the page’s
|
||||
// security context so we can access the API easily. Setup as much as
|
||||
// possible without requiring scripts.
|
||||
@ -81,9 +80,9 @@ document.getElementsByTagName('body')[0].innerHTML = ''
|
||||
+ ' <input id="redeem" placeholder="Redeem code…" type="text"/>'
|
||||
+ ' <div id="toolbox"><a onmouseover="setPermaLink(this)">permalink</a></div>'
|
||||
+ ' <div id="spacer"></div>'
|
||||
+ ' <div id="updatestatus"></div>'
|
||||
+ ' </div>';
|
||||
+ '</div>';
|
||||
+ ' </div>'
|
||||
+ '</div>'
|
||||
+ '<div id="updatestatus"></div>';
|
||||
|
||||
// putting everything in a wrapper function that in turn is placed in a
|
||||
// script tag on the website allows us to execute in the site’s context
|
||||
@ -147,6 +146,9 @@ var MIN_AP_FOR_LEVEL = [0, 10000, 30000, 70000, 150000, 300000, 600000, 1200000]
|
||||
var HACK_RANGE = 40; // in meters, max. distance from portal to be able to access it
|
||||
var OCTANTS = ['E', 'NE', 'N', 'NW', 'W', 'SW', 'S', 'SE'];
|
||||
var DEFAULT_PORTAL_IMG = 'http://commondatastorage.googleapis.com/ingress/img/default-portal-image.png';
|
||||
var DESTROY_RESONATOR = 75; //AP for destroying portal
|
||||
var DESTROY_LINK = 187; //AP for destroying link
|
||||
var DESTROY_FIELD = 750; //AP for destroying field
|
||||
|
||||
// OTHER MORE-OR-LESS CONSTANTS //////////////////////////////////////
|
||||
var NOMINATIM = 'http://nominatim.openstreetmap.org/search?format=json&limit=1&q=';
|
||||
|
45
style.css
45
style.css
@ -10,39 +10,43 @@ body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#map {
|
||||
margin-right:302px;
|
||||
}
|
||||
|
||||
#scrollwrapper {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
right: -38px;
|
||||
top: 0;
|
||||
width: 340px;
|
||||
bottom: 45px;
|
||||
z-index: 1001;
|
||||
|
||||
/*
|
||||
* NOTE: following 2 items are needed for back compatability
|
||||
* between new css and old plugin versions (0.4) as of 2013-02-11 UTC.
|
||||
*/
|
||||
background-color: rgba(8, 48, 78, 1);
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
background: #000;
|
||||
border-left: 2px solid #c3c3c3;
|
||||
background-color: rgba(8, 48, 78, 0.9);
|
||||
border-left: 1px solid #20A8B1;
|
||||
color: #888;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-height: 100%;
|
||||
overflow-y:scroll;
|
||||
overflow-x:hidden;
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
#sidebartoggle {
|
||||
display: block;
|
||||
padding: 10px 5px;
|
||||
padding: 20px 5px;
|
||||
margin-top: -31px;
|
||||
line-height: 10px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
z-index: 3000;
|
||||
z-index: 3001;
|
||||
background-color: rgba(8, 48, 78, 0.9);
|
||||
color: #FFCE00;
|
||||
border: 1px solid #20A8B1;
|
||||
@ -257,7 +261,7 @@ summary {
|
||||
/* sidebar ************************************************************/
|
||||
|
||||
#sidebar > * {
|
||||
border-bottom: 1px solid #c3c3c3;
|
||||
border-bottom: 1px solid #20A8B1;
|
||||
}
|
||||
|
||||
|
||||
@ -321,7 +325,7 @@ h2 sup, h2 sub {
|
||||
|
||||
/* geosearch input, and others */
|
||||
input {
|
||||
background: #313131;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
color: #ffce00;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
@ -369,8 +373,7 @@ h3 {
|
||||
font-size: 40px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
/* simulate an outline with multiple shadows */
|
||||
text-shadow: -2px -2px #000000, 2px -2px #000000, -2px 2px #000000, 2px 2px #000000;
|
||||
text-shadow: -1px -1px #000, 1px -1px #000, -1px 1px #000, 1px 1px #000, 0 0 5px #fff;
|
||||
top: 100px;
|
||||
}
|
||||
|
||||
@ -382,7 +385,7 @@ h3 {
|
||||
}
|
||||
|
||||
.mods span {
|
||||
background: #313131;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
/* can’t use inline-block because Webkit’s implementation is buggy and
|
||||
* introduces additional margins in random cases. No clear necessary,
|
||||
* as that’s solved by setting height on .mods. */
|
||||
@ -527,30 +530,30 @@ aside:nth-child(odd) span {
|
||||
}
|
||||
|
||||
#spacer {
|
||||
/* cheap hack to prevent sidebar content being overlayed by the map
|
||||
* status box */
|
||||
height: 55px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* a common portal display takes this much space (prevents moving
|
||||
* content when first selecting a portal) */
|
||||
|
||||
#portaldetails {
|
||||
min-height: 532px;
|
||||
min-height: 553px;
|
||||
}
|
||||
|
||||
|
||||
/* update status */
|
||||
#updatestatus {
|
||||
background: #000;
|
||||
background-color: rgba(8, 48, 78, 1);
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid #c3c3c3;
|
||||
border-top: 1px solid #20A8B1;
|
||||
border-left: 1px solid #20A8B1;
|
||||
bottom: 0;
|
||||
color: #ffce00;
|
||||
font-size:13px;
|
||||
padding: 4px;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
z-index:3002;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user