Changeset 0e5b46e7


Ignore:
Timestamp:
Oct 25, 2017 9:31:13 AM (3 years ago)
Author:
str4d <str4d@…>
Branches:
master
Children:
5ecae1a
Parents:
97267a4
Message:

Console sidebar improvements

Sidebar:

  • Adjust vertical spacing of general section
  • Rename 'General' section to 'Router Info' and move ident info to h3 tooltip (ticket #1996)
  • Replace 'Short Router Info' with a new 'Advanced Router Info' section in default advanced sidebar (adds memory usage and clock skew)
  • Add optional embedded bandwidth graph (experimental)
  • Add optional memory usage bar
  • Add optional Advanced Peers section (adds failing and banned peers)
  • Add Help link to 'I2P Internals' section
  • Add help page anchored links and troubleshooting to 'Help & FAQ' section
  • Add download progress bar for router and plugin updates
  • Add 'Advanced Minimal' sidebar configuration
  • Add Jobs and Events links to Advanced section
  • Add additional reachability states for clockskew and vmcomm (with icons)

Homepage: Add 'Customize Sidebar' link to signpost the feature now that there

are more optional sections available (ticket #1996)

Files:
2 added
20 edited

Legend:

Unmodified
Added
Removed
  • apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java

    r97267a4 r0e5b46e7  
    998998    public void notifyProgress(UpdateTask task, String status, long downloaded, long totalSize) {
    999999        StringBuilder buf = new StringBuilder(64);
    1000         buf.append(status).append(' ');
     1000        buf.append("<div class=\"sb_updatestatus\">");
     1001        buf.append(status).append("</div>");
    10011002        double pct = ((double)downloaded) / ((double)totalSize);
    10021003        synchronized (_pct) {
     1004            buf.append("<div class=\"percentBarOuter\"><div class=\"percentBarText\">");
     1005            buf.append(DataHelper.formatSize2(downloaded));
     1006            buf.append("B / ");
     1007            buf.append(DataHelper.formatSize2(totalSize));
     1008            buf.append("B</div><div class=\"percentBarInner\" style=\"width: ");
    10031009            buf.append(_pct.format(pct));
    1004         }
    1005         buf.append("<br>\n");
    1006         buf.append(_t("{0}B transferred", DataHelper.formatSize2(downloaded)));
     1010            buf.append("\">");
     1011        }
    10071012        updateStatus(buf.toString());
    10081013    }
  • apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java

    r97267a4 r0e5b46e7  
    5050        UpdateRunner update = new UpdateRunner(_context, _mgr, type, method, updateSources);
    5151        // set status before thread to ensure UI feedback
    52         _mgr.notifyProgress(update, "<b>" + _mgr._t("Updating") + "</b>");
     52        _mgr.notifyProgress(update, "<b>" + _mgr._t("Updating") + " I2P</b>");
    5353        return update;
    5454    }
  • apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java

    r97267a4 r0e5b46e7  
    260260            return;
    261261        long d = currentWrite + bytesTransferred;
    262         String status = "<b>" + _t("Updating") + "</b>";
     262        String status = "<b>" + _t("Updating") + " I2P</b>";
    263263        _mgr.notifyProgress(this, status, d, d + bytesRemaining);
    264264    }
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigSummaryHandler.java

    r97267a4 r0e5b46e7  
    4141                          _t("Summary bar will refresh shortly."));
    4242        } else if (_action.equals(_t("Restore minimal default"))) {
    43             _context.router().saveConfig(SummaryHelper.PROP_SUMMARYBAR + "default", SummaryHelper.DEFAULT_MINIMAL);
     43            _context.router().saveConfig(SummaryHelper.PROP_SUMMARYBAR + "default", isAdvanced() ? SummaryHelper.DEFAULT_MINIMAL_ADVANCED : SummaryHelper.DEFAULT_MINIMAL);
    4444            addFormNotice(_t("Minimal summary bar default restored.") + " " +
    4545                          _t("Summary bar will refresh shortly."));
  • apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java

    r97267a4 r0e5b46e7  
    3333        _x("Configure UI") + S + _x("Select console theme & language & set optional console password").replace("&", "&amp;") + S + "/configui" + S + I + "info/ui.png" + S +
    3434        _x("Customize Home Page") + S + _x("I2P Home Page Configuration") + S + "/confighome" + S + I + "home_page.png" + S +
     35        _x("Customize Sidebar") + S + _x("Customize the sidebar by adding or removing or repositioning elements") + S + "/configsidebar" + S + I + "info/sidebar.png" + S +
    3536        _x("Email") + S + _x("Anonymous webmail client") + S + "/susimail/susimail" + S + I + "email.png" + S +
    3637        _x("Help") + S + _x("I2P Router Help") + S + "/help" + S + I + "support.png" + S +
  • apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java

    r97267a4 r0e5b46e7  
    2727
    2828    static final String ALL_SECTIONS[] =
    29         {"HelpAndFAQ", "I2PServices", "I2PInternals", "General", "ShortGeneral", "NetworkReachability",
    30         "UpdateStatus", "RestartStatus", "Peers", "FirewallAndReseedStatus", "Bandwidth", "Tunnels",
     29        {"HelpAndFAQ", "I2PServices", "I2PInternals", "RouterInfo", "ShortRouterInfo", "AdvancedRouterInfo", "MemoryBar", "NetworkReachability",
     30        "UpdateStatus", "RestartStatus", "Peers", "PeersAdvanced", "FirewallAndReseedStatus", "Bandwidth", "BandwidthGraph", "Tunnels",
    3131        "Congestion", "TunnelStatus", "Destinations", "NewsHeadings", "Advanced" };
    3232    static final Map<String, String> SECTION_NAMES;
     
    3737        aMap.put("I2PServices", "I2P Services");
    3838        aMap.put("I2PInternals", "I2P Internals");
    39         aMap.put("General", "General");
    40         aMap.put("ShortGeneral", "Short General");
     39        aMap.put("RouterInfo", "Router Information");
     40        aMap.put("ShortRouterInfo", "Short Router Information");
     41        aMap.put("AdvancedRouterInfo", "Router Information (advanced)");
     42        aMap.put("MemoryBar", "Memory Usage Bar");
    4143        aMap.put("NetworkReachability", "Network Reachability");
    4244        aMap.put("UpdateStatus", "Update Status");
    4345        aMap.put("RestartStatus", "Restart Status");
    4446        aMap.put("Peers", "Peers");
     47        aMap.put("PeersAdvanced", "Peers (advanced)");
    4548        aMap.put("FirewallAndReseedStatus", "Firewall &amp; Reseed Status");
    4649        aMap.put("Bandwidth", "Bandwidth");
     50        aMap.put("BandwidthGraph", "Bandwidth Graph (experimental)");
    4751        aMap.put("Tunnels", "Tunnels");
    4852        aMap.put("Congestion", "Congestion");
     
    5054        aMap.put("Destinations", "Local Tunnels");
    5155        aMap.put("NewsHeadings", "News &amp; Updates");
    52         aMap.put("Advanced", "Advanced");
     56        aMap.put("Advanced", "Advanced Console Links");
    5357        SECTION_NAMES = Collections.unmodifiableMap(aMap);
    5458    }
     
    9296            else if ("Advanced".equals(section))
    9397                buf.append(renderAdvancedHTML());
    94             else if ("General".equals(section))
    95                 buf.append(renderGeneralHTML());
    96             else if ("ShortGeneral".equals(section))
    97                 buf.append(renderShortGeneralHTML());
     98            else if ("RouterInfo".equals(section) || "General".equals(section)) // Backwards-compatibility
     99                buf.append(renderRouterInfoHTML());
     100            else if ("ShortRouterInfo".equals(section) || "ShortGeneral".equals(section)) //Backwards-compatibility
     101                buf.append(renderShortRouterInfoHTML());
     102            else if ("AdvancedRouterInfo".equals(section))
     103                buf.append(renderAdvancedRouterInfoHTML());
     104            else if ("MemoryBar".equals(section))
     105                buf.append(renderMemoryBarHTML());
    98106            else if ("NetworkReachability".equals(section))
    99107                buf.append(renderNetworkReachabilityHTML());
     
    104112            else if ("Peers".equals(section))
    105113                buf.append(renderPeersHTML());
     114            else if ("PeersAdvanced".equals(section))
     115                buf.append(renderPeersAdvancedHTML());
    106116            else if ("FirewallAndReseedStatus".equals(section))
    107117                buf.append(renderFirewallAndReseedStatusHTML());
    108118            else if ("Bandwidth".equals(section))
    109119                buf.append(renderBandwidthHTML());
     120            else if ("BandwidthGraph".equals(section))
     121                buf.append(renderBandwidthGraphHTML());
    110122            else if ("Tunnels".equals(section))
    111123                buf.append(renderTunnelsHTML());
     
    131143           .append("\">")
    132144           .append(_t("Help &amp; FAQ"))
    133            .append("</a></h3>");
     145           .append("</a></h3><hr class=\"b\">\n" +
     146
     147                   "<table id=\"sb_help\"><tr><td>" +
     148
     149                   "<a href=\"/help#advancedsettings\" target=\"_top\" title=\"")
     150           .append(_t("A guide to some of the less-used configuration settings"))
     151           .append("\">")
     152           .append(nbsp(_t("Advanced Settings")))
     153           .append("</a>\n" +
     154
     155                   "<a href=\"/help#changelog\" target=\"_top\" title=\"")
     156           .append(_t("Recent development changes to the router"))
     157           .append("\">")
     158           .append(nbsp(_t("Changelog")))
     159           .append("</a>\n" +
     160
     161                   "<a href=\"/help#configurationhelp\" target=\"_top\" title=\"")
     162           .append(_t("An introduction to configuring your router"))
     163           .append("\">")
     164           .append(nbsp(_t("Configuration")))
     165           .append("</a>\n" +
     166
     167                   "<a href=\"/help#faq\" target=\"_top\" title=\"")
     168           .append(_t("A shortened version of the official Frequently Asked Questions"))
     169           .append("\">")
     170           .append(nbsp(_t("FAQ")))
     171           .append("</a>\n" +
     172
     173                   "<a href=\"/help#legal\" target=\"_top\" title=\"")
     174           .append(_t("Information regarding software and licenses used by I2P"))
     175           .append("\">")
     176           .append(nbsp(_t("Legal")))
     177           .append("</a>\n" +
     178
     179                   "<a href=\"/help#reachability\" target=\"_top\" title=\"")
     180           .append(_t("A short guide to the sidebar's network reachability notification"))
     181           .append("\">")
     182           .append(nbsp(_t("Reachability")))
     183           .append("</a>\n" +
     184
     185                   "<a href=\"/help#sidebarhelp\" target=\"_top\" title=\"")
     186           .append(_t("An introduction to the router sidebar"))
     187           .append("\">")
     188           .append(nbsp(_t("Sidebar")))
     189           .append("</a>\n" +
     190
     191                   "<a href=\"/console#trouble\" target=\"_top\" title=\"")
     192           .append(_t("Troubleshooting &amp; Further Assistance"))
     193           .append("\">")
     194           .append(nbsp(_t("Troubleshoot")))
     195           .append("</a>\n")
     196
     197           .append("</td></tr></table>\n");
    134198        return buf.toString();
    135199    }
     
    197261        }
    198262
    199         buf.append("<a href=\"/i2ptunnelmgr\" target=\"_top\" title=\"")
     263        buf.append("<a href=\"/help\" target=\"_top\" title=\"")
     264           .append(_t("Router Help and FAQ"))
     265           .append("\">")
     266           .append(nbsp(_t("Help")))
     267           .append("</a>\n" +
     268
     269                   "<a href=\"/i2ptunnelmgr\" target=\"_top\" title=\"")
    200270           .append(_t("Local Tunnels"))
    201271           .append("\">")
    202272           .append(nbsp(_t("Hidden Services Manager")))
    203273           .append("</a>\n" +
    204 
    205        //          "<a href=\"/jobs.jsp\" target=\"_top\" title=\"")
    206        //  .append(_t("Show the router's workload, and how it's performing"))
    207        //  .append("\">")
    208        //  .append(_t("Jobs"))
    209        //  .append("</a>\n" +
    210274
    211275                   "<a href=\"/logs\" target=\"_top\" title=\"")
     
    248312        buf.append("<h3 id=\"advanced\"><a title=\"")
    249313           .append(_t("Advanced Configuration"))
    250            .append("\" href=\"/configadvanced\">")
     314           .append("\" href=\"/configadvanced\" target=\"_top\">")
    251315           .append(_t("Advanced"))
    252316           .append("</a></h3>\n")
     
    254318           .append("<hr class=\"b\"><table id=\"sb_advanced\"><tr><td>")
    255319
    256            .append("<a title=\"")
     320           .append("<a target=\"_top\" title=\"")
    257321           .append(_t("Review active encryption certificates used in console"))
    258322           .append("\" href=\"/certs\">")
     
    268332           .append("<a title=\"")
    269333           .append(_t("View router debug information"))
    270            .append("\" href=\"/debug\">")
     334           .append("\" href=\"/debug\" target=\"_top\">")
    271335           .append(nbsp(_t("Debug")))
     336           .append("</a>\n")
     337
     338           .append("<a href=\"/events\" target=\"_top\" title=\"")
     339           .append(_t("View historical log of router events"))
     340           .append("\">")
     341           .append(nbsp(_t("Events")))
    272342           .append("</a>\n")
    273343
    274344           .append("<a title=\"")
    275345           .append(_t("Review extended info about installed .jar and .war files"))
    276            .append("\" href=\"/jars\">")
     346           .append("\" href=\"/jars\" target=\"_top\">")
    277347           .append(nbsp(_t("Jars")))
    278348           .append("</a>\n");
     
    280350        File javadoc = new File(_context.getBaseDir(), "docs/javadoc/index.html");
    281351        if (javadoc.exists())
    282             buf.append("<a href=\"/javadoc/index.html\" target=\"_blank\">Javadoc</a>\n");
    283 
    284         buf.append("<a title=\"")
     352            buf.append("<a title=\"")
     353               .append(_t("Documentation for the I2P API"))
     354               .append("\" href=\"/javadoc/index.html\" target=\"_blank\">Javadoc</a>\n");
     355
     356        buf.append("<a href=\"/jobs\" target=\"_top\" title=\"")
     357           .append(_t("Show the router's workload, and how it's performing"))
     358           .append("\">")
     359           .append(nbsp(_t("Jobs")))
     360           .append("</a>\n")
     361
     362           .append("<a title=\"")
    285363           .append(_t("View active leasesets (debug mode)"))
    286            .append("\" href=\"/netdb?l=2\">")
     364           .append("\" href=\"/netdb?l=2\" target=\"_top\">")
    287365           .append(nbsp(_t("LeaseSets")))
    288366           .append("</a>\n")
     
    290368           .append("<a title=\"")
    291369           .append(_t("Network database search tool"))
    292            .append("\" href=\"/netdb?f=4\">")
     370           .append("\" href=\"/netdb?f=4\" target=\"_top\">")
    293371           .append(nbsp(_t("NetDB Search")))
    294372           .append("</a>\n")
     
    296374           .append("<a title=\"")
    297375           .append(_t("Signed proof of ownership of this router"))
    298            .append("\" href=\"/proof\">")
     376           .append("\" href=\"/proof\" target=\"_top\">")
    299377           .append(nbsp(_t("Proof")))
    300378           .append("</a>\n")
     
    308386           .append("<a title=\"")
    309387           .append(_t("Review possible sybils in network database"))
    310            .append("\" href=\"/netdb?f=3\">")
     388           .append("\" href=\"/netdb?f=3\" target=\"_top\">")
    311389           .append(nbsp(_t("Sybils")))
    312390           .append("</a>\n")
     
    316394    }
    317395
    318     public String renderGeneralHTML() {
    319         if (_helper == null) return "";
    320         StringBuilder buf = new StringBuilder(512);
    321         buf.append("<h3><a href=\"/help\" target=\"_top\" title=\"")
    322            .append(_t("I2P Router Help"))
    323            .append("\">")
    324            .append(_t("General"))
     396    public String renderRouterInfoHTML() {
     397        if (_helper == null) return "";
     398        StringBuilder buf = new StringBuilder(512);
     399        buf.append("<h3><a href=\"/netdb?r=.\" target=\"_top\" title=\"")
     400           .append(_t("Your Local Identity [{0}] is your unique I2P router identity, similar to an IP address but tailored to I2P. ", _helper.getIdent()))
     401           .append(_t("Never disclose this to anyone, as it can reveal your real world IP."))
     402           .append("\">")
     403           .append(_t("Router Info"))
    325404           .append("</a></h3><hr class=\"b\">\n" +
    326405
    327                    "<table id=\"sb_localid\"><tr>" +
    328                    "<td align=\"left\"><b title=\"")
    329            .append(_t("Your Local Identity is your unique I2P router identity, similar to an ip address but tailored to I2P. "))
    330            .append(_t("Never disclose this to anyone, as it can reveal your real world ip."))
    331            .append("\">")
    332            .append(_t("Local Identity"))
    333            .append(":</b></td>" +
    334                    "<td align=\"right\">" +
    335                    "<a title=\"")
    336            .append(_t("Your unique I2P router identity is"))
    337            .append(' ')
    338            .append(_helper.getIdent())
    339            .append(", ")
    340            .append(_t("never reveal it to anyone"))
    341            .append("\" href=\"/netdb?r=.\" target=\"_top\">")
    342            .append(_t("show"))
    343            .append("</a></td></tr>\n" +
    344 
    345                    "</table><table id=\"sb_version\">" + // fix for some rows with a big left side and some with a big right side
     406                   "</table><table id=\"sb_general\">" +
    346407                   "<tr title=\"")
    347408           .append(_t("The version of the I2P software we are running"))
     
    354415           .append("</td></tr>\n" +
    355416
    356                    "</table><table id=\"sb_uptime\">" + // fix for some rows with a big left side and some with a big right side
    357417                   "<tr title=\"")
    358418           .append(_t("How long we've been running for this session"))
     
    367427    }
    368428
    369     public String renderShortGeneralHTML() {
     429    public String renderShortRouterInfoHTML() {
    370430        if (_helper == null) return "";
    371431        StringBuilder buf = new StringBuilder(512);
     
    393453    }
    394454
     455    /** @since 0.9.32 */
     456    public String renderAdvancedRouterInfoHTML() {
     457        if (_helper == null) return "";
     458        StringBuilder buf = new StringBuilder(512);
     459        buf.append("<h3><a href=\"/netdb?r=.\" target=\"_top\" title=\"")
     460           .append(_t("Your Local Identity [{0}] is your unique I2P router identity, similar to an IP address but tailored to I2P. ", _helper.getIdent()))
     461           .append(_t("Never disclose this to anyone, as it can reveal your real world IP."))
     462           .append("\">")
     463           .append(_t("Router Info"))
     464           .append("</a></h3><hr class=\"b\">\n" +
     465
     466                   "<table id=\"sb_advancedgeneral\">" +
     467                   "<tr title=\"")
     468           .append(_t("The version of the I2P software we are running"))
     469           .append("\">" +
     470                   "<td align=\"left\"><b>")
     471           .append(_t("Version"))
     472           .append(":</b></td>" +
     473                   "<td align=\"right\">")
     474           .append(_helper.getVersion())
     475           .append("</td></tr>\n" +
     476
     477                   "<tr title=\"")
     478           .append(_t("How long we've been running for this session"))
     479           .append("\">" +
     480                   "<td align=\"left\"><b>")
     481           .append(_t("Uptime"))
     482           .append(":</b></td>" +
     483                   "<td align=\"right\">")
     484           .append(_helper.getUptime())
     485           .append("</td></tr>\n" +
     486
     487                   "<tr title=\"")
     488           .append(_t("Difference between network-synced time and local time"))
     489           .append("\">" +
     490                   "<td align=\"left\"><b>")
     491           .append(_t("Clock Skew"))
     492           .append(":</b></td>" +
     493                   "<td align=\"right\">")
     494           .append(_context.clock().getOffset())
     495           .append(" ms</td></tr>\n" +
     496
     497                   "<tr title=\"")
     498           .append(_t("How much RAM I2P is using / total RAM available to I2P (excludes RAM allocated to the JVM)"))
     499           .append("\">" +
     500                   "<td align=\"left\"><b>")
     501           .append(_t("Memory"))
     502           .append(":</b></td>" +
     503                   "<td align=\"right\">")
     504           .append(_helper.getMemory())
     505           .append("</td></tr></table>\n");
     506        return buf.toString();
     507    }
     508
     509    /** @since 0.9.32 */
     510    public String renderMemoryBarHTML() {
     511        if (_helper == null) return "";
     512        StringBuilder buf = new StringBuilder(512);
     513        buf.append(_helper.getMemoryBar());
     514        return buf.toString();
     515    }
     516
    395517    public String renderNetworkReachabilityHTML() {
    396518        if (_helper == null) return "";
    397519        StringBuilder buf = new StringBuilder(512);
    398520        SummaryHelper.NetworkStateMessage reachability = _helper.getReachability();
    399         buf.append("<h4><span class=\"");
     521        buf.append("<h4><span class=\"sb_netstatus ");
    400522        switch (reachability.getState()) {
     523            case VMCOMM:
     524                buf.append("vmcomm");
     525                break;
     526            case CLOCKSKEW:
     527                buf.append("clockskew");
     528                break;
    401529            case ERROR:
    402530                buf.append("error");
     
    529657    }
    530658
     659    public String renderPeersAdvancedHTML() {
     660        if (_helper == null) return "";
     661        StringBuilder buf = new StringBuilder(512);
     662        buf.append("<h3><a href=\"/peers\" target=\"_top\" title=\"")
     663           .append(_t("Show all current peer connections"))
     664           .append("\">")
     665           .append(_t("Peers"))
     666           .append("</a></h3><hr class=\"b\">\n" +
     667
     668                   "<table id=\"sb_peersadvanced\">\n" +
     669
     670                   "<tr title=\"")
     671           .append(_t("Peers we've been talking to in the last few minutes/last hour"))
     672           .append("\">" +
     673                   "<td align=\"left\"><b>")
     674           .append(_t("Active"))
     675           .append(":</b></td><td align=\"right\">");
     676        int active = _helper.getActivePeers();
     677        buf.append(active)
     678           .append(SummaryHelper.THINSP)
     679           .append(Math.max(active, _helper.getActiveProfiles()))
     680           .append("</td></tr>\n" +
     681
     682                   "<tr title=\"")
     683           .append(_t("The number of peers available for building client tunnels"))
     684           .append("\">" +
     685                   "<td align=\"left\"><b>")
     686           .append(_t("Fast"))
     687           .append(":</b></td><td align=\"right\">")
     688           .append(_helper.getFastPeers())
     689           .append("</td></tr>\n" +
     690
     691                   "<tr title=\"")
     692           .append(_t("The number of peers available for building exploratory tunnels"))
     693           .append("\">" +
     694                   "<td align=\"left\"><b>")
     695           .append(_t("High capacity"))
     696           .append(":</b></td><td align=\"right\">")
     697           .append(_helper.getHighCapacityPeers())
     698           .append("</td></tr>\n" +
     699
     700                   "<tr title=\"")
     701           .append(_t("The number of peers available for network database inquiries"))
     702           .append("\">" +
     703                   "<td align=\"left\"><b>")
     704           .append(_t("Integrated"))
     705           .append(":</b></td><td align=\"right\">")
     706           .append(_helper.getWellIntegratedPeers())
     707           .append("</td></tr>\n" +
     708
     709                   "<tr title=\"")
     710           .append(_t("The total number of peers in our network database"))
     711           .append("\">" +
     712                   "<td align=\"left\"><b>")
     713           .append(_t("Known"))
     714           .append(":</b></td><td align=\"right\">")
     715           .append(_helper.getAllPeers())
     716           .append("</td></tr>\n" +
     717
     718                   "<tr class=\"separator\"><td colspan=\"2\"><hr></td></tr>" +
     719
     720                   "<tr title=\"")
     721           .append(_t("The number of peers failing network tests"))
     722           .append("\">" +
     723                   "<td align=\"left\"><a href=\"/profiles\"><b>")
     724           .append(_t("Failing"))
     725           .append(":</b></a></td><td align=\"right\">")
     726           .append(_helper.getFailingPeers())
     727           .append("</td></tr>\n" +
     728
     729                   "<tr title=\"")
     730           .append(_t("The number of banned peers"))
     731           .append("\">" +
     732                   "<td align=\"left\"><a href=\"/profiles?f=3\"><b>")
     733           .append(_t("Banned"))
     734           .append(":</b></a></td><td align=\"right\">")
     735           .append(_helper. getBanlistedPeers())
     736           .append("</td></tr>\n" +
     737
     738                   "</table>\n");
     739        return buf.toString();
     740    }
     741
     742
    531743    public String renderFirewallAndReseedStatusHTML() {
    532744        if (_helper == null) return "";
     
    577789
    578790                   "</table>\n");
     791        return buf.toString();
     792    }
     793
     794    /** @since 0.9.32 */
     795    public String renderBandwidthGraphHTML() {
     796        if (_helper == null) return "";
     797        StringBuilder buf = new StringBuilder(512);
     798        if (!StatSummarizer.isDisabled())
     799            buf.append("<div id=\"sb_graphcontainer\"><a href=\"/graphs\"><table id=\"sb_bandwidthgraph\">" +
     800                       "<tr title=\"")
     801               .append(_t("Our inbound &amp; outbound traffic for the last 20 minutes"))
     802               .append("\"><td><span id=\"sb_graphstats\">")
     803               .append(_helper.getSecondKBps())
     804               .append("Bps</span></td></tr></table></a></div>\n");
     805//               .append("<script src=\"/js/refreshGraph.js\" type=\"text/javascript\"></script>");
    579806        return buf.toString();
    580807    }
  • apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java

    r97267a4 r0e5b46e7  
    3131/**
    3232 * Simple helper to query the appropriate router for data necessary to render
    33  * the summary sections on the router console. 
     33 * the summary sections on the router console.
    3434 *
    3535 * For the full summary bar use renderSummaryBar()
     
    4444
    4545    static final String DEFAULT_FULL =
    46         "HelpAndFAQ" + S +
    47         "ShortGeneral" + S +
     46        "RouterInfo" + S +
    4847        "UpdateStatus" + S +
    4948        "Bandwidth" + S +
     
    5251        "I2PServices" + S +
    5352        "I2PInternals" + S +
     53        "HelpAndFAQ" + S +
    5454        "Peers" + S +
    5555        "Tunnels" + S +
     
    6060
    6161    static final String DEFAULT_FULL_ADVANCED =
    62         "HelpAndFAQ" + S +
    63         "ShortGeneral" + S +
     62        "AdvancedRouterInfo" + S +
     63        "MemoryBar" + S +
    6464        "UpdateStatus" + S +
    6565        "Bandwidth" + S +
     
    7878
    7979    static final String DEFAULT_MINIMAL =
    80         "ShortGeneral" + S +
     80        "ShortRouterInfo" + S +
     81        "Bandwidth" + S +
     82        "UpdateStatus" + S +
     83        "NewsHeadings" + S +
     84        "NetworkReachability" + S +
     85        "FirewallAndReseedStatus" + S +
     86        "RestartStatus" + S +
     87        "Destinations" + S +
     88        "";
     89
     90     /** @since 0.9.32 */
     91    static final String DEFAULT_MINIMAL_ADVANCED =
     92        "AdvancedRouterInfo" + S +
     93        "MemoryBar" + S +
    8194        "Bandwidth" + S +
    8295        "UpdateStatus" + S +
     
    153166        RUNNING,
    154167        WARN,
    155         ERROR;
     168        ERROR,
     169        CLOCKSKEW,
     170        VMCOMM;
    156171    }
    157172
     
    198213    private NetworkStateMessage reachability() {
    199214        if (_context.commSystem().isDummy())
    200             return new NetworkStateMessage(NetworkState.RUNNING, "VM Comm System");
     215            return new NetworkStateMessage(NetworkState.VMCOMM, "VM Comm System");
    201216        if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) &&
    202217            !_context.clientManager().isAlive())
     
    208223        // Display the actual skew, not the offset
    209224        if (Math.abs(skew) > 30*1000)
    210             return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Clock Skew of {0}", DataHelper.formatDuration2(Math.abs(skew))));
     225            return new NetworkStateMessage(NetworkState.CLOCKSKEW, _t("ERR-Clock Skew of {0}", DataHelper.formatDuration2(Math.abs(skew))));
    211226        if (_context.router().isHidden())
    212227            return new NetworkStateMessage(NetworkState.HIDDEN, _t("Hidden"));
     
    282297     *
    283298     */
    284 /********
     299
    285300    public String getMemory() {
    286301        DecimalFormat integerFormatter = new DecimalFormat("###,###,##0");
    287         long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024;
     302        long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024;
    288303        long usedPc = 100 - ((Runtime.getRuntime().freeMemory() * 100) / Runtime.getRuntime().totalMemory());
    289         return integerFormatter.format(used) + "KB (" + usedPc + "%)";
    290     }
    291 ********/
     304        long total = (Runtime.getRuntime().totalMemory())/1024/1024;
     305        // long free = Runtime.getRuntime().freeMemory()/1024/1024;
     306        // return integerFormatter.format(used) + "MB (" + usedPc + "%)";
     307        // return integerFormatter.format(used) + "MB / " + free + " MB";
     308        return integerFormatter.format(used) + " / " + total + "MB";
     309    }
     310
     311    public String getMemoryBar() {
     312        DecimalFormat integerFormatter = new DecimalFormat("###,###,##0");
     313        long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024;
     314        long usedPc = 100 - ((Runtime.getRuntime().freeMemory() * 100) / Runtime.getRuntime().totalMemory());
     315        long total = (Runtime.getRuntime().totalMemory())/1024/1024;
     316        // long free = Runtime.getRuntime().freeMemory()/1024/1024;
     317        // return integerFormatter.format(used) + "MB (" + usedPc + "%)";
     318        // return integerFormatter.format(used) + "MB / " + free + " MB";
     319        return "<div class=\"percentBarOuter\"><div class=\"percentBarText\">RAM: " + integerFormatter.format(used) + " / " + total + "MB" +
     320        "</div><div class=\"percentBarInner\" style=\"width: " + integerFormatter.format(usedPc) +
     321        "%;\"></div></div>";
     322    }
    292323
    293324    /**
     
    295326     *
    296327     */
    297     public int getActivePeers() { 
    298         if (_context == null) 
     328    public int getActivePeers() {
     329        if (_context == null)
    299330            return 0;
    300331        else
     
    306337     */
    307338    public boolean showFirewallWarning() {
    308         return _context != null && 
     339        return _context != null &&
    309340               _context.netDb().isInitialized() &&
    310341               _context.router().getUptime() > 2*60*1000 &&
     
    318349     *
    319350     */
    320     public int getActiveProfiles() { 
    321         if (_context == null) 
     351    public int getActiveProfiles() {
     352        if (_context == null)
    322353            return 0;
    323354        else
     
    328359     *
    329360     */
    330     public int getFastPeers() { 
    331         if (_context == null) 
     361    public int getFastPeers() {
     362        if (_context == null)
    332363            return 0;
    333364        else
     
    338369     *
    339370     */
    340     public int getHighCapacityPeers() { 
    341         if (_context == null) 
     371    public int getHighCapacityPeers() {
     372        if (_context == null)
    342373            return 0;
    343374        else
     
    348379     *
    349380     */
    350     public int getWellIntegratedPeers() { 
    351         if (_context == null) 
     381    public int getWellIntegratedPeers() {
     382        if (_context == null)
    352383            return 0;
    353384        //return _context.profileOrganizer().countWellIntegratedPeers();
     
    358389     *
    359390     */
    360 /********
    361     public int getFailingPeers() { 
    362         if (_context == null) 
     391
     392    public int getFailingPeers() {
     393        if (_context == null)
    363394            return 0;
    364395        else
    365396            return _context.profileOrganizer().countFailingPeers();
    366397    }
    367 ********/
     398
    368399    /**
    369400     * How many peers totally suck.
    370401     *
    371402     */
    372 /********
    373     public int getBanlistedPeers() { 
    374         if (_context == null) 
     403
     404    public int getBanlistedPeers() {
     405        if (_context == null)
    375406            return 0;
    376407        else
    377408            return _context.banlist().getRouterCount();
    378409    }
    379 ********/
    380  
     410
     411
    381412    /**
    382413     *    @return "x.xx / y.yy {K|M}"
    383414     */
    384     public String getSecondKBps() { 
    385         if (_context == null) 
     415    public String getSecondKBps() {
     416        if (_context == null)
    386417            return "0 / 0";
    387         return formatPair(_context.bandwidthLimiter().getReceiveBps(), 
     418        return formatPair(_context.bandwidthLimiter().getReceiveBps(),
    388419                          _context.bandwidthLimiter().getSendBps());
    389420    }
     
    393424     */
    394425    public String getFiveMinuteKBps() {
    395         if (_context == null) 
     426        if (_context == null)
    396427            return "0 / 0";
    397428
     
    416447     *    @return "x.xx / y.yy {K|M}"
    417448     */
    418     public String getLifetimeKBps() { 
    419         if (_context == null) 
     449    public String getLifetimeKBps() {
     450        if (_context == null)
    420451            return "0 / 0";
    421452
     
    465496     *
    466497     */
    467     public String getInboundTransferred() { 
    468         if (_context == null) 
     498    public String getInboundTransferred() {
     499        if (_context == null)
    469500            return "0";
    470501
     
    479510     *
    480511     */
    481     public String getOutboundTransferred() { 
    482         if (_context == null) 
     512    public String getOutboundTransferred() {
     513        if (_context == null)
    483514            return "0";
    484515
     
    530561                        buf.append(" ").append(_t("ago")).append(". ").append(_t("Rebuilding")).append("&hellip;\"></td></tr>\n");
    531562                    } else {
    532                         // green light 
     563                        // green light
    533564                        buf.append("<td><img src=\"/themes/console/images/local_up.png\" alt=\"Ready\" title=\"").append(_t("Ready")).append("\"></td></tr>\n");
    534565                    }
     
    586617     *
    587618     */
    588     public int getInboundTunnels() { 
    589         if (_context == null) 
     619    public int getInboundTunnels() {
     620        if (_context == null)
    590621            return 0;
    591622        else
     
    597628     *
    598629     */
    599     public int getOutboundTunnels() { 
    600         if (_context == null) 
     630    public int getOutboundTunnels() {
     631        if (_context == null)
    601632            return 0;
    602633        else
     
    608639     *
    609640     */
    610     public int getInboundClientTunnels() { 
    611         if (_context == null) 
     641    public int getInboundClientTunnels() {
     642        if (_context == null)
    612643            return 0;
    613644        else
     
    619650     *
    620651     */
    621     public int getOutboundClientTunnels() { 
    622         if (_context == null) 
     652    public int getOutboundClientTunnels() {
     653        if (_context == null)
    623654            return 0;
    624655        else
     
    630661     *
    631662     */
    632     public int getParticipatingTunnels() { 
    633         if (_context == null) 
     663    public int getParticipatingTunnels() {
     664        if (_context == null)
    634665            return 0;
    635666        else
     
    638669 
    639670    /** @since 0.7.10 */
    640     public String getShareRatio() { 
    641         if (_context == null) 
     671    public String getShareRatio() {
     672        if (_context == null)
    642673            return "0";
    643674        double sr = _context.tunnelManager().getShareRatio();
     
    651682     *
    652683     */
    653     public String getJobLag() { 
    654         if (_context == null) 
     684    public String getJobLag() {
     685        if (_context == null)
    655686            return "0";
    656687
     
    667698     *
    668699     */
    669     public String getMessageDelay() { 
    670         if (_context == null) 
     700    public String getMessageDelay() {
     701        if (_context == null)
    671702            return "0";
    672703
     
    679710     *
    680711     */
    681     public String getTunnelLag() { 
    682         if (_context == null) 
     712    public String getTunnelLag() {
     713        if (_context == null)
    683714            return "0";
    684715
     
    686717    }
    687718
    688     public String getTunnelStatus() { 
    689         if (_context == null) 
     719    public String getTunnelStatus() {
     720        if (_context == null)
    690721            return "";
    691722        return _context.throttle().getTunnelStatus();
     
    723754********/
    724755
    725     private static boolean updateAvailable() { 
     756    private static boolean updateAvailable() {
    726757        return NewsHelper.isUpdateAvailable();
    727758    }
    728759
    729     private boolean unsignedUpdateAvailable() { 
     760    private boolean unsignedUpdateAvailable() {
    730761        return NewsHelper.isUnsignedUpdateAvailable(_context);
    731762    }
    732763
    733764    /** @since 0.9.20 */
    734     private boolean devSU3UpdateAvailable() { 
     765    private boolean devSU3UpdateAvailable() {
    735766        return NewsHelper.isDevSU3UpdateAvailable(_context);
    736767    }
    737768
    738     private static String getUpdateVersion() { 
     769    private static String getUpdateVersion() {
    739770        return DataHelper.escapeHTML(NewsHelper.updateVersion());
    740771    }
    741772
    742     private static String getUnsignedUpdateVersion() { 
     773    private static String getUnsignedUpdateVersion() {
    743774        // value is a formatted date, does not need escaping
    744775        return NewsHelper.unsignedUpdateVersion();
     
    746777
    747778    /** @since 0.9.20 */
    748     private static String getDevSU3UpdateVersion() { 
     779    private static String getDevSU3UpdateVersion() {
    749780        return DataHelper.escapeHTML(NewsHelper.devSU3UpdateVersion());
    750781    }
     
    760791        boolean needSpace = false;
    761792        if (status.length() > 0) {
    762             buf.append("<h4 class=\"sb_info\">").append(status).append("</h4>\n");
     793            buf.append("<h4 class=\"sb_info sb_update\">").append(status).append("</h4>\n");
    763794            needSpace = true;
    764795        }
     
    776807            else
    777808                needSpace = true;
    778             buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update downloaded")).append("<br>");
     809            buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update downloaded")).append("<br>");
    779810            if (_context.hasWrapper())
    780811                buf.append(_t("Click Restart to install"));
     
    797828            else
    798829                needSpace = true;
    799             buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update available")).append(":<br>");
     830            buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update available")).append(":<br>");
    800831            buf.append(_t("Version {0}", getUpdateVersion())).append("<br>");
    801832            buf.append(constraint).append("</b></h4>");
     
    809840            else
    810841                needSpace = true;
    811             buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update available")).append(":<br>");
     842            buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update available")).append(":<br>");
    812843            buf.append(_t("Version {0}", getUnsignedUpdateVersion())).append("<br>");
    813844            buf.append(unsignedConstraint).append("</b></h4>");
     
    821852            else
    822853                needSpace = true;
    823             buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update available")).append(":<br>");
     854            buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update available")).append(":<br>");
    824855            buf.append(_t("Version {0}", getDevSU3UpdateVersion())).append("<br>");
    825856            buf.append(devSU3Constraint).append("</b></h4>");
     
    931962        String config = "";
    932963        if ("home".equals(page)) {
    933             config = _context.getProperty(PROP_SUMMARYBAR + page, DEFAULT_MINIMAL);
     964            config = _context.getProperty(PROP_SUMMARYBAR + page, isAdvanced() ? DEFAULT_MINIMAL_ADVANCED : DEFAULT_MINIMAL);
    934965        } else {
    935966            config = _context.getProperty(PROP_SUMMARYBAR + page);
     
    9821013        List<String> sections = getSummaryBarSections("default");
    9831014        TreeSet<String> sortedSections = new TreeSet<String>();
     1015
     1016        // Forward-convert old section names
     1017        int pos = sections.indexOf("General");
     1018        if (pos >= 0) {
     1019            sections.set(pos, "RouterInfo");
     1020        }
     1021        pos = sections.indexOf("ShortGeneral");
     1022        if (pos >= 0) {
     1023            sections.set(pos, "ShortRouterInfo");
     1024        }
    9841025
    9851026        for (int i = 0; i < allSections.length; i++) {
  • apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java

    r97267a4 r0e5b46e7  
    267267                def.line(dsNames[1], LINE_COLOR, "Events per period");
    268268            */
    269             if (hideLegend) 
     269            if (hideLegend)
    270270                def.setNoLegend(true);
    271271            if (hideGrid) {
  • apps/routerconsole/jsp/js/ajax.js

    r97267a4 r0e5b46e7  
    3535      //document.getElementByClassName("hideifdown").style.display="none";
    3636    }
     37
     38    // conditionally load sidebar refreshGraph script
     39    var graph = document.getElementById('sb_graphcontainer');
     40    if (graph) {
     41      var js_refreshGraph = document.createElement('script');
     42      js_refreshGraph.type = "text/javascript";
     43      js_refreshGraph.src = "/js/refreshGraph.js";
     44      js_refreshGraph.async = true;
     45      document.getElementsByTagName('head')[0].appendChild(js_refreshGraph);
     46    }
     47
    3748    setTimeout(function() {ajax(url, target, refresh);}, refresh);
    3849  }
  • history.txt

    r97267a4 r0e5b46e7  
    66     - Modify image font color to better blend with themes
    77     - Tweak spacing of elements for non-Debian installs
     8   - Sidebar:
     9     - Adjust vertical spacing of general section
     10     - Rename 'General' section to 'Router Info' and move ident info to h3
     11       tooltip (ticket #1996)
     12     - Replace 'Short Router Info' with a new 'Advanced Router Info' section in
     13       default advanced sidebar (adds memory usage and clock skew)
     14     - Add optional embedded bandwidth graph (experimental)
     15     - Add optional memory usage bar
     16     - Add optional Advanced Peers section (adds failing and banned peers)
     17     - Add Help link to 'I2P Internals' section
     18     - Add help page anchored links and troubleshooting to 'Help & FAQ' section
     19     - Add download progress bar for router and plugin updates
     20     - Add 'Advanced Minimal' sidebar configuration
     21     - Add Jobs and Events links to Advanced section
     22     - Add additional reachability states for clockskew and vmcomm (with icons)
     23   - Homepage: Add 'Customize Sidebar' link to signpost the feature now that
     24     there are more optional sections available (ticket #1996)
    825
    9262017-10-11 zzz
  • installer/resources/themes/console/classic/console.css

    r97267a4 r0e5b46e7  
    528528}
    529529
    530 #sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
     530#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
    531531     margin-bottom: -5px !important;
    532532     margin-top: -6px !important;
    533533}
    534534
    535 #sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after, #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
     535#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     536#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    536537   content: "";
    537538   display: inline-block;
     
    539540}
    540541
    541 #sb_peers td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child, #sb_bandwidth td:first-child, #sb_general td:first-child, #sb_shortgeneral td:first-child {
     542#sb_peers td:first-child, #sb_peersadvanced td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child,
     543#sb_bandwidth td:first-child, #sb_general td:first-child, #sb_shortgeneral td:first-child, #sb_advancedgeneral td:first-child {
    542544     white-space: nowrap;
    543545}
     
    548550}
    549551
     552#sb_peersadvanced a {
     553     padding: 0;
     554}
     555
     556#sb_peersadvanced a b {
     557     color: #2c354f;
     558}
     559
     560#sb_peersadvanced a:hover b {
     561     color: #f60;
     562}
     563
     564#sb_peersadvanced .separator td::after {
     565     min-height: 0;
     566}
     567
     568#sb_peersadvanced .separator hr {
     569     margin: 3px 0 2px !important;
     570     color: transparent;
     571     background: transparent;
     572     border-bottom: 1px dashed #89f;
     573}
     574
    550575#sb_localid {
    551576     margin: -3px 0 -1px;
     
    560585}
    561586
    562 #sb_internals, #sb_services, #sb_advanced {
     587#sb_internals, #sb_services, #sb_advanced, #sb_help {
    563588     margin-top: -3px !important;
    564589}
    565590
    566 #sb_internals a, #sb_services a, #sb_advanced a {
     591#sb_internals a, #sb_services a, #sb_advanced a, #sb_help a {
    567592     display: inline-block;
    568593     padding: 2px;
     
    834859
    835860/* end network status */
     861
     862/* mini sidebar graph */
     863
     864#sb_bandwidthgraph {
     865     width: 202px !important;
     866     margin: 0;
     867     margin: -20px 0 0 0;
     868     border-collapse: separate;
     869     border-spacing: 0;
     870     padding: 0;
     871     border: 1px solid #89f;
     872     border-radius: 2px;
     873     box-shadow: 0 0 1px #ccf;
     874}
     875
     876#sb_bandwidthgraph:hover {
     877     border: 1px solid #f60;
     878     cursor: url(/themes/console/images/cursor_zoom.png), pointer;
     879}
     880
     881a:active #sb_bandwidthgraph {
     882     border: 1px solid #f30;
     883}
     884
     885#sb_bandwidthgraph td {
     886     background: linear-gradient(to top, #f3f3ff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #f3f3ff 93%), linear-gradient(to right, #f3f3ff, rgba(255,255,255,0.0) 2%, rgba(255,255,255,0.0) 98%, #f3f3ff), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
     887     padding: 0 1px;
     888     box-shadow: inset 0 0 0 1px #fff;
     889     height: 38px;
     890     vertical-align: top;
     891}
     892
     893#sb_graphstats {
     894     display: inline-block;
     895     padding: 2px 8px;
     896     font-weight: bold;
     897     background: #ddf;
     898     background: linear-gradient(to right, #ddf, #efefff, #ddf);
     899     border: 1px solid #89f;
     900     border-top: none;
     901     border-radius: 0 0 3px 3px;
     902     box-shadow: inset 0 0 0 1px #fff;
     903     opacity: 0;
     904     transition: ease opacity 0.3s;
     905}
     906
     907#sb_graphcontainer:hover #sb_graphstats {
     908     opacity: 1;
     909     transition: ease opacity 0.3s;
     910}
     911
     912#sb_graphcontainer {
     913     background-color: #f3f3ff;
     914     background-position: left -60px top -35px !important;
     915     background-position: left -60px top -29px !important;
     916     background-size: 280px 92px !important;
     917     background-size: 280px 77px !important;
     918     background-repeat: no-repeat !important;
     919     background-blend-mode: multiply;
     920     margin: 0 2px -21px 1px !important;
     921     padding: 0 5px 0 0;
     922}
     923
     924@media screen and (min-width: 1500px) {
     925#sb_bandwidthgraph {
     926     width: 223px !important;
     927     background-size: 300px 92px !important;
     928}
     929
     930#sb_graphcontainer {
     931     background-size: 300px 77px !important;
     932}
     933}
     934/* end mini sidebar graph */
     935
     936/* status bars */
     937
     938.percentBarOuter {
     939     width: 196px;
     940     margin: -4px 0 -5px 3px;
     941     text-align: center;
     942     border: 1px solid #99f;
     943     box-shadow: 0 0 1px rgba(200,200,200,0.8);
     944     background: #eef;
     945     background: repeating-linear-gradient(to right, rgba(180, 180, 255,0.7) 1px, rgba(180, 180, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 4px);
     946}
     947
     948@media screen and (min-width: 1500px) {
     949.percentBarOuter {
     950     width: 210px;
     951}
     952}
     953
     954.percentBarInner {
     955     vertical-align: middle;
     956     border: none;
     957     height: 14px;
     958     background: #bbf;
     959     background: linear-gradient(to right, rgba(0,255,0,0.1) 65px, rgba(255,255,0,0.1) 110px, rgba(255,128,0,0.1) 175px, rgba(255,0,0,0.1)), linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
     960     box-shadow: inset 0 0 0 1px #ddf;
     961}
     962
     963.percentBarText {
     964     display: inline !important;
     965     white-space: nowrap;
     966     text-align: center !important;
     967     font-weight: bold !important;
     968     color: #2c354f;
     969     text-shadow: 0 1px 1px rgba(255,255,255,0.8);
     970     float: left;
     971     width: 100%;
     972     height: 14px;
     973     padding: 0;
     974     opacity: 0;
     975     transition: ease opacity 0.2s;
     976}
     977
     978.percentBarOuter:hover .percentBarText {
     979     opacity: 1;
     980     transition: ease opacity 0.2s;
     981}
     982
     983/* updates download bar */
     984
     985.sb_updatestatus {
     986     display: block;
     987     border: 1px solid #99f;
     988     border-top: none;
     989     color: #2c354f;
     990     border-radius: 0 0 3px 3px;
     991     box-sizing: border-box;
     992     background: #ccf;
     993     background: linear-gradient(to right, #eef, #eff2ff 30%, #eff2ff 60%, #eef);
     994     box-shadow: inset 0 0 0 1px #fff;
     995     margin: -8px 2px 5px !important;
     996     padding: 3px 0 4px;
     997     font-style: italic;
     998}
     999
     1000.sb_info .percentBarOuter {
     1001     margin: 3px -4px -5px 2px;
     1002     background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
     1003}
     1004
     1005@keyframes downloadbar {
     1006from {
     1007     background: repeating-linear-gradient(135deg, rgba(221, 221, 255, 0.7) 1px, rgba(221, 221, 255, 0.7) 6px, rgba(238, 238, 255,0.7) 7px, rgba(238, 238, 255,0.7) 11px);
     1008}
     1009
     1010to {
     1011     background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
     1012}
     1013}
     1014
     1015.sb_info .percentBarOuter {
     1016     animation: downloadbar 3s infinite;
     1017}
     1018
     1019.sb_info .percentBarInner {
     1020     height: 16px;
     1021     background: linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
     1022
     1023}
     1024
     1025.sb_info .percentBarText {
     1026     opacity: 1;
     1027     padding-top: 2px;
     1028     mix-blend-mode: multiply;
     1029     color: #33f;
     1030
     1031}
     1032/* end updates download bar */
     1033/* end status bars */
    8361034
    8371035/* end sidebar */
     
    68877085
    68887086@media screen and (max-width: 1500px) {
    6889 #sb_general td:first-child::after, #sb_shortgeneral td:first-child::after, #sb_bandwidth td:first-child::after,
    6890 #sb_peers td:first-child::after, #sb_tunnels td:first-child::after, #sb_queue td:first-child::after {
     7087#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     7088#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    68917089   min-height: 12px;
    68927090}
     
    69897187}
    69907188
    6991 #sb_internals a, #sb_services a, #sb_advanced a {
     7189#sb_internals a, #sb_services a, #sb_advanced a, #sb_help a {
    69927190     max-width: 212px;
    69937191}
     
    69967194     min-width: 100px;
    69977195     margin: 2px 4px 1px;
     7196}
     7197
     7198.percentBarOuter {
     7199     width: 217px;
    69987200}
    69997201
  • installer/resources/themes/console/classic/console_big.css

    r97267a4 r0e5b46e7  
    6767}
    6868
    69 #sb_bandwidth td:last-child, #sb_peers td:last-child, #sb_queue td:last-child,  #sb_tunnels td:last-child, #sb_general td:last-child, #sb_shortgeneral td:last-child {
     69#sb_bandwidth td:last-child, #sb_peers td:last-child, #sb_peersadvanced td:last-child, #sb_queue td:last-child,  #sb_tunnels td:last-child, #sb_general td:last-child, #sb_shortgeneral td:last-child, #sb_advancedgeneral td:last-child {
    7070     font-size: 10pt !important;
    7171}
     
    7575     font-weight: normal;
    7676     text-shadow: none;
     77}
     78
     79#sb_bandwidthgraph {
     80     width: 218px !important;
     81     margin: -25px 0 -6px !important;
     82}
     83
     84#sb_graphstats {
     85     font-size: 9pt !important;
     86}
     87
     88#sb_graphcontainer {
     89     background-position: left -66px top -30px !important;
     90     background-size: 340px 80px !important;
     91}
     92
     93.percentBarOuter {
     94     width: 212px !important;
     95     margin: -3px 0 -4px 3px;
     96}
     97
     98.percentBarText {
     99     font-size: 9pt !important;
     100     padding: 0 !important;
     101     margin-top: -1px;
    77102}
    78103
  • installer/resources/themes/console/dark/console.css

    r97267a4 r0e5b46e7  
    398398}
    399399
    400 #sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
     400#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
    401401     margin-bottom: -4px !important;
    402402}
    403403
    404 #sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
    405 #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
     404#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     405#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    406406   content: "";
    407407   display: inline-block;
     
    409409}
    410410
    411 #sb_general td, #sb_shortgeneral td {
     411#sb_general td, #sb_shortgeneral td, #sb_advancedgeneral td, #sb_peersadvanced td {
    412412     white-space: nowrap;
    413413}
    414414
    415 #sb_general td:first-child, #sb_shortgeneral td:first-child {
     415#sb_general td:first-child, #sb_shortgeneral td:first-child,  #sb_advancedgeneral td:first-child, #sb_peersadvanced td:first-child {
    416416     max-width: 130px;
    417417}
     
    458458}
    459459
    460 #sb_internals td, #sb_services td, #sb_advanced td { /* color ellipsis */
     460#sb_internals td, #sb_services td, #sb_advanced td, #sb_help td { /* color ellipsis */
    461461     color: #595 !important;
    462462}
    463463
    464 #sb_services, #sb_internals, #sb_advanced {
     464#sb_services, #sb_internals, #sb_advanced, #sb_help {
    465465     margin-top: -4px !important;
    466466}
    467467
    468 #sb_internals a, #sb_services a, #sb_advanced a {
     468#sb_internals a, #sb_services a, #sb_advanced a, #sb_help a {
    469469     padding: 1px 3px;
    470470     display: inline-block;
     
    481481}
    482482
    483 #sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
     483#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
    484484     word-break: break-all;
    485485     max-width: 192px;
     
    488488     text-overflow: ellipsis;
    489489     line-height: 140%;
     490}
     491
     492#sb_peersadvanced a {
     493     color: #ee9;
     494}
     495
     496#sb_peersadvanced .separator td::after {
     497     min-height: 0;
     498}
     499
     500.routersummary .separator hr, .routersummary .separator hr:last-child {
     501     display: block !important;
     502     color: transparent;
     503     background: transparent;
     504     border-bottom: 1px dashed #141;
     505     height: 1px;
     506     margin: 4px 0 3px !important;
    490507}
    491508
     
    679696
    680697/* end sidebar news */
     698
     699/* mini sidebar graph */
     700
     701#sb_bandwidthgraph {
     702     width: 100%;
     703     margin: -5px 0 -5px -5px;
     704     border-collapse: separate;
     705     border-spacing: 0;
     706     padding: 0;
     707     border: 1px solid #5df;
     708     box-shadow: 0 0 1px #ccf;
     709}
     710
     711#sb_bandwidthgraph:hover {
     712     border: 1px solid #f60;
     713     cursor: url(/themes/console/images/cursor_zoom.png), pointer;
     714}
     715
     716a:active #sb_bandwidthgraph {
     717     border: 1px solid #f30;
     718}
     719
     720#sb_bandwidthgraph td {
     721     background: linear-gradient(to top, #fff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #fff 93%), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
     722     padding: 0 1px;
     723     box-shadow: inset 0 0 0 1px #fff;
     724     height: 40px;
     725     vertical-align: top;
     726}
     727
     728#sb_graphstats {
     729     display: inline-block;
     730     padding: 2px 8px;
     731     font-weight: bold;
     732     background: #ddf;
     733     background: linear-gradient(to right, #ddf, #efefff, #ddf);
     734     border: 1px solid #89f;
     735     border-top: none;
     736     border-radius: 0 0 3px 3px;
     737     box-shadow: inset 0 0 0 1px #fff, 0 0 1px #fff;
     738     opacity: 0;
     739     transition: ease opacity 0.3s;
     740     color: #89f;
     741}
     742
     743#sb_graphcontainer:hover #sb_graphstats {
     744     opacity: 1;
     745     transition: ease opacity 0.3s;
     746}
     747
     748#sb_graphcontainer {
     749     background-color: #000;
     750     background-position: left -72px top -23px !important;
     751     background-size: 280px 77px !important;
     752     background-repeat: no-repeat !important;
     753     margin-bottom: -7px !important;
     754     filter: invert(1) hue-rotate(90deg);
     755}
     756
     757/* reduce flicker as graph image gets inverted and hue-rotated */
     758
     759@keyframes graphfadein {
     760from {
     761     filter: invert(1) hue-rotate(90deg) opacity(0);
     762}
     763
     764to {
     765     filter: invert(1) hue-rotate(90deg) opacity(1);
     766}
     767}
     768
     769#sb_graphcontainer {
     770     animation: graphfadein 0.3s ease-in;
     771}
     772
     773@media screen and (min-width: 1500px) {
     774#sb_graphcontainer {
     775     background-size: 300px 77px !important;
     776}
     777}
     778/* end mini sidebar graph */
     779
     780/* status bar */
     781
     782.percentBarOuter {
     783     width: 194px;
     784     background: #000;
     785     background: repeating-linear-gradient(135deg, #000 1px, #000 5px, #010 6px, #010 11px);
     786     background: repeating-linear-gradient(to right, #000 1px, #000 2px, #010 2px, #010 4px);
     787     border: 1px solid #040;
     788     border-bottom: 1px solid #020;
     789     border-right: 1px solid #020;
     790     opacity: 1;
     791     box-shadow: 0 0 1px 1px rgba(0,0,0,0.8);
     792     margin: -3px 0 -5px -6px;
     793}
     794
     795@media screen and (min-width: 1500px) {
     796.percentBarOuter {
     797     width: 220px;
     798}
     799}
     800
     801.percentBarOuter:hover .percentBarText {
     802     opacity: 1;
     803     transition: ease opacity 0.2s;
     804}
     805
     806.percentBarInner {
     807     height: 14px;
     808     background: #0e5f00;
     809     background: linear-gradient(to bottom, rgba(28, 148, 58, 0.6) 0%, rgba(9, 47, 16, 0.6) 50%, rgba(13, 39, 7, 0.6) 50%, rgba(9, 27, 5, 0.6) 50%, rgba(9, 21, 3, 0.6) 100%);
     810     box-shadow: inset 0 0 0 1px #000;
     811}
     812
     813.percentBarText {
     814     width: 100%;
     815     font-weight: bold;
     816     text-align: center;
     817     vertical-align: middle;
     818     float: left;
     819     opacity: 0;
     820     transition: ease opacity 0.2s;
     821}
     822
     823/* update bar */
     824
     825.sb_updatestatus {
     826     background: #000;
     827     background: linear-gradient(to right, #020, #000, #020);
     828     margin: -6px -2px -2px;
     829     padding: 2px 0 4px;
     830     border-bottom: 1px solid #494;
     831}
     832
     833.sb_info .percentBarOuter {
     834     margin: 6px -2px -18px 2px;
     835     box-shadow: none !important;
     836     background: repeating-linear-gradient(135deg, #000 1px, #000 5px, #010 6px, #010 11px);
     837     animation: downloadbar 3s infinite alternate;
     838}
     839
     840.sb_info .percentBarText {
     841     opacity: 1;
     842     padding-top: 2px;
     843}
     844
     845.sb_info .percentBarInner {
     846     height: 16px;
     847}
     848
     849@keyframes downloadbar {
     850from {
     851     background: repeating-linear-gradient(135deg, #000 1px, #000 5px, #010 6px, #010 11px);
     852}
     853
     854to {
     855     background: repeating-linear-gradient(135deg, #010 1px, #010 6px, #000 7px, #000 11px);
     856}
     857}
     858
     859/* end status bar */
    681860/* end sidebar */
    682861
     
    68977076
    68987077@media screen and (max-width: 1500px) {
    6899 #sb_general td:first-child::after, #sb_shortgeneral td:first-child::after, #sb_bandwidth td:first-child::after,
    6900 #sb_peers td:first-child::after, #sb_tunnels td:first-child::after, #sb_queue td:first-child::after {
     7078#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     7079#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    69017080   min-height: 12px;
    69027081}
     
    70827261}
    70837262
    7084 #sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
     7263#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
    70857264     max-width: 216px !important;
    70867265}
  • installer/resources/themes/console/dark/console_ar.css

    r97267a4 r0e5b46e7  
    533533}
    534534
     535.percentBarOuter {
     536     margin: -3px -6px -5px 0;
     537}
     538
     539.sb_info .percentBarOuter {
     540     margin: 6px 2px -18px -2px;
     541}
     542
     543.sb_info .percentBarText {
     544     font-size: 9pt;
     545     padding-top: 1px;
     546     direction: ltr;
     547}
     548
    535549.main#console .twocol {
    536550     margin: 15px 35px 5px 0 !important;
  • installer/resources/themes/console/dark/console_big.css

    r97267a4 r0e5b46e7  
    202202}
    203203
     204#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     205#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
     206   content: "";
     207   display: inline-block;
     208   min-height: 14px !important;
     209}
     210
    204211.sb_newsheadings td, .sb_newsheadings tr:hover td {
    205212     background-position: 4px center !important;
     
    209216.search select, .search button, .search input[type="text"] {
    210217     font-size: 10pt !important;
     218}
     219
     220.percentBarOuter {
     221     width: 206px;
     222     margin: -1px 0 -2px -4px;
     223}
     224
     225#sb_graphcontainer {
     226     background-position: left -74px top -21px !important;
     227     background-size: 300px 77px !important;
    211228}
    212229
  • installer/resources/themes/console/light/console.css

    r97267a4 r0e5b46e7  
    1414     background: #a4a4cb url(images/tile2.png) fixed;
    1515     background-size: 32px 32px;
     16}
    1617}
    1718
     
    131132.routersummary div[style="height: 36px;"] {
    132133     margin: 0;
    133      padding: 0;
     134     padding: 0 0 1px;
    134135     text-align: center;
    135136}
     
    142143
    143144.routersummary img[src$="i2plogo.png"] {
    144      opacity: 0.9;
     145     opacity: 0.7;
    145146     transition: ease filter 0.3s 0s, ease opacity 0.3s 0s;
    146      margin-top: -1px;
    147      margin-left: -1px !important;
    148      width: 194px;
     147     margin: 0 !important;
     148     width: 190px;
    149149     height: auto;
    150150     filter: drop-shadow(0 0 1px #ccf);
    151 }
    152 
    153 @media screen and (-webkit-min-device-pixel-ratio: 0) {
    154 .routersummary img[src$="i2plogo.png"] {
    155      margin-top: -2px !important;
    156 }
    157151}
    158152
     
    163157}
    164158
     159.routersummary a[href="/"]:focus img, .routersummary a[href="/console"]:focus img {
     160     filter: drop-shadow(0 0 1px #f60);
     161}
     162
    165163.routersummary a:active img[src$="i2plogo.png"] {
    166      filter: drop-shadow(0 0 2px #f30);
     164     filter: drop-shadow(0 0 2px #d30);
    167165}
    168166
     
    171169}
    172170
    173 .routersummary a[href="/"]:focus img, .routersummary a[href="/console"]:focus img {
    174      filter: drop-shadow(0 0 1px #f60);
    175 }
    176 
    177171.routersummary form {
    178      margin: 0 -7px;
     172     margin: -2px -7px;
    179173     padding: 0 0 3px;
    180174}
    181175
    182 .routersummary form[action="/config"] {
    183      margin: -2px -7px;
     176@media screen and (-webkit-min-device-pixel-ratio:0) {
     177.routersummary form {
     178     margin: -1px -7px -3px !important;
     179}
    184180}
    185181
     
    332328
    333329#sb_version {
    334      margin-top: 5px !important;
    335      margin-bottom: 8px !important;
     330     margin-top: 7px !important;
     331     margin-bottom: 10px !important;
    336332}
    337333
     
    375371}
    376372
    377 #sb_internals, #sb_advanced {
    378      margin: -9px -6px -6px;
    379 }
    380 
    381 #sb_internals a, #sb_advanced a {
     373#sb_internals, #sb_advanced, #sb_help {
     374     margin: -9px -6px -5px;
     375     width: 204px !important;
     376}
     377
     378#sb_internals a, #sb_advanced a, #sb_help a {
    382379     padding: 2px;
    383380     display: inline-block;
     
    388385}
    389386
    390 #sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
     387#sb_internals a:hover, #sb_advanced a:hover, #sb_help a:hover {
     388     background: #ffd;
     389     border-radius: 3px;
     390}
     391
     392#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
    391393     margin-bottom: -4px !important;
    392394     margin-top: -10px !important;
    393395}
    394396
    395 #sb_general, #sb_shortgeneral {
     397@media screen and (-webkit-min-device-pixel-ratio:0) {
     398#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
     399     margin-bottom: -6px !important;
     400}
     401}
     402
     403#sb_shortgeneral {
    396404     margin-top: -7px !important;
    397405}
    398406
    399 #sb_general td, #sb_shortgeneral td {
     407#sb_general td, #sb_shortgeneral td, #sb_advancedgeneral td {
    400408     white-space: nowrap;
    401409}
    402410
    403 #sb_general td:first-child, #sb_shortgeneral td:first-child {
     411#sb_general td:first-child, #sb_shortgeneral td:first-child, #sb_advancedgeneral td:first-child {
    404412     max-width: 130px;
    405413}
    406414
    407 #sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
    408 #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
     415#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     416#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    409417   content: "";
    410418   display: inline-block;
     
    412420}
    413421
    414 #sb_peers td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child, #sb_bandwidth td:first-child, #sb_general td:first-child, #sb_shortgeneral td:first-child {
     422#sb_peers td:first-child, #sb_peersadvanced td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child, #sb_bandwidth td:first-child,
     423#sb_general td:first-child, #sb_shortgeneral td:first-child, #sb_advancedgeneral td:first-child {
    415424     text-transform: capitalize;
    416425}
     426
     427#sb_peersadvanced a:hover b, #sb_peersadvanced a:visited:hover b {
     428     color: #f60 !important
     429}
     430
     431#sb_peersadvanced a:active b, #sb_peersadvanced a:visited:active b {
     432     color: #f90 !important
     433}
     434
     435#sb_peersadvanced .separator td {
     436     padding: 0;
     437}
     438
     439.separator hr, .separator hr:last-child {
     440     color: transparent;
     441     background: transparent;
     442     height: 1px;
     443     border-bottom: 1px dashed #99f !important;
     444     margin: 3px 0 -10px !important;
     445     display: block !important;
     446}
     447
     448/* mini sidebar graph */
     449
     450#sb_bandwidthgraph {
     451     width: 100%;
     452     margin: -5px 0 -5px -5px;
     453     border-collapse: separate;
     454     border-spacing: 0;
     455     padding: 0;
     456     border: 1px solid #89f;
     457     border-radius: 2px;
     458     box-shadow: 0 0 1px #ccf;
     459}
     460
     461@media screen and (-webkit-min-device-pixel-ratio: 0) {
     462#sb_bandwidthgraph {
     463     margin: -5px 0 -6px -5px !important;
     464}
     465}
     466
     467#sb_bandwidthgraph:hover {
     468     border: 1px solid #f60;
     469     cursor: url(/themes/console/images/cursor_zoom.png), pointer;
     470}
     471
     472a:active #sb_bandwidthgraph {
     473     border: 1px solid #f30;
     474}
     475
     476#sb_bandwidthgraph td {
     477     background: linear-gradient(to top, #f3f3ff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #f3f3ff 93%), linear-gradient(to right, #f3f3ff, rgba(255,255,255,0.0) 2%, rgba(255,255,255,0.0) 98%, #f3f3ff), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
     478     padding: 0 1px;
     479     box-shadow: inset 0 0 0 1px #fff;
     480     height: 40px;
     481     vertical-align: top;
     482}
     483
     484#sb_graphstats {
     485     display: inline-block;
     486     padding: 2px 8px;
     487     font-weight: bold;
     488     background: #ddf;
     489     background: linear-gradient(to right, #ddf, #efefff, #ddf);
     490     border: 1px solid #89f;
     491     border-top: none;
     492     border-radius: 0 0 3px 3px;
     493     box-shadow: inset 0 0 0 1px #fff, 0 0 1px #fff;
     494     opacity: 0;
     495     transition: ease opacity 0.3s;
     496}
     497
     498#sb_graphcontainer:hover #sb_graphstats {
     499     opacity: 1;
     500     transition: ease opacity 0.3s;
     501}
     502
     503#sb_graphcontainer {
     504     background-color: #f3f3ff;
     505     background-position: left -60px top -23px !important;
     506     background-size: 280px 77px !important;
     507     background-repeat: no-repeat !important;
     508     background-blend-mode: multiply;
     509}
     510
     511@media screen and (min-width: 1500px) {
     512#sb_graphcontainer {
     513     background-size: 300px 77px !important;
     514}
     515}
     516/* end mini sidebar graph */
     517
     518/* status bars for memory usage and router/plugin updates */
     519
     520.percentBarOuter {
     521     width: 196px;
     522     margin: -4px -5px -4px -3px;
     523     text-align: center;
     524     border: 1px solid #99f;
     525     box-shadow: 0 0 1px rgba(200,200,200,0.8);
     526     background: #eef;
     527     background: linear-gradient(to right, rgba(0,255,0,0.05) 50%, rgba(255,255,0,0.05) 75%, rgba(255,128,0,0.05) 90%, rgba(255,0,0,0.1)), repeating-linear-gradient(to right, rgba(180, 180, 255,0.7) 1px, rgba(180, 180, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 4px);
     528}
     529
     530@media screen and (min-width: 1500px) {
     531.percentBarOuter {
     532     width: 212px;
     533}
     534}
     535
     536.percentBarInner {
     537     vertical-align: middle;
     538     border: none;
     539     height: 14px;
     540     background: #bbf;
     541     background: linear-gradient(to right, rgba(0,255,0,0.1) 65px, rgba(255,255,0,0.1) 110px, rgba(255,128,0,0.1) 175px, rgba(255,0,0,0.1)), linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
     542     background: linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
     543     box-shadow: inset 0 0 0 1px #ddf;
     544}
     545
     546.percentBarText {
     547     display: inline !important;
     548     white-space: nowrap;
     549     text-align: center !important;
     550     font-weight: bold !important;
     551     color: #41465f;
     552     text-shadow: 0 1px 1px rgba(255,255,255,0.8);
     553     float: left;
     554     width: 100%;
     555     height: 14px;
     556     padding: 0;
     557     opacity: 0;
     558     transition: ease opacity 0.2s;
     559}
     560
     561.percentBarOuter:hover .percentBarText {
     562     opacity: 1;
     563     transition: ease opacity 0.2s;
     564}
     565
     566/* updates download bar */
     567
     568.sb_update a {
     569    white-space: nowrap;
     570    vertical-align: baseline;
     571}
     572
     573.sb_updatestatus {
     574     display: block;
     575     font-style: italic;
     576     border: 1px solid #99f;
     577     border-top: none;
     578     border-radius: 0 0 3px 3px;
     579     background: #ccf;
     580     background: linear-gradient(to right, #ddf, #efefff 30%, #efefff 60%, #ddf);
     581     box-shadow: inset 0 0 0 1px #fff;
     582     margin: -7px 2px 5px !important;
     583     padding: 4px 0 3px;
     584     filter: drop-shadow(0 0 1px #ccf);
     585}
     586
     587.sb_info .percentBarOuter {
     588     margin: 3px -4px -19px 2px;
     589     background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
     590}
     591
     592@keyframes downloadbar {
     593from {
     594     background: repeating-linear-gradient(135deg, rgba(221, 221, 255, 0.7) 1px, rgba(221, 221, 255, 0.7) 6px, rgba(238, 238, 255,0.7) 7px, rgba(238, 238, 255,0.7) 11px);
     595}
     596
     597to {
     598     background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
     599}
     600}
     601
     602.sb_info .percentBarOuter {
     603     animation: downloadbar 3s infinite;
     604}
     605
     606.sb_info .percentBarInner {
     607     height: 16px;
     608}
     609
     610.sb_info .percentBarText {
     611     opacity: 1;
     612     padding-top: 3px;
     613     mix-blend-mode: multiply;
     614}
     615/* end updates download bar */
     616/* end status bars */
    417617
    418618#sb_warning {
     
    550750     background-image: none !important;
    551751     border: 0 !important;
    552 }
    553 
    554 .routersummary img:first-child {
    555      margin-bottom: -2px !important;
    556      opacity: 0.7;
    557 }
    558 
    559 .routersummary img:hover:first-child {
    560      margin-bottom: -2px !important;
    561      opacity: 1;
    562752}
    563753
     
    714904.sb_newsheadings table {
    715905     table-layout: auto;
    716      width: 202px !important;
     906     width: 204px !important;
    717907     margin: -12px 0 -8px -14px;
    718908}
     
    17161906#sidebarconf button {
    17171907     margin: 2px 0 2px 3px !important;
    1718      padding: 2px;
     1908     padding: 2px 3px;
    17191909     min-width: 0;
    17201910     background-size: 100% 100% !important;
     
    31043294     background: linear-gradient(135deg, #fcfcff, rgba(252,252,255,0) 600px), linear-gradient(to bottom, #fcfcff 50%, rgba(248,248,255,0.6) 50%), repeating-linear-gradient(135deg, rgba(255,255,255,0.5) 2px, rgba(221, 221, 255, 0.3) 3px, #fff 5px) #fafaff !important;
    31053295     border: 1px solid #447;
    3106      border-radius: 2px;
     3296     border-radius: 2px 2px 0 0;
    31073297     min-width: 546px;
    31083298     z-index: 999;
     
    70767266}
    70777267
    7078 #sb_general td:first-child::after, #sb_shortgeneral td:first-child::after, #sb_bandwidth td:first-child::after,
    7079 #sb_peers td:first-child::after, #sb_tunnels td:first-child::after, #sb_queue td:first-child::after {
     7268#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after,
     7269#sb_bandwidth td::after, #sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    70807270   min-height: 12px;
    70817271}
    70827272
    7083 #sb_internals a, #sb_advanced a {
     7273#sb_internals a, #sb_advanced a #sb_help a {
    70847274     max-width: 200px;
    70857275}
     
    72597449}
    72607450
    7261 #sb_internals a, #sb_advanced a {
     7451#sb_internals a, #sb_advanced a, #sb_help a {
    72627452     max-width: 212px;
    72637453}
    72647454
    7265 #sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
     7455#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
    72667456     margin-bottom: -4px !important;
    72677457     margin-top: -10px !important;
    72687458}
    72697459
    7270 #sb_general, #sb_shortgeneral {
    7271      margin-top: -7px !important; 
    7272 }
    7273 
    7274 #sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
    7275 #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
    7276    min-height: 14px;
     7460#sb_general, #sb_shortgeneral, #sb_advancedgeneral {
     7461     margin-top: -7px !important;
     7462}
     7463
     7464#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     7465#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
     7466     min-height: 14px;
    72777467}
    72787468
  • installer/resources/themes/console/light/console_ar.css

    r97267a4 r0e5b46e7  
    4545.buckets {
    4646     margin-bottom: -10px !important;
     47}
     48
     49.routersummaryouter {
     50     margin-right: -1px;
     51}
     52
     53.routersummary {
     54     margin-bottom: 4px;
    4755}
    4856
     
    202210     padding-right: 28px !important;
    203211     background-position: right 6px center !important;
     212}
     213
     214#sb_graphcontainer {
     215     background-position: left -60px top -20px !important;
     216     transform: scale(-1, +1);
     217}
     218
     219#sb_bandwidthgraph {
     220     margin: -5px -5px -5px 0;
     221}
     222
     223
     224@media screen and (-webkit-min-device-pixel-ratio: 0) {
     225#sb_bandwidthgraph {
     226     margin: -5px -5px -6px 0 !important;
     227}
     228}
     229
     230.percentBarOuter {
     231     margin: -4px -3px -4px -5px;
     232     background: linear-gradient(to left, rgba(0,255,0,0.05) 50%, rgba(255,255,0,0.05) 75%, rgba(255,128,0,0.05) 90%, rgba(255,0,0,0.1)), repeating-linear-gradient(to right, rgba(180, 180, 255,0.7) 1px, rgba(180, 180, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 4px);
     233}
     234
     235.sb_info .percentBarOuter {
     236     margin: 3px 2px -19px -4px;
     237}
     238
     239.sb_updatestatus, .sb_info .percentBarText {
     240     font-size: 9pt;
     241}
     242
     243.sb_info .percentBarText {
     244     padding-top: 1px;
     245     direction: ltr;
    204246}
    205247
  • installer/resources/themes/console/light/console_big.css

    r97267a4 r0e5b46e7  
    7575}
    7676
     77#sb_graphcontainer {
     78     background-position: left -60px top -20px !important;
     79}
     80
    7781.sb_newsheadings td, .sb_newsheadings tr:hover td {
    7882     background-position: 4px center !important;
    7983     padding-left: 22px !important;
     84}
     85
     86#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after,
     87#sb_bandwidth td::after, #sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
     88   min-height: 15px !important;
    8089}
    8190
  • installer/resources/themes/console/midnight/console.css

    r97267a4 r0e5b46e7  
    12941294}
    12951295
    1296 #sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
     1296#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
    12971297     margin-top: -6px !important;
    12981298     margin-bottom: -5px !important;
    12991299}
    13001300
    1301 #sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
    1302 #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
     1301#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     1302#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    13031303     content: "";
    13041304     display: inline-block;
     
    13071307}
    13081308
    1309 #sb_general td, #sb_shortgeneral td {
     1309#sb_general td, #sb_shortgeneral td, #sb_advancedgeneral td {
    13101310     white-space: nowrap;
    13111311}
     
    13561356}
    13571357
    1358 #sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
     1358#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
    13591359     word-break: break-all;
    13601360     max-width: 190px;
     
    13681368}
    13691369
    1370 #sb_services a:hover, #sb_internals a:hover, #sb_advanced a:hover, #sb_localtunnels tr:hover, #sb_localtunnels tr:hover a,
     1370#sb_services a:hover, #sb_internals a:hover, #sb_advanced a:hover, #sb_localtunnels tr:hover, #sb_localtunnels tr:hover a, #sb_help a:hover,
    13711371.news a:hover, #console a:hover, tt a:hover {
    13721372     background: #652787;
     
    13751375}
    13761376
    1377 #sb_services a:active, #sb_internals a:active, #sb_advanced a:active, #sb_localtunnels tr:active, .news a:active, #console a:active, tt a:active {
     1377#sb_services a:active, #sb_internals a:active, #sb_advanced a:active, #sb_help a:active,
     1378#sb_localtunnels tr:active, .news a:active, #console a:active, tt a:active {
    13781379     background: #39144f;
    13791380     color: #c9ceff !important;
     
    13821383#sb_localtunnels tr:active a {
    13831384     color: #c9ceff !important;
     1385}
     1386
     1387#sb_peersadvanced a {
     1388     padding: 0;
     1389     color: #c9ceff;
     1390}
     1391
     1392#sb_peersadvanced a:hover, #sb_peersadvanced a:focus {
     1393     color: #652787;
     1394}
     1395
     1396#sb_peersadvanced .separator td::after {
     1397     min-height: 0 !important;
     1398}
     1399
     1400#sb_peersadvanced .separator hr, #sb_peersadvanced .separator hr:last-child {
     1401     display: block !important;
     1402     margin: 3px 0 2px !important;
     1403     color: transparent;
     1404     background: transparent;
     1405     border-bottom: 1px dashed #2d296f;
    13841406}
    13851407
     
    15711593
    15721594/* end sidebar news */
     1595
     1596/* mini sidebar graph */
     1597
     1598#sb_bandwidthgraph {
     1599     width: 100%;
     1600     margin: -13px 0 0 -8px !important;
     1601     border-collapse: separate;
     1602     border-spacing: 0;
     1603     padding: 0;
     1604     border: 1px solid #5df;
     1605     box-shadow: 0 0 1px #ccf;
     1606}
     1607
     1608#sb_bandwidthgraph:hover {
     1609     border: 1px solid #f60;
     1610     cursor: url(/themes/console/images/cursor_zoom.png), pointer;
     1611}
     1612
     1613a:active #sb_bandwidthgraph {
     1614     border: 1px solid #f30;
     1615}
     1616
     1617#sb_bandwidthgraph td {
     1618     background: linear-gradient(to top, #f3f3ff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #f3f3ff 93%), linear-gradient(to right, #f3f3ff, rgba(255,255,255,0.0) 2%, rgba(255,255,255,0.0) 98%, #f3f3ff), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
     1619     background: linear-gradient(to top, #fff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #fff 93%), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
     1620     padding: 0 1px;
     1621     box-shadow: inset 0 0 0 1px #fff;
     1622     height: 40px;
     1623     vertical-align: top;
     1624}
     1625
     1626#sb_graphstats {
     1627     display: inline-block;
     1628     padding: 2px 8px;
     1629     font-weight: bold;
     1630     background: #444;
     1631     border: 1px solid #999;
     1632     border-top: none;
     1633     box-shadow: inset 0 0 0 1px #fff, 0 0 1px #fff;
     1634     opacity: 0;
     1635     transition: ease opacity 0.3s;
     1636}
     1637
     1638#sb_graphcontainer:hover #sb_graphstats {
     1639     opacity: 1;
     1640     transition: ease opacity 0.3s;
     1641}
     1642
     1643#sb_graphcontainer {
     1644     background-color: #000;
     1645     background-position: left -72px top -26px !important;
     1646     background-size: 280px 90px !important;
     1647     background-repeat: no-repeat !important;
     1648     margin: -7px 0 -3px !important;
     1649     height: 40px;
     1650     filter: invert(1) sepia(1) hue-rotate(180deg);
     1651}
     1652
     1653@keyframes graphfadein {
     1654from {
     1655     opacity: 0;
     1656}
     1657
     1658to {
     1659     opacity: 1;
     1660}
     1661}
     1662
     1663#sb_graphcontainer {
     1664     animation: graphfadein 0.4s ease-in; /* attempt to mitigate strobe effect as image loads before filters are applied */
     1665}
     1666
     1667@media screen and (min-width: 1500px) {
     1668#sb_graphcontainer {
     1669     background-size: 300px 77px !important;
     1670     background-position: left -72px top -20px !important;
     1671}
     1672
     1673#sb_bandwidthgraph {
     1674     width: 100%;
     1675     margin: -15px 0 0 -8px !important;
     1676}
     1677}
     1678
     1679/* end mini sidebar graph */
     1680
     1681/* status bar */
     1682
     1683.percentBarOuter {
     1684     width: 194px;
     1685     background: #000;
     1686     background: repeating-linear-gradient(135deg, #001 1px, #001 5px, #003 6px, #003 11px);
     1687     background: repeating-linear-gradient(to right, #000 1px, #000 2px, #003 2px, #003 4px);
     1688     border: 1px solid #171c3f;
     1689     opacity: 1;
     1690     box-shadow: 0 0 1px 1px rgba(0,0,0,0.8);
     1691     margin: -3px 0 -5px -6px;
     1692}
     1693
     1694@media screen and (min-width: 1500px) {
     1695.percentBarOuter {
     1696     width: 210px;
     1697}
     1698}
     1699
     1700.percentBarOuter:hover .percentBarText {
     1701     opacity: 1;
     1702     transition: ease opacity 0.2s;
     1703}
     1704
     1705.percentBarInner {
     1706     height: 14px;
     1707     background: #0e5f00;
     1708     background: linear-gradient(to bottom,  #33a 0%, #226 50%, #003 50%, #000 100%);
     1709     box-shadow: inset 0 0 0 1px #000;
     1710}
     1711
     1712.percentBarText {
     1713     width: 100%;
     1714     font-weight: bold;
     1715     text-align: center;
     1716     vertical-align: middle;
     1717     float: left;
     1718     opacity: 0;
     1719     transition: ease opacity 0.2s;
     1720}
     1721
     1722/* update bar */
     1723
     1724.sb_updatestatus {
     1725     background: #000;
     1726     margin: -6px -4px -2px;
     1727     padding: 2px 0 4px;
     1728     border-bottom: 1px solid #443da0;
     1729     color: #c9ceff;
     1730}
     1731
     1732.sb_info .percentBarOuter {
     1733     margin: 5px -2px -4px 0;
     1734     box-shadow: none !important;
     1735     background: repeating-linear-gradient(135deg, #001 1px, #001 5px, #003 6px, #003 11px);
     1736     animation: downloadbar 3s infinite alternate;
     1737}
     1738.sb_info .percentBarText {
     1739     opacity: 1;
     1740     padding-top: 2px;
     1741     color: #c9ceff;
     1742}
     1743
     1744.sb_info .percentBarInner {
     1745     height: 16px;
     1746}
     1747
     1748@keyframes downloadbar {
     1749from {
     1750     background: repeating-linear-gradient(135deg, #001 1px, #001 5px, #003 6px, #003 11px);
     1751}
     1752
     1753to {
     1754     background: repeating-linear-gradient(135deg, #003 1px, #003 6px, #001 7px, #001 11px);
     1755}
     1756}
     1757
     1758/* end status bar */
    15731759/* end sidebar */
    15741760
     
    68076993/* end network status */
    68086994
    6809 #sb_services, #sb_internals, #sb_advanced {
     6995#sb_services, #sb_internals, #sb_advanced, #sb_help {
    68106996     margin-top: -3px !important;
    68116997     margin-bottom: -5px !important;
     
    73357521
    73367522@media screen and (max-width: 1500px) {
    7337 #sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
    7338 #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
     7523#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
     7524#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    73397525   min-height: 14px;
    73407526}
     
    74327618}
    74337619
    7434 #sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after, #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
     7620#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after,
     7621#sb_bandwidth td::after, #sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
    74357622   min-height: 18px;
    74367623}
     
    75127699}
    75137700
    7514 #sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
     7701#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
    75157702     max-width: 207px;
    75167703}
    75177704
    7518 #sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
     7705#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
    75197706     margin-top: -4px !important;
    75207707     margin-bottom: -4px !important;
  • installer/resources/themes/console/midnight/console_ar.css

    r97267a4 r0e5b46e7  
    9090#sb_localtunnels td:last-child {
    9191     text-align: left;
     92}
     93
     94#sb_bandwidthgraph {
     95     margin: -13px -8px 0 0 !important;
     96}
     97
     98#sb_graphcontainer {
     99     background-position: left -72px top -24px !important;
     100}
     101
     102.percentBarOuter {
     103      margin: -3px -6px -5px 0;
     104}
     105
     106.sb_info .percentBarOuter {
     107     margin: 5px 0 -4px -2px;
     108}
     109
     110.sb_updatestatus b {
     111     font-weight: bold !important;
     112}
     113
     114.sb_updatestatus, .sb_info .percentBarText {
     115     font-size: 9pt;
     116}
     117
     118.sb_info .percentBarText {
     119     padding-top: 0;
     120     direction: ltr;
    92121}
    93122
Note: See TracChangeset for help on using the changeset viewer.