Browse Source

Teamspeak viewer, idle-afk mover, and data mining added.

master
Brandon Cornejo 10 years ago
parent
commit
bc52fc0660
  1. 21
      board.py
  2. 21
      models.py
  3. 4
      static/css/app.css
  4. 270
      static/css/ts3_viewer.css
  5. 201
      static/js/world-map-shapes.js
  6. 171
      teamspeak.py
  7. 30
      templates/index.html
  8. 32
      templates/profile.html
  9. 6
      templates/sidenav.html
  10. 53
      templates/teamspeak.html
  11. 64
      utils.py
  12. 25
      views.py

21
board.py

@ -1,4 +1,5 @@
import os
import re
from time import strftime, gmtime
from peewee import *
from app import app, cache
@ -7,26 +8,30 @@ db = MySQLDatabase(app.config['FORUM_NAME'], **{'passwd': app.config['FORUM_PASS
'host': app.config['FORUM_HOST'], 'user': app.config['FORUM_USERNAME']})
@cache.memoize(60*5)
def latest_news(num=2):
def latest_news(num=3):
latest_news = []
try:
try:
db.connect()
news_forum = Forums.get(fn.Lower(Forums.title) % '%news%')
for thread in Threads.select().where(
Threads.forum == news_forum.id).order_by(Threads.date).limit(num):
Threads.forum == news_forum.id).order_by(Threads.date.desc()).limit(num):
# Last revision of the first post
post = Posts.select().where(Posts.thread == thread.id).get()
text = PostsText.select().where(PostsText.pid == post.id).order_by(PostsText.revision.desc()).limit(1).get()
raw_text = PostsText.select().where(PostsText.pid == post.id).order_by(PostsText.revision.desc()).limit(1).get()
#remove BBCode
text = re.sub(r"\[(\/)?(\w+)\]", '', raw_text.text)
timestamp = thread.date
date = strftime('%B %d, %Y %H:%M:%S UTC', gmtime(timestamp))
if not date:
if not timestamp:
post = Posts.select().where(Posts.thread == thread.id).get()
date = post and post.date
timestamp = post and post.date
url = 'http://board.dotanoobs.com/?page=thread&id=%d' % thread.id
latest_news.append({'title':thread.title, 'text':text.text, 'date':date, 'timestamp':timestamp, 'url':url})
latest_news.append({'title':thread.title, 'text':text, 'date':date, 'timestamp':timestamp, 'url':url})
except Exception as e:
latest_news.append({'title':'Error with forum db', 'text':e, 'url':''})
finally:
finally:
db.close()
return latest_news

21
models.py

@ -1,6 +1,18 @@
import simplejson as json
from flask.ext.sqlalchemy import SQLAlchemy
from time import time
from app import db
# Get a little of that Mongoness back
class Json(db.TypeDecorator):
impl = db.Unicode
def process_bind_param(self, value, dialect):
return unicode(json.dumps(value))
def process_result_value(self, value, dialect):
return json.loads(value)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
steam_id = db.Column(db.String(40), unique=True)
@ -18,3 +30,12 @@ class User(db.Model):
def __repr__(self):
return '<User {}>'.format(self.steam_id)
class TeamspeakData(db.Model):
id = db.Column(db.Integer, primary_key=True)
time = db.Column(db.Float())
clients = db.Column(Json())
def __init__(self, clientlist):
self.time = time()
self.clients = clientlist

4
static/css/app.css

@ -54,3 +54,7 @@ footer {
.botpad {
padding-bottom:80px;
}
#streams-online > .uk-article > a > h4 {
margin:0px;
}

270
static/css/ts3_viewer.css

@ -0,0 +1,270 @@
/**
* This file is part of devMX TS3 Webviewer Lite.
* Copyright (C) 2012 Maximilian Narr
*
* devMX Webviewer Lite is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TeamSpeak3 Webviewer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with devMX TS3 Webviewer Lite. If not, see <http://www.gnu.org/licenses/>.
*/
.devmx-webviewer
{
font-family: sans-serif;
font-size: 14px;
white-space: nowrap;
width: 100%;
line-height: 1;
overflow-x: hidden;
overflow-y: scroll;
}
.tswv-link
{
cursor: pointer;
text-decoration: inherit;
color: #000000;
}
/* Servername */
.tswv-servername
{
margin-left: 3px;
}
/* General */
.tswv-channel,
.tswv-client
{
margin-left: 16px;
margin-top: 1px;
}
.tswv-label
{
margin-left: 3px;
}
/* General image */
.tswv-image
{
display: inline-block;
width: 16px;
height: 16px;
background-repeat: no-repeat;
}
/* Left aligned image */
.tswv-image-left
{
float: left;
}
/* Right aligned image */
.tswv-image-right
{
float: right;
margin-left: 3px;
}
/* Channels */
/* normal channel */
.tswv-channel-normal
{
background-image: url("../img/ts3_viewer/channel-normal.png");
}
/* Full channel */
.tswv-channel-full
{
background-image: url("../img/ts3_viewer/channel-full.png");
}
/* Channel with password (channel Icon) */
.tswv-channel-password
{
background-image: url("../img/ts3_viewer/channel-password.png");
}
/* Channel with password (Lock icon) */
.tswv-channel-password-right
{
background-image: url("../img/ts3_viewer/channel-password-right.png");
}
/* Default channel */
.tswv-channel-home
{
background-image: url("../img/ts3_viewer/channel-home.png");
}
/* Moderated channel */
.tswv-channel-moderated
{
background-image: url("../img/ts3_viewer/channel-moderated.png");
}
/* Channel with 48khz codec */
.tswv-channel-48khz
{
background-image: url("../img/ts3_viewer/channel-48khz.png");
}
/* Server image */
.tswv-server-image
{
background-image: url("../img/ts3_viewer/server.png");
}
/* Clients */
/* normal client */
.tswv-client-normal
{
background-image: url("../img/ts3_viewer/client-normal.png");
}
/* talking client */
.tswv-client-talking
{
background-image: url("../img/ts3_viewer/client-talking.png");
}
/* channelcommander */
.tswv-client-channel-commander
{
background-image: url("../img/ts3_viewer/client-channel-commander.png");
}
/* talking channelcommander */
.tswv-client-channel-commander-talking
{
background-image: url("../img/ts3_viewer/client-channel-commander-talking.png");
}
/* mic muted client */
.tswv-client-input-muted
{
background-image: url("../img/ts3_viewer/input-muted.png");
}
/* speaker muted client */
.tswv-client-output-muted
{
background-image: url("../img/ts3_viewer/output-muted.png");
}
/* hardware mic muted client */
.tswv-client-input-muted-hardware
{
background-image: url("../img/ts3_viewer/hardware-input-muted.png");
}
/* hardware speaker muted client */
.tswv-client-output-muted-hardware
{
background-image: url("../img/ts3_viewer/hardware-output-muted.png");
}
/* away client */
.tswv-client-away
{
background-image: url("../img/ts3_viewer/client-away.png");
}
/* Client with priority speaker */
.tswv-client-priority-speaker
{
background-image: url("../img/ts3_viewer/client-priority-speaker.png");
}
/* Client with granted talkpower */
.tswv-client-talkpower-granted
{
background-image: url("../img/ts3_viewer/client-talkpower-granted.png");
}
/* Query Clients */
.tswv-client-query
{
background-image: url("../img/ts3_viewer/client-query.png");
}
/* Spacer */
/* General */
.tswv-spacer
{
margin: 0px;
}
/* right spacer */
.tswv-spacer-right
{
text-align: right;
}
/* left spacer */
.tswv-spacer-left
{
text-align: left;
}
/* center spacer */
.tswv-spacer-center
{
text-align: center;
}
/* ___ */
.tswv-spacer-line
{
background: url(../img/ts3_viewer/linie.png) repeat-x;
}
/* --- */
.tswv-spacer-dash
{
background: url(../img/ts3_viewer/bs.png) repeat-x;
}
/* -.- */
.tswv-spacer-line-point
{
background: url(../img/ts3_viewer/bspunkt.png) repeat-x;
}
/* -.. */
.tswv-spacer-line-double-point
{
background: url(../img/ts3_viewer/bsdpunkt.png) repeat-x;
}
/* ... */
.tswv-spacer-point
{
background: url(../img/ts3_viewer/punkt.png) repeat-x;
}
/* repeat spacer */
.tswv-spacer-overflow
{
width: inherit;
overflow: hidden;
}

201
static/js/world-map-shapes.js

