├── .gitignore ├── Flask-wjr ├── aawsl.py ├── about.html ├── awsl.py ├── flask_server.py ├── post_request.py ├── receive.py └── request.py ├── LICENSE ├── README.md ├── STHacks-wtq ├── css │ └── styles.css ├── data │ ├── Canadian_Community_Hospitals.csv │ ├── CityofToronto_COVID-19_NeighbourhoodData.xlsx │ ├── Ministry_of_Health_Service_Provider_Locations.csv │ ├── all_hospitals_in_toronto.csv │ ├── all_pharmacies_in_toronto.csv │ ├── assessment_centre_locations.csv │ ├── covid_cases_total.csv │ └── toronto.geojson ├── index.html ├── js │ ├── d3 │ │ ├── API.md │ │ ├── CHANGES.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── d3.js │ │ └── d3.min.js │ └── vis.js ├── map.html └── vis.html ├── combined ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── app.js ├── config.js ├── controller │ ├── authController.js │ ├── locationController.js │ ├── mapController.js │ └── userInfoController.js ├── html │ ├── about.html │ ├── index.html │ ├── login.html │ ├── login_already.html │ ├── login_fail.html │ ├── login_success.html │ ├── map-conflict-b551fcc .html │ ├── map-support-b837266.html │ ├── map.html │ ├── signup.html │ ├── signup_already.html │ ├── signup_invalid_passwd.html │ ├── signup_success.html │ ├── support.html │ └── vis.html ├── model │ └── authModel.js ├── package.json ├── readme.md ├── routes │ ├── apiRoutes.js │ └── authRoutes.js ├── static │ ├── assets │ │ ├── bootstrap │ │ │ ├── css │ │ │ │ └── bootstrap.min.css │ │ │ └── js │ │ │ │ └── bootstrap.min.js │ │ ├── css │ │ │ ├── Features-Clean.css │ │ │ ├── Footer-Clean.css │ │ │ ├── Login-Form-Clean-1.css │ │ │ ├── Login-Form-Clean.css │ │ │ ├── Map-Clean.css │ │ │ ├── Navigation-with-Button.css │ │ │ ├── Search-Input-Responsive-with-Icon.css │ │ │ ├── mainCover.css │ │ │ └── styles.css │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fa-brands-400.eot │ │ │ ├── fa-brands-400.svg │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-brands-400.woff │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.eot │ │ │ ├── fa-regular-400.svg │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-regular-400.woff │ │ │ ├── fa-regular-400.woff2 │ │ │ ├── fa-solid-900.eot │ │ │ ├── fa-solid-900.svg │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff │ │ │ ├── fa-solid-900.woff2 │ │ │ ├── font-awesome.min.css │ │ │ ├── fontawesome-all.min.css │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── fontawesome-webfont.woff2 │ │ │ ├── fontawesome5-overrides.min.css │ │ │ ├── ionicons.eot │ │ │ ├── ionicons.min.css │ │ │ ├── ionicons.svg │ │ │ ├── ionicons.ttf │ │ │ └── ionicons.woff │ │ ├── img │ │ │ └── arch.jpg │ │ └── js │ │ │ └── jquery.min.js │ ├── css │ │ └── styles.css │ ├── data │ │ ├── Canadian_Community_Hospitals.csv │ │ ├── CityofToronto_COVID-19_NeighbourhoodData.xlsx │ │ ├── Ministry_of_Health_Service_Provider_Locations.csv │ │ ├── all_hospitals_in_toronto.csv │ │ ├── all_pharmacies_in_toronto.csv │ │ ├── assessment_centre_locations.csv │ │ ├── bloor-danforth-NAD83.csv │ │ ├── covid_cases_total.csv │ │ ├── sheppard-yonge-NAD83.csv │ │ ├── srt-NAD83.csv │ │ ├── toronto.geojson │ │ └── yonge-university-spadina-NAD83.csv │ ├── favicon.ico │ └── js │ │ ├── auth.js │ │ ├── d3 │ │ ├── API.md │ │ ├── CHANGES.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── d3.js │ │ └── d3.min.js │ │ └── vis.js ├── utils │ └── firebase.js └── yarn.lock ├── docs └── img │ ├── homepage.png │ └── logo.png ├── hackathon-01162-xxl ├── assets │ ├── bootstrap │ │ ├── css │ │ │ └── bootstrap.min.css │ │ └── js │ │ │ └── bootstrap.min.js │ ├── css │ │ ├── Footer-Clean.css │ │ ├── Login-Form-Clean-1.css │ │ ├── Login-Form-Clean.css │ │ ├── Map-Clean.css │ │ ├── Navigation-with-Button.css │ │ ├── Search-Input-Responsive-with-Icon.css │ │ ├── mainCover.css │ │ └── styles.css │ ├── fonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ ├── fa-solid-900.woff2 │ │ ├── fontawesome-all.min.css │ │ ├── ionicons.eot │ │ ├── ionicons.min.css │ │ ├── ionicons.svg │ │ ├── ionicons.ttf │ │ └── ionicons.woff │ ├── img │ │ └── arch.jpg │ └── js │ │ └── jquery.min.js ├── index.html ├── login.html ├── map.html ├── readme.md ├── requirements.txt ├── signup.html └── support.html └── python-xxl ├── .gitignore ├── .idea ├── .gitignore ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── python-xxl.iml └── vcs.xml ├── cors.py ├── data ├── all_hospitals_in_toronto.csv ├── assessment_center_locations_utf8.csv ├── covid_cases_total.csv ├── covid_neighborhood_data.csv └── toronto.geojson ├── knn.py ├── predictor.py ├── readme.md └── rec.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /Flask-wjr/aawsl.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request 2 | 3 | app = Flask(__name__) 4 | 5 | 6 | @app.route('/') 7 | def hello_world(): 8 | return 'hello world' 9 | 10 | 11 | @app.route('/register', methods=['POST', 'GET']) 12 | def register(): 13 | if request.method == 'POST': 14 | print(request.headers) 15 | print(request.form) 16 | print(request.form['name']) 17 | print(request.form.get('name')) 18 | print(request.form.getlist('name')) 19 | print(request.form.get('nickname', default='little apple')) 20 | return 'welcome' 21 | 22 | 23 | if __name__ == '__main__': 24 | app.run(debug=True) 25 | -------------------------------------------------------------------------------- /Flask-wjr/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 认真首页 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 37 |
38 |
39 |
40 |

Our Inspiration

41 |

Toronto is a crowded city with huge amounts of traffic. Everyday, over 2 million people commute to work, and possibly would expose to covid-19. We want to provide a one-shot solution to help people stay away from risks from infection, and help people make 42 | better commute decisions.

43 |
44 |
45 |

What does it do?

46 |

