Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
505 commits
Select commit Hold shift + click to select a range
7b11206
update
Jan 28, 2019
685a930
update
Jan 28, 2019
aeab02f
update
Jan 28, 2019
f928084
update
Jan 28, 2019
4f51588
update
Jan 28, 2019
8786cfa
update
Jan 28, 2019
2aa85da
update
Jan 28, 2019
4c37862
update
Jan 28, 2019
ec833d1
update
Jan 28, 2019
0aa6b55
update
Jan 28, 2019
93afa14
update
Jan 28, 2019
77db6f7
update
Jan 28, 2019
c994729
update
Jan 28, 2019
569902e
update
Jan 28, 2019
391c74e
update
Feb 10, 2019
715ddb1
update
Feb 10, 2019
eee01af
update
Feb 10, 2019
f9aa6f0
update
Feb 10, 2019
77d3285
update
Feb 10, 2019
86dad80
update
Feb 10, 2019
13be79e
update
Feb 10, 2019
b97f8b0
update
Feb 10, 2019
305b88b
update
Feb 10, 2019
209fdcb
update
Feb 10, 2019
1b3ced6
update
Feb 10, 2019
5720f5c
update
Feb 10, 2019
b57eec6
update
Feb 10, 2019
1da58bb
update
Feb 10, 2019
0e39cc2
update
Feb 10, 2019
b3c4b83
update
Feb 10, 2019
20bfa36
update
Feb 10, 2019
648e027
update
Feb 10, 2019
90c966d
update
Feb 10, 2019
eb9d842
update
Feb 10, 2019
3d6553b
update
Feb 10, 2019
8d6391a
update
Feb 10, 2019
c55b49b
update
Feb 10, 2019
06b81a3
update
Feb 10, 2019
d0828ad
update
Feb 10, 2019
f828d35
update
Feb 10, 2019
83a3d77
update
Feb 10, 2019
0a8787b
update
Feb 10, 2019
cf22f4f
update
Feb 10, 2019
15babda
update
Feb 10, 2019
9dbb1b9
update
Feb 10, 2019
a73bf8a
update
Feb 10, 2019
c2120c6
update
Feb 10, 2019
56ad356
update
Feb 10, 2019
62b74a3
update
Feb 10, 2019
4aed102
update
Feb 10, 2019
4a69bd3
update
Feb 10, 2019
8fcf24d
update
Feb 10, 2019
ef8c691
update
Feb 10, 2019
e878895
update
Feb 10, 2019
5b3f8fb
update
Feb 10, 2019
56277a6
update
Feb 10, 2019
8377fae
update
Feb 10, 2019
7f728cd
update
Feb 10, 2019
d368082
update
Feb 10, 2019
f8f2947
update
Feb 10, 2019
e06628a
update
Feb 10, 2019
c0e62f8
update
Feb 10, 2019
a968518
update
Feb 10, 2019
fa7324c
update
Feb 10, 2019
eecf048
update
Feb 10, 2019
ce6b9ff
update
Feb 10, 2019
1873307
update
Feb 10, 2019
3a8edc0
update
Feb 10, 2019
b9de480
update
Feb 10, 2019
ca267f1
update
Feb 10, 2019
3d75575
update
Feb 10, 2019
a08ad9b
update
Feb 10, 2019
792b363
update
Feb 10, 2019
ed951ee
update
Feb 10, 2019
0563539
update
Feb 10, 2019
0afb707
update
Feb 10, 2019
4c7ed63
update
Feb 10, 2019
5ce2719
update
Feb 10, 2019
cb47359
update
Feb 10, 2019
a8f765d
update
Feb 10, 2019
96701fb
update
Feb 10, 2019
36d2933
update
Feb 10, 2019
a693a46
update
Feb 10, 2019
15398ed
update
Feb 10, 2019
a5a464f
update
Feb 10, 2019
857dbda
update
Feb 11, 2019
e52cb3b
update
Feb 11, 2019
beeed72
update
Feb 11, 2019
fc66c91
update
Feb 11, 2019
573b7a1
update
Feb 11, 2019
b5cc7bc
update
Feb 11, 2019
84596b2
update
Feb 11, 2019
5db1d2f
update
Feb 11, 2019
31bec77
update
Feb 11, 2019
2106e12
update
Feb 11, 2019
086acce
update
Feb 11, 2019
3523494
update
Feb 11, 2019
bc93569
update
Feb 11, 2019
d7b607f
update
Feb 11, 2019
e8d5f99
update
Feb 11, 2019
82be17c
update
Feb 11, 2019
99c68c6
update
Feb 11, 2019
94da672
update
Feb 11, 2019
33ba039
update
Feb 11, 2019
a4d5553
update
Feb 11, 2019
f0bd241
update
Feb 11, 2019
0fd9c6b
update
Feb 11, 2019
3f9a468
update
Feb 11, 2019
22b3161
update
Feb 11, 2019
6aeeb21
update
Feb 11, 2019
8934eda
update
Feb 11, 2019
137c430
update
Feb 11, 2019
988f5a7
update
Feb 11, 2019
19e31df
update
Feb 11, 2019
e5020e6
update
Feb 11, 2019
3cfcf2d
update
Feb 11, 2019
d3f9004
update
Feb 11, 2019
1f8bb76
update
Feb 11, 2019
543bb25
update
Feb 11, 2019
e273f5f
update
Feb 13, 2019
4c8878e
update
Feb 18, 2019
0a16076
update
Feb 18, 2019
cb76629
update
Feb 18, 2019
9088883
update
Feb 18, 2019
df48048
update
Feb 18, 2019
63c6a6a
update
Feb 18, 2019
6ecb97a
update
Feb 18, 2019
e598912
update
Feb 18, 2019
c2ea49c
update
Feb 18, 2019
18d3c18
update
Feb 18, 2019
a2388ff
update
Feb 19, 2019
3f3d214
update
Feb 19, 2019
3425961
update
Feb 19, 2019
66383c6
update
Feb 19, 2019
76e7ecf
update
Feb 19, 2019
3497573
update
Feb 19, 2019
ea25810
update
Feb 19, 2019
c1b0014
update
Feb 19, 2019
fcad341
update
Feb 19, 2019
7afecfa
update
Feb 19, 2019
f610d4c
update
Feb 19, 2019
0964aa2
update
Feb 19, 2019
b0a63b7
update
Feb 19, 2019
8e2fd51
update
Feb 19, 2019
4b4cb35
update
Feb 19, 2019
aa4b4fb
update
Feb 19, 2019
166a43b
update
Feb 19, 2019
73a627e
update
Feb 19, 2019
2b2525d
update
Feb 19, 2019
59b6b4f
update
Feb 19, 2019
e86cebb
update
Feb 19, 2019
b58adbe
update
Feb 19, 2019
1d25b1f
update
Feb 19, 2019
f5b4722
update
Feb 19, 2019
a59801b
update
Feb 19, 2019
5db5ad5
update
Feb 19, 2019
4d73c0f
update
Feb 19, 2019
fb86a37
update
Feb 19, 2019
19f09b4
update
Feb 19, 2019
6ef395d
update
Feb 19, 2019
2137f86
update
Feb 19, 2019
f7b2b9d
update
Feb 19, 2019
d2ae782
update
Feb 19, 2019
1636eb1
update
Feb 19, 2019
9b48ab3
update
Feb 19, 2019
98e3582
update
Feb 19, 2019
34c41cd
update
Feb 19, 2019
09c4745
update
Feb 19, 2019
a0900a0
update
Feb 19, 2019
ca0abde
update
Feb 19, 2019
8e98e36
update
Feb 19, 2019
3f18bda
update
Feb 19, 2019
547523a
update
Feb 19, 2019
e9689e9
update
Feb 19, 2019
4452bfa
update
Feb 19, 2019
a365a6f
update
Feb 19, 2019
5db91bf
update
Feb 19, 2019
e46f7d8
update
Feb 19, 2019
6a9209d
update
Feb 19, 2019
fe7ba44
update
Feb 19, 2019
c3e7406
update
Feb 19, 2019
ea20eb1
update
Feb 19, 2019
c8aeb49
update
Feb 19, 2019
ca96833
update
Feb 19, 2019
f231d8c
update
Feb 19, 2019
de98767
update
Feb 19, 2019
658de51
update
Feb 19, 2019
2486bbf
update
Feb 19, 2019
db56419
update
Feb 19, 2019
ae78048
update
Feb 19, 2019
96e3dba
update
Feb 19, 2019
11553d7
update
Feb 19, 2019
8f69041
update
Feb 19, 2019
cd4c2c8
update
Feb 19, 2019
3f99478
update
Feb 19, 2019
f08c57b
update
Feb 19, 2019
cd75074
update
Feb 19, 2019
95fb9d4
update
Feb 19, 2019
330222a
update
Feb 19, 2019
0a98652
update
Feb 19, 2019
b88fc4b
update
Feb 19, 2019
fad21ca
update
Feb 19, 2019
02e923f
update
Feb 19, 2019
8554ca7
update
Feb 19, 2019
40760b0
update
Feb 19, 2019
456ab3c
update
Feb 19, 2019
a27fceb
update
Feb 19, 2019
e24a4b3
New feature branch
tmgreenside Mar 25, 2019
acaa2d6
Added Google Speech start script
tmgreenside Apr 1, 2019
abcdef3
Demo ready for alternative that does not use Google
tmgreenside Apr 1, 2019
a0fdab3
update
drichard2 Apr 1, 2019
293a378
setup
drichard2 Apr 1, 2019
f3fcb0e
update april 1
drichard2 Apr 1, 2019
92eb010
completed walkthrough:go to class page
drichard2 Apr 1, 2019
581f501
completed walkthrough:create attempt
drichard2 Apr 1, 2019
c67a02a
Speech to text is demo ready
tmgreenside Apr 3, 2019
e1e5abc
Holdover approved by Dr Hunter
tmgreenside Apr 11, 2019
6527448
update
Apr 14, 2019
9eb9319
update
Apr 14, 2019
68ac6e3
update
Apr 14, 2019
9e6e2ca
updagte
Apr 14, 2019
eecd452
udpate
Apr 14, 2019
5107140
udpate
Apr 14, 2019
55ecb22
udpate
Apr 14, 2019
eb1f50b
udpate
Apr 14, 2019
19fa9a7
udpate
Apr 14, 2019
7852da9
udpate
Apr 14, 2019
e73c628
update
Apr 14, 2019
6f47374
update
Apr 14, 2019
982d413
update
Apr 14, 2019
8c17c01
update
Apr 15, 2019
5ad05e0
Web speech works for teacher creating worksheet as well as student
tmgreenside Apr 17, 2019
e0f0b15
Fixed a jQuery typo in expression_form.html
tmgreenside Apr 17, 2019
b000470
Merge branch 'poster' into csv-upload
drichard2 Apr 23, 2019
b2f3065
Merge pull request #28 from drichard2/csv-upload
drichard2 Apr 23, 2019
09fd274
Merge pull request #29 from drichard2/student-dashboard
drichard2 Apr 23, 2019
d78b966
Merge branch 'poster' into teacher-dashboard
drichard2 Apr 23, 2019
bd4d0f5
update
drichard2 Apr 23, 2019
b94a850
Merge pull request #31 from tmgreenside/SpeechText
drichard2 Apr 24, 2019
6034f96
Merge pull request #32 from tmgreenside/corpus
drichard2 Apr 24, 2019
281d453
finished all help walkthrough, only a couple bugs issues
drichard2 Apr 24, 2019
44f04bb
Merge pull request #30 from drichard2/teacher-dashboard
drichard2 Apr 24, 2019
86b191f
update
drichard2 Apr 25, 2019
237d9ac
update
drichard2 Apr 25, 2019
9620763
finished all student guides
drichard2 Apr 26, 2019
4656607
completed all teacher guides
drichard2 Apr 26, 2019
2449415
update
Apr 28, 2019
f337c2e
Merge branch 'poster' into helpfeature
drichard2 Apr 28, 2019
8c7a2a8
Merge branch 'master' into pr/6
zekehuntergreen Feb 13, 2022
12f0d44
fix tests
zekehuntergreen Feb 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 101 additions & 4 deletions ComSemApp/administrator/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from django.views.generic import ListView, CreateView, UpdateView, FormView, DeleteView
from django.views import View
from django.core.mail import send_mail
from django.core.validators import validate_email
from django.contrib import messages
import re
from django.contrib.auth.models import User