@ -0,0 +1,201 @@
var shapes = {
"ad": "M 4687 2398 L 4679 2402 4679 2398 Z",
"ae": "M 5995 2942 L 6059 2942 6115 2890 6119 2902 6119 2922 6107 2922 6107 2946 6099 2946 6087 2986 6023 2978 Z",
"af": "M 6239 2782 L 6263 2754 6263 2738 6239 2734 6231 2686 6251 2614 6283 2626 6367 2554 6387 2562 6419 2566 6459 2566 6499 2526 6511 2530 6511 2542 6519 2542 6515 2566 6523 2582 6555 2562 6591 2558 6607 2566 6599 2570 6583 2578 6555 2574 6523 2586 6511 2598 6523 2626 6503 2646 6507 2654 6499 2662 6475 2662 6487 2682 6467 2690 6459 2722 6447 2730 6431 2726 6399 2742 6383 2750 6383 2778 6323 2794 6279 2794 Z",
"ag": "M 3015 3131 L 3013 3136 3020 3136 Z M 3014 3116 L 3016 3122 3018 3120 Z",
"ai": "M 2983 3102 L 2980 3105 2986 3102 Z M 2984 3105 L 2980 3108 2984 3110 Z",
"al": "M 5167 2398 L 5183 2418 5179 2442 5191 2454 5191 2462 5171 2494 5151 2470 5155 2422 5147 2422 Z",
"am": "M 5823 2438 L 5783 2442 5787 2478 5811 2486 5843 2494 5851 2514 5859 2514 5859 2490 5839 2482 5847 2470 Z",
"an": "M 2822 3260 L 2834 3268 2831 3269 Z M 2843 3262 L 2849 3265 2846 3270 Z",
"ao": "M 4955 3722 L 4975 3702 4983 3710 4967 3722 4967 3738 4959 3738 Z M 4967 3746 L 4979 3742 5075 3742 5099 3798 5147 3798 5151 3770 5179 3770 5179 3778 5211 3778 5223 3886 5271 3878 5271 3930 5215 3930 5215 4014 5255 4058 5187 4066 5139 4062 5123 4050 5007 4050 4983 4038 4947 4046 4947 4006 4971 3942 4999 3910 5003 3878 4979 3826 4991 3814 4963 3750 Z",
"ar": "M 2875 4198 L 2903 4170 2911 4178 2943 4182 2951 4198 2959 4178 2995 4182 3047 4226 3127 4270 3099 4322 3175 4326 3199 4306 3207 4274 3227 4274 3227 4318 3127 4406 3103 4514 3103 4534 3139 4558 3155 4602 3127 4642 3003 4662 3003 4722 2935 4722 2943 4770 2915 4854 2867 4878 2867 4910 2911 4926 2907 4958 2863 4998 2859 5022 2827 5038 2823 5058 2843 5106 2803 5094 2751 5094 2739 5046 2719 5050 2711 5002 2763 4866 2747 4766 2763 4666 2779 4650 2799 4494 2787 4434 2839 4306 2839 4250 2871 4230 Z",
"as": "M 9613 3964 L 9607 3966 9609 3968 Z",
"at": "M 4895 2238 L 4979 2238 4975 2218 5003 2198 5027 2202 5035 2186 5087 2198 5087 2230 5067 2258 5023 2274 4999 2270 4959 2254 4915 2262 4891 2250 Z",
"au": "M 8331 4062 L 8375 3874 8423 3970 8455 3986 8483 4086 8659 4274 8671 4366 8639 4474 8583 4566 8575 4622 8483 4666 8439 4642 8411 4666 8311 4622 8291 4562 8251 4518 8207 4542 8147 4458 8071 4446 7951 4466 7887 4514 7791 4514 7735 4546 7663 4518 7679 4462 7623 4306 7639 4278 7615 4230 7707 4138 7823 4110 7867 4030 7887 4046 7975 3954 8007 3986 8043 3986 8039 3966 8083 3906 8119 3910 8131 3886 8235 3918 8199 3982 Z M 8439 4718 L 8487 4734 8535 4718 8535 4762 8499 4810 8475 4806 8439 4730 Z",
"aw": "M 2799 3254 L 2804 3259 2800 3258 Z",
"ax": "M 5167 1771 L 5152 1777 5171 1788 Z",
"az": "M 5859 2418 L 5855 2426 5867 2438 5863 2446 5831 2434 5823 2438 5847 2470 5839 2482 5859 2490 5859 2514 5899 2490 5923 2530 5939 2474 5959 2466 5939 2458 5915 2422 5899 2442 Z M 5843 2494 L 5811 2486 5835 2510 5851 2514 Z",
"ba": "M 5143 2322 L 5143 2370 5123 2402 5051 2326 5055 2314 Z",
"bb": "M 3073 3235 L 3079 3240 3074 3243 Z",
"bd": "M 6979 3006 L 6971 2938 6951 2930 6975 2910 6955 2894 6963 2878 6995 2886 6999 2910 7067 2918 7035 2954 7043 2978 7063 2954 7071 3002 7071 3022 7059 3030 7043 2982 Z",
"be": "M 4707 2118 L 4727 2106 4771 2102 4795 2114 4787 2126 4799 2126 4807 2142 4799 2150 4791 2158 4791 2170 4783 2170 Z",
"bf": "M 4663 3298 L 4703 3274 4645 3194 4615 3194 4587 3206 4583 3214 4563 3218 4499 3278 4495 3314 4527 3334 4547 3322 4567 3342 4567 3298 4627 3298 4635 3294 4643 3294 Z",
"bg": "M 5243 2438 L 5239 2418 5227 2406 5243 2378 5227 2358 5235 2346 5243 2358 5315 2362 5355 2350 5391 2362 5387 2374 5359 2402 5375 2418 5331 2426 5327 2438 5303 2442 5283 2430 Z",
"bh": "M 5962 2884 L 5970 2881 5967 2894 Z",
"bi": "M 5447 3650 L 5451 3674 5419 3706 5407 3678 5399 3662 Z",
"bj": "M 4711 3418 L 4711 3350 4719 3350 4739 3314 4731 3286 4735 3278 4711 3258 4703 3274 4663 3298 4659 3314 4679 3326 4687 3422 Z",
"bn": "M 7663 3458 L 7671 3474 7655 3462 7655 3478 7651 3482 7639 3470 Z",
"bo": "M 2815 4050 L 2827 4030 2839 4018 2819 3998 2835 3918 2815 3878 2847 3878 2887 3850 2923 3842 2931 3906 3055 3954 3059 4018 3107 4018 3107 4046 3127 4070 3115 4122 3087 4102 3019 4110 2995 4182 2959 4178 2951 4198 2943 4182 2911 4178 2903 4170 2875 4198 2855 4198 Z",
"br": "M 3283 3478 L 3247 3530 3207 3526 3155 3538 3095 3554 3071 3538 3063 3454 3047 3450 3047 3458 2987 3494 2939 3478 2959 3522 2975 3526 2907 3570 2883 3558 2867 3534 2855 3542 2803 3542 2803 3558 2819 3558 2819 3570 2799 3570 2799 3594 2819 3622 2803 3698 2779 3698 2727 3722 2719 3758 2695 3786 2747 3854 2787 3838 2787 3878 2847 3878 2887 3850 2923 3842 2931 3906 3055 3954 3059 4018 3107 4018 3107 4046 3127 4070 3115 4122 3115 4178 3175 4182 3187 4230 3215 4230 3207 4274 3227 4274 3227 4318 3127 4406 3147 4402 3243 4478 3231 4494 3235 4510 3359 4358 3363 4278 3435 4222 3539 4198 3611 4054 3623 3934 3719 3818 3723 3770 3707 3722 3663 3718 3587 3662 3491 3650 3471 3662 3455 3626 3383 3602 3355 3626 3367 3594 3323 3578 3327 3542 3315 3538 Z",
"bs": "M 2587 2914 L 2579 2930 2591 2938 2599 2930 Z M 2599 2938 L 2591 2942 2603 2954 Z M 2571 2874 L 2595 2866 2595 2870 Z M 2607 2866 L 2619 2878 2611 2890 2615 2878 Z",
"bt": "M 6971 2862 L 6999 2870 7059 2866 7055 2850 7047 2850 7047 2842 7003 2826 Z",
"bw": "M 5299 4058 L 5375 4162 5411 4178 5347 4222 5311 4278 5247 4266 5211 4310 5183 4310 5179 4298 5187 4290 5163 4254 5163 4174 5191 4174 5191 4074 5251 4066 5259 4078 Z",
"by": "M 5379 1934 L 5339 1954 5311 2006 5259 2018 5267 2062 5251 2078 5259 2082 5259 2098 5303 2086 5443 2106 5455 2082 5475 2082 5467 2042 5499 2034 5451 1986 5451 1954 Z",
"bz": "M 2299 3114 L 2319 3094 2319 3146 2303 3166 2299 3166 Z",
"ca": "M 3159 2102 L 3083 2230 3247 2250 3227 2170 3155 2162 3187 2094 Z M 2583 1346 L 2723 1446 2739 1486 2683 1534 2703 1558 2611 1570 2591 1602 2623 1614 2691 1602 2771 1666 2907 1706 2835 1638 2931 1670 2951 1642 2859 1526 2971 1582 3027 1510 2855 1422 2883 1386 2835 1322 2603 1226 2539 1246 2495 1174 2395 1206 2395 1270 2367 1226 2407 1174 2335 1174 2275 1254 2279 1294 2339 1310 2291 1310 2339 1350 2571 1362 Z M 2519 1178 L 2555 1222 2643 1218 2595 1182 Z M 1899 1190 L 1871 1222 1895 1306 1991 1362 1959 1406 1835 1386 1667 1430 1559 1358 1695 1338 1555 1330 1527 1310 1583 1286 1515 1278 1535 1234 1623 1190 1651 1226 1667 1210 1727 1238 1731 1214 1783 1234 1803 1278 1803 1198 1855 1210 1835 1182 1871 1174 Z M 1611 1186 L 1479 1254 1471 1286 1411 1314 1335 1262 1387 1170 1363 1146 1455 1134 1551 1150 Z M 1587 970 L 1415 1042 1559 1038 Z M 1615 1030 L 1559 1098 1707 1142 1859 1098 1863 1054 1799 1046 1775 1006 1743 1078 Z M 1871 870 L 1979 890 2027 954 1907 930 Z M 1903 1022 L 2075 1034 2067 1106 2015 1106 Z M 2135 1082 L 2103 1106 2167 1126 2183 1094 Z M 2091 1002 L 2259 1014 2299 1074 2535 1078 2523 1130 2279 1138 2211 1090 2187 1034 2147 1042 Z M 2051 910 L 2119 974 2199 962 Z M 2627 1434 L 2607 1466 2643 1486 2667 1446 Z M 1659 949 L 1747 933 1751 961 1691 977 Z M 2883 2322 L 2859 2294 2859 2250 2823 2238 2759 2318 2671 2318 2643 2338 2563 2354 2543 2374 2563 2374 2567 2386 2459 2414 2459 2406 2475 2382 2491 2370 2503 2318 2539 2338 2519 2290 2427 2274 2419 2266 2411 2222 2327 2186 2283 2218 2143 2186 1415 2186 1347 2146 1395 2190 1395 2206 1335 2186 1267 2126 1283 2122 1323 2134 1207 2014 1215 1986 1227 1938 1079 1798 1031 1830 935 1770 935 1374 1083 1410 1239 1350 1219 1374 1291 1346 1347 1386 1367 1354 1643 1430 1611 1454 1687 1462 1751 1450 1795 1474 1807 1446 1859 1426 1787 1434 1795 1422 1859 1410 1871 1430 1955 1462 2047 1454 2047 1434 2079 1426 2031 1402 2071 1358 2127 1414 2091 1426 2119 1442 2115 1478 2135 1446 2179 1422 2155 1374 2107 1342 2139 1262 2123 1178 2175 1154 2267 1166 2223 1226 2179 1222 2167 1270 2231 1346 2207 1370 2227 1386 2271 1382 2335 1438 2347 1486 2395 1418 2395 1366 2503 1394 2479 1438 2507 1474 2435 1546 2363 1518 2355 1570 2251 1646 2159 1754 2151 1826 2191 1838 2211 1898 2259 1890 2411 1970 2479 1970 2479 2054 2535 2106 2579 2070 2543 1986 2623 1938 2611 1862 2575 1834 2615 1786 2591 1686 2735 1706 2811 1754 2827 1830 2863 1854 2911 1830 2943 1762 3059 1958 3135 1990 3179 2070 3071 2142 2891 2142 2787 2242 2899 2178 2951 2186 2939 2270 3011 2294 3047 2250 3059 2290 2919 2366 2899 2338 2947 2294 Z M 2387 1558 L 2355 1638 2407 1658 2455 1618 2511 1642 2523 1630 Z M 1999 1174 L 2083 1166 2099 1270 2043 1298 1943 1222 2011 1222 Z M 2339 982 L 2287 1026 2563 1034 2563 990 2687 898 2659 870 2783 838 3031 682 2691 622 2475 658 2459 694 2411 666 2223 730 2383 798 2531 790 2359 814 2443 894 2367 894 2339 942 2403 962 2327 962 Z M 2199 746 L 2307 826 2403 870 2303 938 2223 934 2103 830 Z",
"cd": "M 5407 3678 L 5399 3662 5399 3650 5419 3622 5419 3586 5463 3530 5447 3522 5451 3494 5359 3454 5243 3458 5231 3478 5175 3470 5155 3450 5127 3474 5127 3494 5127 3506 5103 3606 5063 3646 5063 3678 5055 3690 5027 3714 5019 3714 5019 3702 4999 3706 4991 3714 4983 3710 4967 3722 4967 3738 4959 3738 4967 3746 4979 3742 5075 3742 5099 3798 5147 3798 5151 3770 5179 3770 5179 3778 5211 3778 5223 3886 5271 3878 5279 3878 5283 3890 5303 3886 5307 3894 5347 3906 5351 3894 5407 3942 5423 3942 5423 3910 5403 3914 5383 3890 5391 3870 5387 3834 5399 3814 5443 3802 5411 3750 5403 3718 Z",
"cf": "M 5127 3494 L 5127 3474 5155 3450 5175 3470 5231 3478 5243 3458 5359 3454 5243 3298 5127 3374 5047 3386 5019 3430 5063 3530 5075 3494 Z",
"cg": "M 5063 3530 L 5075 3494 5127 3494 5127 3506 5103 3606 5063 3646 5063 3678 5055 3690 5027 3714 5019 3714 5019 3702 4999 3706 4991 3714 4983 3710 4975 3702 4955 3722 4931 3690 4943 3678 4951 3686 4943 3650 4967 3646 4967 3638 4975 3634 4983 3650 5011 3650 5019 3602 5003 3594 5019 3554 4987 3554 4987 3530 5023 3530 5063 3546 Z",
"ch": "M 4839 2238 L 4823 2242 4799 2282 4819 2274 4823 2290 4847 2290 4859 2274 4875 2294 4887 2274 4907 2282 4915 2262 4891 2250 4895 2238 Z",
"ci": "M 4567 3454 L 4555 3414 4575 3370 4567 3342 4547 3322 4527 3334 4495 3314 4479 3322 4475 3310 4455 3322 4431 3318 4419 3390 4415 3414 4443 3438 4439 3474 4491 3454 4543 3450 Z",
"cl": "M 2843 5106 L 2803 5094 2751 5094 2739 5046 2719 5050 2711 5002 2763 4866 2747 4766 2763 4666 2779 4650 2799 4494 2787 4434 2839 4306 2839 4250 2871 4230 2875 4198 2855 4198 2815 4050 2791 4074 2799 4162 2759 4406 2763 4474 2719 4606 2703 4614 2715 4678 2699 4734 2703 4750 2695 4754 2683 4802 2703 4810 2715 4750 2731 4750 2707 4854 2699 4818 2683 4834 2679 4878 2651 4914 2687 4918 2675 4950 2655 4958 2659 5050 2671 5038 2663 5078 2691 5078 2667 5086 2715 5130 2675 5118 2739 5182 2823 5210 2927 5198 2927 5190 2899 5182 2847 5142 2831 5110 2815 5110 2791 5130 2791 5142 2819 5142 2799 5154 2803 5166 2827 5182 2795 5170 2787 5150 2775 5166 2743 5150 2771 5158 2783 5122 2819 5102 Z",
"cm": "M 4895 3530 L 5023 3530 5063 3546 5063 3530 5019 3430 5047 3386 5007 3330 5015 3322 5047 3322 5035 3294 5039 3270 5019 3242 5011 3242 5011 3262 5019 3262 5023 3282 5007 3290 4939 3418 4915 3402 4863 3462 4903 3502 Z",
"cn": "M 6947 2182 L 6935 2186 6891 2210 6891 2250 6819 2250 6795 2314 6747 2322 6747 2410 6691 2446 6659 2450 6643 2466 6607 2466 6583 2478 6579 2494 6575 2494 6583 2522 6603 2526 6607 2566 6635 2582 6639 2606 6683 2618 6715 2650 6707 2658 6731 2698 6715 2710 6707 2702 6699 2706 6711 2738 6767 2770 6795 2770 6895 2830 6955 2838 6971 2830 6971 2862 7003 2826 7047 2842 7075 2834 7127 2798 7147 2802 7163 2794 7195 2826 7207 2818 7231 2846 7231 2894 7203 2926 7203 2946 7235 2942 7239 2970 7255 2974 7243 2998 7267 3002 7271 3018 7295 3014 7299 3022 7311 3026 7307 2994 7311 2990 7323 2990 7331 2982 7347 2990 7407 2966 7443 2982 7443 3002 7475 3018 7491 3010 7527 3018 7519 3030 7531 3050 7543 3042 7535 3030 7623 2994 7623 2978 7631 2986 7643 2986 7707 2966 7779 2894 7847 2782 7811 2770 7843 2750 7835 2718 7819 2702 7799 2650 7771 2634 7843 2570 7855 2574 7859 2558 7847 2554 7835 2558 7815 2542 7779 2566 7763 2554 7763 2534 7735 2534 7735 2506 7763 2506 7771 2498 7823 2450 7851 2462 7831 2490 7835 2506 7823 2514 7823 2518 7887 2482 7907 2482 7975 2422 8003 2438 8007 2418 8047 2402 8055 2386 8071 2406 8071 2390 8083 2386 8083 2326 8103 2310 8135 2322 8179 2214 8079 2234 8051 2178 7991 2162 7947 2058 7879 2030 7815 2038 7791 2058 7791 2066 7811 2066 7811 2086 7735 2170 7703 2158 7675 2218 7683 2234 7755 2222 7791 2258 7783 2270 7723 2270 7627 2326 7583 2318 7567 2342 7579 2362 7515 2402 7455 2406 7399 2430 7287 2394 7175 2394 7139 2342 7087 2322 7027 2314 7019 2302 7031 2286 7007 2226 6951 2202 Z M 7545 3053 L 7510 3059 7493 3075 7495 3096 7518 3106 7541 3090 7555 3063 Z",
"co": "M 2595 3398 L 2611 3378 2607 3358 2623 3366 2671 3294 2715 3290 2759 3258 2771 3270 2751 3282 2711 3346 2759 3402 2799 3402 2815 3426 2867 3422 2855 3470 2871 3498 2859 3510 2875 3526 2883 3558 2867 3534 2855 3542 2803 3542 2803 3558 2819 3558 2819 3570 2799 3570 2799 3594 2819 3622 2803 3698 2783 3686 2799 3658 2755 3646 2719 3650 2703 3618 2663 3590 2571 3550 2611 3490 2603 3478 2607 3410 Z",
"cr": "M 2443 3302 L 2435 3306 2411 3294 2391 3290 2387 3294 2383 3318 2403 3334 2415 3330 2459 3370 2467 3334 Z",
"cu": "M 2423 2990 L 2479 2966 2575 2986 2691 3050 2599 3058 2611 3038 2483 2982 2419 3006 Z M 2459 3002 L 2455 3014 2471 3014 Z",
"cy": "M 5547 2608 L 5524 2618 5504 2617 5500 2625 5488 2627 5505 2642 5532 2628 5531 2620 Z",
"cz": "M 5135 2170 L 5087 2198 5035 2186 5027 2202 5003 2198 4963 2146 5031 2122 5127 2158 Z",
"de": "M 4823 2038 L 4827 2026 4871 2018 4867 1982 4891 1982 4907 1998 4931 1998 4927 2014 4983 1998 5011 2018 5019 2046 5011 2054 5023 2066 5031 2122 4963 2146 5003 2198 4975 2218 4979 2238 4839 2238 4855 2190 4807 2174 4811 2162 4799 2150 4807 2142 4799 2126 4787 2126 4803 2102 4795 2090 4819 2086 4827 2042 Z",
"dj": "M 5771 3254 L 5751 3258 5739 3278 5739 3298 5767 3298 5775 3286 5763 3282 5779 3270 Z",
"dk": "M 4867 1982 L 4891 1982 4895 1958 4915 1978 4923 1962 4907 1954 4899 1958 4899 1954 4927 1922 4911 1918 4915 1874 4887 1898 4867 1898 4851 1922 4851 1958 4867 1962 Z M 4967 1938 L 4951 1942 4951 1950 4943 1942 4931 1954 4935 1970 4959 1978 4959 1970 4967 1966 4959 1958 4971 1954 Z",
"dk": "M 4867 1982 L 4891 1982 4895 1958 4915 1978 4923 1962 4907 1954 4899 1958 4899 1954 4927 1922 4911 1918 4915 1874 4887 1898 4867 1898 4851 1922 4851 1958 4867 1962 Z M 4967 1938 L 4951 1942 4951 1950 4943 1942 4931 1954 4935 1970 4959 1978 4959 1970 4967 1966 4959 1958 4971 1954 Z M 4931 1978 L 4927 1986 4943 1994 4955 1990 4963 1978 4947 1978 4943 1982 Z",
"dm": "M 3024 3173 L 3030 3177 3030 3184 3027 3185 Z",
"do": "M 2755 3062 L 2755 3106 2763 3118 2787 3098 2839 3102 2847 3094 2779 3058 Z",
"dz": "M 4863 2574 L 4859 2626 4835 2666 4879 2718 4887 2770 4887 2886 4955 2958 4831 3034 4795 3074 4751 3082 4723 3082 4667 3026 4506 2917 4411 2854 4411 2842 4411 2814 4539 2742 4539 2726 4607 2714 4583 2630 4719 2574 Z",
"ec": "M 2663 3590 L 2571 3550 2515 3614 2515 3646 2543 3666 2531 3678 2527 3706 2551 3706 2563 3722 2591 3666 2627 3654 2663 3614 Z",
"ee": "M 5231 1826 L 5219 1830 5231 1838 5215 1846 5219 1870 5251 1842 5235 1838 5243 1830 Z M 5279 1870 L 5303 1862 5335 1882 5347 1878 5355 1882 5367 1870 5359 1834 5375 1810 5315 1802 5255 1818 5263 1854 5283 1854 Z",
"eg": "M 5539 2738 L 5559 2790 5539 2838 5491 2778 5575 2970 5531 3010 5511 3002 5299 3002 5299 2730 5318 2729 5403 2754 5455 2734 5507 2746 Z",
"eh": "M 4411 2854 L 4411 2842 4295 2842 4279 2874 4259 2886 4247 2926 4195 3006 4195 3022 4295 3022 4295 2974 4323 2962 4323 2890 4411 2890 Z",
"er": "M 5651 3110 L 5611 3138 5599 3210 5627 3214 5635 3194 5651 3206 5695 3206 5751 3258 5771 3254 5719 3198 5695 3190 5687 3178 5683 3182 5671 3162 5659 3122 Z",
"es": "M 4719 2402 L 4723 2422 4655 2462 4631 2498 4580 2579 4499 2594 4495 2598 4459 2566 4443 2566 4447 2494 4475 2430 4407 2414 4395 2386 4435 2358 4595 2374 4679 2398 4679 2402 4687 2398 Z M 4721 2478 L 4730 2486 4720 2501 4700 2490 Z M 4739 2477 L 4748 2474 4752 2483 Z M 4671 2510 L 4679 2504 4682 2507 4675 2513 Z",
"et": "M 5583 3466 L 5579 3446 5507 3382 5511 3366 5531 3366 5543 3302 5555 3306 5599 3210 5627 3214 5635 3194 5651 3206 5695 3206 5751 3258 5739 3278 5739 3298 5767 3298 5759 3306 5791 3346 5871 3378 5899 3378 5823 3458 5795 3458 5739 3482 5719 3482 5711 3474 5679 3498 5639 3494 5607 3470 Z",
"fi": "M 5271 1550 L 5259 1454 5183 1406 5199 1390 5239 1422 5271 1414 5295 1426 5335 1362 5371 1358 5403 1374 5411 1382 5399 1402 5383 1414 5395 1414 5387 1426 5395 1446 5427 1466 5403 1498 5431 1554 5423 1558 5419 1582 5443 1622 5427 1638 5471 1670 5459 1690 5371 1766 5247 1794 5199 1766 5207 1726 5195 1678 5287 1590 5307 1586 5303 1562 Z",
"fj": "M 9318 4045 L 9292 4064 9317 4074 9334 4066 Z M 9327 4032 L 9334 4038 9373 4033 9362 4015 Z",
"fr": "M 4595 2374 L 4679 2398 4687 2398 4719 2402 4723 2378 4751 2370 4803 2382 4824 2368 4835 2362 4839 2346 4819 2342 4823 2330 4815 2318 4827 2306 4819 2274 4799 2282 4823 2242 4839 2238 4855 2190 4807 2174 4791 2170 4783 2170 4707 2118 4679 2126 4679 2150 4635 2178 4611 2174 4607 2166 4591 2166 4599 2202 4567 2202 4555 2194 4515 2202 4527 2230 4575 2238 4611 2302 4607 2342 Z M 4887 2382 L 4890 2411 4881 2434 4866 2418 4866 2399 4883 2392 Z",
"fk": "M 3119 5070 L 3047 5070 3051 5090 3035 5090 3047 5102 3083 5074 3067 5106 3123 5082 Z",
"ga": "M 4931 3690 L 4943 3678 4951 3686 4943 3650 4967 3646 4967 3638 4975 3634 4983 3650 5011 3650 5019 3602 5003 3594 5019 3554 4987 3554 4987 3530 4939 3530 4939 3562 4891 3562 4887 3586 4871 3610 4883 3638 Z",
"gb": "M 4647 2130 L 4675 2114 4675 2106 4653 2106 4683 2082 4687 2062 4671 2050 4651 2050 4647 2058 4639 2054 4647 2046 4627 1998 4607 1990 4595 1954 4559 1938 4591 1878 4535 1878 4559 1842 4507 1842 4483 1886 4475 1930 4515 1958 4507 1986 4547 1982 4563 2038 4531 2038 4523 2034 4519 2038 4523 2046 4515 2058 4531 2054 4531 2078 4503 2086 4507 2098 4555 2106 4571 2096 4559 2110 4527 2114 4495 2150 4503 2154 4515 2142 4531 2142 4543 2146 4551 2134 4567 2130 4607 2134 4619 2126 Z M 4451 1974 L 4427 1998 4447 2010 4455 1998 4475 2014 4499 1998 4479 1966 Z",
"gd": "M 3018 3264 L 3022 3267 3016 3271 Z",
"ge": "M 5731 2430 L 5759 2430 5783 2442 5823 2438 5831 2434 5863 2446 5867 2438 5855 2426 5859 2418 5839 2410 5843 2402 5695 2366 5691 2374 5727 2394 5735 2426 Z",
"gf": "M 3223 3434 L 3207 3458 3223 3494 3207 3526 3247 3530 3283 3478 3255 3450 Z",
"gh": "M 4671 3426 L 4655 3410 4651 3318 4635 3305 4643 3294 4635 3293 4627 3298 4567 3298 4567 3342 4575 3370 4555 3414 4567 3454 4587 3462 Z",
"gi": "M 4499 2594 L 4500 2596 4498 2596 Z",
"gl": "M 2875 806 L 2935 834 2727 930 2851 986 2775 998 2859 1062 3007 1042 3152 1129 3194 1212 3184 1289 3242 1270 3303 1330 3207 1321 3231 1390 3307 1370 3227 1470 3351 1730 3491 1786 3591 1574 3711 1538 3791 1434 4051 1358 4047 1202 4135 1138 4115 878 4323 730 4195 706 4047 746 4063 674 3767 590 3351 646 3387 694 3275 662 3287 698 3179 682 3011 722 3015 762 2975 758 Z",
"gm": "M 4199 3242 L 4243 3230 4267 3238 4279 3234 4247 3222 4203 3230 Z",
"gn": "M 4291 3350 L 4315 3326 4347 3326 4363 3358 4359 3366 4371 3362 4387 3366 4391 3390 4403 3398 4411 3386 4419 3390 4431 3318 4395 3266 4343 3274 4339 3258 4279 3254 4279 3278 4251 3286 4247 3298 Z",
"gp": "M 3016 3154 L 3022 3155 3025 3149 3032 3157 3022 3159 3018 3165 Z",
"gq": "M 4891 3562 L 4939 3562 4939 3530 4895 3530 4887 3558 Z M 4875 3490 L 4867 3502 4859 3498 4867 3490 Z",
"gr": "M 5171 2494 L 5191 2462 5191 2454 5243 2438 5283 2430 5303 2442 5327 2438 5331 2426 5327 2458 5299 2450 5263 2458 5271 2470 5251 2474 5239 2466 5231 2478 5283 2538 5271 2538 5271 2554 5259 2542 5247 2546 5259 2558 5247 2562 5235 2554 5247 2590 5235 2578 5231 2590 5219 2570 5215 2578 5207 2566 5211 2562 5195 2542 5211 2530 5243 2542 5247 2538 5215 2530 5195 2530 Z M 5259 2614 L 5259 2622 5295 2630 5331 2630 5331 2622 Z",
"gt": "M 2303 3166 L 2299 3166 2299 3114 2251 3114 2251 3130 2239 3130 2263 3162 2231 3162 2215 3202 2243 3218 2271 3222 2291 3206 2323 3170 Z",
"gw": "M 4247 3298 L 4251 3286 4279 3278 4279 3254 4239 3254 4199 3262 4223 3278 4235 3278 4231 3286 Z",
"gy": "M 3071 3366 L 3043 3390 3055 3402 3027 3430 3047 3450 3063 3454 3071 3538 3095 3554 3155 3538 3115 3478 3139 3434 Z",
"hk": "M 7631 2986 L 7643 2986 7639 2994 Z",
"hm": "M 6563 5126 L 6579 5130 6567 5134 Z",
"hn": "M 2291 3206 L 2335 3222 2331 3238 2347 3246 2411 3194 2455 3190 2423 3166 2323 3170 Z",
"hr": "M 5135 2294 L 5107 2294 5071 2270 5051 2286 5043 2306 4999 2306 5003 2326 5123 2402 5051 2326 5055 2314 5143 2322 Z",
"ht": "M 2755 3062 L 2755 3106 2687 3102 2687 3094 2739 3094 2731 3074 2711 3066 2727 3058 Z",
"hu": "M 5223 2210 L 5239 2222 5223 2230 5195 2282 5151 2282 5135 2294 5107 2294 5071 2270 5067 2258 5087 2230 5087 2222 5103 2230 5135 2226 5135 2222 5179 2206 Z",
"id": "M 7139 3442 L 7199 3454 7219 3482 7363 3582 7355 3606 7383 3618 7395 3650 7415 3654 7423 3670 7415 3742 7375 3734 7323 3694 7259 3590 7243 3582 7235 3546 7183 3494 7171 3490 Z M 7399 3642 L 7419 3630 7431 3654 7443 3658 7439 3674 7423 3662 7419 3646 Z M 7467 3658 L 7463 3674 7479 3674 7483 3662 Z M 7423 3746 L 7407 3770 7435 3774 7431 3782 7647 3822 7643 3798 7607 3790 7599 3778 7635 3774 7551 3762 7539 3770 7491 3766 7483 3750 Z M 7735 3482 L 7679 3478 7647 3550 7623 3558 7591 3550 7583 3562 7543 3566 7519 3538 7499 3562 7515 3622 7523 3618 7535 3666 7575 3666 7575 3682 7647 3682 7647 3698 7687 3686 7735 3562 7763 3562 7723 3506 Z M 7919 3542 L 7931 3550 7907 3578 7803 3578 7791 3606 7819 3626 7831 3610 7879 3606 7831 3646 7875 3710 7867 3738 7855 3726 7863 3706 7839 3718 7831 3714 7819 3662 7795 3670 7807 3738 7775 3734 7779 3682 7759 3678 7795 3570 7819 3558 7899 3570 Z M 7647 3806 L 7667 3802 7679 3810 7667 3822 Z M 7691 3806 L 7703 3810 7695 3822 7683 3818 Z M 7711 3810 L 7707 3830 7747 3818 Z M 7731 3802 L 7763 3806 7767 3818 7751 3822 Z M 7783 3818 L 7803 3806 7851 3818 7923 3802 7927 3810 7835 3822 Z M 7919 3826 L 7923 3838 7887 3866 7879 3858 7891 3838 Z M 7803 3862 L 7811 3854 7787 3834 7763 3838 Z M 7951 3674 L 7975 3670 7983 3686 7971 3690 Z M 8003 3666 L 8059 3666 8079 3690 8023 3674 8011 3682 Z M 8015 3522 L 8007 3528 7987 3546 7995 3598 8011 3614 7999 3586 7999 3574 8019 3582 8019 3578 8003 3570 8019 3558 8019 3546 7995 3570 7995 3562 8003 3546 7999 3542 Z M 7991 3626 L 7987 3634 8003 3634 Z M 7907 3634 L 7959 3638 7907 3642 Z M 8079 3622 L 8119 3598 8159 3606 8171 3658 8183 3674 8199 3678 8259 3630 8343 3658 8343 3826 8311 3802 8255 3810 8267 3786 8287 3782 8263 3730 8147 3682 8139 3698 8111 3662 8155 3650 8111 3646 8103 3630 Z M 8171 3734 L 8163 3754 8163 3766 8179 3754 Z M 8095 3778 L 8083 3794 8083 3802 8095 3786 Z",
"ie": "M 4475 2014 L 4455 1998 4447 2010 4427 1998 4451 1974 4455 1966 4423 1970 4407 1990 4419 1994 4411 2002 4375 2002 4375 2034 4395 2046 4367 2078 4383 2102 4471 2078 4483 2050 Z",
"il": "M 5563 2686 L 5575 2682 5575 2698 5571 2746 5559 2790 5539 2738 5551 2722 Z",
"in": "M 6431 2950 L 6507 2934 6495 2898 6487 2898 6483 2874 6471 2874 6467 2862 6491 2834 6499 2842 6527 2834 6599 2746 6599 2726 6619 2710 6603 2706 6579 2650 6591 2638 6631 2646 6683 2618 6715 2650 6707 2658 6731 2698 6715 2710 6707 2702 6699 2706 6711 2738 6767 2770 6739 2806 6827 2854 6847 2850 6863 2854 6863 2862 6883 2870 6951 2878 6955 2838 6971 2830 6971 2862 6999 2870 7059 2866 7055 2850 7047 2850 7047 2842 7075 2834 7127 2798 7147 2802 7163 2794 7195 2826 7195 2838 7183 2850 7191 2862 7175 2854 7139 2874 7111 2950 7091 2946 7087 2994 7071 3002 7063 2954 7043 2978 7035 2954 7067 2918 6999 2910 6995 2886 6963 2878 6955 2894 6975 2910 6951 2930 6971 2938 6979 3006 6927 3014 6923 3038 6743 3182 6751 3238 6735 3282 6735 3318 6723 3318 6715 3342 6695 3350 6691 3370 6675 3378 6651 3354 6643 3326 6571 3166 6547 3062 6555 3042 6543 2998 6531 3026 6499 3038 6451 2994 6483 2986 6483 2978 6467 2982 Z",
"iq": "M 5815 2566 L 5755 2566 5735 2586 5727 2586 5715 2650 5659 2678 5671 2714 5743 2742 5815 2802 5863 2802 5879 2778 5911 2778 5895 2726 5835 2658 5851 2606 5831 2602 Z",
"ir": "M 5911 2778 L 5895 2726 5835 2658 5851 2606 5831 2602 5815 2566 5799 2498 5811 2486 5835 2510 5851 2514 5859 2514 5899 2490 5923 2530 5931 2554 6003 2586 6059 2574 6055 2562 6123 2530 6247 2582 6251 2614 6231 2686 6239 2734 6263 2738 6263 2754 6239 2782 6299 2854 6299 2874 6263 2882 6255 2914 6143 2898 6131 2858 6075 2874 5995 2838 5951 2770 Z",
"is": "M 4019 1586 L 4067 1614 4047 1634 4147 1654 4283 1582 4215 1518 4107 1534 4083 1566 4043 1518 3999 1562 4059 1566 Z",
"it": "M 4835 2362 L 4871 2338 4983 2442 5051 2478 5067 2514 5051 2534 5059 2546 5091 2502 5075 2486 5091 2466 5119 2486 5127 2474 5075 2442 5059 2430 5063 2418 5035 2418 4995 2366 4963 2346 4963 2306 4995 2294 4999 2270 4959 2254 4915 2262 4907 2282 4887 2274 4875 2294 4859 2274 4847 2290 4823 2290 4827 2306 4815 2318 4823 2330 4819 2342 4839 2346 Z M 5047 2534 L 5035 2578 4963 2546 Z M 4887 2442 L 4899 2466 4891 2506 4859 2506 4855 2454 Z",
"jm": "M 2579 3102 L 2607 3094 2639 3110 2611 3118 Z",
"jo": "M 5659 2678 L 5607 2710 5575 2698 5571 2746 5559 2790 5559 2798 5587 2802 5639 2762 5611 2734 5671 2714 Z",
"jp": "M 8359 2310 L 8351 2378 8311 2394 8319 2430 8339 2422 8327 2402 8367 2394 8399 2414 8463 2374 8455 2342 8427 2354 8367 2302 Z M 8159 2650 L 8179 2662 8163 2682 8147 2674 8131 2698 8115 2678 8131 2658 8139 2666 8147 2662 8151 2654 Z M 8079 2662 L 8111 2690 8087 2738 8075 2750 8059 2738 8067 2698 8039 2682 Z M 8327 2438 L 8339 2434 8375 2498 8343 2542 8335 2606 8223 2650 8207 2678 8183 2654 8195 2638 8119 2654 8111 2662 8079 2658 8083 2646 8127 2614 8191 2610 8207 2618 8215 2610 8211 2598 8239 2566 8247 2578 8299 2534 8319 2482 8315 2458 Z",
"ke": "M 5531 3478 L 5543 3466 5583 3466 5607 3470 5639 3494 5679 3498 5711 3474 5719 3482 5739 3482 5715 3514 5715 3610 5731 3630 5707 3654 5695 3658 5695 3674 5671 3710 5627 3678 5631 3670 5535 3614 5531 3582 5563 3534 Z",
"kg": "M 6575 2494 L 6499 2498 6463 2494 6459 2486 6479 2474 6495 2482 6503 2474 6523 2478 6559 2454 6523 2434 6515 2442 6487 2430 6511 2414 6503 2410 6519 2390 6567 2402 6587 2378 6627 2390 6719 2390 6747 2410 6691 2446 6659 2450 6643 2466 6607 2466 6583 2478 6579 2494 Z",
"kh": "M 7383 3314 L 7415 3298 7427 3306 7419 3282 7463 3262 7463 3202 7447 3210 7439 3206 7427 3210 7427 3218 7423 3222 7403 3210 7351 3210 7327 3234 7339 3274 7347 3290 7347 3302 7355 3302 7359 3298 7363 3306 7359 3310 7363 3314 7367 3310 Z",
"kp": "M 7907 2482 L 7975 2422 8003 2438 8007 2418 8047 2402 8055 2386 8071 2406 8043 2430 8047 2454 7987 2486 7987 2506 8011 2522 7967 2546 7919 2538 7931 2494 Z",
"kr": "M 8011 2522 L 8043 2574 8031 2630 7963 2650 7955 2630 7967 2598 7955 2578 7971 2570 7967 2546 Z",
"kw": "M 5911 2778 L 5895 2794 5911 2818 5891 2818 5887 2806 5863 2802 5879 2778 Z",
"ky": "M 2482 3012 L 2490 3008 2486 3012 Z M 2496 3010 L 2498 3012 2502 3008 Z",
"kz": "M 6111 2438 L 6099 2442 6067 2406 6035 2410 6019 2426 6015 2410 6027 2398 6003 2390 5975 2346 5959 2342 5959 2330 5987 2334 5979 2322 5991 2310 6027 2306 6035 2266 5983 2250 5931 2274 5863 2206 5891 2138 5911 2162 5923 2154 5919 2134 5975 2094 6015 2094 6103 2134 6175 2114 6207 2138 6251 2126 6255 2106 6215 2086 6243 2074 6235 2058 6247 2050 6267 2050 6271 2046 6247 2038 6247 2018 6463 1966 6499 1966 6511 2010 6571 2018 6571 2030 6655 2002 6743 2126 6767 2110 6799 2130 6831 2118 6903 2170 6919 2166 6935 2186 6891 2210 6891 2250 6819 2250 6795 2314 6747 2322 6747 2410 6719 2390 6627 2390 6587 2378 6567 2402 6519 2390 6503 2410 6451 2438 6439 2458 6419 2442 6395 2442 6387 2418 6375 2418 6375 2386 6367 2390 6343 2362 6267 2370 6243 2342 6179 2302 6111 2322 Z",
"la": "M 7295 3014 L 7267 3046 7279 3054 7279 3070 7299 3070 7291 3122 7295 3126 7323 3106 7335 3118 7355 3098 7391 3130 7391 3150 7415 3174 7411 3190 7411 3206 7403 3210 7423 3222 7427 3218 7427 3210 7439 3206 7447 3210 7463 3202 7467 3186 7455 3170 7463 3166 7399 3098 7403 3094 7371 3074 7399 3054 7375 3030 7363 3038 7343 3022 7343 3010 7323 2990 7311 2990 7307 2994 7311 3026 7299 3022 Z",
"lb": "M 5583 2642 L 5591 2642 5599 2654 5575 2682 5563 2686 Z",
"lc": "M 3038 3214 L 3035 3222 3039 3224 Z",
"lk": "M 6739 3330 L 6763 3346 6787 3390 6791 3410 6759 3434 6743 3426 6731 3378 6743 3342 Z",
"lr": "M 4439 3474 L 4443 3438 4415 3414 4419 3390 4411 3386 4403 3398 4391 3390 4387 3366 4371 3362 4339 3406 4399 3454 Z",
"lt": "M 5199 1966 L 5191 1938 5223 1926 5295 1926 5339 1954 5311 2006 5259 2018 5235 1998 5235 1974 Z",
"lu": "M 4791 2158 L 4791 2170 4807 2174 4811 2162 4799 2150 Z",
"lv": "M 5191 1938 L 5223 1926 5295 1926 5339 1954 5379 1934 5371 1890 5347 1878 5335 1882 5303 1862 5279 1870 5279 1894 5259 1906 5231 1874 5199 1894 Z",
"ly": "M 5299 2730 L 5299 3002 5299 3058 5271 3058 5271 3070 5059 2962 5035 2973 5015 2986 4995 2970 4955 2958 4887 2886 4887 2770 4911 2754 4903 2734 4943 2706 4943 2686 5039 2710 5051 2734 5143 2770 5171 2742 5163 2726 5211 2690 5247 2702 5251 2714 5295 2722 Z",
"ma": "M 4583 2630 L 4607 2714 4539 2726 4539 2742 4411 2814 4411 2842 4295 2842 4375 2794 4383 2734 4415 2686 4459 2662 4483 2610 4499 2606 4507 2622 Z",
"mc": "M 4823 2370 L 4824 2368 4824 2370 Z",
"md": "M 5343 2210 L 5383 2266 5375 2282 5387 2314 5419 2310 5439 2282 5427 2270 5403 2222 5363 2206 Z",
"me": "M 5175 2386 L 5167 2398 5147 2422 5123 2402 5143 2370 Z",
"mg": "M 5827 4274 L 5875 4258 5967 3994 5935 3902 5875 3990 5807 4018 5791 4050 5807 4118 5779 4166 5787 4218 5803 4262 Z",
"mk": "M 5227 2406 L 5239 2418 5243 2438 5191 2454 5179 2442 5183 2418 Z",
"ml": "M 4507 2918 L 4467 2918 4491 3150 4499 3158 4495 3178 4359 3178 4351 3190 4335 3174 4319 3202 4339 3257 4343 3274 4395 3266 4431 3318 4455 3322 4475 3310 4479 3322 4495 3314 4499 3278 4563 3218 4583 3214 4587 3206 4615 3194 4645 3194 4665 3194 4675 3182 4731 3182 4751 3154 4751 3082 4723 3082 4667 3026 Z",
"mm": "M 7059 3030 L 7071 3022 7071 3002 7087 2994 7091 2946 7111 2950 7139 2874 7175 2854 7191 2862 7183 2850 7195 2838 7195 2826 7207 2818 7231 2846 7231 2894 7203 2926 7203 2946 7235 2942 7239 2970 7255 2974 7243 2998 7267 3002 7271 3018 7295 3014 7267 3046 7215 3066 7199 3098 7207 3118 7235 3154 7227 3166 7227 3182 7219 3186 7227 3210 7247 3226 7243 3242 7255 3278 7227 3326 7227 3302 7231 3282 7231 3258 7187 3130 7179 3150 7147 3174 7115 3162 7123 3122 7107 3086 7095 3074 7099 3066 7079 3054 Z",
"mn": "M 6947 2182 L 6951 2202 7007 2226 7031 2286 7019 2302 7027 2314 7087 2322 7139 2342 7175 2394 7287 2394 7399 2430 7455 2406 7515 2402 7579 2362 7567 2342 7583 2318 7627 2326 7723 2270 7783 2270 7791 2258 7755 2222 7683 2234 7675 2218 7703 2158 7639 2146 7547 2182 7403 2138 7363 2150 7327 2134 7323 2106 7239 2082 7207 2122 7219 2138 7211 2154 7195 2162 7127 2154 7115 2134 7063 2126 Z",
"mq": "M 3031 3194 L 3040 3197 3041 3206 3035 3204 Z",
"mr": "M 4195 3022 L 4295 3022 4295 2974 4323 2962 4323 2890 4411 2890 4411 2854 4507 2918 4467 2918 4491 3150 4499 3158 4495 3178 4359 3178 4351 3190 4335 3174 4319 3202 4263 3146 4207 3158 4219 3118 4207 3074 4215 3050 Z",
"ms": "M 3004 3142 L 3007 3142 3006 3145 Z",
"mt": "M 5013 2597 L 5023 2603 5018 2606 Z",
"mw": "M 5503 3830 L 5535 3842 5559 3894 5555 3950 5583 3974 5579 4014 5563 4026 5567 4042 5539 4006 5547 3990 5543 3970 5523 3974 5511 3958 5523 3866 Z",
"mx": "M 2087 2890 L 2039 2878 1975 2782 1951 2778 1931 2806 1843 2726 1799 2726 1799 2738 1723 2738 1627 2702 1563 2702 1599 2782 1647 2822 1639 2842 1615 2838 1691 2890 1691 2922 1755 2974 1767 2962 1627 2766 1627 2722 1663 2738 1691 2806 1875 3014 1867 3046 1919 3102 2103 3174 2139 3158 2163 3162 2215 3202 2231 3162 2263 3162 2239 3130 2251 3130 2251 3114 2299 3114 2319 3094 2335 3098 2355 3010 2267 3026 2255 3074 2227 3094 2155 3106 2143 3090 2123 3090 2067 2994 Z",
"my": "M 7271 3422 L 7275 3418 7295 3426 7295 3442 7315 3438 7323 3426 7355 3458 7355 3514 7363 3522 7379 3550 7363 3550 7359 3554 7299 3514 7299 3502 7283 3486 Z M 7519 3538 L 7543 3566 7583 3562 7591 3550 7623 3558 7647 3550 7679 3478 7735 3482 7755 3474 7743 3458 7771 3450 7711 3402 7663 3458 7671 3474 7655 3462 7655 3478 7651 3482 7639 3470 7607 3506 7567 3518 7555 3550 Z",
"mz": "M 5703 3866 L 5623 3894 5559 3894 5555 3950 5583 3974 5579 4014 5563 4026 5567 4042 5539 4006 5547 3990 5543 3970 5523 3974 5511 3958 5435 3986 5439 4002 5439 4010 5503 4030 5503 4126 5463 4186 5479 4286 5483 4310 5503 4310 5503 4290 5495 4286 5575 4226 5571 4178 5551 4130 5615 4058 5687 4022 5711 3978 Z",
"na": "M 5163 4254 L 5163 4174 5191 4174 5191 4074 5251 4066 5259 4078 5299 4058 5279 4050 5255 4058 5187 4066 5139 4062 5123 4050 5007 4050 4983 4038 4947 4046 5019 4202 5031 4298 5071 4362 5087 4342 5099 4362 5147 4370 5163 4354 Z",
"nc": "M 8945 4124 L 8983 4144 9025 4185 8974 4158 Z",
"ne": "M 4735 3278 L 4711 3258 4703 3274 4644 3194 4665 3194 4675 3182 4731 3182 4751 3154 4751 3082 4795 3074 4831 3034 4955 2958 4995 2970 5015 2986 5035 2974 5059 3046 5047 3138 4995 3206 4995 3226 4967 3242 4923 3234 4891 3250 4847 3234 4823 3246 4759 3222 Z",
"ng": "M 4863 3462 L 4915 3402 4939 3418 5007 3290 5023 3282 5019 3262 5011 3262 5011 3242 4995 3226 4967 3242 4923 3234 4891 3250 4847 3234 4823 3246 4759 3222 4735 3278 4731 3286 4739 3314 4719 3350 4711 3350 4711 3418 4755 3418 4799 3474 Z",
"ni": "M 2347 3246 L 2411 3194 2455 3190 2435 3286 2443 3302 2435 3306 2411 3294 2411 3290 2399 3274 2383 3270 2391 3290 2387 3294 2339 3250 Z",
"nl": "M 4795 2114 L 4803 2102 4795 2090 4819 2086 4827 2042 4819 2034 4787 2038 4767 2050 4759 2074 4727 2106 4771 2102 Z",
"no": "M 4931 1826 L 4947 1826 4951 1794 4967 1786 4963 1750 4979 1734 4959 1718 4955 1658 4979 1622 5007 1626 5011 1606 4999 1602 5019 1534 5035 1534 5067 1494 5063 1478 5095 1450 5107 1454 5115 1430 5163 1438 5167 1406 5183 1406 5199 1390 5239 1422 5271 1414 5295 1426 5335 1362 5371 1358 5403 1374 5411 1382 5399 1402 5451 1370 5395 1354 5431 1358 5455 1342 5395 1318 5375 1334 5387 1314 5355 1314 5335 1342 5339 1314 5299 1350 5319 1310 5287 1314 5247 1358 5243 1346 5135 1362 4883 1646 4779 1702 4767 1746 4787 1846 4827 1866 4855 1862 4919 1810 Z",
"np": "M 6955 2838 L 6951 2878 6883 2870 6863 2862 6863 2854 6847 2850 6827 2854 6739 2806 6767 2770 6795 2770 6895 2830 Z",
"nz": "M 9179 4530 L 9231 4630 9223 4666 9203 4678 9243 4706 9231 4738 9247 4750 9331 4630 9299 4634 9259 4622 Z M 9175 4714 L 9187 4738 9219 4734 9215 4758 9175 4810 9183 4822 9139 4834 9095 4910 9011 4894 9023 4866 9127 4790 9143 4754 9159 4742 9159 4726 Z",
"om": "M 6115 2890 L 6119 2882 6123 2882 6119 2902 Z M 6119 2922 L 6107 2922 6107 2946 6099 2946 6087 2986 6103 3002 6083 3058 6003 3086 6035 3150 6159 3086 6211 2986 Z",
"pa": "M 2467 3334 L 2459 3370 2491 3374 2515 3398 2539 3390 2527 3370 2555 3350 2583 3366 2579 3374 2595 3398 2611 3378 2607 3358 2575 3338 2547 3334 2507 3358 Z",
"pe": "M 2531 3678 L 2527 3706 2551 3706 2563 3722 2591 3666 2627 3654 2663 3614 2663 3590 2703 3618 2719 3650 2755 3646 2799 3658 2783 3686 2803 3698 2779 3698 2727 3722 2719 3758 2695 3786 2747 3854 2787 3838 2787 3878 2815 3878 2835 3918 2819 3998 2803 3994 2803 4010 2823 4018 2827 4030 2815 4050 2791 4074 2635 3958 2639 3946 2539 3766 2507 3738 2507 3698 Z",
"pg": "M 8343 3826 L 8343 3658 8459 3706 8467 3730 8511 3746 8523 3766 8499 3766 8543 3830 8559 3826 8599 3866 8519 3858 8467 3798 8435 3786 8387 3838 Z M 8527 3734 L 8575 3758 8635 3730 8639 3702 8619 3702 8623 3718 8599 3734 Z M 8655 3718 L 8659 3694 8603 3658 8647 3694 Z M 8703 3730 L 8739 3762 8727 3770 8707 3746 Z",
"ph": "M 7814 3092 L 7848 3103 7851 3151 7826 3184 7846 3217 7900 3226 7897 3251 7841 3221 7814 3227 7786 3156 7804 3160 Z M 7801 3231 L 7827 3232 7826 3266 Z M 7873 3273 L 7878 3256 7896 3271 7881 3265 Z M 7841 3274 L 7878 3284 7845 3309 Z M 7854 3329 L 7880 3298 7877 3334 7897 3293 7896 3314 7870 3347 Z M 7902 3257 L 7928 3253 7942 3299 Z M 7920 3285 L 7906 3295 7927 3323 Z M 7902 3318 L 7888 3339 7908 3329 Z M 7777 3285 L 7784 3311 7716 3369 7772 3306 Z M 7937 3318 L 7933 3349 7896 3371 7885 3358 7848 3377 7843 3406 7861 3385 7867 3395 7889 3379 7903 3392 7896 3421 7934 3439 7939 3417 7931 3408 7945 3391 7952 3422 7965 3383 Z M 7837 3414 L 7853 3412 7845 3419 Z",
"pk": "M 6255 2914 L 6263 2882 6299 2874 6299 2854 6239 2782 6279 2794 6323 2794 6383 2778 6383 2750 6431 2726 6447 2730 6459 2722 6467 2690 6487 2682 6475 2662 6499 2662 6507 2654 6503 2646 6523 2626 6511 2598 6523 2586 6555 2574 6583 2578 6607 2566 6635 2582 6639 2606 6683 2618 6631 2646 6591 2638 6579 2650 6603 2706 6619 2710 6599 2726 6599 2746 6527 2834 6499 2842 6491 2834 6467 2862 6471 2874 6483 2874 6487 2898 6495 2898 6507 2934 6431 2950 6415 2950 6387 2906 Z",
"pl": "M 5011 2018 L 5123 1986 5135 2002 5235 1998 5259 2018 5267 2062 5251 2078 5259 2082 5259 2098 5271 2138 5235 2170 5239 2186 5231 2186 5135 2170 5127 2158 5031 2122 5023 2066 5011 2054 5019 2046 Z",
"pr": "M 2875 3098 L 2875 3110 2911 3110 2915 3098 Z",
"pt": "M 4407 2414 L 4475 2430 4447 2494 4443 2566 4403 2570 4407 2526 4391 2522 4411 2442 Z",
"py": "M 2995 4182 L 3019 4110 3087 4102 3115 4122 3115 4178 3175 4182 3187 4230 3215 4230 3207 4274 3199 4306 3175 4326 3099 4322 3127 4270 3047 4226 Z",
"qa": "M 5987 2934 L 5975 2926 5975 2898 5987 2886 5995 2894 5995 2922 Z",
"ro": "M 5239 2222 L 5223 2230 5195 2282 5171 2282 5235 2346 5243 2358 5315 2362 5355 2350 5391 2362 5403 2326 5415 2326 5419 2310 5387 2314 5375 2282 5383 2266 5343 2210 5295 2234 Z",
"rs": "M 5171 2282 L 5235 2346 5227 2358 5243 2378 5227 2406 5183 2418 5167 2398 5175 2386 5143 2370 5143 2322 5135 2294 5151 2282 Z",
"ru": "M 5135 2002 L 5199 1966 5235 1974 5235 1998 Z M 5375 1810 L 5359 1834 5367 1870 5355 1882 5371 1890 5379 1934 5451 1954 5451 1986 5499 2034 5467 2042 5475 2082 5527 2070 5539 2110 5559 2110 5575 2142 5603 2146 5623 2138 5691 2170 5683 2226 5651 2230 5643 2250 5675 2254 5631 2270 5647 2282 5619 2310 5603 2306 5599 2314 5691 2374 5695 2366 5843 2402 5839 2410 5859 2418 5899 2442 5915 2422 5867 2338 5891 2298 5919 2290 5931 2274 5863 2206 5891 2138 5911 2162 5923 2154 5919 2134 5975 2094 6015 2094 6103 2134 6175 2114 6207 2138 6251 2126 6255 2106 6215 2086 6243 2074 6235 2058 6247 2050 6267 2050 6271 2046 6247 2038 6247 2018 6463 1966 6499 1966 6511 2010 6571 2018 6571 2030 6655 2002 6743 2126 6767 2110 6799 2130 6831 2118 6903 2170 6919 2166 6935 2186 6947 2182 7063 2126 7115 2134 7127 2154 7195 2162 7211 2154 7219 2138 7207 2122 7239 2082 7323 2106 7327 2134 7363 2150 7403 2138 7547 2182 7639 2146 7703 2158 7735 2170 7811 2086 7811 2066 7791 2066 7791 2058 7815 2038 7879 2030 7947 2058 7991 2162 8051 2178 8079 2234 8179 2214 8135 2322 8103 2310 8083 2326 8083 2386 8071 2390 8071 2406 8115 2382 8135 2394 8199 2358 8319 2206 8355 2038 8287 2002 8263 2030 8195 1978 8399 1814 8715 1818 8691 1798 8771 1718 8851 1714 8847 1762 8959 1682 8963 1690 8935 1750 8763 1882 8727 1962 8755 2122 8903 1986 8895 1938 8927 1934 8919 1870 8895 1866 8967 1790 9127 1770 9299 1682 9343 1698 9359 1678 9287 1594 9363 1586 9395 1542 9547 1614 9635 1534 9519 1490 9511 1506 9503 1478 9263 1366 9111 1354 9131 1406 9091 1414 9067 1362 8871 1390 8807 1314 8643 1326 8535 1250 8339 1222 8311 1290 8163 1302 8127 1270 8075 1326 8015 1206 7883 1178 7863 1218 7611 1166 7435 1206 7627 1090 7619 1046 7551 1018 7447 1030 7455 1006 7379 962 7159 1066 6991 1078 6895 1138 6907 1166 6751 1190 6771 1246 6827 1282 6763 1262 6671 1238 6639 1282 6699 1314 6615 1294 6611 1230 6559 1294 6591 1338 6583 1402 6647 1410 6595 1426 6595 1470 6539 1530 6483 1522 6543 1486 6571 1430 6547 1314 6559 1222 6487 1202 6435 1278 6391 1370 6451 1414 6435 1434 6291 1374 6215 1362 6243 1410 6203 1422 6191 1410 6035 1418 5899 1470 5891 1498 5827 1486 5863 1454 5803 1426 5787 1486 5795 1534 5743 1522 5679 1562 5695 1598 5611 1574 5603 1594 5635 1614 5627 1634 5555 1606 5551 1542 5491 1502 5495 1490 5575 1526 5647 1538 5695 1530 5727 1494 5719 1466 5587 1402 5451 1370 5399 1402 5383 1414 5395 1414 5387 1426 5395 1446 5427 1466 5403 1498 5431 1554 5423 1558 5419 1582 5443 1622 5427 1638 5471 1670 5459 1690 5371 1766 5427 1786 5379 1798 Z M 5923 1382 L 5903 1414 5931 1418 5959 1394 Z M 6135 1338 L 5995 1290 6119 1110 6247 1046 6403 1010 6451 1018 6439 1050 6243 1102 6147 1182 6095 1250 6107 1298 6155 1322 Z M 7319 870 L 7251 950 7395 926 Z M 7263 842 L 7259 898 7103 854 Z M 7091 842 L 7191 814 7211 786 7147 762 7039 834 Z M 8367 2034 L 8367 2282 8403 2266 8387 2222 8411 2174 8431 2182 8395 2018 Z",
"rw": "M 5439 3614 L 5427 3626 5419 3622 5399 3650 5399 3662 5447 3650 Z",
"sa": "M 5911 2818 L 5891 2818 5887 2806 5863 2802 5815 2802 5743 2742 5671 2714 5611 2734 5639 2762 5587 2802 5559 2798 5547 2830 5559 2830 5627 2938 5651 2954 5667 2994 5663 3002 5687 3050 5707 3062 5763 3154 5775 3146 5775 3130 5783 3126 5867 3134 5879 3142 5903 3110 6003 3086 6083 3058 6103 3002 6087 2986 6023 2978 5995 2942 5987 2934 5975 2926 5955 2894 5951 2866 5923 2846 Z",
"sb": "M 8749 3763 L 8766 3771 8777 3784 Z M 8800 3786 L 8838 3805 8833 3811 Z M 8833 3829 L 8852 3835 8862 3847 8841 3846 Z M 8857 3807 L 8864 3807 8880 3842 8862 3826 Z M 8877 3853 L 8899 3863 8896 3874 Z M 8762 3795 L 8777 3799 8793 3819 8771 3811 Z",
"sd": "M 5243 3298 L 5215 3246 5247 3170 5271 3170 5271 3070 5271 3058 5299 3058 5299 3002 5511 3002 5531 3010 5575 2970 5607 2998 5623 3090 5651 3110 5611 3138 5599 3210 5555 3306 5543 3302 5531 3366 5511 3366 5507 3382 5579 3446 5583 3466 5543 3466 5531 3478 5519 3490 5451 3494 5359 3454 Z",
"se": "M 4931 1826 L 4979 1922 4967 1934 4983 1966 5015 1958 5023 1938 5063 1934 5083 1842 5139 1798 5111 1766 5095 1758 5091 1722 5127 1666 5207 1606 5195 1590 5227 1546 5271 1550 5259 1454 5183 1406 5167 1406 5163 1438 5115 1430 5107 1454 5095 1450 5063 1478 5067 1494 5035 1534 5019 1534 4999 1602 5011 1606 5007 1626 4979 1622 4955 1658 4959 1718 4979 1734 4963 1750 4967 1786 4951 1794 4947 1826 Z",
"sg": "M 7363 3550 L 7359 3554 7367 3558 7371 3550 Z",
"si": "M 4995 2294 L 4999 2270 5023 2274 5067 2258 5071 2270 5051 2286 5043 2306 4999 2306 Z",
"sk": "M 5135 2170 L 5231 2186 5223 2210 5179 2206 5135 2222 5135 2226 5103 2230 5087 2222 5087 2198 Z",
"sl": "M 4339 3406 L 4371 3362 4359 3366 4363 3358 4347 3326 4315 3326 4291 3350 4295 3370 4311 3390 Z",
"sn": "M 4199 3262 L 4239 3254 4279 3254 4339 3258 4319 3202 4263 3146 4207 3158 4203 3174 4183 3198 4203 3230 4247 3222 4279 3234 4267 3238 4243 3230 4199 3242 Z",
"so": "M 5739 3482 L 5795 3458 5823 3458 5899 3378 5871 3378 5791 3346 5759 3306 5767 3298 5775 3286 5803 3314 5819 3314 5979 3274 5987 3310 5927 3418 5899 3470 5847 3526 5779 3574 5731 3630 5715 3610 5715 3514 Z",
"sr": "M 3139 3434 L 3115 3478 3155 3538 3207 3526 3223 3494 3207 3458 3223 3434 Z",
"sv": "M 2291 3206 L 2335 3222 2331 3238 2271 3222 Z",
"sy": "M 5583 2602 L 5595 2602 5603 2578 5659 2578 5755 2566 5735 2586 5727 2586 5715 2650 5659 2678 5607 2710 5575 2698 5575 2682 5599 2654 5591 2642 5583 2642 Z",
"sz": "M 5479 4286 L 5463 4278 5447 4298 5459 4322 5479 4322 5483 4310 Z",
"td": "M 5035 2974 L 5059 2962 5271 3070 5271 3170 5247 3170 5215 3246 5243 3298 5127 3374 5047 3386 5007 3330 5015 3322 5047 3322 5035 3294 5039 3270 5019 3242 5011 3242 4995 3226 4995 3206 5047 3138 5059 3046 Z",
"tf": "M 6451 4978 L 6471 4994 6491 4990 6483 5014 6447 5010 Z",
"tg": "M 4687 3422 L 4679 3326 4659 3314 4663 3298 4643 3294 4635 3306 4651 3318 4655 3410 4671 3426 Z",
"th": "M 7339 3274 L 7327 3234 7351 3210 7403 3210 7411 3206 7411 3190 7415 3174 7391 3150 7391 3130 7355 3098 7335 3118 7323 3106 7295 3126 7291 3122 7299 3070 7279 3070 7279 3054 7267 3046 7215 3066 7199 3098 7207 3118 7235 3154 7227 3166 7227 3182 7219 3186 7227 3210 7247 3226 7243 3242 7255 3278 7227 3326 7223 3386 7231 3370 7271 3422 7275 3418 7295 3426 7295 3442 7315 3438 7323 3426 7303 3406 7291 3410 7279 3398 7263 3346 7247 3346 7243 3322 7267 3270 7267 3234 7291 3234 7287 3254 7319 3258 Z",
"tj": "M 6459 2566 L 6419 2566 6435 2538 6431 2514 6407 2502 6415 2490 6439 2490 6491 2446 6499 2454 6487 2466 6503 2474 6495 2482 6479 2474 6459 2486 6463 2494 6499 2498 6575 2494 6583 2522 6603 2526 6607 2566 6591 2558 6555 2562 6523 2582 6515 2566 6519 2542 6511 2542 6511 2530 6499 2526 Z",
"tl": "M 7919 3826 L 7927 3818 7979 3810 7983 3814 7923 3838 Z",
"tm": "M 6055 2562 L 6123 2530 6247 2582 6251 2614 6283 2626 6367 2554 6387 2562 6387 2542 6279 2478 6255 2438 6219 2434 6215 2406 6171 2394 6135 2422 6139 2438 6111 2438 6099 2442 6067 2406 6035 2410 6019 2426 6027 2438 6027 2422 6035 2414 6055 2414 6075 2446 6051 2462 6035 2454 6027 2442 6023 2478 6043 2482 6043 2494 6035 2498 6047 2502 Z",
"tn": "M 4943 2686 L 4943 2706 4903 2734 4911 2754 4887 2770 4879 2718 4835 2666 4859 2626 4863 2574 4899 2562 4915 2578 4931 2570 4915 2598 4931 2626 4903 2658 Z",
"to": "M 9489 4149 L 9498 4151 9493 4155 Z",
"tr": "M 5375 2418 L 5331 2426 5327 2458 5343 2462 5367 2446 5403 2450 5411 2458 5367 2470 5355 2466 5339 2466 5327 2482 5327 2494 5343 2502 5347 2530 5335 2530 5367 2562 5363 2570 5423 2598 5439 2590 5443 2574 5483 2586 5499 2602 5527 2598 5555 2578 5571 2586 5583 2574 5591 2582 5579 2590 5583 2602 5595 2602 5603 2578 5659 2578 5755 2566 5815 2566 5799 2498 5811 2486 5787 2478 5783 2442 5759 2430 5731 2430 5695 2450 5647 2450 5595 2442 5559 2414 5515 2418 5463 2438 5459 2446 5403 2442 5379 2430 Z",
"tt": "M 3016 3320 L 3025 3316 3021 3304 3039 3301 3036 3321 Z M 3041 3292 L 3048 3288 3049 3291 Z",
"tw": "M 7819 2918 L 7843 2918 7815 3006 7791 2978 7795 2954 Z",
"tz": "M 5671 3710 L 5627 3678 5631 3670 5534 3613 5515 3637 5527 3646 5519 3654 5475 3654 5475 3614 5439 3614 5447 3650 5451 3674 5419 3706 5427 3742 5423 3754 5435 3762 5459 3814 5503 3830 5535 3842 5559 3894 5623 3894 5703 3866 5683 3850 5671 3806 5679 3770 5659 3746 Z",
"ua": "M 5475 2082 L 5455 2082 5443 2106 5303 2086 5259 2098 5271 2138 5235 2170 5239 2186 5231 2186 5223 2210 5239 2222 5295 2234 5343 2210 5363 2206 5403 2222 5427 2270 5439 2282 5447 2270 5523 2290 5495 2306 5519 2314 5519 2334 5535 2338 5595 2318 5599 2306 5571 2310 5547 2294 5567 2274 5643 2250 5651 2230 5683 2226 5691 2170 5623 2138 5603 2146 5575 2142 5559 2110 5539 2110 5527 2070 Z",
"ug": "M 5451 3494 L 5519 3490 5531 3478 5563 3534 5531 3582 5515 3578 5479 3590 5475 3614 5439 3614 5427 3626 5419 3622 5419 3586 5463 3530 5447 3522 Z",
"us": "M 1563 2702 L 1627 2702 1723 2738 1799 2738 1799 2726 1843 2726 1931 2806 1951 2778 1975 2782 2039 2878 2087 2890 2079 2850 2159 2786 2235 2786 2259 2806 2307 2766 2379 2766 2403 2786 2431 2770 2471 2810 2463 2834 2507 2910 2531 2910 2539 2870 2499 2758 2511 2722 2655 2606 2635 2542 2647 2554 2695 2486 2699 2462 2791 2422 2779 2390 2795 2358 2883 2322 2859 2294 2859 2250 2823 2238 2759 2318 2671 2318 2643 2338 2635 2366 2623 2374 2563 2374 2567 2386 2559 2398 2491 2430 2459 2430 2451 2418 2475 2382 2463 2350 2439 2362 2451 2314 2415 2294 2375 2330 2367 2366 2375 2386 2359 2422 2343 2426 2331 2378 2363 2294 2399 2282 2411 2286 2443 2286 2419 2270 2407 2262 2351 2274 2319 2250 2323 2238 2295 2254 2223 2262 2283 2218 2143 2186 1415 2186 1415 2214 1363 2210 1383 2282 1383 2334 1367 2390 1383 2438 1371 2466 1475 2642 1539 2666 Z M 1215 1986 L 1227 1938 1079 1798 1031 1830 935 1770 935 1374 523 1298 275 1410 267 1434 411 1522 391 1538 335 1534 335 1510 227 1554 279 1598 363 1598 407 1586 415 1634 351 1666 323 1654 279 1718 307 1750 291 1766 347 1798 375 1782 391 1806 387 1838 431 1826 463 1846 515 1830 499 1882 307 1990 319 1998 455 1942 615 1830 591 1818 667 1742 651 1818 755 1786 759 1754 787 1750 863 1786 955 1798 963 1794 971 1806 1047 1854 1103 1930 1115 1914 1155 1986 1179 1978 Z",
"uy": "M 3235 4510 L 3231 4494 3243 4478 3147 4402 3127 4406 3103 4514 3163 4542 3219 4538 Z",
"uz": "M 6419 2566 L 6387 2562 6387 2542 6279 2478 6255 2438 6219 2434 6215 2406 6171 2394 6135 2422 6139 2438 6111 2438 6111 2322 6179 2302 6243 2342 6267 2370 6343 2362 6367 2390 6375 2386 6375 2418 6387 2418 6395 2442 6419 2442 6439 2458 6451 2438 6503 2410 6511 2414 6487 2430 6515 2442 6523 2434 6559 2454 6523 2478 6503 2474 6487 2466 6499 2454 6491 2446 6439 2490 6415 2490 6407 2502 6431 2514 6435 2538 Z",
"vc": "M 3031 3234 L 3034 3236 3032 3242 3029 3238 Z",
"ve": "M 2751 3282 L 2711 3346 2759 3402 2799 3402 2815 3426 2867 3422 2855 3470 2871 3498 2859 3510 2875 3526 2883 3558 2907 3570 2975 3526 2959 3522 2939 3478 2987 3494 3047 3458 3047 3450 3027 3430 3055 3402 3043 3390 3071 3366 3043 3358 3039 3338 2991 3306 2935 3322 2903 3306 2855 3310 2819 3282 2763 3302 2775 3338 2759 3346 2743 3330 2759 3306 Z",
"vn": "M 7475 3018 L 7443 3002 7443 2982 7407 2966 7347 2990 7331 2982 7323 2990 7343 3010 7343 3022 7363 3038 7375 3030 7399 3054 7371 3074 7403 3094 7399 3098 7463 3166 7455 3170 7467 3186 7463 3202 7463 3262 7419 3282 7427 3306 7415 3298 7383 3314 7399 3326 7391 3366 7503 3290 7515 3250 7499 3186 7411 3086 7423 3058 Z",
"vu": "M 9015 3976 L 9019 4002 9032 4000 Z M 9031 4008 L 9038 4026 9047 4022 Z",
"wa": "M 9556 3944 L 9568 3942 9571 3951 9563 3951 Z M 9575 3953 L 9582 3952 9590 3959 Z",
"wf": "M 9415 3964 L 9420 3967 9417 3967 Z",
"ye": "M 5763 3154 L 5775 3146 5775 3130 5783 3126 5867 3134 5879 3142 5903 3110 6003 3086 6035 3150 6011 3162 6011 3174 5787 3258 Z",
"za": "M 5503 4310 L 5483 4310 5479 4322 5459 4322 5447 4298 5463 4278 5479 4286 5463 4186 5411 4178 5347 4222 5311 4278 5247 4266 5211 4310 5183 4310 5179 4298 5187 4290 5163 4254 5163 4354 5147 4370 5099 4362 5087 4342 5071 4362 5123 4474 5111 4482 5163 4542 5215 4526 5315 4518 5423 4442 5491 4358 Z",
"ls": "M 5375 4418 L 5415 4382 5391 4358 5351 4390 Z",
"zm": "M 5255 4058 L 5215 4014 5215 3930 5271 3930 5271 3878 5279 3878 5283 3890 5303 3886 5307 3894 5347 3906 5351 3894 5407 3942 5423 3942 5423 3910 5403 3914 5383 3890 5391 3870 5387 3834 5399 3814 5443 3802 5439 3810 5455 3818 5459 3814 5503 3830 5523 3866 5511 3958 5435 3986 5439 4002 5399 4010 5395 4026 5351 4062 5299 4058 5279 4050 Z",
"zw": "M 5463 4186 L 5503 4126 5503 4030 5439 4010 5439 4002 5399 4010 5395 4026 5351 4062 5299 4058 5375 4162 5411 4178 Z"
};