47 |

    48 |

    49 |
    50 |
    51 |
    52 |

    Customized for Toronto

    53 |

    Fine tuned Toronto covid data aren't readily available before we made it. 

    54 |
    55 |
    56 |

    Always available

    57 |

    We use APIs developed on our own to get up-to-date information about the covid.

    58 |
    59 |
    60 |

    Customizable

    61 |

    It aims to find the suitable route for customers with their commute preferences. Customize the trip with efficiency, convenience and safety.

    62 |
    63 |
    64 |

    Comprehensive

    65 |

    We provide the latest information about COVID-19, the Customized route for preventing potential risks. We are also able to recommend the nearest COVID-19 detecting point and hospital, and the analysis of drug stores. Moreover, we recommend the safe subway station given by travellers flows. From precaution to healing, we cover them all.

    66 |
    67 |
    68 |

    Efficient

    69 |

    We provide not only the efficient route for customers commuting to work, but also provide location of the nearest hospital and drug store options if customers feel uncomfortable. This would prevent infection in the first place.

    70 |
    71 |
    72 |

    Mobile-first

    73 |

    Customers are able to use this application through mobile devices easily. So people can receive the latest infromation by their mobile devices.

    74 |
    75 |
    76 |

    Custon system

    77 |

    abaaba

    78 |
    79 |
    80 |
    81 |

    How we built it?

    82 |

    Write this part after the project is almost done

    83 |
    84 |
    85 |
    86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /Flask-wjr/awsl.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask import jsonify 3 | from flask import request, Response 4 | import random 5 | import time 6 | 7 | app = Flask(__name__) 8 | 9 | 10 | def random_str(): 11 | data = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+=-" 12 | 13 | random.seed(time.time()) 14 | 15 | # randomly choose data 16 | sa = [] 17 | for i in range(8): 18 | sa.append(random.choice(data)) 19 | salt = ''.join(sa) 20 | 21 | return salt 22 | 23 | 24 | # response 25 | def make_response(): 26 | content = '{"result": "%s", "data": "%s"}' % (random_str(), random_str()) 27 | resp = Response(content) 28 | resp.headers["Access-Control-Origin"] = '*' 29 | 30 | return resp 31 | 32 | 33 | # http GET 34 | @app.route("/query", methods=["GET"]) 35 | def query(): 36 | print("///////////////////////////") 37 | return jsonify( 38 | username=random_str(), 39 | password=random_str() 40 | ) 41 | 42 | 43 | # http POST 44 | @app.route("/update", methods=["POST"]) 45 | def update(): 46 | return make_response() 47 | 48 | 49 | # http delete 50 | @app.route("/delete", methods=["DELETE"]) 51 | def delete(): 52 | return make_response() 53 | 54 | 55 | # http head 56 | @app.route("/head", methods=["HEAD"]) 57 | def head(): 58 | return make_response() 59 | 60 | 61 | if __name__ == "__main__": 62 | app.run(debug=True) -------------------------------------------------------------------------------- /Flask-wjr/flask_server.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, jsonify, url_for 2 | from flask import request 3 | 4 | app = Flask(__name__) 5 | 6 | 7 | @app.route('/login', methods=['POST']) 8 | def login(): 9 | print(request.get_json()) 10 | json_data = {'success': 'true'} 11 | url_for('static', filename='style.css') 12 | return jsonify(json_data) 13 | 14 | 15 | if __name__ == '__main__': 16 | app.run() 17 | -------------------------------------------------------------------------------- /Flask-wjr/post_request.py: -------------------------------------------------------------------------------- 1 | import urllib.request 2 | import json 3 | 4 | 5 | def post(): 6 | url = "http://127.0.0.1:5000/login" 7 | post_dict = { 8 | 'username': 'test', 9 | 'password': '123', 10 | 'login': 'I\'m login' 11 | } 12 | headers = {'Content-Type': 'application/json'} 13 | request = urllib.request.Request(url, headers=headers, data=bytes(json.dumps(post_dict), 'utf8')) 14 | request.get_method = lambda: "POST" 15 | response = urllib.request.urlopen(request) 16 | print(response.read()) 17 | 18 | 19 | if __name__ == '__main__': 20 | post() 21 | -------------------------------------------------------------------------------- /Flask-wjr/receive.py: -------------------------------------------------------------------------------- 1 | from run_oa_con import extract_single 2 | from flask import Flask, request 3 | import json 4 | import os 5 | 6 | app = Flask(__name__) 7 | 8 | 9 | @app.route('/index', methods=['POST']) 10 | def index(): 11 | ff = request.files['file'] 12 | save_path = './static' 13 | ff.save(os.path.join(save_path, ff.filename)) 14 | try: 15 | dic, state = extract_single(os.path.join(save_path, ff.filename)) 16 | except Exception as e: 17 | print(e) 18 | dic, state = {}, 0 19 | res = json.dumps({'data': dic, 'success': state}, ensure_ascii=False) 20 | return res 21 | 22 | 23 | if __name__ == '__main__': 24 | app.run(port=5000, host='0.0.0.0') 25 | -------------------------------------------------------------------------------- /Flask-wjr/request.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | data = {'file': open('/test.doc', 'rb')} 4 | rr = requests.post('http://xxx.xx.xxx.x:5000/index', files=data) 5 | -------------------------------------------------------------------------------- /STHacks-wtq/css/styles.css: -------------------------------------------------------------------------------- 1 | #map { 2 | width: 960px; 3 | height: 500px; 4 | } -------------------------------------------------------------------------------- /STHacks-wtq/data/CityofToronto_COVID-19_NeighbourhoodData.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/STHacks-wtq/data/CityofToronto_COVID-19_NeighbourhoodData.xlsx -------------------------------------------------------------------------------- /STHacks-wtq/data/assessment_centre_locations.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/STHacks-wtq/data/assessment_centre_locations.csv -------------------------------------------------------------------------------- /STHacks-wtq/data/covid_cases_total.csv: -------------------------------------------------------------------------------- 1 | Neighbourhood ID,Neighbourhood Name,"Rate per 100,000 people",Case Count,Rate 2 | 138,Eglinton East,3464.172813,789,0.22776 3 | 47,Don Valley Village,1829.876899,495,0.27051 4 | 38,Lansing-Westgate,1336.302895,216,0.16164 5 | 9,Edenbridge-Humber Valley,2471.837786,384,0.15535 6 | 44,Flemingdon Park,3720.421283,816,0.21933 7 | 59,Danforth East York,1222.351572,210,0.1718 8 | 129,Agincourt North,2109.02346,614,0.29113 9 | 99,Mount Pleasant East,846.4977645,142,0.16775 10 | 137,Woburn,3791.717304,2028,0.53485 11 | 102,Forest Hill North,2045.915977,262,0.12806 12 | 111,Rockcliffe-Smythe,3205.070574,713,0.22246 13 | 130,Milliken,2009.634201,534,0.26572 14 | 55,Thorncliffe Park,4368.012128,922,0.21108 15 | 7,Willowridge-Martingrove-Richview,2735.150749,606,0.22156 16 | 60,Woodbine-Lumsden,1068.022886,84,0.07865 17 | 12,Markland Wood,1317.036195,139,0.10554 18 | 10,Princess-Rosethorn,1502.126504,166,0.11051 19 | 15,Kingsway South,1391.43566,129,0.09271 20 | 114,Lambton Baby Point,1214.777708,97,0.07985 21 | 133,Centennial Scarborough,2342.463703,313,0.13362 22 | 75,Church-Yonge Corridor,1620.931717,508,0.3134 23 | 26,Downsview-Roding-CFB,5232.226406,1834,0.35052 24 | 61,Taylor-Massey,2588.79041,406,0.15683 25 | 124,Kennedy Park,3177.013374,544,0.17123 26 | 100,Yonge-Eglinton,981.6366252,116,0.11817 27 | 120,Clairlea-Birchmount,3183.367922,859,0.26984 28 | 90,Junction Area,1781.985243,256,0.14366 29 | 115,Mount Dennis,4333.112632,589,0.13593 30 | 32,Englemount-Lawrence,4568.210263,1022,0.22372 31 | 77,Waterfront Communities-The Island,1530.805759,1009,0.65913 32 | 74,North St. James Town,3002.954607,559,0.18615 33 | 70,South Riverdale,1033.146793,288,0.27876 34 | 106,Humewood-Cedarvale,1454.925165,209,0.14365 35 | 93,Dovercourt-Wallace Emerson-Junction,1722.866894,631,0.36625 36 | 42,Banbury-Don Mills,1346.813504,373,0.27695 37 | 97,Yonge-St.Clair,941.890166,118,0.12528 38 | 53,Henry Farm,2474.082554,389,0.15723 39 | 104,Mount Pleasant West,1864.589655,553,0.29658 40 | 8,Humber Heights-Westmount,3397.880891,372,0.10948 41 | 89,Runnymede-Bloor West Village,645.4816286,65,0.1007 42 | 85,South Parkdale,3002.42574,656,0.21849 43 | 140,Guildwood,2964.606232,294,0.09917 44 | 118,Tam O'Shanter-Sullivan,2313.634045,635,0.27446 45 | 36,Newtonbrook West,3659.099492,872,0.23831 46 | ,Missing Address/Postal Code,,1389,#DIV/0! 47 | 84,Little Portugal,2217.366155,345,0.15559 48 | 49,Bayview Woods-Steeles,2151.436825,283,0.13154 49 | 82,Niagara,1417.575369,442,0.3118 50 | 14,Islington-City Centre West,2522.461049,1109,0.43965 51 | 123,Cliffcrest,2453.71823,391,0.15935 52 | 117,L'Amoreaux,2336.73539,1028,0.43993 53 | 122,Birchcliffe-Cliffside,2651.294244,591,0.22291 54 | 81,Trinity-Bellwoods,1304.662962,216,0.16556 55 | 11,Eringate-Centennial-West Deane,1689.261889,314,0.18588 56 | 5,Elms-Old Rexdale,3955.160745,374,0.09456 57 | 51,Willowdale East,854.5822263,431,0.50434 58 | 87,High Park-Swansea,1538.140021,368,0.23925 59 | 68,North Riverdale,939.9127224,112,0.11916 60 | 71,Cabbagetown-South St. James Town,2245.265233,262,0.11669 61 | 83,Dufferin Grove,1832.838354,216,0.11785 62 | 30,Brookhaven-Amesbury,3919.58101,696,0.17757 63 | 24,Black Creek,6095.597369,1325,0.21737 64 | 20,Alderwood,1800.232288,217,0.12054 65 | 4,Rexdale-Kipling,3903.504606,411,0.10529 66 | 125,Ionview,1898.687779,259,0.13641 67 | 110,Keelesdale-Eglinton West,2839.57316,314,0.11058 68 | 2,Mount Olive-Silverstone-Jamestown,6463.555259,2130,0.32954 69 | 52,Bayview Village,1051.59843,225,0.21396 70 | 72,Regent Park,2119.781542,229,0.10803 71 | 80,Palmerston-Little Italy,998.119485,138,0.13826 72 | 116,Steeles,2834.748,698,0.24623 73 | 16,Stonegate-Queensway,1285.377829,322,0.25051 74 | 135,Morningside,3678.029218,642,0.17455 75 | 98,Rosedale-Moore Park,831.6207045,174,0.20923 76 | 136,West Hill,2522.634346,691,0.27392 77 | 29,Maple Leaf,6201.167046,627,0.10111 78 | 1,West Humber-Clairville,5586.575408,1861,0.33312 79 | 101,Forest Hill South,810.6597093,87,0.10732 80 | 112,Beechborough-Greenbrook,4682.986164,308,0.06577 81 | 79,University,1892.993296,144,0.07607 82 | 109,Caledonia-Fairbank,3013.561025,300,0.09955 83 | 56,Leaside-Bennington,1099.358213,185,0.16828 84 | 103,Lawrence Park South,935.5029976,142,0.15179 85 | 73,Moss Park,2350.531552,482,0.20506 86 | 31,Yorkdale-Glen Park,5052.688463,748,0.14804 87 | 25,Glenfield-Jane Heights,5559.017415,1695,0.30491 88 | 91,Weston-Pelham Park,3072.625698,341,0.11098 89 | 66,Danforth,1313.883716,127,0.09666 90 | 3,Thistletown-Beaumond Heights,6650.579151,689,0.1036 91 | 88,High Park North,1055.861384,234,0.22162 92 | 58,Old East York,1516.300227,140,0.09233 93 | 139,Scarborough Village,4944.989237,827,0.16724 94 | 21,Humber Summit,5565.399485,691,0.12416 95 | 19,Long Branch,1378.421261,139,0.10084 96 | 46,Pleasant View,1820.710583,288,0.15818 97 | 131,Rouge,4049.810736,1883,0.46496 98 | 18,New Toronto,2128.58763,244,0.11463 99 | 34,Bathurst Manor,3950.10395,627,0.15873 100 | 67,Playter Estates-Danforth,1729.882112,135,0.07804 101 | 54,O'Connor-Parkview,1718.875502,321,0.18675 102 | 17,Mimico (includes Humber Bay Shores),2028.618537,689,0.33964 103 | 64,Woodbine Corridor,813.3322702,102,0.12541 104 | 126,Dorset Park,4267.487901,1067,0.25003 105 | 57,Broadview North,1434.907383,165,0.11499 106 | 121,Oakridge,3257.49368,451,0.13845 107 | 6,Kingsview Village-The Westway,4159.090909,915,0.22 108 | 127,Bendale,3324.432577,996,0.2996 109 | 107,Oakwood Village,2564.827911,544,0.2121 110 | 45,Parkwoods-Donalda,1781.353254,620,0.34805 111 | 69,Blake-Jones,1358.87149,105,0.07727 112 | 119,Wexford/Maryvale,2604.14801,727,0.27917 113 | 108,Briar Hill-Belgravia,2945.921302,420,0.14257 114 | 27,York University Heights,4943.282717,1364,0.27593 115 | 22,Humbermede,5969.765198,928,0.15545 116 | 41,Bridle Path-Sunnybrook-York Mills,938.9164688,87,0.09266 117 | 128,Agincourt South-Malvern West,2134.107842,507,0.23757 118 | 23,Pelmo Park-Humberlea,4542.063048,487,0.10722 119 | 28,Rustic,3148.576602,313,0.09941 120 | 86,Roncesvalles,1375.717911,206,0.14974 121 | 78,Kensington-Chinatown,1733.073279,311,0.17945 122 | 92,Corso Italia-Davenport,2426.944032,343,0.14133 123 | 63,The Beaches,625.9563222,135,0.21567 124 | 48,Hillcrest Village,1334.593126,226,0.16934 125 | 43,Victoria Village,3021.130782,529,0.1751 126 | 50,Newtonbrook East,938.0629931,151,0.16097 127 | 62,East End-Danforth,1412.469015,302,0.21381 128 | 40,St.Andrew-Windfields,976.8695262,174,0.17812 129 | 132,Malvern,3995.981185,1750,0.43794 130 | 96,Casa Loma,1285.557987,141,0.10968 131 | 134,Highland Creek,3609.732672,451,0.12494 132 | 65,Greenwood-Coxwell,1297.079836,187,0.14417 133 | 39,Bedford Park-Nortown,2216.388363,515,0.23236 134 | 13,Etobicoke West Mall,3241.053342,384,0.11848 135 | 33,Clanton Park,2234.09422,368,0.16472 136 | 105,Lawrence Park North,944.7525159,138,0.14607 137 | 35,Westminster-Branson,4483.519829,1178,0.26274 138 | 113,Weston,5491.32948,988,0.17992 139 | 94,Wychwood,1693.497805,243,0.14349 140 | 95,Annex,1821.398152,556,0.30526 141 | 37,Willowdale West,1287.198866,218,0.16936 142 | 76,Bay Street Corridor,1066.015428,275,0.25797 -------------------------------------------------------------------------------- /STHacks-wtq/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 认真首页 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 |
    35 |
    36 |
    37 |

    Toronto Covid
    Intelligence

    The Map v1
    38 |
    39 |
    40 |
    41 |
    42 | icon1 43 |
    44 |
    Plan your trips and get minimum exposure of public during your essential trips
    45 |
    46 | 47 |
    48 | 49 |
    50 |
    51 | icon2 52 |
    53 |
    Get up-to date covid intelligence, and get to fetch a covid-test quick.
    54 |
    55 | 56 |
    57 | 58 |
    59 |
    60 |
    61 |
    62 |
    63 |
    64 |
    65 | 67 |
    68 |
    69 |
    70 |
    71 |
    72 |
    73 |
    74 |
    75 | 83 |
    84 |
    85 |
    86 |
    87 |
    88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /STHacks-wtq/js/d3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2020 Mike Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of contributors may be used to 15 | endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /STHacks-wtq/js/d3/README.md: -------------------------------------------------------------------------------- 1 | # D3: Data-Driven Documents 2 | 3 | 4 | 5 | **D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. 6 | 7 | ## Resources 8 | 9 | * [Introduction](https://observablehq.com/@d3/learn-d3) 10 | * [API Reference](https://github.com/d3/d3/blob/master/API.md) 11 | * [Releases](https://github.com/d3/d3/releases) 12 | * [Examples](https://observablehq.com/@d3/gallery) 13 | * [Wiki](https://github.com/d3/d3/wiki) 14 | 15 | ## Installing 16 | 17 | If you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | For the minified version: 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: 36 | 37 | ```js 38 | import {scaleLinear} from "d3-scale"; 39 | ``` 40 | 41 | Or import everything into a namespace (here, `d3`): 42 | 43 | ```js 44 | import * as d3 from "d3"; 45 | ``` 46 | 47 | In Node: 48 | 49 | ```js 50 | const d3 = require("d3"); 51 | ``` 52 | 53 | You can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): 54 | 55 | ```js 56 | const d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection")); 57 | ``` 58 | -------------------------------------------------------------------------------- /STHacks-wtq/vis.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Leaflet Web Map 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 37 | 38 | 39 | 40 |
    41 |
    42 | 43 |
    44 |
    Infection Rate(out of 1)
    45 |
    46 |
    47 |
    48 | 49 |
    50 | 51 | 52 | 53 |
    54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /combined/.eslintignore: -------------------------------------------------------------------------------- 1 | html/ 2 | node_modules/ 3 | static/ 4 | 5 | yarn.lock 6 | readme.md 7 | package.json 8 | .eslintignore 9 | .eslintrc.js 10 | .gitignore -------------------------------------------------------------------------------- /combined/.eslintrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | env: { 5 | node: true, 6 | commonjs: true, 7 | es2021: true, 8 | }, 9 | root: true, 10 | extends: ["eslint:recommended", "plugin:prettier/recommended"], 11 | parserOptions: { 12 | ecmaVersion: 12, 13 | }, 14 | rules: { 15 | indent: ["error", 4], 16 | quotes: ["error", "double"], 17 | semi: ["error", "always"], 18 | strict: [2, "global"], 19 | "no-unused-vars": ["warn"], 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /combined/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /combined/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | static/ 3 | 4 | yarn.lock 5 | readme.md -------------------------------------------------------------------------------- /combined/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "trailingComma": "es5", 4 | "printWidth": 120 5 | } 6 | -------------------------------------------------------------------------------- /combined/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const express = require("express"); 4 | const bodyParser = require("body-parser"); 5 | const swaggerUI = require("swagger-ui-express"); 6 | const swaggerJsonDoc = require("swagger-jsdoc"); 7 | const cookieParser = require("cookie-parser"); 8 | 9 | const { PORT, STATIC_DIR, SWAGGER_OPTION, SALT } = require("./config"); 10 | const apiRoutes = require("./routes/apiRoutes"); 11 | const authRoutes = require("./routes/authRoutes"); 12 | const { serveMap } = require("./controller/mapController"); 13 | const { isLogin } = require("./utils/firebase"); 14 | const app = express(); 15 | const htmlDir = "./html"; 16 | 17 | //adding middleware 18 | //! Notice, all the file under static folder are auto served by the next line 19 | app.use(express.static(STATIC_DIR)); 20 | app.use(cookieParser(SALT)); 21 | app.use(express.json()); 22 | app.use(bodyParser.urlencoded({ extended: false })); 23 | app.use(bodyParser.json()); 24 | 25 | //setting up swagger 26 | const specs = swaggerJsonDoc(SWAGGER_OPTION); 27 | 28 | //register all the routers 29 | app.use("/swagger", swaggerUI.serve); 30 | app.get("/swagger", swaggerUI.setup(specs)); 31 | app.use("/api/v1", apiRoutes.routes); 32 | app.use("/", authRoutes.routes); 33 | app.get("/map", isLogin, serveMap); 34 | //* / route have to be the last one here. 35 | app.use(express.static(htmlDir, { extensions: ["html"] })); 36 | 37 | //everything are shiny and ready, launch! 38 | app.listen(PORT, () => { 39 | console.log(`Site is up on port ${PORT}`); 40 | }); 41 | -------------------------------------------------------------------------------- /combined/config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const path = require("path"); 4 | const assert = require("assert"); 5 | const { Firebase_Auth } = require("./model/authModel"); 6 | 7 | const HOST = "localhost"; 8 | const PORT = 3000; 9 | //! NOTE: DO NOT USE DEVELOPMENT SALT IN PRODUCTION MODE! 10 | const SALT = "5462272e-91b0-4d64-810e-df7bda96ac36"; 11 | 12 | //TODO Add your firebase credential here. 13 | //! NEVER LEAVE THE CREDENTIAL HERE!!!!!!!! 14 | const FIREBASE_TOKEN = Firebase_Auth.from({ 15 | type: "service_account", 16 | project_id: "chefetown", 17 | private_key_id: "7b573a174f0874c4a4759bf0a6aecff73854e86d", 18 | private_key: 19 | "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDbL01Wrf2HdyNz\nw667F4cNGsUWfCfu0IyWuDWe+7lvtpyI8VyRDaGPMd+Oy/RYqsTZN2JGan+fvl6p\nUvPGUQMo2isOD1qipgAWjmlS6PrYNkMNJCwj/uY4LMcYREfqa+vuvnp+8Ahxb/Es\nlDs+Z3Zc4XGrj71oRZpjVM5YVhmiyupyNerc4U/uGF4YdAPrI77MfJPS26dTtxaH\nVHzEDEUMOe8RpO9mtwumP8OoeMPCwjmb+Of/rY3HxjHlUtrp+51M15ArF7ssxWG1\nmeDrm8Nnui4WHxlKIxG/0r8SImv99yvVVdor3srWGzqWL5/6A8oGXweWtuR0B1w4\nC3YMJovTAgMBAAECggEAFhafwB77oEW43Gc5eiBGW2M5vmjXq2D38g5xVOrARspL\n3x8XuYR6phAcG+tg3fijqtJChJ8h6mrIZl72MyOh4mGOGjYg56g79Qn4AkN5WAWr\n3yyoiB4dfEbC76ad6rlihuZKOPWenDPwRZJQoBrUGksb5fKv30y4YM9AljVjEv0Z\nIrkSQjyk2eK7z7irERPbrb75HxN/XfFsP1q7DL1aidAjhwomwGAlnX+/K5pHUoBL\nWYwcyxrpA++DCgjgOQIGroUy8C36clV89mDp86rZ7anUazVpjr/n5yj7hDUv0UKz\nJp5VVSznLb5bfjpBR2UcfxDPPREJ9d5TMUQe7B4VUQKBgQD+bzKcfi03pjAuX7re\nXtl0x1dKWuOqpNfvLbEfWsx7Ep2KjlerFtScrHzAgg1hlDUJ6SD8PLOxm3sdu0Z9\nong4eI89srYFkfIij/PpFz+SiznkFy2tFKHio0ZzVmoi28BXPE0UeMRMOhz541Rn\n6Frz+eSD172I9IPsPZN7AyjlYwKBgQDciJOsgnIAz0cu3t2DXE5yMTsdZRtNCbKq\n5VDdZxAaAs9U07Sc63AqQ+rzDO+QH2kf49vXjvg6NtrOpM8hdJ83nLj74cIG1jDd\nDAgjVgtPtwJAxOeCQgudWLXSZw6WSlTktdC0qeN1fqY8Va798LxlPv4FO8F7UyjF\noz5G4c2C0QKBgQCgXr5r3SvrE5jy4ewLFYXDEZJ3j2pIuLZST16BAN46BLXAC5A+\niplgV2gaft6oTp5PrN3Znvk0TWgAiXYY4jscfQDsRqRsRl10Y3+9v6WWXKMUnXdw\nzLxs+bUCJcmoRxKo6Z079hLkaQyyhRNCmzYY6b2bTHRuypAMa5N1ybwROQKBgDBD\nt8YOenLQ6mxInEQuhICbY6uoQBRZJgAe1dbOwoheyw9ukd2x7Udiu93bm+Z36WLw\nVGHVyV+8N6D4EtjolBvwsc92didW4zTNeE57e1hD3jtcnKo2WCJkks5sfZXIyNGR\nNQ8FC2HgiPM1cWnkMOcbpS5yCIM8DPVMJ8oNixOxAoGALiGqZJ1FHDRup1qHPCRn\nxcLxwVd5tleAaBG5UksJfA3ingtNI0/sgfO239KNvGfxE+nFnQJetz7fBwnSlPDv\ngQV3fNNd52sc6J1ayjj1AkzQIO3bbTE2khYXYVBPSE7UvMjYXkd9jaiifAJz50Lr\nO0sjEjV2ODdcpZWTUoPs9+8=\n-----END PRIVATE KEY-----\n", 20 | client_email: "firebase-adminsdk-l6wmr@chefetown.iam.gserviceaccount.com", 21 | client_id: "115330923188517803230", 22 | auth_uri: "https://accounts.google.com/o/oauth2/auth", 23 | token_uri: "https://oauth2.googleapis.com/token", 24 | auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs", 25 | client_x509_cert_url: 26 | "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-l6wmr%40chefetown.iam.gserviceaccount.com", 27 | }); 28 | 29 | assert(PORT, "PORT is mandatory"); 30 | assert(HOST, "HOST is mandatory"); 31 | 32 | const HTML_DIR = path.join(__dirname, "html"); 33 | const STATIC_DIR = path.join(__dirname, "static"); 34 | 35 | const { name, version, description } = require("./package.json"); 36 | const TITLE = name; 37 | 38 | const SWAGGER_OPTION = { 39 | swaggerDefinition: { 40 | openapi: "3.0.0", 41 | info: { 42 | title: `${TITLE} Api`, 43 | version, 44 | description, 45 | }, 46 | servers: [ 47 | { 48 | url: `http://${HOST}:${PORT}/api/v1`, 49 | }, 50 | ], 51 | }, 52 | apis: ["./routes/*.js"], 53 | }; 54 | 55 | module.exports = { 56 | PORT, 57 | HOST, 58 | TITLE, 59 | HTML_DIR, 60 | STATIC_DIR, 61 | SWAGGER_OPTION, 62 | FIREBASE_TOKEN, 63 | SALT, 64 | }; 65 | -------------------------------------------------------------------------------- /combined/controller/authController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { LoginModel, SignUpModel } = require("../model/authModel"); 4 | const { saltedHash, db } = require("../utils/firebase"); 5 | const { tokenCheck } = require("../utils/firebase"); 6 | 7 | const postLogin = async (req, res, next) => { 8 | try { 9 | const logInfo = LoginModel.from(req.body); 10 | const passwd = saltedHash(logInfo.password); 11 | const { Token } = req.signedCookies; 12 | const { User } = req.cookies; 13 | if (Token && User && (await tokenCheck(Token, User)) && User == logInfo.email) { 14 | res.redirect("login_already"); 15 | res.end(); 16 | return; 17 | } 18 | const users = db.collection("user"); 19 | const query = await users 20 | .where("name", "==", logInfo.email) 21 | .where("password", "==", passwd) //! password validation is done here 22 | .get() 23 | .then((resp) => { 24 | var data = []; 25 | if (resp.empty) { 26 | return data; 27 | } 28 | resp.forEach((doc) => { 29 | data.push({ id: doc.id, data: doc.data() }); 30 | }); 31 | return data; 32 | }) 33 | .catch((err) => { 34 | console.log("error with database", err); 35 | }); 36 | if (query.length != 0) { 37 | const record = query[0]; 38 | const id = record.id; 39 | console.log(`User ${logInfo.email} with doc id ${id} logged in successfully`); 40 | res.cookie("Token", id, { signed: true }); 41 | res.cookie("User", logInfo.email); 42 | res.redirect("/login_success"); 43 | res.end(); 44 | } else { 45 | res.redirect("/login_fail"); 46 | res.end(); 47 | } 48 | } catch (error) { 49 | res.status(400).send("Invalid Request"); 50 | console.log(error); 51 | } 52 | }; 53 | 54 | const postSignUp = async (req, res, next) => { 55 | try { 56 | const regInfo = SignUpModel.from(req.body); 57 | if (regInfo.password[0] == regInfo.password[1]) { 58 | // query for if this email is already used 59 | const users = db.collection("user"); 60 | const query = await users 61 | .where("name", "==", regInfo.email) 62 | .get() 63 | .then((resp) => { 64 | var data = []; 65 | if (resp.empty) { 66 | return data; 67 | } 68 | resp.forEach((doc) => { 69 | data.push({ id: doc.id, data: doc.data() }); 70 | }); 71 | return data; 72 | }) 73 | .catch((err) => { 74 | console.log("error with database", err); 75 | }); 76 | //if not 77 | if (query.length == 0) { 78 | const passwd = saltedHash(regInfo.password[0]); 79 | const userInfo = { 80 | name: regInfo.email, 81 | password: passwd, 82 | favorite_location: [], 83 | }; 84 | const record = await db.collection("user").add(userInfo); 85 | if (record.id) { 86 | res.cookie("Token", record.id, { signed: true }); 87 | res.cookie("User", regInfo.email); 88 | res.redirect("/signup_success"); 89 | res.end(); 90 | } 91 | } else { 92 | res.redirect("/signup_already"); 93 | res.end(); 94 | } 95 | } else { 96 | res.redirect("/signup_invalid_passwd"); 97 | res.end(); 98 | } 99 | } catch (error) { 100 | res.status(400).send("Invalid Request"); 101 | console.log(error); 102 | } 103 | }; 104 | 105 | module.exports = { 106 | postLogin, 107 | postSignUp, 108 | }; 109 | -------------------------------------------------------------------------------- /combined/controller/locationController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { tokenCheck, db } = require("../utils/firebase"); 4 | 5 | const getAllLocations = async function (id) { 6 | const users = db.collection("user").doc(id); 7 | const query = await users 8 | .get() 9 | .then((doc) => { 10 | if (doc.exists) { 11 | console.log(doc.data()); 12 | return doc.data().favorite_location; 13 | } 14 | return []; 15 | }) 16 | .catch((err) => { 17 | console.log("error with database", err); 18 | }); 19 | return query; 20 | }; 21 | 22 | const addLocation = async function (req, res) { 23 | try { 24 | const { Token } = req.signedCookies; 25 | const { User } = req.cookies; 26 | if (Token && User && (await tokenCheck(Token, User))) { 27 | //user is logged in 28 | const locations = await getAllLocations(Token); 29 | const newLocation = { 30 | latitude: req.body.latitude, 31 | longitude: req.body.longitude, 32 | name: req.body.name, 33 | }; 34 | locations.push(newLocation); 35 | const users = db.collection("user").doc(Token); 36 | const query = await users.update({ 37 | favorite_location: locations, 38 | }); 39 | res.send({ 40 | code: 0, 41 | }); 42 | } 43 | } catch (err) { 44 | console.log(err); 45 | res.send({ 46 | code: 100, 47 | }); 48 | } 49 | }; 50 | 51 | const getLocations = async function (req, res) { 52 | try { 53 | const { Token } = req.signedCookies; 54 | const { User } = req.cookies; 55 | if (Token && User && (await tokenCheck(Token, User))) { 56 | //user is logged in 57 | const locations = await getAllLocations(Token); 58 | res.send({ 59 | code: 0, 60 | data: locations, 61 | }); 62 | } 63 | } catch (err) { 64 | console.log(err); 65 | res.send({ 66 | code: 100, 67 | }); 68 | } 69 | }; 70 | 71 | module.exports = { 72 | addLocation, 73 | getLocations, 74 | }; 75 | -------------------------------------------------------------------------------- /combined/controller/mapController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { HTML_DIR } = require("../config"); 4 | 5 | const serveMap = async function (req, res) { 6 | const fileName = "map.html"; 7 | const options = { 8 | root: HTML_DIR, 9 | dotfiles: "deny", 10 | headers: { 11 | "x-timestamp": Date.now(), 12 | "x-sent": true, 13 | }, 14 | }; 15 | 16 | res.sendFile(fileName, options); 17 | }; 18 | 19 | module.exports = { 20 | serveMap, 21 | }; 22 | -------------------------------------------------------------------------------- /combined/controller/userInfoController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { tokenCheck } = require("../utils/firebase"); 4 | 5 | const getUsername = async function (req, res) { 6 | try { 7 | const { Token } = req.signedCookies; 8 | const { User } = req.cookies; 9 | if (Token && User && (await tokenCheck(Token, User))) { 10 | res.send({ 11 | code: 0, 12 | data: User, 13 | }); 14 | return; 15 | } 16 | res.send({ 17 | code: 100, 18 | data: "Invalid Token or User", 19 | }); 20 | } catch (error) { 21 | res.send({ 22 | code: 101, 23 | data: "Internal Server Issue", 24 | }); 25 | console.log(error.message); 26 | } 27 | }; 28 | 29 | module.exports = { 30 | getUsername, 31 | }; 32 | -------------------------------------------------------------------------------- /combined/html/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SafeMap | About 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 46 | 47 |
    48 |
    49 |
    50 |

    Our Inspiration

    51 |

    52 | Toronto is a crowded city with huge amounts of traffic. Everyday, over 2 million people commute 53 | to work, and possibly would expose to covid-19. We want to provide a one-shot solution to help 54 | people stay away from risks from infection, and help people make better commute decisions. 55 |

    56 |
    57 |
    58 |

    What does it do?

    59 |
      60 |
      61 |
      62 |
      63 | 64 |

      Customized and refined for Toronto

      65 |

      66 | Fine tuned Toronto covid data aren't readily available before we made it.  Our data 67 | visualization and algorithms are more informative and straightforward than simple 68 | charts.  69 |

      70 |
      71 |
      72 | 73 |

      Always available

      74 |

      75 | We use APIs from various sources and recommendation systems develop on our own to get 76 | up-to-date information about the covid. 77 |

      78 |
      79 |
      80 | 81 |

      Customizable

      82 |

      83 | Our data visualization, map systems, and recommendation system are incorporated with 84 | well-designed query systems for Toronto.  With APIs and relevant data provided, we can 85 | apply our design to every city in the world.  86 |

      87 |
      88 |
      89 | 90 |

      Lightweight

      91 |

      92 | For more reliable performance and effective presentation of features, we choose to use 93 | lightweight frameworks such as Leaflet.js and jQuery in our design.   94 |

      95 |
      96 |
      97 | 98 |

      Fast

      99 |

      Data is preprocessed and pulled only when needed.  

      100 |
      101 |
      102 | 103 |

      Trackable Sources

      104 |

      All data come from reliable and trackable sources.

      105 |
      106 |
      107 |
      108 |

      How we built it?

      109 |

      Write this part after the project is almost done

      110 |
      111 |
      112 |
      113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /combined/html/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SafeMap | Log In 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |

      Login to SafeMap

      46 |
      47 |
      48 |

      Login Form

      49 |
      50 | 51 |
      52 |
      53 | 54 |
      55 |
      56 | 63 |
      64 |
      65 | 66 |
      67 | Forgot your email or password? 68 |
      69 |
      70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /combined/html/login_already.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login Success 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |
      46 |
      47 |

      Login Form

      48 |
      49 |

      You are already Logged in!

      50 |

      Redirecting...

      51 | 52 |
      53 | Or: Click here to get back manually 54 |
      55 |
      56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /combined/html/login_fail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login Failed 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |
      46 |
      47 |

      Login Form

      48 |
      49 |

      Login Failed

      50 |

      Redirecting...

      51 | 52 |
      53 | Or: Click here to get back manually 54 |
      55 |
      56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /combined/html/login_success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login Success 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |
      46 |
      47 |

      Login Form

      48 |
      49 |

      Login Success!

      50 |

      Redirecting...

      51 | 52 |
      53 | Or: Click here to get back manually 54 |
      55 |
      56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /combined/html/map-support-b837266.html: -------------------------------------------------------------------------------- 1 | !DOCTYPE html html head meta charset=utf-8 meta name=viewport content=width=device-width, initial-scale=1.0, 2 | shrink-to-fit=no title认真首页title link rel=canonical href= link rel=stylesheet 3 | href=assetsbootstrapcssbootstrap.min.css link rel=stylesheet href=assetsfontsfontawesome-all.min.css link rel=stylesheet 4 | href=assetsfontsionicons.min.css link rel=stylesheet href=assetscssFooter-Clean.css link rel=stylesheet 5 | href=assetscssLogin-Form-Clean-1.css link rel=stylesheet href=assetscssLogin-Form-Clean.css link rel=stylesheet 6 | href=assetscssmainCover.css link rel=stylesheet href=assetscssMap-Clean.css link rel=stylesheet 7 | href=assetscssNavigation-with-Button.css link rel=stylesheet href=assetscssSearch-Input-Responsive-with-Icon.css link 8 | rel=stylesheet href=assetscssstyles.css head body nav class=navbar navbar-light navbar-expand-md navigation-clean-button 9 | div class=containera class=navbar-brand href=.index.htmlSafeMapabutton data-toggle=collapse class=navbar-toggler 10 | data-target=#navcol-1span class=sr-onlyToggle navigationspanspan class=navbar-toggler-iconspanbutton div class=collapse 11 | navbar-collapse id=navcol-1 ul class=nav navbar-nav mr-auto li class=nav-itema class=nav-link active 12 | href=.index.htmlHomeali li class=nav-itema class=nav-link href=.map.htmlMapali li class=nav-itema class=nav-link 13 | href=.support.htmlSupportali li class=nav-itemli ulspan class=navbar-text actions a class=login href=login.htmlLog Inaa 14 | class=btn btn-light action-button role=button href=signup.htmlSign Upaspandiv div nav div class=row div class=col-md-10 15 | offset-md-1 style=padding-right 20px;padding-left 20px;padding-bottom 25px; div class=card m-auto style=max-width850px 16 | div class=card-body style=padding-top 0px;padding-bottom 0px; form class=d-flex align-items-centeri class=fas fa-search 17 | d-none d-sm-block h4 text-body m-0iinput class=form-control form-control-lg flex-shrink-1 form-control-borderless 18 | type=search placeholder=Search topics or keywords name=searchbar style=padding-top 1px;padding-bottom 1px; button 19 | class=btn btn-success btn-lg type=submit style=height 40px;padding-right 12px;padding-left 12px;padding-top 20 | 5px;Searchbutton form div div div div div class=container div class=card div class=card-body div align =center a 21 | class=twitter-timeline data-lang=en data-width=700 data-height=520 22 | href=httpstwitter.comTOPublicHealthref_src=twsrc%5EtfwTweets by TOhealtha div div div class=card-group div class=cardimg 23 | class=card-img-top w-100 d-block div class=card-body h4 class=card-titleOntario Ministry of Healthh4 div a 24 | class=twitter-timeline data-lang=en data-width=300 data-height=280 25 | href=httpstwitter.comONThealthref_src=twsrc%5EtfwTweets by ONThealtha div div div div class=cardimg class=card-img-top 26 | w-100 d-block div class=card-body h4 class=card-titleGlobal Newsh4 div a class=twitter-timeline data-lang=en 27 | data-width=300 data-height=280 href=httpstwitter.comglobalnewsref_src=twsrc%5EtfwTweets by globalnewsa script async 28 | src=httpsplatform.twitter.comwidgets.js charset=utf-8script div div div div class=cardimg class=card-img-top w-100 29 | d-block div class=card-body h4 class=card-titleThe Globe and Mail h4 div a class=twitter-timeline data-lang=en 30 | data-width=300 data-height=280 href=httpstwitter.comglobeandmailref_src=twsrc%5EtfwTweets by globeandmaila script async 31 | src=httpsplatform.twitter.comwidgets.js charset=utf-8script div div div div div script src=assetsjsjquery.min.jsscript 32 | script src=assetsbootstrapjsbootstrap.min.jsscript script async src=httpsplatform.twitter.comwidgets.js 33 | charset=utf-8script body html 34 | -------------------------------------------------------------------------------- /combined/html/signup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SafeMap | Sign Up 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |

      Creating a new account

      46 |
      47 |
      48 |

      Login Form

      49 |
      50 | 51 |
      52 |
      53 | 54 |
      55 |
      56 | 63 |
      64 |
      65 | 72 |
      73 |
      74 | 77 |
      78 |
      79 |
      80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /combined/html/signup_already.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login Success 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |
      46 |
      47 |

      Login Form

      48 |
      49 |

      Account already exists!

      50 |

      Redirecting...

      51 | 52 |
      53 | Or: Click here to get back manually 54 |
      55 |
      56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /combined/html/signup_invalid_passwd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login Success 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |
      46 |
      47 |

      Login Form

      48 |
      49 |

      50 | The two passwords are not the same! 51 |

      52 |

      Redirecting...

      53 | 54 |
      55 | Or: Click here to get back manually 56 |
      57 |
      58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /combined/html/signup_success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login Success 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 |
      46 |
      47 |

      Login Form

      48 |
      49 |

      Sign Up success!

      50 |

      Redirecting...

      51 | 52 |
      53 | Or: Click here to get back manually 54 |
      55 |
      56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /combined/html/support.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SafeMap | Info 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 46 |
      47 |
      48 |
      49 |

      News and Authorities

      50 |
      51 |
      52 |
      53 |
      54 |
      55 |
      56 |
      57 | 65 |
      66 |
      67 |
      68 |
      69 | 70 |
      71 |

      Ontario Ministry of Health

      72 | 82 |
      83 |
      84 |
      85 | 86 |
      87 |

      Global News

      88 |
      89 | 97 | 98 |
      99 |
      100 |
      101 |
      102 | 103 |
      104 |

      The Globe and Mail

      105 |
      106 | 114 | 115 |
      116 |
      117 |
      118 |
      119 |
      120 |
      121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /combined/html/vis.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 16 | 21 | 26 | 27 | Leaflet Web Map 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 56 | 57 | 58 |
      59 |
      60 | 61 |
      62 |
      Infection Rate(out of 1)
      63 |
      64 |
      65 |
      66 | 67 |
      68 | 71 | 74 | 77 |
      78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /combined/model/authModel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class Firebase_Auth { 4 | constructor( 5 | type, 6 | project_id, 7 | private_key_id, 8 | private_key, 9 | client_email, 10 | client_id, 11 | auth_uri, 12 | token_uri, 13 | auth_provider_x509_cert_url, 14 | client_x509_cert_url 15 | ) { 16 | this.type = type; 17 | this.project_id = project_id; 18 | this.private_key_id = private_key_id; 19 | this.private_key = private_key; 20 | this.client_email = client_email; 21 | this.client_id = client_id; 22 | this.auth_uri = auth_uri; 23 | this.token_uri = token_uri; 24 | this.auth_provider_x509_cert_url = auth_provider_x509_cert_url; 25 | this.client_x509_cert_url = client_x509_cert_url; 26 | } 27 | 28 | static from(json) { 29 | return Object.assign(new Firebase_Auth(), json); 30 | } 31 | } 32 | 33 | class LoginModel { 34 | /** 35 | * The data structure used by ogin page 36 | * @param {string} email 37 | * @param {string} passwordRepeated 38 | * @constructor 39 | */ 40 | constructor(email, password) { 41 | this.email = email; 42 | this.password = password; 43 | } 44 | 45 | static from(json) { 46 | return Object.assign(new LoginModel(), json); 47 | } 48 | } 49 | 50 | class SignUpModel { 51 | /** 52 | * The data structure used by sign up page 53 | * @param {string} email 54 | * @param {[string, string]} passwordRepeated 55 | * @constructor 56 | */ 57 | constructor(email, passwordRepeated) { 58 | this.email = email; 59 | this.password = passwordRepeated; 60 | } 61 | 62 | static from(json) { 63 | return Object.assign(new SignUpModel(), json); 64 | } 65 | } 66 | 67 | class Location { 68 | /** 69 | * The data structure used by location model 70 | * @param {number} latitude 71 | * @param {number} longitude 72 | * @param {string} name 73 | */ 74 | constructor(latitude, longitude, name) { 75 | this.latitude = latitude; 76 | this.longitude = longitude; 77 | this.name = name; 78 | } 79 | 80 | static from(json) { 81 | return Object.assign(new Location(), json); 82 | } 83 | } 84 | 85 | class UserModel { 86 | /** 87 | * 88 | * @param {*} name 89 | * @param {*} password 90 | * @param {*} favorite_location 91 | */ 92 | constructor(name, password, favorite_location) { 93 | this.name = name; 94 | this.password = password; 95 | this.favorite_location = Location.from(favorite_location); 96 | } 97 | 98 | static from(json) { 99 | return Object.assign(new UserModel(), json); 100 | } 101 | } 102 | 103 | module.exports = { 104 | LoginModel, 105 | Firebase_Auth, 106 | SignUpModel, 107 | Location, 108 | UserModel, 109 | }; 110 | -------------------------------------------------------------------------------- /combined/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "the-map", 3 | "version": "1.0.3", 4 | "description": "The Toronto COVID-19 Realtime Map", 5 | "main": "app.js", 6 | "license": "MIT", 7 | "private": true, 8 | "scripts": { 9 | "start": "node app.js", 10 | "dev": "nodemon app.js", 11 | "format": "prettier --write .", 12 | "lint": "eslint ." 13 | }, 14 | "dependencies": { 15 | "body-parser": "^1.19.0", 16 | "cookie-parser": "^1.4.5", 17 | "express": "^4.17.1", 18 | "firebase-admin": "^9.4.2", 19 | "swagger-jsdoc": "^6.0.1", 20 | "swagger-ui-express": "^4.1.6" 21 | }, 22 | "devDependencies": { 23 | "eslint": "^7.18.0", 24 | "eslint-config-prettier": "^7.1.0", 25 | "eslint-plugin-prettier": "^3.3.1", 26 | "nodemon": "^2.0.7", 27 | "prettier": "^2.2.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /combined/readme.md: -------------------------------------------------------------------------------- 1 | # SafeMap Repo 2 | 3 | 4 | 5 | 6 | 7 | ## Node server 8 | 9 | ### Tech Spec 10 | 11 | 1. Using `ES6` and `use strict` to ensure the basic convenience. 12 | 2. Using `eslint` and `prettier` to eliminate dumb errors and make code easier for human to read. 13 | 3. Using `Firebase` to provide data persistence. 14 | 4. Using `express` as a http framework which can greatly accelerate the backend working progress. 15 | 5. Using `Swagger` to provide a user-friendly api testing interface. 16 | 6. Using `yarn` to do package management **instead of npm** 17 | 18 | ### Folder structure 19 | 20 | All of your static html file goes into `html` folder, and other static files are located under the `static` folder. 21 | 22 | `controller`, `model`, `routes`, `utils` are what then mean literally, I'm doing a MVC modeling here. 23 | 24 | `node_modules` is the auto-generated folder by `yarn` which contains all the packages required to make this run. Make sure you never ever alter it manually. 25 | 26 | ### How to launch the server? 27 | 28 | If you have not installed nodejs and yarn, please help you to get one. Some helpful links are down below: 29 | 30 | - [NodeJS official site](https://nodejs.dev/) 31 | - [yarn official site](https://yarnpkg.com/) 32 | - [How to install yarn along with NodeJS (Chinese)](https://zhuanlan.zhihu.com/p/304386068) 33 | 34 | Notice that it's not necessary to use Chinese mirror server since we are not going to download a whole Costco. But if you are experiencing unbearable slow international internet from your network provider, don't hesitate to use a mirror. 35 | 36 | Then open this folder with your favorite con-emulator and type `yarn install` to initiate the package install proceeds. 37 | When you have 38 | 39 | ```text 40 | success Already up-to-date 41 | Done in xxxs. 42 | ``` 43 | 44 | prompted after executing the above instruction, you are ready to fire the server up. 45 | 46 | You can now type `yarn dev` to start a development server which is capable to auto re-launch the node server every time you change the file. 47 | 48 | Alternatively, you can type `yarn start` to launch a vanilla node server with express. 49 | 50 | ### How to access the swagger api? 51 | 52 | Simply navigate to [http://localhost:3000/swagger](http://localhost:3000/swagger) to start hacking. 53 | Notice this is the default behavior, you need to change the port if you changed the PORT constant from the `.env` file. 54 | 55 | ### How to write swagger api document? 56 | 57 | We are using `OpenAPI 3.0` here, so it's helpful to check the following links to make a general view. 58 | 59 | - [Swagger Document with OpenAPI 3.0 Basics](https://swagger.io/docs/specification/basic-structure/) 60 | - [Swagger-jsDOC getting started](https://github.com/Surnet/swagger-jsdoc/blob/master/docs/GETTING-STARTED.md) 61 | 62 | ### About linting and formatting 63 | 64 | You can use `yarn lint` to manually lint your js code, and use `yarn format` to formatting both your js and your html code. 65 | 66 | You can also install `eslint` and `prettier` plugin to your favorite editor, such as vscode or atom, to have the linting service run on-the-fly. 67 | -------------------------------------------------------------------------------- /combined/routes/apiRoutes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const express = require("express"); 4 | const router = express.Router(); 5 | /** 6 | * @swagger 7 | * tags: 8 | * name: Testing 9 | * description: API for testing use. 10 | */ 11 | 12 | /** 13 | * @swagger 14 | * /testing: 15 | * get: 16 | * description: Greeting message from API 17 | * tags: 18 | * - Testing 19 | * responses: 20 | * "200": 21 | * content: 22 | * application/json: 23 | * schema: 24 | * type: object 25 | * properties: 26 | * text: 27 | * type: string 28 | * example: API works 29 | */ 30 | router.get("/testing", function (req, res) { 31 | res.send({ text: "API works" }); 32 | }); 33 | 34 | const { getUsername } = require("../controller/userInfoController"); 35 | /** 36 | * @swagger 37 | * tags: 38 | * name: UserInfo 39 | * description: API for Get User Info 40 | */ 41 | 42 | /** 43 | * @swagger 44 | * components: 45 | * securitySchemes: 46 | * cookieAuth: 47 | * type: apiKey 48 | * in: cookie 49 | * name: Token 50 | * cookieName: 51 | * type: apiKey 52 | * in: cookie 53 | * name: User 54 | */ 55 | 56 | /** 57 | * @swagger 58 | * /username: 59 | * get: 60 | * description: Get the user name of current signed in user 61 | * tags: 62 | * - UserInfo 63 | * security: 64 | * - cookieAuth: [] 65 | * - cookieName: [] 66 | * responses: 67 | * "200": 68 | * content: 69 | * application/json: 70 | * schema: 71 | * type: object 72 | * properties: 73 | * code: 74 | * type: number 75 | * oneOf: 76 | * - 0: Success 77 | * - 100: Not Logged In 78 | * - 101: Server Internal Error 79 | * data: 80 | * type: string 81 | * oneOf: 82 | * - User's email: if success 83 | * - error info: if request failed 84 | * example: "abc@abc.abc" 85 | */ 86 | router.get("/username", getUsername); 87 | 88 | const { addLocation, getLocations } = require("../controller/locationController"); 89 | 90 | /** 91 | * @swagger 92 | * /location: 93 | * get: 94 | * description: Get the list of user favorite locations. 95 | * tags: 96 | * - UserInfo 97 | * security: 98 | * - cookieAuth: [] 99 | * - cookieName: [] 100 | * responses: 101 | * "200": 102 | * content: 103 | * application/json: 104 | * schema: 105 | * type: object 106 | * properties: 107 | * code: 108 | * type: number 109 | * oneOf: 110 | * - 0: Success 111 | * - 100: Not Logged In 112 | * data: 113 | * type: list 114 | * example: 115 | * [ 116 | * { 117 | * longitude: 123, 118 | * latitude: 456, 119 | * name: "fake" 120 | * } 121 | * ] 122 | */ 123 | router.get("/location", getLocations); 124 | /** 125 | * @swagger 126 | * /location: 127 | * put: 128 | * description: Add 1 location to user's favorite 129 | * requestBody: 130 | * required: true 131 | * content: 132 | * application/json: 133 | * schema: 134 | * type: object 135 | * properties: 136 | * longitude: number 137 | * latitude: number 138 | * name: string 139 | * example: 140 | * { 141 | * longitude: 123, 142 | * latitude: 456, 143 | * name: "fake" 144 | * } 145 | * tags: 146 | * - UserInfo 147 | * security: 148 | * - cookieAuth: [] 149 | * - cookieName: [] 150 | * responses: 151 | * "200": 152 | * content: 153 | * application/json: 154 | * schema: 155 | * type: object 156 | * properties: 157 | * code: 158 | * type: number 159 | * oneOf: 160 | * - 0: Success 161 | * - 100: Not Logged In 162 | */ 163 | router.put("/location", addLocation); 164 | 165 | module.exports = { 166 | routes: router, 167 | }; 168 | -------------------------------------------------------------------------------- /combined/routes/authRoutes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const express = require("express"); 4 | 5 | const router = express.Router(); 6 | const { postLogin, postSignUp } = require("../controller/authController"); 7 | 8 | router.post("/login", postLogin); 9 | router.post("/signup", postSignUp); 10 | 11 | module.exports = { 12 | routes: router, 13 | }; 14 | -------------------------------------------------------------------------------- /combined/static/assets/css/Features-Clean.css: -------------------------------------------------------------------------------- 1 | .features-clean { 2 | color: #313437; 3 | background-color: #fff; 4 | padding-bottom: 30px; 5 | } 6 | 7 | @media (max-width:767px) { 8 | .features-clean { 9 | padding-bottom: 10px; 10 | } 11 | } 12 | 13 | .features-clean p { 14 | color: #7d8285; 15 | } 16 | 17 | .features-clean h2 { 18 | font-weight: bold; 19 | margin-bottom: 40px; 20 | padding-top: 40px; 21 | color: inherit; 22 | } 23 | 24 | @media (max-width:767px) { 25 | .features-clean h2 { 26 | margin-bottom: 25px; 27 | padding-top: 25px; 28 | font-size: 24px; 29 | } 30 | } 31 | 32 | .features-clean .intro { 33 | font-size: 16px; 34 | max-width: 500px; 35 | margin: 0 auto 60px; 36 | } 37 | 38 | @media (max-width:767px) { 39 | .features-clean .intro { 40 | margin-bottom: 40px; 41 | } 42 | } 43 | 44 | .features-clean .item { 45 | min-height: 100px; 46 | padding-left: 80px; 47 | margin-bottom: 40px; 48 | } 49 | 50 | @media (max-width:767px) { 51 | .features-clean .item { 52 | min-height: 0; 53 | } 54 | } 55 | 56 | .features-clean .item .name { 57 | font-size: 20px; 58 | font-weight: bold; 59 | margin-top: 0; 60 | margin-bottom: 20px; 61 | color: inherit; 62 | } 63 | 64 | .features-clean .item .description { 65 | font-size: 15px; 66 | margin-bottom: 0; 67 | } 68 | 69 | .features-clean .item .icon { 70 | font-size: 40px; 71 | color: #1485ee; 72 | float: left; 73 | margin-left: -65px; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /combined/static/assets/css/Footer-Clean.css: -------------------------------------------------------------------------------- 1 | .footer-clean { 2 | padding: 50px 0; 3 | background-color: #fff; 4 | color: #4b4c4d; 5 | } 6 | 7 | .footer-clean h3 { 8 | margin-top: 0; 9 | margin-bottom: 12px; 10 | font-weight: bold; 11 | font-size: 16px; 12 | } 13 | 14 | .footer-clean ul { 15 | padding: 0; 16 | list-style: none; 17 | line-height: 1.6; 18 | font-size: 14px; 19 | margin-bottom: 0; 20 | } 21 | 22 | .footer-clean ul a { 23 | color: inherit; 24 | text-decoration: none; 25 | opacity: 0.8; 26 | } 27 | 28 | .footer-clean ul a:hover { 29 | opacity: 1; 30 | } 31 | 32 | .footer-clean .item.social { 33 | text-align: right; 34 | } 35 | 36 | @media (max-width:767px) { 37 | .footer-clean .item { 38 | text-align: center; 39 | padding-bottom: 20px; 40 | } 41 | } 42 | 43 | @media (max-width: 768px) { 44 | .footer-clean .item.social { 45 | text-align: center; 46 | } 47 | } 48 | 49 | .footer-clean .item.social > a { 50 | font-size: 24px; 51 | width: 40px; 52 | height: 40px; 53 | line-height: 40px; 54 | display: inline-block; 55 | text-align: center; 56 | border-radius: 50%; 57 | border: 1px solid #ccc; 58 | margin-left: 10px; 59 | margin-top: 22px; 60 | color: inherit; 61 | opacity: 0.75; 62 | } 63 | 64 | .footer-clean .item.social > a:hover { 65 | opacity: 0.9; 66 | } 67 | 68 | @media (max-width:991px) { 69 | .footer-clean .item.social > a { 70 | margin-top: 40px; 71 | } 72 | } 73 | 74 | @media (max-width:767px) { 75 | .footer-clean .item.social > a { 76 | margin-top: 10px; 77 | } 78 | } 79 | 80 | .footer-clean .copyright { 81 | margin-top: 14px; 82 | margin-bottom: 0; 83 | font-size: 13px; 84 | opacity: 0.6; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /combined/static/assets/css/Login-Form-Clean-1.css: -------------------------------------------------------------------------------- 1 | .login-clean { 2 | background: #f1f7fc; 3 | /*padding: 80px 0;*/ 4 | } 5 | 6 | .login-clean form { 7 | max-width: 320px; 8 | width: 90%; 9 | margin: 0 auto; 10 | background-color: #ffffff; 11 | padding: 40px; 12 | border-radius: 4px; 13 | color: #505e6c; 14 | box-shadow: 1px 1px 5px rgba(0,0,0,0.1); 15 | } 16 | 17 | .login-clean .illustration { 18 | text-align: center; 19 | padding: 0 0 20px; 20 | font-size: 100px; 21 | color: rgb(244,71,107); 22 | } 23 | 24 | .login-clean form .form-control { 25 | background: #f7f9fc; 26 | border: none; 27 | border-bottom: 1px solid #dfe7f1; 28 | border-radius: 0; 29 | box-shadow: none; 30 | outline: none; 31 | color: inherit; 32 | text-indent: 8px; 33 | height: 42px; 34 | } 35 | 36 | .login-clean form .btn-primary { 37 | background: #f4476b; 38 | border: none; 39 | border-radius: 4px; 40 | padding: 11px; 41 | box-shadow: none; 42 | margin-top: 26px; 43 | text-shadow: none; 44 | outline: none !important; 45 | } 46 | 47 | .login-clean form .btn-primary:hover, .login-clean form .btn-primary:active { 48 | background: #eb3b60; 49 | } 50 | 51 | .login-clean form .btn-primary:active { 52 | transform: translateY(1px); 53 | } 54 | 55 | .login-clean form .forgot { 56 | display: block; 57 | text-align: center; 58 | font-size: 12px; 59 | color: #6f7a85; 60 | opacity: 0.9; 61 | text-decoration: none; 62 | } 63 | 64 | .login-clean form .forgot:hover, .login-clean form .forgot:active { 65 | opacity: 1; 66 | text-decoration: none; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /combined/static/assets/css/Login-Form-Clean.css: -------------------------------------------------------------------------------- 1 | .login-clean { 2 | /*background: #f1f7fc;*/ 3 | /*padding: 80px 0;*/ 4 | } 5 | 6 | .login-clean form { 7 | max-width: 320px; 8 | width: 90%; 9 | margin: 0 auto; 10 | background-color: #ffffff; 11 | padding: 40px; 12 | border-radius: 4px; 13 | color: #505e6c; 14 | box-shadow: 1px 1px 5px rgba(0,0,0,0.1); 15 | } 16 | 17 | .login-clean .illustration { 18 | text-align: center; 19 | padding: 0 0 20px; 20 | font-size: 100px; 21 | color: rgb(244,71,107); 22 | } 23 | 24 | .login-clean form .form-control { 25 | background: #f7f9fc; 26 | border: none; 27 | border-bottom: 1px solid #dfe7f1; 28 | border-radius: 0; 29 | box-shadow: none; 30 | outline: none; 31 | color: inherit; 32 | text-indent: 8px; 33 | height: 42px; 34 | } 35 | 36 | .login-clean form .btn-primary { 37 | background: #f4476b; 38 | border: none; 39 | border-radius: 4px; 40 | padding: 11px; 41 | box-shadow: none; 42 | margin-top: 26px; 43 | text-shadow: none; 44 | outline: none !important; 45 | } 46 | 47 | .login-clean form .btn-primary:hover, .login-clean form .btn-primary:active { 48 | background: #eb3b60; 49 | } 50 | 51 | .login-clean form .btn-primary:active { 52 | transform: translateY(1px); 53 | } 54 | 55 | .login-clean form .forgot { 56 | display: block; 57 | text-align: center; 58 | font-size: 12px; 59 | color: #6f7a85; 60 | opacity: 0.9; 61 | text-decoration: none; 62 | } 63 | 64 | .login-clean form .forgot:hover, .login-clean form .forgot:active { 65 | opacity: 1; 66 | text-decoration: none; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /combined/static/assets/css/Map-Clean.css: -------------------------------------------------------------------------------- 1 | .map-clean { 2 | color: #313437; 3 | background-color: #fff; 4 | } 5 | 6 | .map-clean p { 7 | color: #7d8285; 8 | } 9 | 10 | .map-clean h2 { 11 | font-weight: bold; 12 | margin-bottom: 40px; 13 | padding-top: 40px; 14 | color: inherit; 15 | } 16 | 17 | @media (max-width:767px) { 18 | .map-clean h2 { 19 | margin-bottom: 25px; 20 | padding-top: 25px; 21 | font-size: 24px; 22 | } 23 | } 24 | 25 | .map-clean .intro { 26 | font-size: 16px; 27 | max-width: 500px; 28 | margin: 0 auto 40px; 29 | } 30 | 31 | .map-clean iframe { 32 | background-color: #eee; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /combined/static/assets/css/Navigation-with-Button.css: -------------------------------------------------------------------------------- 1 | .navigation-clean-button { 2 | background: #fff; 3 | padding-top: .75rem; 4 | padding-bottom: .75rem; 5 | color: #333; 6 | border-radius: 0; 7 | box-shadow: none; 8 | border: none; 9 | margin-bottom: 0; 10 | } 11 | 12 | @media (min-width:768px) { 13 | .navigation-clean-button { 14 | padding-top: 1rem; 15 | padding-bottom: 1rem; 16 | } 17 | } 18 | 19 | .navigation-clean-button .navbar-brand { 20 | font-weight: bold; 21 | color: inherit; 22 | } 23 | 24 | .navigation-clean-button .navbar-brand:hover { 25 | color: #222; 26 | } 27 | 28 | .navigation-clean-button.navbar-dark .navbar-brand:hover { 29 | color: #f0f0f0; 30 | } 31 | 32 | .navigation-clean-button .navbar-brand img { 33 | height: 100%; 34 | display: inline-block; 35 | margin-right: 10px; 36 | width: auto; 37 | } 38 | 39 | .navigation-clean-button .navbar-toggler { 40 | border-color: #ddd; 41 | } 42 | 43 | .navigation-clean-button .navbar-toggler:hover, .navigation-clean-button .navbar-toggler:focus { 44 | background: none; 45 | } 46 | 47 | .navigation-clean-button.navbar-dark .navbar-toggler { 48 | border-color: #555; 49 | } 50 | 51 | .navigation-clean-button .navbar-toggler { 52 | color: #888; 53 | } 54 | 55 | .navigation-clean-button.navbar-dark .navbar-toggler { 56 | color: #eee; 57 | } 58 | 59 | .navigation-clean-button .navbar-collapse, .navigation-clean-button .form-inline { 60 | border-top-color: #ddd; 61 | } 62 | 63 | .navigation-clean-button.navbar-dark .navbar-collapse, .navigation-clean-button.navbar-dark .form-inline { 64 | border-top-color: #333; 65 | } 66 | 67 | .navigation-clean-button .navbar-nav a.active, .navigation-clean-button .navbar-nav > .show > a { 68 | background: none; 69 | box-shadow: none; 70 | } 71 | 72 | .navigation-clean-button.navbar-light .navbar-nav a.active, .navigation-clean-button.navbar-light .navbar-nav a.active:focus, .navigation-clean-button.navbar-light .navbar-nav a.active:hover { 73 | color: #8f8f8f; 74 | box-shadow: none; 75 | background: none; 76 | pointer-events: none; 77 | } 78 | 79 | .navigation-clean-button.navbar .navbar-nav .nav-link { 80 | padding-left: 18px; 81 | padding-right: 18px; 82 | } 83 | 84 | .navigation-clean-button.navbar-light .navbar-nav .nav-link { 85 | color: #465765; 86 | } 87 | 88 | .navigation-clean-button.navbar-light .navbar-nav .nav-link:focus, .navigation-clean-button.navbar-light .navbar-nav .nav-link:hover { 89 | color: #37434d !important; 90 | background-color: transparent; 91 | } 92 | 93 | .navigation-clean-button .navbar-nav > li > .dropdown-menu { 94 | margin-top: -5px; 95 | box-shadow: 0 4px 8px rgba(0,0,0,.1); 96 | background-color: #fff; 97 | border-radius: 2px; 98 | } 99 | 100 | .navigation-clean-button .dropdown-menu .dropdown-item:focus, .navigation-clean-button .dropdown-menu .dropdown-item { 101 | line-height: 2; 102 | font-size: 14px; 103 | color: #37434d; 104 | } 105 | 106 | .navigation-clean-button .dropdown-menu .dropdown-item:focus, .navigation-clean-button .dropdown-menu .dropdown-item:hover { 107 | background: #eee; 108 | color: inherit; 109 | } 110 | 111 | @media (max-width:767px) { 112 | .navigation-clean-button .navbar-nav .show .dropdown-menu { 113 | box-shadow: none; 114 | } 115 | } 116 | 117 | @media (max-width:767px) { 118 | .navigation-clean-button .navbar-nav .show .dropdown-menu .dropdown-item { 119 | color: #37434d; 120 | padding-top: 12px; 121 | padding-bottom: 12px; 122 | line-height: 1; 123 | } 124 | } 125 | 126 | .navigation-clean-button.navbar-dark { 127 | background-color: #1f2021; 128 | color: #fff; 129 | } 130 | 131 | .navigation-clean-button.navbar-dark .navbar-nav a.active, .navigation-clean-button.navbar-dark .navbar-nav a.active:focus, .navigation-clean-button.navbar-dark .navbar-nav a.active:hover { 132 | color: #8f8f8f; 133 | box-shadow: none; 134 | background: none; 135 | pointer-events: none; 136 | } 137 | 138 | .navigation-clean-button.navbar-dark .navbar-nav .nav-link { 139 | color: #dfe8ee; 140 | } 141 | 142 | .navigation-clean-button.navbar-dark .navbar-nav .nav-link:focus, .navigation-clean-button.navbar-dark .navbar-nav .nav-link:hover { 143 | color: #fff !important; 144 | background-color: transparent; 145 | } 146 | 147 | .navigation-clean-button.navbar-dark .navbar-nav > li > .dropdown-menu { 148 | background-color: #1f2021; 149 | } 150 | 151 | .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item:focus, .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item { 152 | color: #f2f5f8; 153 | } 154 | 155 | .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item:focus, .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item:hover { 156 | background: #363739; 157 | } 158 | 159 | @media (max-width:767px) { 160 | .navigation-clean-button.navbar-dark .navbar-nav .show .dropdown-menu .dropdown-item { 161 | color: #fff; 162 | } 163 | } 164 | 165 | .navigation-clean-button .actions .login { 166 | margin-right: 1rem; 167 | text-decoration: none; 168 | color: #465765; 169 | } 170 | 171 | .navigation-clean-button.navbar-dark .actions .login { 172 | color: #dfe8ee; 173 | } 174 | 175 | .navigation-clean-button.navbar-dark .actions .login:hover { 176 | color: #fff; 177 | } 178 | 179 | .navigation-clean-button .navbar-text .action-button, .navigation-clean-button .navbar-text .action-button:active, .navigation-clean-button .navbar-text .action-button:hover { 180 | background: #508991; 181 | border-radius: 20px; 182 | font-size: inherit; 183 | color: #fff; 184 | box-shadow: none; 185 | border: none; 186 | text-shadow: none; 187 | padding: .5rem 1rem; 188 | transition: background-color 0.25s; 189 | font-size: inherit; 190 | } 191 | 192 | .navigation-clean-button .navbar-text .action-button:hover { 193 | background: #508991; 194 | } 195 | 196 | .navigation-clean-button.navbar-dark .action-button, .navigation-clean-button.navbar-dark .action-button:active { 197 | background: #208f8f; 198 | } 199 | 200 | .navigation-clean-button.navbar-dark .action-button:hover { 201 | background: #269d9d; 202 | } 203 | 204 | -------------------------------------------------------------------------------- /combined/static/assets/css/Search-Input-Responsive-with-Icon.css: -------------------------------------------------------------------------------- 1 | .form-control-borderless { 2 | border: none; 3 | } 4 | 5 | .form-control-borderless:hover, .form-control-borderless:active, .form-control-borderless:focus { 6 | border: none; 7 | outline: none; 8 | box-shadow: none; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /combined/static/assets/css/mainCover.css: -------------------------------------------------------------------------------- 1 | .contact-clean { 2 | background: #f1f7fc; 3 | padding: 80px 0; 4 | } 5 | 6 | 7 | .bg-map { top: 0; left: 0; 8 | width: 100vw; 9 | height: 100vh; 10 | display: block; 11 | position: absolute; 12 | z-index: 1000; 13 | background:#FFFBFE; 14 | padding: 0px; 15 | } 16 | 17 | .front-box { 18 | display: block; 19 | position: absolute; 20 | top: 22%; left: 50%; 21 | -webkit-transform:translateX(-50%); 22 | width: 80vw; 23 | height: 60vh; 24 | z-index: 1001; 25 | background:rgba(222,222,222,.9); 26 | padding: 20px; 27 | 28 | border-radius: 12px; 29 | box-shadow: .5px 4px 20px rgba(0,0,0,.5);; 30 | /* filter: blur(25px); */ 31 | } 32 | 33 | h1.main-title { 34 | font-family: 'Roboto'; 35 | /*width: 450px;*/ 36 | /*height: 168px;*/ 37 | /*left: 116px;*/ 38 | top: 198px; 39 | font-family: Roboto; 40 | font-style: normal; 41 | font-weight: bold; 42 | font-size: 2rem; 43 | line-height: 2rem; 44 | color: #13262F; 45 | } 46 | 47 | h2.headings { 48 | font-family: 'Roboto'; 49 | /*width: 450px;*/ 50 | /*height: 168px;*/ 51 | /*left: 116px;*/ 52 | top: 30px; 53 | font-family: Roboto; 54 | font-style: normal; 55 | font-weight: bold; 56 | font-size: 40px; 57 | line-height: 64px; 58 | color: #13262F; 59 | margin-top: 0.4em; 60 | } 61 | 62 | h5.map-code { 63 | top: 60px; 64 | font-family: Roboto; 65 | font-style: normal; 66 | font-weight: bold; 67 | font-size: 24px; 68 | line-height: 28px; 69 | color: #969696; 70 | margin-top: 0em; 71 | } 72 | 73 | .btn:not(:disabled):not(.disabled) { 74 | /* background-color: #66d7d7; */ 75 | border: none; 76 | border-radius: 20px; 77 | } 78 | 79 | .btn-success{ 80 | background-color: #66d7d7!important; 81 | } 82 | 83 | div.frontMap { 84 | margin-top: 6em; 85 | } 86 | 87 | div.legends{ 88 | display:inline; 89 | } 90 | 91 | 92 | .features-clean .item .icon{ 93 | color: #66d7d7; 94 | } 95 | 96 | 97 | @media (max-width:767px) { 98 | .contact-clean { 99 | padding: 20px 0; 100 | } 101 | } 102 | @media (min-width: 576px){ 103 | .form-inline .form-control{ 104 | width:20em!important; 105 | }} 106 | 107 | @media (min-width: 1015px){ 108 | h1.main-title{ 109 | font-family: 'Roboto'; 110 | /*width: 450px;*/ 111 | /*height: 168px;*/ 112 | /*left: 116px;*/ 113 | top: 198px; 114 | font-family: Roboto; 115 | font-style: normal; 116 | font-weight: bold; 117 | font-size: 60px; 118 | line-height: 84px; 119 | color: #13262F; 120 | margin-top: 1em; 121 | } 122 | } 123 | 124 | @media (min-width: 475px){ 125 | h1.main-title{ 126 | font-size:3rem; 127 | line-height: 3rem; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /combined/static/assets/css/styles.css: -------------------------------------------------------------------------------- 1 | div { 2 | } 3 | 4 | .btn:not(:disabled):hover { 5 | background-color: #172A3a; 6 | } 7 | 8 | .h1, .h2, .h3, .h4, .h5, h1, h2, h3, h4, h5, div, p, a { 9 | color: #13262F; 10 | } 11 | 12 | .h5, h5 { 13 | color: #13262F; 14 | } 15 | 16 | body { 17 | background-color: #FFFBFE; 18 | } 19 | 20 | .div.mapHome { 21 | margin-top: 6.28rem; 22 | } 23 | 24 | h1.login-prompt { 25 | /*margin-top: 3em;*/ 26 | font-family: 'Roboto'; 27 | left: 116px; 28 | font-family: Roboto; 29 | font-style: normal; 30 | font-weight: normal; 31 | font-size: 50px; 32 | line-height: 65px; 33 | color: #13262F; 34 | /*padding-left: 0.5em;*/ 35 | } 36 | 37 | .login-clean { 38 | padding: 40px 0 !important; 39 | background: none; 40 | } 41 | 42 | .login-clean form { 43 | background-color: #FFFBFE; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /combined/static/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/favicon.ico -------------------------------------------------------------------------------- /combined/static/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-brands-400.eot -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-brands-400.woff -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-regular-400.eot -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-regular-400.woff -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-solid-900.eot -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-solid-900.woff -------------------------------------------------------------------------------- /combined/static/assets/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /combined/static/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /combined/static/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /combined/static/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /combined/static/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /combined/static/assets/fonts/fontawesome5-overrides.min.css: -------------------------------------------------------------------------------- 1 | .fab.fa-bitcoin:before{content:"\f379"}.far.fa-calendar:before,.fas.fa-calendar:before{content:"\f133"}.far.fa-clipboard:before,.fas.fa-clipboard:before{content:"\f328"}.fab.fa-facebook-f:before{content:"\f39e"}.fab.fa-google-plus:before{content:"\f2b3"}.fas.fa-hotel:before{content:"\f594"}.fab.fa-linkedin:before{content:"\f08c"}.fas.fa-reply:before{content:"\f3e5"}.fas.fa-thermometer:before{content:"\f491"}.fab.fa-vimeo:before{content:"\f40a"}.far.fa-window-close:before,.fas.fa-window-close:before{content:"\f410"}.fab.fa-youtube-square:before{content:"\f431"} -------------------------------------------------------------------------------- /combined/static/assets/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/ionicons.eot -------------------------------------------------------------------------------- /combined/static/assets/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/ionicons.ttf -------------------------------------------------------------------------------- /combined/static/assets/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/fonts/ionicons.woff -------------------------------------------------------------------------------- /combined/static/assets/img/arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/assets/img/arch.jpg -------------------------------------------------------------------------------- /combined/static/css/styles.css: -------------------------------------------------------------------------------- 1 | #map { 2 | width: 960px; 3 | height: 500px; 4 | } -------------------------------------------------------------------------------- /combined/static/data/CityofToronto_COVID-19_NeighbourhoodData.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/data/CityofToronto_COVID-19_NeighbourhoodData.xlsx -------------------------------------------------------------------------------- /combined/static/data/assessment_centre_locations.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/data/assessment_centre_locations.csv -------------------------------------------------------------------------------- /combined/static/data/bloor-danforth-NAD83.csv: -------------------------------------------------------------------------------- 1 | X,Y,station_name 2 | 43.63802031,-79.53638812,Kipling 3 | 43.64595008,-79.52394798,Islington 4 | 43.64880444,-79.51154051,Royal York 5 | 43.65057649,-79.49522499,Old Mill 6 | 43.65029127,-79.48477178,Jane 7 | 43.65216695,-79.47649916,Runnymede 8 | 43.65459423,-79.46552962,High Park 9 | 43.65570079,-79.46031548,Keele 10 | 43.65714206,-79.45267843,Dundas West 11 | 43.65914292,-79.44296991,Lansdowne 12 | 43.6606651,-79.4359558,Dufferin 13 | 43.66266333,-79.42615682,Ossington 14 | 43.66425178,-79.41869303,Christie 15 | 43.66599176,-79.41158255,Bathurst 16 | 43.66764776,-79.4037584,Spadina 17 | 43.66831164,-79.39864323,St George 18 | 43.67040029,-79.39027029,Bay 19 | 43.67070606,-79.38587981,Yonge 20 | 43.67234508,-79.37698161,Sherbourne 21 | 43.67414063,-79.36879416,Castle Frank 22 | 43.67686172,-79.35852385,Broadview 23 | 43.67837735,-79.35141628,Chester 24 | 43.67968493,-79.34520853,Pape 25 | 43.68105008,-79.33792557,Donlands 26 | 43.68270361,-79.33027644,Greenwood 27 | 43.68414917,-79.32352724,Coxwell 28 | 43.6863529,-79.31335711,Woodbine 29 | 43.68891661,-79.30272876,Main Street 30 | 43.69432082,-79.29031894,Victoria Park 31 | 43.71224201,-79.27898037,Warden 32 | 43.73211815,-79.26569845,Kennedy -------------------------------------------------------------------------------- /combined/static/data/covid_cases_total.csv: -------------------------------------------------------------------------------- 1 | Neighbourhood ID,Neighbourhood Name,"Rate per 100,000 people",Case Count,Rate 2 | 138,Eglinton East,3464.172813,789,0.22776 3 | 47,Don Valley Village,1829.876899,495,0.27051 4 | 38,Lansing-Westgate,1336.302895,216,0.16164 5 | 9,Edenbridge-Humber Valley,2471.837786,384,0.15535 6 | 44,Flemingdon Park,3720.421283,816,0.21933 7 | 59,Danforth East York,1222.351572,210,0.1718 8 | 129,Agincourt North,2109.02346,614,0.29113 9 | 99,Mount Pleasant East,846.4977645,142,0.16775 10 | 137,Woburn,3791.717304,2028,0.53485 11 | 102,Forest Hill North,2045.915977,262,0.12806 12 | 111,Rockcliffe-Smythe,3205.070574,713,0.22246 13 | 130,Milliken,2009.634201,534,0.26572 14 | 55,Thorncliffe Park,4368.012128,922,0.21108 15 | 7,Willowridge-Martingrove-Richview,2735.150749,606,0.22156 16 | 60,Woodbine-Lumsden,1068.022886,84,0.07865 17 | 12,Markland Wood,1317.036195,139,0.10554 18 | 10,Princess-Rosethorn,1502.126504,166,0.11051 19 | 15,Kingsway South,1391.43566,129,0.09271 20 | 114,Lambton Baby Point,1214.777708,97,0.07985 21 | 133,Centennial Scarborough,2342.463703,313,0.13362 22 | 75,Church-Yonge Corridor,1620.931717,508,0.3134 23 | 26,Downsview-Roding-CFB,5232.226406,1834,0.35052 24 | 61,Taylor-Massey,2588.79041,406,0.15683 25 | 124,Kennedy Park,3177.013374,544,0.17123 26 | 100,Yonge-Eglinton,981.6366252,116,0.11817 27 | 120,Clairlea-Birchmount,3183.367922,859,0.26984 28 | 90,Junction Area,1781.985243,256,0.14366 29 | 115,Mount Dennis,4333.112632,589,0.13593 30 | 32,Englemount-Lawrence,4568.210263,1022,0.22372 31 | 77,Waterfront Communities-The Island,1530.805759,1009,0.65913 32 | 74,North St. James Town,3002.954607,559,0.18615 33 | 70,South Riverdale,1033.146793,288,0.27876 34 | 106,Humewood-Cedarvale,1454.925165,209,0.14365 35 | 93,Dovercourt-Wallace Emerson-Junction,1722.866894,631,0.36625 36 | 42,Banbury-Don Mills,1346.813504,373,0.27695 37 | 97,Yonge-St.Clair,941.890166,118,0.12528 38 | 53,Henry Farm,2474.082554,389,0.15723 39 | 104,Mount Pleasant West,1864.589655,553,0.29658 40 | 8,Humber Heights-Westmount,3397.880891,372,0.10948 41 | 89,Runnymede-Bloor West Village,645.4816286,65,0.1007 42 | 85,South Parkdale,3002.42574,656,0.21849 43 | 140,Guildwood,2964.606232,294,0.09917 44 | 118,Tam O'Shanter-Sullivan,2313.634045,635,0.27446 45 | 36,Newtonbrook West,3659.099492,872,0.23831 46 | ,Missing Address/Postal Code,,1389,#DIV/0! 47 | 84,Little Portugal,2217.366155,345,0.15559 48 | 49,Bayview Woods-Steeles,2151.436825,283,0.13154 49 | 82,Niagara,1417.575369,442,0.3118 50 | 14,Islington-City Centre West,2522.461049,1109,0.43965 51 | 123,Cliffcrest,2453.71823,391,0.15935 52 | 117,L'Amoreaux,2336.73539,1028,0.43993 53 | 122,Birchcliffe-Cliffside,2651.294244,591,0.22291 54 | 81,Trinity-Bellwoods,1304.662962,216,0.16556 55 | 11,Eringate-Centennial-West Deane,1689.261889,314,0.18588 56 | 5,Elms-Old Rexdale,3955.160745,374,0.09456 57 | 51,Willowdale East,854.5822263,431,0.50434 58 | 87,High Park-Swansea,1538.140021,368,0.23925 59 | 68,North Riverdale,939.9127224,112,0.11916 60 | 71,Cabbagetown-South St. James Town,2245.265233,262,0.11669 61 | 83,Dufferin Grove,1832.838354,216,0.11785 62 | 30,Brookhaven-Amesbury,3919.58101,696,0.17757 63 | 24,Black Creek,6095.597369,1325,0.21737 64 | 20,Alderwood,1800.232288,217,0.12054 65 | 4,Rexdale-Kipling,3903.504606,411,0.10529 66 | 125,Ionview,1898.687779,259,0.13641 67 | 110,Keelesdale-Eglinton West,2839.57316,314,0.11058 68 | 2,Mount Olive-Silverstone-Jamestown,6463.555259,2130,0.32954 69 | 52,Bayview Village,1051.59843,225,0.21396 70 | 72,Regent Park,2119.781542,229,0.10803 71 | 80,Palmerston-Little Italy,998.119485,138,0.13826 72 | 116,Steeles,2834.748,698,0.24623 73 | 16,Stonegate-Queensway,1285.377829,322,0.25051 74 | 135,Morningside,3678.029218,642,0.17455 75 | 98,Rosedale-Moore Park,831.6207045,174,0.20923 76 | 136,West Hill,2522.634346,691,0.27392 77 | 29,Maple Leaf,6201.167046,627,0.10111 78 | 1,West Humber-Clairville,5586.575408,1861,0.33312 79 | 101,Forest Hill South,810.6597093,87,0.10732 80 | 112,Beechborough-Greenbrook,4682.986164,308,0.06577 81 | 79,University,1892.993296,144,0.07607 82 | 109,Caledonia-Fairbank,3013.561025,300,0.09955 83 | 56,Leaside-Bennington,1099.358213,185,0.16828 84 | 103,Lawrence Park South,935.5029976,142,0.15179 85 | 73,Moss Park,2350.531552,482,0.20506 86 | 31,Yorkdale-Glen Park,5052.688463,748,0.14804 87 | 25,Glenfield-Jane Heights,5559.017415,1695,0.30491 88 | 91,Weston-Pelham Park,3072.625698,341,0.11098 89 | 66,Danforth,1313.883716,127,0.09666 90 | 3,Thistletown-Beaumond Heights,6650.579151,689,0.1036 91 | 88,High Park North,1055.861384,234,0.22162 92 | 58,Old East York,1516.300227,140,0.09233 93 | 139,Scarborough Village,4944.989237,827,0.16724 94 | 21,Humber Summit,5565.399485,691,0.12416 95 | 19,Long Branch,1378.421261,139,0.10084 96 | 46,Pleasant View,1820.710583,288,0.15818 97 | 131,Rouge,4049.810736,1883,0.46496 98 | 18,New Toronto,2128.58763,244,0.11463 99 | 34,Bathurst Manor,3950.10395,627,0.15873 100 | 67,Playter Estates-Danforth,1729.882112,135,0.07804 101 | 54,O'Connor-Parkview,1718.875502,321,0.18675 102 | 17,Mimico (includes Humber Bay Shores),2028.618537,689,0.33964 103 | 64,Woodbine Corridor,813.3322702,102,0.12541 104 | 126,Dorset Park,4267.487901,1067,0.25003 105 | 57,Broadview North,1434.907383,165,0.11499 106 | 121,Oakridge,3257.49368,451,0.13845 107 | 6,Kingsview Village-The Westway,4159.090909,915,0.22 108 | 127,Bendale,3324.432577,996,0.2996 109 | 107,Oakwood Village,2564.827911,544,0.2121 110 | 45,Parkwoods-Donalda,1781.353254,620,0.34805 111 | 69,Blake-Jones,1358.87149,105,0.07727 112 | 119,Wexford/Maryvale,2604.14801,727,0.27917 113 | 108,Briar Hill-Belgravia,2945.921302,420,0.14257 114 | 27,York University Heights,4943.282717,1364,0.27593 115 | 22,Humbermede,5969.765198,928,0.15545 116 | 41,Bridle Path-Sunnybrook-York Mills,938.9164688,87,0.09266 117 | 128,Agincourt South-Malvern West,2134.107842,507,0.23757 118 | 23,Pelmo Park-Humberlea,4542.063048,487,0.10722 119 | 28,Rustic,3148.576602,313,0.09941 120 | 86,Roncesvalles,1375.717911,206,0.14974 121 | 78,Kensington-Chinatown,1733.073279,311,0.17945 122 | 92,Corso Italia-Davenport,2426.944032,343,0.14133 123 | 63,The Beaches,625.9563222,135,0.21567 124 | 48,Hillcrest Village,1334.593126,226,0.16934 125 | 43,Victoria Village,3021.130782,529,0.1751 126 | 50,Newtonbrook East,938.0629931,151,0.16097 127 | 62,East End-Danforth,1412.469015,302,0.21381 128 | 40,St.Andrew-Windfields,976.8695262,174,0.17812 129 | 132,Malvern,3995.981185,1750,0.43794 130 | 96,Casa Loma,1285.557987,141,0.10968 131 | 134,Highland Creek,3609.732672,451,0.12494 132 | 65,Greenwood-Coxwell,1297.079836,187,0.14417 133 | 39,Bedford Park-Nortown,2216.388363,515,0.23236 134 | 13,Etobicoke West Mall,3241.053342,384,0.11848 135 | 33,Clanton Park,2234.09422,368,0.16472 136 | 105,Lawrence Park North,944.7525159,138,0.14607 137 | 35,Westminster-Branson,4483.519829,1178,0.26274 138 | 113,Weston,5491.32948,988,0.17992 139 | 94,Wychwood,1693.497805,243,0.14349 140 | 95,Annex,1821.398152,556,0.30526 141 | 37,Willowdale West,1287.198866,218,0.16936 142 | 76,Bay Street Corridor,1066.015428,275,0.25797 -------------------------------------------------------------------------------- /combined/static/data/sheppard-yonge-NAD83.csv: -------------------------------------------------------------------------------- 1 | X,Y,station_name 2 | 43.76161811,-79.41098864,Sheppard-Yonge 3 | 43.76725222,-79.38739865,Bayview 4 | 43.76912679,-79.37672419,Bessarion 5 | 43.77113245,-79.36741635,Leslie 6 | 43.77556464,-79.34693642,Don Mills -------------------------------------------------------------------------------- /combined/static/data/srt-NAD83.csv: -------------------------------------------------------------------------------- 1 | X,Y,station_name 2 | 43.73219165,-79.26569632,Kennedy 3 | 43.7502148,-79.27090721,Lawrence East 4 | 43.76722615,-79.27731467,Ellesmere 5 | 43.77016839,-79.27248232,Midland 6 | 43.77384411,-79.25786316,Scarborough Centre 7 | 43.77551255,-79.25154339,McCowan -------------------------------------------------------------------------------- /combined/static/data/yonge-university-spadina-NAD83.csv: -------------------------------------------------------------------------------- 1 | X,Y,station_name 2 | 43.75005381,-79.46234274,Downsview 3 | 43.73458062,-79.44992871,Wilson 4 | 43.72481302,-79.44750946,Yorkdale 5 | 43.71638143,-79.44402915,Lawrence West 6 | 43.70981996,-79.44152842,Glencairn 7 | 43.69899665,-79.43598953,Eglinton West 8 | 43.68435203,-79.41453588,St Clair West 9 | 43.67490988,-79.40725667,Dupont 10 | 43.66771459,-79.40375197,Spadina 11 | 43.66831877,-79.39867229,St George 12 | 43.66717707,-79.39350223,Museum 13 | 43.65970495,-79.39034904,Queen's Park 14 | 43.65461164,-79.38829598,St Patrick 15 | 43.65087411,-79.38661732,Osgoode 16 | 43.64764565,-79.38513048,St Andrew 17 | 43.64572267,-79.38046226,Union 18 | 43.64912088,-79.37804513,King 19 | 43.65234651,-79.3793265,Queen 20 | 43.65613653,-79.38072965,Dundas 21 | 43.66122997,-79.38278217,College 22 | 43.66518294,-79.38377079,Wellesley 23 | 43.670672,-79.38595009,Bloor 24 | 43.67690095,-79.38872589,Rosedale 25 | 43.68245,-79.39117824,Summerhill 26 | 43.68816298,-79.39328435,St Clair 27 | 43.69812339,-79.39733141,Davisville 28 | 43.70664584,-79.39915846,Eglinton 29 | 43.72542192,-79.40187758,Lawrence 30 | 43.74499592,-79.40533068,York Mills 31 | 43.76167434,-79.41098715,Sheppard 32 | 43.76924125,-79.4129116,North York Centre 33 | 43.78149012,-79.41567261,Finch -------------------------------------------------------------------------------- /combined/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/combined/static/favicon.ico -------------------------------------------------------------------------------- /combined/static/js/auth.js: -------------------------------------------------------------------------------- 1 | function SubmitSignup() { 2 | var username = document.getElementById("signup-email").value; 3 | var password = document.getElementById("signup-passwd2").value; 4 | 5 | // 没有验证两次密码相同; 6 | 7 | $.ajax({ 8 | type: "GET", 9 | url: "myapi.php", 10 | dataType: 'json', 11 | data:{ 12 | data: '{"name": "' + username + '", "passwd" : "' + password + '"}', 13 | } 14 | }); 15 | } 16 | 17 | 18 | function SubmitLogin() { 19 | 20 | var username = document.getElementById("email-input").value; 21 | var password = document.getElementById("password-input").value; 22 | 23 | $.ajax({ 24 | type: "GET", 25 | url: "myapi.php", 26 | dataType: 'json', 27 | data:{ 28 | data: '{"name": "' + username + '", "passwd" : "' + password + '"}', 29 | } 30 | }); 31 | } 32 | 33 | function readCookie(){ 34 | //作废 35 | var cookie = document.cookie; 36 | console.log(cookie); 37 | 38 | // https://gist.github.com/rendro/525bbbf85e84fa9042c2#gistcomment-2784930 39 | //cookie的 hash-array 40 | var cookieArray = document.cookie 41 | .split(';') 42 | .reduce((res, c) => { 43 | const [key, val] = c.trim().split('=').map(decodeURIComponent) 44 | const allNumbers = str => /^\d+$/.test(str); 45 | try { 46 | return Object.assign(res, { [key]: allNumbers(val) ? val : JSON.parse(val) }) 47 | } catch (e) { 48 | return Object.assign(res, { [key]: val }) 49 | } 50 | }, {}); 51 | //读取cookie以后把 52 | console.log(cookieArray); 53 | console.log(cookieArray["grav-tabs-state"]["User"]); 54 | 55 | document.getElementById("loginButton"); 56 | document.getElementById("signupButton"); 57 | } 58 | 59 | function changeLoginStatus(){ 60 | //code: 0, 100, 101 61 | //data: username / fail reason 62 | $.getJSON("http://localhost:3000/api/v1/username", function(data6) { 63 | let code = data6["code"]; 64 | let data = data6["data"]; 65 | console.log(code + ' ' + data); 66 | if (code == 0){ //success 67 | console.log("login success"); 68 | document.getElementById("loginButton").remove(); 69 | document.getElementById("signupButton").innerHTML = data; 70 | document.getElementById("signupButton").href = "#"; 71 | }else { 72 | console.log("login fail"); 73 | } 74 | }); 75 | } 76 | 77 | //Auto-initialization 78 | changeLoginStatus(); -------------------------------------------------------------------------------- /combined/static/js/d3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2020 Mike Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of contributors may be used to 15 | endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /combined/static/js/d3/README.md: -------------------------------------------------------------------------------- 1 | # D3: Data-Driven Documents 2 | 3 | 4 | 5 | **D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. 6 | 7 | ## Resources 8 | 9 | * [Introduction](https://observablehq.com/@d3/learn-d3) 10 | * [API Reference](https://github.com/d3/d3/blob/master/API.md) 11 | * [Releases](https://github.com/d3/d3/releases) 12 | * [Examples](https://observablehq.com/@d3/gallery) 13 | * [Wiki](https://github.com/d3/d3/wiki) 14 | 15 | ## Installing 16 | 17 | If you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | For the minified version: 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: 36 | 37 | ```js 38 | import {scaleLinear} from "d3-scale"; 39 | ``` 40 | 41 | Or import everything into a namespace (here, `d3`): 42 | 43 | ```js 44 | import * as d3 from "d3"; 45 | ``` 46 | 47 | In Node: 48 | 49 | ```js 50 | const d3 = require("d3"); 51 | ``` 52 | 53 | You can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): 54 | 55 | ```js 56 | const d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection")); 57 | ``` 58 | -------------------------------------------------------------------------------- /combined/utils/firebase.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const firebase = require("firebase-admin"); 4 | const { SALT, FIREBASE_TOKEN } = require("../config"); 5 | const crypto = require("crypto"); 6 | 7 | const Firebase = firebase.initializeApp({ 8 | credential: firebase.credential.cert(FIREBASE_TOKEN), 9 | }); 10 | 11 | /** 12 | * Convert the text to salted and hashed version. 13 | * @param {string} text 14 | */ 15 | const saltedHash = function (text) { 16 | return crypto.createHmac("sha256", SALT).update(text).digest("base64"); 17 | }; 18 | 19 | const db = Firebase.firestore(); 20 | 21 | async function tokenCheck(token, email) { 22 | try { 23 | const id = token; 24 | const users = db.collection("user").doc(id); 25 | const query = await users 26 | .get() 27 | .then((doc) => { 28 | if (doc.exists) { 29 | if (doc.data().name == email) { 30 | return true; 31 | } 32 | } 33 | return false; 34 | }) 35 | .catch((err) => { 36 | console.log("error with database", err); 37 | }); 38 | return query; 39 | } catch (error) { 40 | console.log(error); 41 | return false; 42 | } 43 | } 44 | 45 | async function isLogin(req, res, next) { 46 | const { Token } = req.signedCookies; 47 | const { User } = req.cookies; 48 | if (Token && User && (await tokenCheck(Token, User))) { 49 | next(); 50 | } else { 51 | res.redirect("/login"); 52 | res.end(); 53 | } 54 | } 55 | 56 | module.exports = { 57 | Firebase, 58 | db, 59 | saltedHash, 60 | tokenCheck, 61 | isLogin, 62 | }; 63 | -------------------------------------------------------------------------------- /docs/img/homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/docs/img/homepage.png -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/docs/img/logo.png -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/Footer-Clean.css: -------------------------------------------------------------------------------- 1 | .footer-clean { 2 | padding: 50px 0; 3 | background-color: #fff; 4 | color: #4b4c4d; 5 | } 6 | 7 | .footer-clean h3 { 8 | margin-top: 0; 9 | margin-bottom: 12px; 10 | font-weight: bold; 11 | font-size: 16px; 12 | } 13 | 14 | .footer-clean ul { 15 | padding: 0; 16 | list-style: none; 17 | line-height: 1.6; 18 | font-size: 14px; 19 | margin-bottom: 0; 20 | } 21 | 22 | .footer-clean ul a { 23 | color: inherit; 24 | text-decoration: none; 25 | opacity: 0.8; 26 | } 27 | 28 | .footer-clean ul a:hover { 29 | opacity: 1; 30 | } 31 | 32 | .footer-clean .item.social { 33 | text-align: right; 34 | } 35 | 36 | @media (max-width:767px) { 37 | .footer-clean .item { 38 | text-align: center; 39 | padding-bottom: 20px; 40 | } 41 | } 42 | 43 | @media (max-width: 768px) { 44 | .footer-clean .item.social { 45 | text-align: center; 46 | } 47 | } 48 | 49 | .footer-clean .item.social > a { 50 | font-size: 24px; 51 | width: 40px; 52 | height: 40px; 53 | line-height: 40px; 54 | display: inline-block; 55 | text-align: center; 56 | border-radius: 50%; 57 | border: 1px solid #ccc; 58 | margin-left: 10px; 59 | margin-top: 22px; 60 | color: inherit; 61 | opacity: 0.75; 62 | } 63 | 64 | .footer-clean .item.social > a:hover { 65 | opacity: 0.9; 66 | } 67 | 68 | @media (max-width:991px) { 69 | .footer-clean .item.social > a { 70 | margin-top: 40px; 71 | } 72 | } 73 | 74 | @media (max-width:767px) { 75 | .footer-clean .item.social > a { 76 | margin-top: 10px; 77 | } 78 | } 79 | 80 | .footer-clean .copyright { 81 | margin-top: 14px; 82 | margin-bottom: 0; 83 | font-size: 13px; 84 | opacity: 0.6; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/Login-Form-Clean-1.css: -------------------------------------------------------------------------------- 1 | .login-clean { 2 | background: #f1f7fc; 3 | /*padding: 80px 0;*/ 4 | } 5 | 6 | .login-clean form { 7 | max-width: 320px; 8 | width: 90%; 9 | margin: 0 auto; 10 | background-color: #ffffff; 11 | padding: 40px; 12 | border-radius: 4px; 13 | color: #505e6c; 14 | box-shadow: 1px 1px 5px rgba(0,0,0,0.1); 15 | } 16 | 17 | .login-clean .illustration { 18 | text-align: center; 19 | padding: 0 0 20px; 20 | font-size: 100px; 21 | color: rgb(244,71,107); 22 | } 23 | 24 | .login-clean form .form-control { 25 | background: #f7f9fc; 26 | border: none; 27 | border-bottom: 1px solid #dfe7f1; 28 | border-radius: 0; 29 | box-shadow: none; 30 | outline: none; 31 | color: inherit; 32 | text-indent: 8px; 33 | height: 42px; 34 | } 35 | 36 | .login-clean form .btn-primary { 37 | background: #f4476b; 38 | border: none; 39 | border-radius: 4px; 40 | padding: 11px; 41 | box-shadow: none; 42 | margin-top: 26px; 43 | text-shadow: none; 44 | outline: none !important; 45 | } 46 | 47 | .login-clean form .btn-primary:hover, .login-clean form .btn-primary:active { 48 | background: #eb3b60; 49 | } 50 | 51 | .login-clean form .btn-primary:active { 52 | transform: translateY(1px); 53 | } 54 | 55 | .login-clean form .forgot { 56 | display: block; 57 | text-align: center; 58 | font-size: 12px; 59 | color: #6f7a85; 60 | opacity: 0.9; 61 | text-decoration: none; 62 | } 63 | 64 | .login-clean form .forgot:hover, .login-clean form .forgot:active { 65 | opacity: 1; 66 | text-decoration: none; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/Login-Form-Clean.css: -------------------------------------------------------------------------------- 1 | .login-clean { 2 | /*background: #f1f7fc;*/ 3 | /*padding: 80px 0;*/ 4 | } 5 | 6 | .login-clean form { 7 | max-width: 320px; 8 | width: 90%; 9 | margin: 0 auto; 10 | background-color: #ffffff; 11 | padding: 40px; 12 | border-radius: 4px; 13 | color: #505e6c; 14 | box-shadow: 1px 1px 5px rgba(0,0,0,0.1); 15 | } 16 | 17 | .login-clean .illustration { 18 | text-align: center; 19 | padding: 0 0 20px; 20 | font-size: 100px; 21 | color: rgb(244,71,107); 22 | } 23 | 24 | .login-clean form .form-control { 25 | background: #f7f9fc; 26 | border: none; 27 | border-bottom: 1px solid #dfe7f1; 28 | border-radius: 0; 29 | box-shadow: none; 30 | outline: none; 31 | color: inherit; 32 | text-indent: 8px; 33 | height: 42px; 34 | } 35 | 36 | .login-clean form .btn-primary { 37 | background: #f4476b; 38 | border: none; 39 | border-radius: 4px; 40 | padding: 11px; 41 | box-shadow: none; 42 | margin-top: 26px; 43 | text-shadow: none; 44 | outline: none !important; 45 | } 46 | 47 | .login-clean form .btn-primary:hover, .login-clean form .btn-primary:active { 48 | background: #eb3b60; 49 | } 50 | 51 | .login-clean form .btn-primary:active { 52 | transform: translateY(1px); 53 | } 54 | 55 | .login-clean form .forgot { 56 | display: block; 57 | text-align: center; 58 | font-size: 12px; 59 | color: #6f7a85; 60 | opacity: 0.9; 61 | text-decoration: none; 62 | } 63 | 64 | .login-clean form .forgot:hover, .login-clean form .forgot:active { 65 | opacity: 1; 66 | text-decoration: none; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/Map-Clean.css: -------------------------------------------------------------------------------- 1 | .map-clean { 2 | color: #313437; 3 | background-color: #fff; 4 | } 5 | 6 | .map-clean p { 7 | color: #7d8285; 8 | } 9 | 10 | .map-clean h2 { 11 | font-weight: bold; 12 | margin-bottom: 40px; 13 | padding-top: 40px; 14 | color: inherit; 15 | } 16 | 17 | @media (max-width:767px) { 18 | .map-clean h2 { 19 | margin-bottom: 25px; 20 | padding-top: 25px; 21 | font-size: 24px; 22 | } 23 | } 24 | 25 | .map-clean .intro { 26 | font-size: 16px; 27 | max-width: 500px; 28 | margin: 0 auto 40px; 29 | } 30 | 31 | .map-clean iframe { 32 | background-color: #eee; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/Navigation-with-Button.css: -------------------------------------------------------------------------------- 1 | .navigation-clean-button { 2 | background: #fff; 3 | padding-top: .75rem; 4 | padding-bottom: .75rem; 5 | color: #333; 6 | border-radius: 0; 7 | box-shadow: none; 8 | border: none; 9 | margin-bottom: 0; 10 | } 11 | 12 | @media (min-width:768px) { 13 | .navigation-clean-button { 14 | padding-top: 1rem; 15 | padding-bottom: 1rem; 16 | } 17 | } 18 | 19 | .navigation-clean-button .navbar-brand { 20 | font-weight: bold; 21 | color: inherit; 22 | } 23 | 24 | .navigation-clean-button .navbar-brand:hover { 25 | color: #222; 26 | } 27 | 28 | .navigation-clean-button.navbar-dark .navbar-brand:hover { 29 | color: #f0f0f0; 30 | } 31 | 32 | .navigation-clean-button .navbar-brand img { 33 | height: 100%; 34 | display: inline-block; 35 | margin-right: 10px; 36 | width: auto; 37 | } 38 | 39 | .navigation-clean-button .navbar-toggler { 40 | border-color: #ddd; 41 | } 42 | 43 | .navigation-clean-button .navbar-toggler:hover, .navigation-clean-button .navbar-toggler:focus { 44 | background: none; 45 | } 46 | 47 | .navigation-clean-button.navbar-dark .navbar-toggler { 48 | border-color: #555; 49 | } 50 | 51 | .navigation-clean-button .navbar-toggler { 52 | color: #888; 53 | } 54 | 55 | .navigation-clean-button.navbar-dark .navbar-toggler { 56 | color: #eee; 57 | } 58 | 59 | .navigation-clean-button .navbar-collapse, .navigation-clean-button .form-inline { 60 | border-top-color: #ddd; 61 | } 62 | 63 | .navigation-clean-button.navbar-dark .navbar-collapse, .navigation-clean-button.navbar-dark .form-inline { 64 | border-top-color: #333; 65 | } 66 | 67 | .navigation-clean-button .navbar-nav a.active, .navigation-clean-button .navbar-nav > .show > a { 68 | background: none; 69 | box-shadow: none; 70 | } 71 | 72 | .navigation-clean-button.navbar-light .navbar-nav a.active, .navigation-clean-button.navbar-light .navbar-nav a.active:focus, .navigation-clean-button.navbar-light .navbar-nav a.active:hover { 73 | color: #8f8f8f; 74 | box-shadow: none; 75 | background: none; 76 | pointer-events: none; 77 | } 78 | 79 | .navigation-clean-button.navbar .navbar-nav .nav-link { 80 | padding-left: 18px; 81 | padding-right: 18px; 82 | } 83 | 84 | .navigation-clean-button.navbar-light .navbar-nav .nav-link { 85 | color: #465765; 86 | } 87 | 88 | .navigation-clean-button.navbar-light .navbar-nav .nav-link:focus, .navigation-clean-button.navbar-light .navbar-nav .nav-link:hover { 89 | color: #37434d !important; 90 | background-color: transparent; 91 | } 92 | 93 | .navigation-clean-button .navbar-nav > li > .dropdown-menu { 94 | margin-top: -5px; 95 | box-shadow: 0 4px 8px rgba(0,0,0,.1); 96 | background-color: #fff; 97 | border-radius: 2px; 98 | } 99 | 100 | .navigation-clean-button .dropdown-menu .dropdown-item:focus, .navigation-clean-button .dropdown-menu .dropdown-item { 101 | line-height: 2; 102 | font-size: 14px; 103 | color: #37434d; 104 | } 105 | 106 | .navigation-clean-button .dropdown-menu .dropdown-item:focus, .navigation-clean-button .dropdown-menu .dropdown-item:hover { 107 | background: #eee; 108 | color: inherit; 109 | } 110 | 111 | @media (max-width:767px) { 112 | .navigation-clean-button .navbar-nav .show .dropdown-menu { 113 | box-shadow: none; 114 | } 115 | } 116 | 117 | @media (max-width:767px) { 118 | .navigation-clean-button .navbar-nav .show .dropdown-menu .dropdown-item { 119 | color: #37434d; 120 | padding-top: 12px; 121 | padding-bottom: 12px; 122 | line-height: 1; 123 | } 124 | } 125 | 126 | .navigation-clean-button.navbar-dark { 127 | background-color: #1f2021; 128 | color: #fff; 129 | } 130 | 131 | .navigation-clean-button.navbar-dark .navbar-nav a.active, .navigation-clean-button.navbar-dark .navbar-nav a.active:focus, .navigation-clean-button.navbar-dark .navbar-nav a.active:hover { 132 | color: #8f8f8f; 133 | box-shadow: none; 134 | background: none; 135 | pointer-events: none; 136 | } 137 | 138 | .navigation-clean-button.navbar-dark .navbar-nav .nav-link { 139 | color: #dfe8ee; 140 | } 141 | 142 | .navigation-clean-button.navbar-dark .navbar-nav .nav-link:focus, .navigation-clean-button.navbar-dark .navbar-nav .nav-link:hover { 143 | color: #fff !important; 144 | background-color: transparent; 145 | } 146 | 147 | .navigation-clean-button.navbar-dark .navbar-nav > li > .dropdown-menu { 148 | background-color: #1f2021; 149 | } 150 | 151 | .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item:focus, .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item { 152 | color: #f2f5f8; 153 | } 154 | 155 | .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item:focus, .navigation-clean-button.navbar-dark .dropdown-menu .dropdown-item:hover { 156 | background: #363739; 157 | } 158 | 159 | @media (max-width:767px) { 160 | .navigation-clean-button.navbar-dark .navbar-nav .show .dropdown-menu .dropdown-item { 161 | color: #fff; 162 | } 163 | } 164 | 165 | .navigation-clean-button .actions .login { 166 | margin-right: 1rem; 167 | text-decoration: none; 168 | color: #465765; 169 | } 170 | 171 | .navigation-clean-button.navbar-dark .actions .login { 172 | color: #dfe8ee; 173 | } 174 | 175 | .navigation-clean-button.navbar-dark .actions .login:hover { 176 | color: #fff; 177 | } 178 | 179 | .navigation-clean-button .navbar-text .action-button, .navigation-clean-button .navbar-text .action-button:active, .navigation-clean-button .navbar-text .action-button:hover { 180 | background: #508991; 181 | border-radius: 20px; 182 | font-size: inherit; 183 | color: #fff; 184 | box-shadow: none; 185 | border: none; 186 | text-shadow: none; 187 | padding: .5rem 1rem; 188 | transition: background-color 0.25s; 189 | font-size: inherit; 190 | } 191 | 192 | .navigation-clean-button .navbar-text .action-button:hover { 193 | background: #508991; 194 | } 195 | 196 | .navigation-clean-button.navbar-dark .action-button, .navigation-clean-button.navbar-dark .action-button:active { 197 | background: #208f8f; 198 | } 199 | 200 | .navigation-clean-button.navbar-dark .action-button:hover { 201 | background: #269d9d; 202 | } 203 | 204 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/Search-Input-Responsive-with-Icon.css: -------------------------------------------------------------------------------- 1 | .form-control-borderless { 2 | border: none; 3 | } 4 | 5 | .form-control-borderless:hover, .form-control-borderless:active, .form-control-borderless:focus { 6 | border: none; 7 | outline: none; 8 | box-shadow: none; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/mainCover.css: -------------------------------------------------------------------------------- 1 | .contact-clean { 2 | background: #f1f7fc; 3 | padding: 80px 0; 4 | } 5 | 6 | @media (max-width:767px) { 7 | .contact-clean { 8 | padding: 20px 0; 9 | } 10 | } 11 | 12 | div { 13 | } 14 | 15 | h1.main-title { 16 | font-family: 'Roboto'; 17 | /*width: 450px;*/ 18 | /*height: 168px;*/ 19 | /*left: 116px;*/ 20 | top: 198px; 21 | font-family: Roboto; 22 | font-style: normal; 23 | font-weight: bold; 24 | font-size: 60px; 25 | line-height: 84px; 26 | color: #13262F; 27 | margin-top: 1.4em; 28 | } 29 | 30 | h5.map-code { 31 | position: absolute; 32 | /*width: 131px;*/ 33 | /*height: 28px;*/ 34 | /*left: 116px;*/ 35 | top: 60px; 36 | font-family: Roboto; 37 | font-style: normal; 38 | font-weight: bold; 39 | font-size: 24px; 40 | line-height: 28px; 41 | color: #969696; 42 | margin-top: 0em; 43 | } 44 | 45 | .btn:not(:disabled):not(.disabled) { 46 | background-color: #66d7d7; 47 | border: none; 48 | border-radius: 20px; 49 | } 50 | 51 | div.frontMap { 52 | margin-top: 6em; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/css/styles.css: -------------------------------------------------------------------------------- 1 | div { 2 | } 3 | 4 | .btn:not(:disabled):hover { 5 | background-color: #172A3a; 6 | } 7 | 8 | .h1, .h2, .h3, .h4, .h5, h1, h2, h3, h4, h5, div, p, a { 9 | color: #13262F; 10 | } 11 | 12 | .h5, h5 { 13 | color: #13262F; 14 | } 15 | 16 | body { 17 | background-color: #FFFBFE; 18 | } 19 | 20 | .div.mapHome { 21 | margin-top: 6.28rem; 22 | } 23 | 24 | h1.login-prompt { 25 | /*margin-top: 3em;*/ 26 | font-family: 'Roboto'; 27 | left: 116px; 28 | font-family: Roboto; 29 | font-style: normal; 30 | font-weight: normal; 31 | font-size: 50px; 32 | line-height: 65px; 33 | color: #13262F; 34 | /*padding-left: 0.5em;*/ 35 | } 36 | 37 | .login-clean { 38 | padding: 40px 0 !important; 39 | background: none; 40 | } 41 | 42 | .login-clean form { 43 | background-color: #FFFBFE; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-brands-400.eot -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-brands-400.woff -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-regular-400.eot -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-regular-400.woff -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-solid-900.eot -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-solid-900.woff -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/ionicons.eot -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/ionicons.ttf -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/fonts/ionicons.woff -------------------------------------------------------------------------------- /hackathon-01162-xxl/assets/img/arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/hackathon-01162-xxl/assets/img/arch.jpg -------------------------------------------------------------------------------- /hackathon-01162-xxl/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 认真首页 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 |
      35 |
      36 |
      37 |

      Toronto Covid
      Intelligence

      The Map v1
      38 |
      39 |
      40 |
      41 |
      42 | icon1 43 |
      44 |
      Plan your trips and get minimum exposure of public during your essential trips
      45 |
      46 | 47 |
      48 | 49 |
      50 |
      51 | icon2 52 |
      53 |
      Get up-to date covid intelligence, and get to fetch a covid-test quick.
      54 |
      55 | 56 |
      57 | 58 |
      59 |
      60 |
      61 |
      62 |
      63 |
      64 |
      65 | 67 |
      68 |
      69 |
      70 |
      71 |
      72 |
      73 |
      74 |
      75 | 83 |
      84 |
      85 |
      86 |
      87 |
      88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 认真首页 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 |

      Login to theMap

      35 |
      36 |
      37 |

      Login Form

      38 |
      39 |
      40 |
      41 |
      Forgot your email or password?
      42 |
      43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 认真首页 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 |

      theMap

      35 |
      36 |
      37 |
      38 |
      39 |
      40 | 42 |
      43 |
      44 |
      45 |
      46 |
      47 |
      48 |
      49 |
      50 |
      51 |
      52 |
      53 |
      54 |
      Weekly new cases
      55 |
      114
      56 |
      57 |
      58 |
      59 |
      60 |
      61 |
      62 |
      63 |
      64 |
      65 |
      66 |
      67 |
      Total Cases
      68 |
      514
      69 |
      70 |
      71 |
      72 |
      73 |
      74 |
      75 |
      76 |
      77 |
      78 |
      79 |
      80 |
      vaccine rate
      81 |
      82 |
      83 |
      50%
      84 |
      85 |
      86 |
      87 |
      50%
      88 |
      89 |
      90 |
      91 |
      92 |
      93 |
      94 |
      95 |
      96 |
      97 |
      98 |
      99 |
      100 |
      101 |
      102 |
      Pending Requests
      103 |
      18
      104 |
      105 |
      106 |
      107 |
      108 |
      109 |
      110 |
      111 |
      112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/readme.md: -------------------------------------------------------------------------------- 1 | 这是不会动的前端 -------------------------------------------------------------------------------- /hackathon-01162-xxl/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy>=1.19.1 2 | scikit-learn>=0.23.2 3 | Flask>=1.1.2 -------------------------------------------------------------------------------- /hackathon-01162-xxl/signup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 认真首页 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 |

      Creating a new account

      35 |
      36 |
      37 |

      Login Form

      38 |
      39 |
      40 |
      41 |
      42 |
      43 |
      44 |
      45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /hackathon-01162-xxl/support.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 认真首页 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 |
      35 |
      36 |
      37 |

      Title

      38 |
      Subtitle
      39 |

      Nullam id dolor id nibh ultricies vehicula ut id elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus.

      LinkLink
      40 |
      41 |
      42 |
      43 |
      44 |

      Title

      45 |

      Nullam id dolor id nibh ultricies vehicula ut id elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus.

      46 |
      47 |
      48 |
      49 |

      Title

      50 |

      Nullam id dolor id nibh ultricies vehicula ut id elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus.

      51 |
      52 |
      53 |
      54 |

      Title

      55 |

      Nullam id dolor id nibh ultricies vehicula ut id elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus.

      56 |
      57 |
      58 |
      59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /python-xxl/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | __pycache__/ -------------------------------------------------------------------------------- /python-xxl/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /python-xxl/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | -------------------------------------------------------------------------------- /python-xxl/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /python-xxl/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /python-xxl/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /python-xxl/.idea/python-xxl.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /python-xxl/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python-xxl/cors.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trojblue/SafeMap/e087305ac4ff705e406f84a28ce5b19223d6db5e/python-xxl/cors.py -------------------------------------------------------------------------------- /python-xxl/data/covid_cases_total.csv: -------------------------------------------------------------------------------- 1 | Neighbourhood ID,Neighbourhood Name,"Rate per 100,000 people",Case Count,Rate 2 | 138,Eglinton East,3464.172813,789,0.22776 3 | 47,Don Valley Village,1829.876899,495,0.27051 4 | 38,Lansing-Westgate,1336.302895,216,0.16164 5 | 9,Edenbridge-Humber Valley,2471.837786,384,0.15535 6 | 44,Flemingdon Park,3720.421283,816,0.21933 7 | 59,Danforth East York,1222.351572,210,0.1718 8 | 129,Agincourt North,2109.02346,614,0.29113 9 | 99,Mount Pleasant East,846.4977645,142,0.16775 10 | 137,Woburn,3791.717304,2028,0.53485 11 | 102,Forest Hill North,2045.915977,262,0.12806 12 | 111,Rockcliffe-Smythe,3205.070574,713,0.22246 13 | 130,Milliken,2009.634201,534,0.26572 14 | 55,Thorncliffe Park,4368.012128,922,0.21108 15 | 7,Willowridge-Martingrove-Richview,2735.150749,606,0.22156 16 | 60,Woodbine-Lumsden,1068.022886,84,0.07865 17 | 12,Markland Wood,1317.036195,139,0.10554 18 | 10,Princess-Rosethorn,1502.126504,166,0.11051 19 | 15,Kingsway South,1391.43566,129,0.09271 20 | 114,Lambton Baby Point,1214.777708,97,0.07985 21 | 133,Centennial Scarborough,2342.463703,313,0.13362 22 | 75,Church-Yonge Corridor,1620.931717,508,0.3134 23 | 26,Downsview-Roding-CFB,5232.226406,1834,0.35052 24 | 61,Taylor-Massey,2588.79041,406,0.15683 25 | 124,Kennedy Park,3177.013374,544,0.17123 26 | 100,Yonge-Eglinton,981.6366252,116,0.11817 27 | 120,Clairlea-Birchmount,3183.367922,859,0.26984 28 | 90,Junction Area,1781.985243,256,0.14366 29 | 115,Mount Dennis,4333.112632,589,0.13593 30 | 32,Englemount-Lawrence,4568.210263,1022,0.22372 31 | 77,Waterfront Communities-The Island,1530.805759,1009,0.65913 32 | 74,North St. James Town,3002.954607,559,0.18615 33 | 70,South Riverdale,1033.146793,288,0.27876 34 | 106,Humewood-Cedarvale,1454.925165,209,0.14365 35 | 93,Dovercourt-Wallace Emerson-Junction,1722.866894,631,0.36625 36 | 42,Banbury-Don Mills,1346.813504,373,0.27695 37 | 97,Yonge-St.Clair,941.890166,118,0.12528 38 | 53,Henry Farm,2474.082554,389,0.15723 39 | 104,Mount Pleasant West,1864.589655,553,0.29658 40 | 8,Humber Heights-Westmount,3397.880891,372,0.10948 41 | 89,Runnymede-Bloor West Village,645.4816286,65,0.1007 42 | 85,South Parkdale,3002.42574,656,0.21849 43 | 140,Guildwood,2964.606232,294,0.09917 44 | 118,Tam O'Shanter-Sullivan,2313.634045,635,0.27446 45 | 36,Newtonbrook West,3659.099492,872,0.23831 46 | ,Missing Address/Postal Code,,1389,#DIV/0! 47 | 84,Little Portugal,2217.366155,345,0.15559 48 | 49,Bayview Woods-Steeles,2151.436825,283,0.13154 49 | 82,Niagara,1417.575369,442,0.3118 50 | 14,Islington-City Centre West,2522.461049,1109,0.43965 51 | 123,Cliffcrest,2453.71823,391,0.15935 52 | 117,L'Amoreaux,2336.73539,1028,0.43993 53 | 122,Birchcliffe-Cliffside,2651.294244,591,0.22291 54 | 81,Trinity-Bellwoods,1304.662962,216,0.16556 55 | 11,Eringate-Centennial-West Deane,1689.261889,314,0.18588 56 | 5,Elms-Old Rexdale,3955.160745,374,0.09456 57 | 51,Willowdale East,854.5822263,431,0.50434 58 | 87,High Park-Swansea,1538.140021,368,0.23925 59 | 68,North Riverdale,939.9127224,112,0.11916 60 | 71,Cabbagetown-South St. James Town,2245.265233,262,0.11669 61 | 83,Dufferin Grove,1832.838354,216,0.11785 62 | 30,Brookhaven-Amesbury,3919.58101,696,0.17757 63 | 24,Black Creek,6095.597369,1325,0.21737 64 | 20,Alderwood,1800.232288,217,0.12054 65 | 4,Rexdale-Kipling,3903.504606,411,0.10529 66 | 125,Ionview,1898.687779,259,0.13641 67 | 110,Keelesdale-Eglinton West,2839.57316,314,0.11058 68 | 2,Mount Olive-Silverstone-Jamestown,6463.555259,2130,0.32954 69 | 52,Bayview Village,1051.59843,225,0.21396 70 | 72,Regent Park,2119.781542,229,0.10803 71 | 80,Palmerston-Little Italy,998.119485,138,0.13826 72 | 116,Steeles,2834.748,698,0.24623 73 | 16,Stonegate-Queensway,1285.377829,322,0.25051 74 | 135,Morningside,3678.029218,642,0.17455 75 | 98,Rosedale-Moore Park,831.6207045,174,0.20923 76 | 136,West Hill,2522.634346,691,0.27392 77 | 29,Maple Leaf,6201.167046,627,0.10111 78 | 1,West Humber-Clairville,5586.575408,1861,0.33312 79 | 101,Forest Hill South,810.6597093,87,0.10732 80 | 112,Beechborough-Greenbrook,4682.986164,308,0.06577 81 | 79,University,1892.993296,144,0.07607 82 | 109,Caledonia-Fairbank,3013.561025,300,0.09955 83 | 56,Leaside-Bennington,1099.358213,185,0.16828 84 | 103,Lawrence Park South,935.5029976,142,0.15179 85 | 73,Moss Park,2350.531552,482,0.20506 86 | 31,Yorkdale-Glen Park,5052.688463,748,0.14804 87 | 25,Glenfield-Jane Heights,5559.017415,1695,0.30491 88 | 91,Weston-Pelham Park,3072.625698,341,0.11098 89 | 66,Danforth,1313.883716,127,0.09666 90 | 3,Thistletown-Beaumond Heights,6650.579151,689,0.1036 91 | 88,High Park North,1055.861384,234,0.22162 92 | 58,Old East York,1516.300227,140,0.09233 93 | 139,Scarborough Village,4944.989237,827,0.16724 94 | 21,Humber Summit,5565.399485,691,0.12416 95 | 19,Long Branch,1378.421261,139,0.10084 96 | 46,Pleasant View,1820.710583,288,0.15818 97 | 131,Rouge,4049.810736,1883,0.46496 98 | 18,New Toronto,2128.58763,244,0.11463 99 | 34,Bathurst Manor,3950.10395,627,0.15873 100 | 67,Playter Estates-Danforth,1729.882112,135,0.07804 101 | 54,O'Connor-Parkview,1718.875502,321,0.18675 102 | 17,Mimico (includes Humber Bay Shores),2028.618537,689,0.33964 103 | 64,Woodbine Corridor,813.3322702,102,0.12541 104 | 126,Dorset Park,4267.487901,1067,0.25003 105 | 57,Broadview North,1434.907383,165,0.11499 106 | 121,Oakridge,3257.49368,451,0.13845 107 | 6,Kingsview Village-The Westway,4159.090909,915,0.22 108 | 127,Bendale,3324.432577,996,0.2996 109 | 107,Oakwood Village,2564.827911,544,0.2121 110 | 45,Parkwoods-Donalda,1781.353254,620,0.34805 111 | 69,Blake-Jones,1358.87149,105,0.07727 112 | 119,Wexford/Maryvale,2604.14801,727,0.27917 113 | 108,Briar Hill-Belgravia,2945.921302,420,0.14257 114 | 27,York University Heights,4943.282717,1364,0.27593 115 | 22,Humbermede,5969.765198,928,0.15545 116 | 41,Bridle Path-Sunnybrook-York Mills,938.9164688,87,0.09266 117 | 128,Agincourt South-Malvern West,2134.107842,507,0.23757 118 | 23,Pelmo Park-Humberlea,4542.063048,487,0.10722 119 | 28,Rustic,3148.576602,313,0.09941 120 | 86,Roncesvalles,1375.717911,206,0.14974 121 | 78,Kensington-Chinatown,1733.073279,311,0.17945 122 | 92,Corso Italia-Davenport,2426.944032,343,0.14133 123 | 63,The Beaches,625.9563222,135,0.21567 124 | 48,Hillcrest Village,1334.593126,226,0.16934 125 | 43,Victoria Village,3021.130782,529,0.1751 126 | 50,Newtonbrook East,938.0629931,151,0.16097 127 | 62,East End-Danforth,1412.469015,302,0.21381 128 | 40,St.Andrew-Windfields,976.8695262,174,0.17812 129 | 132,Malvern,3995.981185,1750,0.43794 130 | 96,Casa Loma,1285.557987,141,0.10968 131 | 134,Highland Creek,3609.732672,451,0.12494 132 | 65,Greenwood-Coxwell,1297.079836,187,0.14417 133 | 39,Bedford Park-Nortown,2216.388363,515,0.23236 134 | 13,Etobicoke West Mall,3241.053342,384,0.11848 135 | 33,Clanton Park,2234.09422,368,0.16472 136 | 105,Lawrence Park North,944.7525159,138,0.14607 137 | 35,Westminster-Branson,4483.519829,1178,0.26274 138 | 113,Weston,5491.32948,988,0.17992 139 | 94,Wychwood,1693.497805,243,0.14349 140 | 95,Annex,1821.398152,556,0.30526 141 | 37,Willowdale West,1287.198866,218,0.16936 142 | 76,Bay Street Corridor,1066.015428,275,0.25797 -------------------------------------------------------------------------------- /python-xxl/data/covid_neighborhood_data.csv: -------------------------------------------------------------------------------- 1 | Neighbourhood ID,Neighbourhood Name,"Rate per 100,000 people",Case Count 2 | 138,Eglinton East,3464.172813,789 3 | 047,Don Valley Village,1829.876899,495 4 | 038,Lansing-Westgate,1336.302895,216 5 | 009,Edenbridge-Humber Valley,2471.837786,384 6 | 044,Flemingdon Park,3720.421283,816 7 | 059,Danforth East York,1222.351572,210 8 | 129,Agincourt North,2109.02346,614 9 | 099,Mount Pleasant East,846.4977645,142 10 | 137,Woburn,3791.717304,2028 11 | 102,Forest Hill North,2045.915977,262 12 | 111,Rockcliffe-Smythe,3205.070574,713 13 | 130,Milliken,2009.634201,534 14 | 055,Thorncliffe Park,4368.012128,922 15 | 007,Willowridge-Martingrove-Richview,2735.150749,606 16 | 060,Woodbine-Lumsden,1068.022886,84 17 | 012,Markland Wood,1317.036195,139 18 | 010,Princess-Rosethorn,1502.126504,166 19 | 015,Kingsway South,1391.43566,129 20 | 114,Lambton Baby Point,1214.777708,97 21 | 133,Centennial Scarborough,2342.463703,313 22 | 075,Church-Yonge Corridor,1620.931717,508 23 | 026,Downsview-Roding-CFB,5232.226406,1834 24 | 061,Taylor-Massey,2588.79041,406 25 | 124,Kennedy Park,3177.013374,544 26 | 100,Yonge-Eglinton,981.6366252,116 27 | 120,Clairlea-Birchmount,3183.367922,859 28 | 090,Junction Area,1781.985243,256 29 | 115,Mount Dennis,4333.112632,589 30 | 032,Englemount-Lawrence,4568.210263,1022 31 | 077,Waterfront Communities-The Island,1530.805759,1009 32 | 074,North St. James Town,3002.954607,559 33 | 070,South Riverdale,1033.146793,288 34 | 106,Humewood-Cedarvale,1454.925165,209 35 | 093,Dovercourt-Wallace Emerson-Junction,1722.866894,631 36 | 042,Banbury-Don Mills,1346.813504,373 37 | 097,Yonge-St.Clair,941.890166,118 38 | 053,Henry Farm,2474.082554,389 39 | 104,Mount Pleasant West,1864.589655,553 40 | 008,Humber Heights-Westmount,3397.880891,372 41 | 089,Runnymede-Bloor West Village,645.4816286,65 42 | 085,South Parkdale,3002.42574,656 43 | 140,Guildwood,2964.606232,294 44 | 118,Tam O'Shanter-Sullivan,2313.634045,635 45 | 036,Newtonbrook West,3659.099492,872 46 | 084,Little Portugal,2217.366155,345 47 | 049,Bayview Woods-Steeles,2151.436825,283 48 | 082,Niagara,1417.575369,442 49 | 014,Islington-City Centre West,2522.461049,1109 50 | 123,Cliffcrest,2453.71823,391 51 | 117,L'Amoreaux,2336.73539,1028 52 | 122,Birchcliffe-Cliffside,2651.294244,591 53 | 081,Trinity-Bellwoods,1304.662962,216 54 | 011,Eringate-Centennial-West Deane,1689.261889,314 55 | 005,Elms-Old Rexdale,3955.160745,374 56 | 051,Willowdale East,854.5822263,431 57 | 087,High Park-Swansea,1538.140021,368 58 | 068,North Riverdale,939.9127224,112 59 | 071,Cabbagetown-South St. James Town,2245.265233,262 60 | 083,Dufferin Grove,1832.838354,216 61 | 030,Brookhaven-Amesbury,3919.58101,696 62 | 024,Black Creek,6095.597369,1325 63 | 020,Alderwood,1800.232288,217 64 | 004,Rexdale-Kipling,3903.504606,411 65 | 125,Ionview,1898.687779,259 66 | 110,Keelesdale-Eglinton West,2839.57316,314 67 | 002,Mount Olive-Silverstone-Jamestown,6463.555259,2130 68 | 052,Bayview Village,1051.59843,225 69 | 072,Regent Park,2119.781542,229 70 | 080,Palmerston-Little Italy,998.119485,138 71 | 116,Steeles,2834.748,698 72 | 016,Stonegate-Queensway,1285.377829,322 73 | 135,Morningside,3678.029218,642 74 | 098,Rosedale-Moore Park,831.6207045,174 75 | 136,West Hill,2522.634346,691 76 | 029,Maple Leaf,6201.167046,627 77 | 001,West Humber-Clairville,5586.575408,1861 78 | 101,Forest Hill South,810.6597093,87 79 | 112,Beechborough-Greenbrook,4682.986164,308 80 | 079,University,1892.993296,144 81 | 109,Caledonia-Fairbank,3013.561025,300 82 | 056,Leaside-Bennington,1099.358213,185 83 | 103,Lawrence Park South,935.5029976,142 84 | 073,Moss Park,2350.531552,482 85 | 031,Yorkdale-Glen Park,5052.688463,748 86 | 025,Glenfield-Jane Heights,5559.017415,1695 87 | 091,Weston-Pelham Park,3072.625698,341 88 | 066,Danforth,1313.883716,127 89 | 003,Thistletown-Beaumond Heights,6650.579151,689 90 | 088,High Park North,1055.861384,234 91 | 058,Old East York,1516.300227,140 92 | 139,Scarborough Village,4944.989237,827 93 | 021,Humber Summit,5565.399485,691 94 | 019,Long Branch,1378.421261,139 95 | 046,Pleasant View,1820.710583,288 96 | 131,Rouge,4049.810736,1883 97 | 018,New Toronto,2128.58763,244 98 | 034,Bathurst Manor,3950.10395,627 99 | 067,Playter Estates-Danforth,1729.882112,135 100 | 054,O'Connor-Parkview,1718.875502,321 101 | 017,Mimico (includes Humber Bay Shores),2028.618537,689 102 | 064,Woodbine Corridor,813.3322702,102 103 | 126,Dorset Park,4267.487901,1067 104 | 057,Broadview North,1434.907383,165 105 | 121,Oakridge,3257.49368,451 106 | 006,Kingsview Village-The Westway,4159.090909,915 107 | 127,Bendale,3324.432577,996 108 | 107,Oakwood Village,2564.827911,544 109 | 045,Parkwoods-Donalda,1781.353254,620 110 | 069,Blake-Jones,1358.87149,105 111 | 119,Wexford/Maryvale,2604.14801,727 112 | 108,Briar Hill-Belgravia,2945.921302,420 113 | 027,York University Heights,4943.282717,1364 114 | 022,Humbermede,5969.765198,928 115 | 041,Bridle Path-Sunnybrook-York Mills,938.9164688,87 116 | 128,Agincourt South-Malvern West,2134.107842,507 117 | 023,Pelmo Park-Humberlea,4542.063048,487 118 | 028,Rustic,3148.576602,313 119 | 086,Roncesvalles,1375.717911,206 120 | 078,Kensington-Chinatown,1733.073279,311 121 | 092,Corso Italia-Davenport,2426.944032,343 122 | 063,The Beaches,625.9563222,135 123 | 048,Hillcrest Village,1334.593126,226 124 | 043,Victoria Village,3021.130782,529 125 | 050,Newtonbrook East,938.0629931,151 126 | 062,East End-Danforth,1412.469015,302 127 | 040,St.Andrew-Windfields,976.8695262,174 128 | 132,Malvern,3995.981185,1750 129 | 096,Casa Loma,1285.557987,141 130 | 134,Highland Creek,3609.732672,451 131 | 065,Greenwood-Coxwell,1297.079836,187 132 | 039,Bedford Park-Nortown,2216.388363,515 133 | 013,Etobicoke West Mall,3241.053342,384 134 | 033,Clanton Park,2234.09422,368 135 | 105,Lawrence Park North,944.7525159,138 136 | 035,Westminster-Branson,4483.519829,1178 137 | 113,Weston,5491.32948,988 138 | 094,Wychwood,1693.497805,243 139 | 095,Annex,1821.398152,556 140 | 037,Willowdale West,1287.198866,218 141 | 076,Bay Street Corridor,1066.015428,275 142 | -------------------------------------------------------------------------------- /python-xxl/knn.py: -------------------------------------------------------------------------------- 1 | import json 2 | import numpy as np 3 | from sklearn.neighbors import KNeighborsClassifier 4 | 5 | GEOJSON = './data/toronto.geojson' 6 | 7 | def get_data(): 8 | """读取geoJSON, 输出numpy array 9 | """ 10 | with open(GEOJSON) as f: 11 | data = json.load(f) 12 | 13 | Xtrain_all, Ttrain_all = None, None 14 | 15 | for feature in data['features']: 16 | coord = (feature['geometry']['coordinates']) 17 | area = (feature['properties']['AREA_S_CD']) 18 | 19 | if Xtrain_all is None: 20 | Xtrain_all = np.array(coord[0]) 21 | Ttrain_all = np.full(Xtrain_all.shape[0], fill_value=area) 22 | else: 23 | Xtrain = np.array(coord[0]) 24 | Ttrain = np.full(Xtrain.shape[0], fill_value=area) 25 | 26 | Xtrain_all = np.concatenate((Xtrain_all, Xtrain), axis=0) 27 | Ttrain_all = np.concatenate((Ttrain_all, Ttrain), axis=0) 28 | 29 | return Xtrain_all, Ttrain_all 30 | 31 | 32 | def get_classifier(): 33 | Xtrain, Ttrain = get_data() 34 | k=21 # 达到99.99%置信度的最小值; k越小速度越快 35 | clf = KNeighborsClassifier(k) 36 | clf.fit(Xtrain, Ttrain) 37 | return clf 38 | 39 | def get_community(clf, coords): 40 | """clf: classifier 41 | coords: (x, y) 42 | return: community(string) 43 | """ 44 | prediction = clf.predict([[coords[0], coords[1]]]) 45 | str_form = prediction[0].item() 46 | 47 | return str_form 48 | 49 | def get_community_auto(coords): 50 | """单次, 重新加载数据, 稍微慢一点""" 51 | c = coords 52 | if isinstance(coords[0], str): 53 | c=(float(coords[0]), float(coords[1])) 54 | 55 | Xtrain, Ttrain = get_data() 56 | k=21 # 达到99.99%置信度的最小值; k越小速度越快 57 | clf = KNeighborsClassifier(k) 58 | clf.fit(Xtrain, Ttrain) 59 | return get_community(clf, c) 60 | 61 | 62 | if __name__ == '__main__': 63 | clf = get_classifier() 64 | 65 | pred = get_community(clf, (-79.4, 43.7)) 66 | print(pred) 67 | 68 | -------------------------------------------------------------------------------- /python-xxl/predictor.py: -------------------------------------------------------------------------------- 1 | import flask 2 | from flask_cors import CORS 3 | import csv 4 | import heapq 5 | from flask import request, jsonify 6 | 7 | app = flask.Flask(__name__) 8 | app.config["DEBUG"] = True 9 | CORS(app) 10 | 11 | 12 | 13 | # Create some test data for our catalog in the form of a list of dictionaries. 14 | books = [ 15 | {'id': 0, 16 | 'title': 'A Fire Upon the Deep', 17 | 'author': 'Vernor Vinge', 18 | 'first_sentence': 'The coldsleep itself was dreamless.', 19 | 'year_published': '1992'}, 20 | {'id': 1, 21 | 'title': 'The Ones Who Walk Away From Omelas', 22 | 'author': 'Ursula K. Le Guin', 23 | 'first_sentence': 'With a clamor of bells that set the swallows soaring, the Festival of Summer came to the city Omelas, bright-towered by the sea.', 24 | 'published': '1973'}, 25 | {'id': 2, 26 | 'title': 'Dhalgren', 27 | 'author': 'Samuel R. Delany', 28 | 'first_sentence': 'to wound the autumnal city.', 29 | 'published': '1975'} 30 | ] 31 | 32 | 33 | @app.route('/', methods=['GET']) 34 | def home(): 35 | return '''

      Distant Reading Archive

      36 |

      A prototype API for distant reading of science fiction novels.

      ''' 37 | 38 | @app.route('/foo', methods=['POST']) 39 | def foo(): 40 | response = flask.jsonify({'result': request.json}) 41 | response.headers.add('Access-Control-Allow-Origin', '*') 42 | return response 43 | 44 | @app.route('/api/v1/resources/books/all', methods=['GET']) 45 | def api_all(): 46 | return jsonify(books) 47 | 48 | 49 | @app.route('/api/v1/resources/books', methods=['GET']) 50 | def api_id(): 51 | # Check if an ID was provided as part of the URL. 52 | # If ID is provided, assign it to a variable. 53 | # If no ID is provided, display an error in the browser. 54 | if 'id' in request.args: 55 | id = int(request.args['id']) 56 | else: 57 | return "Error: No id field provided. Please specify an id." 58 | 59 | # Create an empty list for our results 60 | results = [] 61 | 62 | # Loop through the data and match results that fit the requested ID. 63 | # IDs are unique, but other fields might return many results 64 | for book in books: 65 | if book['id'] == id: 66 | results.append(book) 67 | 68 | # Use the jsonify function from Flask to convert our list of 69 | # Python dictionaries to the JSON format. 70 | return jsonify(results) 71 | 72 | app.run() 73 | -------------------------------------------------------------------------------- /python-xxl/rec.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import math 3 | import knn, flask 4 | from flask import request, jsonify 5 | from flask_cors import CORS 6 | 7 | HOSPITALS = "./data/all_hospitals_in_toronto.csv" 8 | CASES = "./data/covid_cases_total.csv" 9 | COMMUNITY = "./data/covid_neighborhood_data.csv" 10 | ASSESSMENT = "./data/assessment_center_locations_utf8.csv" 11 | 12 | 13 | class communityNotFoundError(Exception): 14 | pass 15 | 16 | def get_assessment_list(coords): 17 | reader = csv.DictReader(open(ASSESSMENT, 'rt', encoding="utf8")) 18 | dict_list = [] 19 | for line in reader: 20 | if not line['longitude']: 21 | continue 22 | try: 23 | curr_coord = (float(line['longitude']), float(line['latitude'])) #这里和get_hospital_list不一样 24 | curr_dist = math.dist(curr_coord, coords) 25 | line['dist'] = curr_dist 26 | line['X'] = curr_coord[0] 27 | line['Y'] = curr_coord[1] 28 | dict_list.append(line) 29 | dict_list.append(line) 30 | except ValueError: 31 | continue 32 | return dict_list 33 | 34 | def get_hospital_list(coords): 35 | """coords: (x, y) 36 | return:[Dict(json)] 37 | """ 38 | reader = csv.DictReader(open(HOSPITALS, 'rt', encoding="utf8")) 39 | dict_list = [] 40 | for line in reader: 41 | x, y = float(line['\ufeffX']), float(line['Y']) 42 | curr_dist = math.dist((x,y), coords) 43 | line['dist'] = curr_dist 44 | 45 | line['X']=str(x) #修复开头的乱码 46 | # line.pop('\ufeffX', None) 47 | 48 | dict_list.append(line) 49 | return dict_list 50 | 51 | def get_cases_list(coords): 52 | """coords: (x, y) 53 | return:[Dict(json)] 54 | """ 55 | reader = csv.DictReader(open(CASES, 'rt', encoding="utf8")) 56 | dict_list = [] 57 | for line in reader: 58 | curr_coord = (float(line['X']), float(line['Y'])) #这里和get_hospital_list不一样 59 | curr_dist = math.dist(curr_coord, coords) 60 | line['dist'] = curr_dist 61 | dict_list.append(line) 62 | return dict_list 63 | 64 | 65 | def get_community_list(): 66 | reader = csv.DictReader(open(COMMUNITY, 'rt', encoding="utf8")) 67 | dict_list = [] 68 | for line in reader: 69 | dict_list.append(line) 70 | return dict_list 71 | 72 | def get_community_by_id(id:str): 73 | """输入id, 输出community json 74 | community的csv不大, 所以直接重复读取了 75 | """ 76 | com = get_community_list() 77 | 78 | for i in com: 79 | if id in i.values(): 80 | return i 81 | 82 | return None 83 | 84 | def get_community(com_id, com_list): 85 | curr_community = None # 找community json 86 | for com in com_list: 87 | if com['Neighbourhood ID'] == com_id: 88 | curr_community = com 89 | break 90 | if not curr_community: 91 | raise communityNotFoundError 92 | return curr_community 93 | 94 | 95 | def get_infection_rate_list(lst_sorted, count): 96 | """helper; 距离最近count个医院添加感染率信息 97 | lst:sorted: 按距离从小到大排列的所有医院 98 | """ 99 | com_list = get_community_list() 100 | rate_basis = lst_sorted[:count] 101 | 102 | clf = knn.get_classifier() 103 | for base in rate_basis: 104 | coords = (base['X'], base['Y']) 105 | com_id = knn.get_community(clf, coords) # 三位数str 106 | base['community'] = com_id 107 | curr_community = get_community(com_id, com_list) 108 | 109 | base['infection_rate'] = curr_community['Rate per 100,000 people'] 110 | return rate_basis 111 | 112 | 113 | def get_recommend(coord): 114 | """返回List[[json],[json],[json]] 115 | 对应最短路径, 最短路径walk-in, 感染率最低 116 | """ 117 | response = [] 118 | lst = get_assessment_list(coord) 119 | lst_sorted = sorted(lst, key=lambda k: k['dist']) # 距离从少到大排列 120 | response.append(lst_sorted[:3]) 121 | 122 | walk_ins = [] # 最短路径walk-in 123 | for i in lst_sorted: 124 | if i.get('walk_ins', None).lower() == 'yes' and len(walk_ins) < 3: 125 | walk_ins.append(i) 126 | response.append(walk_ins) 127 | 128 | rate_basis = get_infection_rate_list(lst_sorted, count=20) # 距离最近20个医院添加感染率信息 129 | rate_lst_sorted = sorted(rate_basis, key=lambda k: k['infection_rate']) 130 | response.append(rate_lst_sorted[:3]) 131 | 132 | return response 133 | 134 | def run_flask_server(): 135 | app = flask.Flask(__name__) 136 | app.config["DEBUG"] = True 137 | CORS(app) 138 | 139 | # @app.route('/foo', methods=['POST']) 140 | # def foo(): 141 | # response = flask.jsonify({'result': request.json}) 142 | # response.headers.add('Access-Control-Allow-Origin', '*') 143 | # return response 144 | 145 | @app.route('/foo', methods=['POST']) 146 | def recommend(): 147 | x, y = request.json['lac'], request.json['lng'] #TODO: 记得改回X和Y 148 | recommends = get_recommend((float(x), float(y))) 149 | 150 | response = flask.jsonify({'result': { 151 | 'nearest':recommends[0], 152 | 'nearest_walk_in':recommends[1], 153 | 'nearest_safest':recommends[2] 154 | }}) 155 | response.headers.add('Access-Control-Allow-Origin', '*') 156 | return response 157 | 158 | app.run() 159 | 160 | 161 | 162 | if __name__ == '__main__': 163 | 164 | print("flask server running...") 165 | run_flask_server() 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | --------------------------------------------------------------------------------