from ComSemApp.models import *
Expand All @@ -17,7 +19,6 @@
from ComSemApp.libs.mixins import RoleViewMixin



class AdminViewMixin(RoleViewMixin):

role_class = Admin
Expand Down Expand Up @@ -66,6 +67,104 @@ def _send_email(self, user, password):
fail_silently=False,
)

def db_create_user(self, **kwargs):
user = User.objects.create(**kwargs)
password = User.objects.make_random_password()
user.set_password(password)
user.save()
self._send_email(user, password)
return user

def db_create_student(self, **kwargs):
institution = self.insititution
user = self.db_create_user(**kwargs)
return Student.objects.create(user=user, institution=institution)

#handle CSV upload
def post(self, request, *args, **kwargs):
if (len(request.FILES) > 0): #check to make sure file was uploaded
csv_file = request.FILES['file']
file_data = csv_file.read().decode("utf-8")
lines = file_data.split("\n")
message_content = [""]
linecount = 0
rejectcount = 0
for line in lines:
if len(line): #make sure line isnt empty
fields = line.split(",")
okToCreate = True
rejected = False
linecount += 1
if (fields[0] == "" or fields[0] == ""):
#end of file
break
if (len(fields) < 4):
message = "!!! Missing columns, please make sure you have columns as follows: firstname,lastname,email,username"
message_content.append(message)
rejected = True
rejectcount += 1
break
if (fields[0].isalpha() == False or fields[1].isalpha() == False):
message = (str(linecount) + " " + fields[0] + " " + fields[1] + " " + fields[2] + " " + fields[3] + " Invalid First or Last Name \n")
message_content.append(message)
rejectcount += 1
rejected = True
okToCreate = False
for user in Student.objects.filter(institution=self.institution):
if(user.user.email== fields[2]):
okToCreate = False
if (rejected == False): ##if rejected is false, we need to increment the number of rejects, if its already false, dont increment it but still log error
rejectcount += 1
rejected = True
message = (str(linecount) + " " + fields[0] + " " + fields[1] + " " + fields[2] + " " + fields[3] + " Duplicate Email Address \n")
message_content.append(message)