171
teamspeak.py

@ -0,0 +1,171 @@
import operator
import os
import ts3
import time
import requests
from xml.etree import ElementTree
from flask import url_for
from bs4 import BeautifulSoup
from app import app
from models import TeamspeakData
def getTeamspeakWindow(window=605800):
current_time = time.time()
return TeamspeakData.query.filter(TeamspeakData.time < current_time, TeamspeakData.time > current_time-window).order_by(TeamspeakData.time).all()
def create_teamspeak_viewer():
try:
server = ts3.TS3Server(app.config['TS3_HOST'], app.config['TS3_PORT'])
server.login(app.config['TS3_USERNAME'], app.config['TS3_PASSWORD'])
server.use(1)
serverinfo = server.send_command('serverinfo').data
channellist = server.send_command('channellist', opts=("limits", "flags", "voice", "icon")).data
clientlist = server.send_command('clientlist', opts=("away", "voice", "info", "icon", "groups", "country")).data
servergrouplist = server.send_command('servergrouplist').data
channelgrouplist = server.send_command('channelgrouplist').data
soup = BeautifulSoup()
div_tag = soup.new_tag('div')
div_tag['class'] ='devmx-webviewer'
soup.append(div_tag)
def construct_channels(parent_tag, cid):
num_clients = 0
for channel in channellist:
if int(channel['pid']) == int(cid):
# Construct the channel
channel_tag = soup.new_tag('div')
channel_tag['class'] = 'tswv-channel'
# Channel image
image_tag = soup.new_tag('span')
image_tag['class'] = 'tswv-image tswv-image-right'
if int(channel['channel_flag_password']) == 1:
image_tag['class'] += ' tswv-channel-password-right'
if int(channel['channel_flag_default']) == 1:
image_tag['class'] += ' tswv-channel-home'
if int(channel['channel_needed_talk_power']) > 0:
image_tag['class'] += ' tswv-channel-moderated'
if int(channel['channel_icon_id']) != 0:
pass
image_tag.append(' ')
channel_tag.append(image_tag)
# Status image
status_tag = soup.new_tag('span')
status_tag['class'] = 'tswv-image'
if int(channel['channel_flag_password']) == 1:
status_tag['class'] += ' tswv-channel-password'
elif int(channel['total_clients']) == int(channel['channel_maxclients']):
status_tag['class'] += ' tswv-channel-full'
else:
status_tag['class'] += ' tswv-channel-normal'
status_tag.append(' ')
channel_tag.append(status_tag)
# Label
label_tag = soup.new_tag('span')
label_tag['class'] = 'tswv-label'
label_tag.append(channel['channel_name'])
channel_tag.append(label_tag)
# Clients
channel_tag, channel_clients = construct_clients(channel_tag, channel['cid'])
# Recurse through sub-channels, collecting total number of clients as we go
channel_tag, sub_clients = construct_channels(channel_tag, channel['cid'])
channel_clients += sub_clients
# Only show non-empty channels
if channel_clients > 0:
parent_tag.append(channel_tag)
num_clients += channel_clients
return parent_tag, num_clients
def construct_clients(parent_tag, cid):
num_clients = 0
for client in clientlist:
if int(client['cid']) == int(cid):
# Skip ServerQuery clients
if int(client['client_type']) == 1: continue
num_clients += 1
client_tag = soup.new_tag('div')
client_tag['class'] = 'tswv-client'
# Status image
status_tag = soup.new_tag('span')
status_tag['class'] = 'tswv-image'
if int(client['client_type']) == 1:
status_tag['class'] += ' tswv-client-query'
elif int(client['client_away']) == 1:
status_tag['class'] += " tswv-client-away"
elif int(client['client_input_muted']) == 1:
status_tag['class'] += " tswv-client-input-muted"
elif int(client['client_output_muted']) == 1:
status_tag['class'] += " tswv-client-output-muted"
elif int(client['client_input_hardware']) == 0:
status_tag['class'] += " tswv-client-input-muted-hardware"
elif int(client['client_output_hardware']) == 0:
status_tag['class'] += " tswv-client-output-muted-hardware"
elif (int(client['client_flag_talking']) == 1) and (int(client['client_is_channel_commander']) == 1):
status_tag['class'] += " tswv-client-channel-commander-talking"
elif int(client['client_is_channel_commander']) == 1:
status_tag['class'] += " tswv-client-channel-commander"
elif int(client['client_flag_talking']) == 1:
status_tag['class'] += " tswv-client-talking"
else:
status_tag['class'] += " tswv-client-normal"
status_tag.append(' ')
client_tag.append(status_tag)
# Country image
if client['client_country']:
country_tag = soup.new_tag('span')
country_tag['class'] = 'tswv-image tswv-image-right'
country_tag['title'] = ' '.join([word.capitalize() for word in ISO3166_MAPPING[client['client_country']].split(' ')])
country_tag['style'] = 'background: url("%s") center center no-repeat;' % url_for('static', filename='img/ts3_viewer/countries/%s.png' % client['client_country'].lower())
country_tag.append(' ')
client_tag.append(country_tag)
# Server group images
sgids = [int(sg) for sg in client['client_servergroups'].split(',')]
servergroups = [servergroup for servergroup in servergrouplist if int(servergroup['sgid']) in sgids]
servergroups.sort(key=operator.itemgetter('sortid'))
for servergroup in servergroups:
if not servergroup['iconid']: continue
img_fname = 'img/ts3_viewer/%s.png' % servergroup['iconid']
if not os.path.exists(os.path.join(app.static_folder, img_fname)):
continue
image_tag = soup.new_tag('span')
image_tag['class'] = 'tswv-image tswv-image-right'
image_tag['title'] = servergroup['name']
image_tag['style'] = 'background-image: url("%s")' % url_for('static', filename=img_fname)
image_tag.append(' ')
client_tag.append(image_tag)
# Check if client is in a moderated channel
channel = [channel for channel in channellist if int(channel['cid']) == int(client['cid'])][0]
if int(channel['channel_needed_talk_power']) > 0:
status_tag = soup.new_tag('span')
status_tag['class'] = 'tswv-image tswv-image-right'
if int(client['client_is_talker']) == 0:
status_tag['class'] += ' tswv-client-input-muted'
else:
status_tag['class'] += ' tswv-client-talkpower-granted'
status_tag.append(' ')
client_tag.append(status_tag)
# Label
label_tag = soup.new_tag('span')
label_tag['class'] = 'tswv-label'
label_tag.append(client['client_nickname'])
client_tag.append(label_tag)
parent_tag.append(client_tag)
return parent_tag, num_clients
div_tag, num_clients = construct_channels(div_tag, 0)
return (soup.prettify(), num_clients)
except Exception as inst:
return "error: %s" % inst
def get_ISO3166_mapping():
data = requests.get('http://www.iso.org/iso/home/standards/country_codes/country_names_and_code_elements_xml.html')
xml = ElementTree.fromstring(data.text.encode('utf-8'))
d = dict()
for entry in xml.findall('ISO_3166-1_Entry'):
d[entry.find('ISO_3166-1_Alpha-2_Code_element').text] = entry.find('ISO_3166-1_Country_name').text
return d
ISO3166_MAPPING = get_ISO3166_mapping()