if(user.user.username== fields[3]):
okToCreate = False
if (rejected == False): ##if rejected is false, we need to increment the number of rejects, if its already false, dont increment it but still log error
rejectcount += 1
rejected = True
message = (str(linecount) + " " + fields[0] + " " + fields[1] + " " + fields[2] + " " + fields[3] + " Duplicate Username \n")
message_content.append(message)
if(okToCreate == False):
break

# Check if a valid email address
match = re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', fields[2].lower())

if (match == None):
if(rejected == False):
rejectcount += 1
rejected = True
okToCreate = False
message = (str(linecount) + " " + fields[0] + " " + fields[1] + " " + fields[2] + " " + fields[3] + " Invalid Email Address \n")
message_content.append(message)

# Check for valid username
usernameCheck = re.match('^[\w.@+-]+$', fields[3])
if (usernameCheck == None):
if(rejected == False):
rejectcount += 1
rejected = True
okToCreate = False
message = (str(linecount) + " " + fields[0] + " " + fields[1] + " " + fields[2] + " " + fields[3] + " Invalid Username \n")
message_content.append(message)

if (okToCreate == True):
user = {
"first_name": fields[0],
"last_name": fields[1],
"email": fields[2],
"username": fields[3]
}
self.db_create_student(**user)
print("student made")
message_content.insert(0, ("" + str((linecount - rejectcount)) + "/" + str(linecount)+ " Accounts created sucessfully\n" + "The below users were not added, Their line numbers are listed to the left,\nLines with multiple errors will be listed multiple times \n \n"))
message_disp = "".join(message_content)
messages.add_message(request, messages.ERROR, message_disp)
request.FILES.pop('file', None) #delete the csv file from memory
return HttpResponseRedirect(self.success_url)

@atomic
def _create_student(self, **kwargs):
user = User.objects.create_user(**kwargs)
Expand Down Expand Up @@ -134,11 +233,9 @@ def post(self, request):
messages.add_message(request, messages.ERROR, message)
return HttpResponseRedirect(self.success_url)


def get_queryset(self):
def get_queryset(self):
return Student.objects.filter(institution=self.institution)


class CourseListView(AdminViewMixin, ListView):
model = Course
template_name = 'ComSemApp/admin/course_list.html'
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions ComSemApp/static/ComSemApp/DKNotus-Tour-master/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2016 DK Notus IT Team

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
235 changes: 235 additions & 0 deletions ComSemApp/static/ComSemApp/DKNotus-Tour-master/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
# DK Notus Tour

#### This compact solution for guided tours has 27 languages support. It requires only two very common dependencies: **jQuery** and **Bootstrap**. Also has useful features like auto scroll and "spotlight". We hope you enjoy it.

![DK Notus Tour](DKNotusTour.png)

We tried to keep all data regarding usage as short as possible.
## 1. Features

Features that we considerble important:

- **small requirements** - only jQuery and Bootstrap;
- **simple usage** - one function for common usage - yes, it's that simple;
- **events** - for advanced programmers usage;
- **scroll** - and some more useful features;
- **multi elements selection** - you can point more then one element for one tour step;
- **translations** - 27 languages support.