30
templates/index.html

@ -1,12 +1,15 @@
{% extends "layout.html" %}
{% block head %} <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/ts3_viewer.css') }}"> {% endblock %}
{% block title %}Dota Noobs{% endblock %}
{% block content %}
{% cache 60*5 %}
{% set teamspeak_data = get_teamspeak_window() %}
<div class="uk-grid" data-uk-grid-margin>
<div class="uk-width-large-1-2 uk-width-medium-1-1">
<div class=" uk-panel uk-panel-space uk-panel-box">
<div class=" uk-panel uk-panel-space">
<h1 class="uk-panel-title">Who Are The Doobs!?</h1>
<p>Welcome to DotaNoobs! We are a community formed by a group of redditors in an effort to provide a fun and rage-free environment for Dota2 players of all skill levels to enjoy the game and learn from each other. We have a TeamSpeak server open to the public for voice communication; hopping into the server is the best way to get involved, so click on "Server" to the right to get started. </p>
<div id="about-us-more">
@ -22,8 +25,8 @@
<a href="ts3server://voice.dotanoobs.com"><div class="uk-panel-badge uk-badge uk-badge-success"><i class="uk-icon-microphone"> Connect to Teamspeak</i></div></a>
<h1 class="uk-panel-title">Our TeamSpeak Server</h1>
<ul>
<li>Current Users: {# active_doobs #}</li>
<li>Unique Clients This Month: {# num_unique_clients(teamspeak_data) #}</li>
<li>Current Users: {{ ts3_current_clients() }}</li>
<li>Active Countries: {{ ts3_countries_active(teamspeak_data) }}</li>
</ul>
<button class="uk-button" data-uk-modal="{target:'#tsviewer'}">Viewer</button>
<a class="uk-button" href="{{ url_for('teamspeak') }}">Statistics</a>
@ -55,7 +58,7 @@
<div id="tsviewer" class="uk-modal">
<div class="uk-modal-dialog">
<a class="uk-modal-close uk-close"></a>
{# ts3_viewer() | safe #}
{{ ts3_viewer() | safe }}
</div>
</div>
</div>
@ -74,11 +77,11 @@
{% endfor %}
</div>
</div>
{#
<div class="uk-hidden-large uk-width-medium-1-1">
<div class="uk-panel uk-panel-space uk-panel-box uk-panel-header">
<a href="{{ url_for('list_events') }}"><div class="uk-panel-badge uk-badge uk-badge-success"><i class="uk-icon-calendar"> View All Events</i></div></a>
<h1 class="uk-panel-title">Events</h1>
{#
{% if active_event %}
<article class="uk-article">
<h4>Right Now</h4>
@ -95,12 +98,12 @@
{% else %}
<em>No events planned for the near future. Suggest one on the forum!</em>
{% endif %}
#}
<em>No events planned for the near future. Suggest one on the forum!</em>
</div>
</div>
#}
<div class="uk-width-large-1-3 uk-width-medium-1-1">
<div class="uk-panel uk-panel-space uk-panel-box uk-panel-header">
<div class="uk-panel uk-panel-space">
<h1 class="uk-panel-title">Live Streams</h1>
<ul id="streams-online"></ul>
<hr id="stream-divider" class="uk-article-divider" style="display:none;" />
@ -109,12 +112,13 @@
</div>
</div>
</div>
{% endcache %}
{% endblock %}
{% block pagescripts %}
<script>
$(document).ready(function() {
{% cache 60*5 %}
// Add the streams
var stream_url = "https://api.twitch.tv/kraken/streams/";
var channels = ["dotanoobs", "bearhugdota", "kreejaffakree", "prettypenguins", "shaneomad"];
@ -124,10 +128,10 @@ $(document).ready(function() {
$('#streams-online').append("<article class='uk-article' id='" + data.stream.channel.name + "'>");
var jquery_selector = '#'+data.stream.channel.name;
$(jquery_selector).append("<a href='"+data.stream.channel.url+"'><h4>" + data.stream.channel.display_name + "</h4></a>")
var span_text = "<p class='uk-article-meta'>";
var span_text = "<span class='uk-article-meta'>";
span_text = span_text + "Playing: " + data.stream.game + "<br />";
span_text = span_text + "Viewers: " + data.stream.viewers + "<br />";
span_text = span_text + "</p>";
span_text = span_text + "</span>";
$(jquery_selector).append(span_text);
$(jquery_selector).append("<img src='" + data.stream.preview.medium + "' />")
$('#streams-online').append("</article>");
@ -136,13 +140,14 @@ $(document).ready(function() {
$.getJSON(data._links.channel+"?callback=?", function(data) {
$('#streams-offline').append("<article class='uk-article' id='" + data.name + "'>");
$('#'+data.name).append("<a href='"+data.url+"'><h4>" + data.display_name + "</h4></a>");
$('#'+data.name).append("<img src='" + data.logo + "' style='float: right;' width='62' height='62' /><br />");
//$('#'+data.name).append("<img src='" + data.logo + "' style='float: right;' width='62' height='62' /><br />");
$('#'+data.name).append("<p class='uk-article-meta'><strong>Offline</strong></p>");
$('#streams-offline').append("</div>");
});
}
});
}
{% endcache %}
// Localize the events
$('.date').each( function( index ) {
@ -159,5 +164,4 @@ $(document).ready(function() {
});
</script>
{% endblock %}

32
templates/profile.html

@ -0,0 +1,32 @@
{% extends "layout.html" %}
{% block title %}Profile - {{ user.nickname }}{% endblock %}
{% block content %}
<div class="uk-grid" data-uk-grid-margin>
<div class="uk-width-1-1 uk-panel">
<img class="uk-align-center" src="{{ user.avatar }}" />
<h2 class="uk-panel-title uk-text-center">Profile for {{ user.nickname }}</h2>
</div>
<!--Main content area -->
<div class="uk-width-large-2-3 uk-width-medium-1-1 uk-panel">
<div class="uk-panel">
main content area
</div>
</div>
<!-- Side bar -->
<div class="uk-width-large-1-3 uk-width-medium-1-1 uk-panel uk-panel-box">
<ul>
<li>Points [value]</li>
<li><a href="http://board.dotanoobs.com/?page=profile&id={{ user.id | safe }}">Forum Profile</a>
<li>Last seen on TeamSpeak: [value]<li>
</ul>
<hr class="uk-panel-divider" />
<div class="uk-container-center uk-text-center">
Randomstats
<span>Current Hero</span>
Heroimg
</div>
</div>
</div>
{% endblock %}

6
templates/sidenav.html

@ -15,11 +15,11 @@
<li><a href="http://www.youtube.com/user/DotaNoobsVods"><i class="uk-icon-youtube"> YouTube</i></a></li>
<li><a href="http://webchat.oftc.net/?channels=dotanoobs&uio=d4"><i class="uk-icon-comments-alt"> IRC Chat</i></a></li>
<li class="uk-nav-divider"></li>
{% if not g.doob%}
{% if not g.user%}
<li><a href="{{ url_for('login') }}"><i class="uk-icon-off"> Login</i></a></li>
<li><a href="{{ url_for('login') }}"><i class="uk-icon-cog"> Register</i></a></li>
{% else %}
<li {% if request.endpoint == 'doob_summary' %} class='uk-active' {% endif %}><a href="{{ url_for('doob_summary', playerid=g.doob._id) }}"><i class="uk-icon-home"> Profile</i></a></li>
<li><a href="{{ url_for('doob_summary', playerid=g.doob._id) }}"><i class="uk-icon-cog"> Settings</i></a></li>
<li {% if request.endpoint == 'user_profile' %} class='uk-active' {% endif %}><a href="{{ url_for('user_profile', userid=g.user.id) }}"><i class="uk-icon-home"> Profile</i></a></li>
<li><a href="{{ url_for('user_profile', userid=g.user.id) }}"><i class="uk-icon-cog"> Settings</i></a></li>
<li><a href="{{ url_for('logout') }}"><i class="uk-icon-off"> Logout</i></a></li>
{% endif %}

53
templates/teamspeak.html

@ -3,10 +3,6 @@
{% block title %}Dota Noobs - Teamspeak{% endblock %}
{% block head %}
<script src="http://code.highcharts.com/3.0.1/highcharts.js"></script>
<script type="text/javascript" src="http://github.highcharts.com/75c66eb3/modules/map.src.js"></script>
<script type="text/javascript" src="http://github.highcharts.com/75c66eb3/modules/data.src.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/world-map-shapes.js') }}"></script>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/ts3_viewer.css') }}">
{% endblock %}
@ -15,52 +11,41 @@
<div class="uk-grid">
<div class="uk-width-large-1-2 uk-width-medium-1-1">
<h3 class="uk-text-bold uk-text-center">Recent Activity</h3>
<div class="uk-panel uk-panel-box" id="teamspeak_active_users"></div>
<div class="uk-panel uk-panel-box" id="unique_clients"></div>
<div class="uk-panel uk-panel-box" id="teamspeak_map"></div>
<div class="uk-panel">
<ul>
<li>Active users connected: <span id="unique_clients"></span></li>
<li>Total users connected: <span id="current_clients">{{ ts3_current_clients() }}</span></li>
<li>Countries active on server: <span id="country_clients"></span></li>
</div>
<div class="uk-panel" id="teamspeak_active_users"></div>
<div class="uk-panel" id="teamspeak_map"></div>
<div class="uk-panel uk-panel-divider"></div>
</div>
<div class="uk-width-large-1-2 uk-width-medium-1-1">
<h3 class="uk-text-bold uk-text-center">Current Status</h3>
<div class="uk-panel uk-panel-space uk-panel-box uk-text-center">
<h3 class="uk-text-bold uk-text-center">Current Status</h3>
<a class="uk-button uk-button-success" href="ts3server://voice.dotanoobs.com">Connect</a>
<a class="uk-button uk-button-primary" href="http://www.teamspeak.com/download">Download</a>
<div class="uk-panel">
<h5>Server: voice.dotanoobs.com</h5>
<div class="uk-panel uk-text-left">
{{ ts3_viewer() | safe }}
</div>
<h5>Server: voice.dotanoobs.com</h5>
</div>
</div>
</div>
{#
<div>
<div class="panel left" style="margin-left: 5em; width: 45%;">
<h2 style="text-align: center">Last Week's Activity</h2>
<div class="panel vertical" id="teamspeak_active_users"></div>
<div class="panel vertical" id="unique_clients"></div>
<div class="panel vertical" id="teamspeak_map"></div>
</div>
<div class="panel right" style="width: 30%; margin-right: 5em">
<h2>Current Status</h2>
<div class='panel vertical clickable' data-href="ts3server://voice.dotanoobs.com">
<h5>Server: voice.dotanoobs.com</h5>
</div>
<div class='panel vertical'>
{{ ts3_viewer() | safe }}
</div>
</div>
</div>
#}
{% endblock %}
{% block pagescripts %}
{% cache 60*5 %}
{% set teamspeak_data = getTeamspeakWindow() %}
{% set teamspeak_data = get_teamspeak_window() %}
<script src="http://code.highcharts.com/3.0.1/highcharts.js"></script>
<script type="text/javascript" src="http://github.highcharts.com/75c66eb3/modules/map.src.js"></script>
<script type="text/javascript" src="http://github.highcharts.com/75c66eb3/modules/data.src.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/world-map-shapes.js') }}"></script>
<script>
$(document).ready(function() {
$('#unique_clients').html("<h3>Number of unique clients: {{ num_unique_clients(teamspeak_data) }}</h3>");
$('#unique_clients').html("{{ ts3_active_clients(teamspeak_data) }}");
$('#country_clients').html("{{ ts3_countries_active(teamspeak_data) }}");
Highcharts.setOptions({
global: {
useUTC: false
@ -160,7 +145,7 @@ $(document).ready(function() {
}]
};
// Populate the data points
var data = {{ num_unique_clients_by_country(teamspeak_data) | tojson | safe }};
var data = {{ num_unique_clients_by_country(teamspeak_data) | tojson | safe }};
var country_names = {{ country_abbreviation_mapping() | tojson | safe }};
for (var key in shapes) {
var num = 0;

64
utils.py

@ -1,5 +1,9 @@
import requests
from app import app
import re
from time import strptime, strftime, gmtime
from calendar import timegm
from app import app, cache
from teamspeak import create_teamspeak_viewer, getTeamspeakWindow, ISO3166_MAPPING
def get_steam_userinfo(steam_id):
options = {
@ -9,3 +13,61 @@ def get_steam_userinfo(steam_id):
data = requests.get('http://api.steampowered.com/ISteamUser/' \
'GetPlayerSummaries/v0001/', params=options).json()
return data['response']['players']['player'][0] or {}
# For Templates
@app.template_filter('shorten')
def shorten_filter(s, num_words=20):
space_iter = re.finditer('\s+', s)
output = u''
while num_words > 0:
match = space_iter.next()
if not match: break
output = s[:match.end()]
num_words -= 1
else:
output += '...'
return output
@app.context_processor
def utility_processor():
@cache.memoize(60*5)
def ts3_viewer():
html = create_teamspeak_viewer()[0]
return html
@cache.memoize(60*5)
def ts3_current_clients():
num = create_teamspeak_viewer()[1]
return num
def get_teamspeak_window():
data_list = getTeamspeakWindow()
return data_list
def ts3_active_clients(teamspeak_data):
unique_clients = set()
for data in teamspeak_data:
unique_clients.update(data.clients)
return len(unique_clients)
def num_unique_clients_by_country(teamspeak_data):
unique_clients = {}
for data in teamspeak_data:
for client_id, client_data in data.clients.iteritems():
unique_clients[client_id] = (client_data['country'] or 'Unknown').lower()
country = {}
for client_id, country_code in unique_clients.iteritems():
country[country_code] = country.get(country_code, 0) + 1
return country
def ts3_countries_active(teamspeak_data):
data = num_unique_clients_by_country(teamspeak_data)
return len(data)
def country_abbreviation_mapping():
mapping = {}
for key, name in ISO3166_MAPPING.iteritems():
mapping[key.lower()] = ' '.join([word.capitalize() for word in name.split(' ')])
return mapping
def timestamp_to_js_date(timestamp):
return strftime('%B %d, %Y %H:%M:%S UTC', gmtime(timestamp))
def js_date_to_timestamp(date):
return timegm(strptime(date, '%s, %d %b %Y %H:%M:%S %Z'))
return dict(ts3_viewer=ts3_viewer, ts3_current_clients=ts3_current_clients, get_teamspeak_window=get_teamspeak_window, \
ts3_active_clients=ts3_active_clients, timestamp_to_js_date=timestamp_to_js_date, js_date_to_timestamp=js_date_to_timestamp, \
num_unique_clients_by_country=num_unique_clients_by_country, country_abbreviation_mapping=country_abbreviation_mapping, \
ts3_countries_active=ts3_countries_active)

25
views.py

@ -1,6 +1,6 @@
import re
from flask import render_template, flash, redirect, g, request, url_for, session
from app import app, db, oid
from app import app, db, oid, cache
from models import User
from utils import get_steam_userinfo
from board import latest_news
@ -41,23 +41,10 @@ def logout():
return redirect(oid.get_next_url())
@app.template_filter('shorten')
def shorten_filter(s, num_words=20):
space_iter = re.finditer('\s+', s)
output = u''
while num_words > 0:
match = space_iter.next()
if not match: break
output = s[:match.end()]
num_words -= 1
else:
output += '...'
return output
### TEMPORARY ###
@app.route('/teamspeak')
def teamspeak():
return "Teamspeak!"
return render_template('teamspeak.html')
@app.route('/list_events')
def list_events():
return "Events list!"
@ -71,6 +58,12 @@ def community():
def ladder():
return "Ladder!"
#From league/doobs_blueprint.py
@app.route('/profile/<int:userid>')
def user_profile(userid):
user = User.query.filter_by(id=userid).first_or_404()
return render_template('profile.html', user=user)
'''
from flask import render_template, flash, redirect, g, request, url_for
from app import app, oid

Loading…
Cancel
Save