## 2. Simple use case

Lets start with two step tour for elements below:

First of all we need to include two common libraries jQuery and Bootstrap. You ca use some CDN for that.

<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

Then it's time tour library `dknotus-tour.js` or `dknotus-tour.min.js`.

<script src="dknotus-tour.js"></script>

Finally we can define our own tour and run it with Tour.run(). Yes, it's that simple.

```javascript
$(function(){
$('#simpleBtn').click(function(){
Tour.run([
{
element: $('#btn1'),
content: 'first btn'
},
{
element: $('#btn2'),
content: 'and the second one<br>description might be <strong>HTML</strong>'
},
]);
});
});
```

## 3. Different tour positions
```javascript
$(function(){
$('#positionsBtn').click(function(){
Tour.run([
{
element: $('#posBtn'),
content: 'by default tour is on the right'
},
{
element: $('#posBtn'),
content: 'but it can be on top',
position: 'top'
},
{
element: $('#posBtn'),
content: 'bottom',
position: 'bottom'
},
{
element: $('#posBtn'),
content: 'and finally on the left',
position: 'left'
}
]);
});
});
```

## 4. Global and local parameters

Tour may be run with two parameters: tour description (mandatory) and global options (optional) Tour.run(tourDescription, options). If for some tour hint some parameter is not set, then if it's possible it's taken from options.

Possible parameters for hints descriptions and for global options:

Parameter | Default value | Description
--------- | ------------- | -----------
element | *none* | jQuery element (might be more then one), if it's not set then hint is skipped.
content | *empty string* | It's for contents of particular hints.
close | true | Defines if close button should be shown.
language | en | Defines interface language. Available languages:
|| en | English (default)
|| pl | Polish
|| be | Belarusian
|| ca | Catalan
|| cs | Czech
|| da | Danish
|| de | German
|| el | Greek
|| es | Spanish
|| et | Estonian
|| fi | Finnish
|| fr | French
|| hu | Hungarian
|| it | Italian
|| lt | Lithuanian
|| lv | Latvian
|| mk | Macedonian
|| nl | Dutch
|| no | Norwegian
|| pt | Portuguese
|| ru | Russian
|| sk | Slovak
|| sl | Slovenian
|| sq | Albanian
|| sv | Swedish
|| tr | Turkish
|| uk | Ukrainian
padding | 5 | Extra space around tour exposed elements. (Has only sense when spotlight option is true).
position | right | Determines where hint should be shown relatively to element it describes.
||| Possible values: right, left, top and bottom.
scroll | true | If true then scrolls window so selected element and hint would be as close as possible to the view center.
spotlight | true | If true then covers everything except selected element and hint with shadow.
forceCorrectionLeft | 0 | Useful if for some reason left offset needs to be modified.
forceCorrectionTop | 0 | Useful if for some reason top offset needs to be modified.
forceCorrectionWidth | 0 | Useful if for some reason width needs to be modified.
forceCorrectionHeight | 0 | Useful if for some reason height needs to be modified.

All above options can be used for both: single hint description and for global options. With global options previous example can be written like:

```javascript
$(function(){
$('#positionsShorterBtn').click(function(){
var globalOptions = {
element: $('#posBtn')
};

var tourDescription = [
{
content: 'by default tour is on the right'
},
{
content: 'but it can be on top',
position: 'top'
},
{
content: 'bottom',
position: 'bottom'
},
{
content: 'and finally on the left',
position: 'left'
}
];

Tour.run(tourDescription, globalOptions);
});
});
```

## 5. Events example

There are four events that can be used by developers:

- **onstart()** - Triggered when new tour starts ( `Tour.run()` );
- **onfinish()** - Triggered when Finish button is clicked;
- **onclose()** - Triggered when Close button is pressed ( `Tour.close()` );
- **onstep( currentStep )** - Triggered on every step shown ( `Tour.next()` or `Tour.prev()` );
- **onresize()** - By default this one is set.

```javascript
$(function(){
$('#eventsBtn').click(function(){
Tour.onstart = function(){
console.log('We started!');
};

Tour.onfinish = function(){
console.log('The End');
};

Tour.onclose = function(){
console.log('Tour interupted');
};

Tour.onstep = function(currentStep){
console.log('"That\'s one small step for a man ..."');
console.log(currentStep);
};

Tour.run([
{
element: $('#eventBtn1').add('#eventBtn3'),
content: 'You prefer photos?',
position: 'top'
},
{
element: $('#eventBtn3').add('#eventBtn4'),
content: 'or videos?',
onstep: function(currentStep) {
console.log('Events defined in step, overwrites global definition');
}
}
]);
});
});
```

## 6. Tour interface

#### Methods

Method | Description
------ | -----------
**Tour.run( tourDescription, globlOptions )** | Function for running Tour.
**Tour.next()** | Goes to next tour step.
**Tour.prev()** | Goes to previous tour step.
**Tour.close()** | Interrupts tour and closes it.
**Tour.current()** | Returns current step description.

#### Events

By default all except `onresize` are set to null.

Event | Description
----- | -----------
**Tour.onstart()** | Triggered when new tour starts ( Tour.run() ).
**Tour.onfinish()** | Triggered when Finish button is clicked.
**Tour.onclose()** | Triggered when Close button is pressed ( Tour.close() ).
**Tour.onstep( currentEvent )** | Triggered on every step shown ( Tour.next() or Tour.prev() ).
**Tour.onresize()** | By default this one is set.

## 7. Contact

Jan Doleczek <jan@doleczek.pl>
Loading