Merge branch 'master' of github.com:ZeusWPI/zeus.ugent.be into tibovanheule-master

This commit is contained in:
Lorin Werthen 2018-10-16 22:24:19 +02:00
commit ddbfe9ed05
No known key found for this signature in database
GPG key ID: F11FFC921E0E08E0
255 changed files with 11785 additions and 1450 deletions

View file

@ -1 +1 @@
2.3.1
2.5.0

View file

@ -1,26 +1,44 @@
language: ruby
bundler_args: --without development,nanoc
cache:
apt: true
bundler: true
# Cache nanoc directories
directories:
- output
- tmp
# NEVER MIND LOL
# directories:
# - output
# - tmp
addons:
apt:
packages:
- pandoc
- texlive
- lmodern
branches:
only:
- master
rvm:
- 2.3.1
- 2.5.0
notifications:
slack:
secure: tej68wbYns4DYg488iz+4ncU3/CHJvG/5c1qntGcEjti6vZp24atuH32BzNMY+gqa5ftZtcRfqIiJ0I0tkbiFWEDzjSk89bgjG4sgwXq1gMqi/Fj4bqEpjU5m7QLa786q4UfYyTF+srca1fHPLVS5REdGjRr2wxX+bcFnTRxreGCIrlNdWhoZPPJyS37R4RR9k+l5ZWZnqWgUN6bD448O8EzMRVRWoUSxQcJ6+u4QLpinEvem4iXe+WcHOyFfsNmavxGGMMpkOSed/tzA1l+gNpl224qOJl3yAk2qrGi4N6SOnSkeJFfUO5RzX56KDC/tcCL1oJpamhDmzDvRrbDNnCjSriv+g+PkXEjiwBF/tkZwIe7nMKyc9QF698Zvdgb6Ffbq21obsRnkkddkxijthdbUKMAIREPQuU7pXRL4ykPkBeB5GkNjPlErOooxvUHvQEVElJ8NMD4ychQqW6relaYJ0W0uy0QMvrtS+cHkpprZAOZzWLa3AdEOvD50kiS2hDhJway5JHJg/LMl3I6XVVMx6fNGdNWBcezeCqkDZM+nuMJqgAtQ+Tz8bwrHLCJgS5u0lQq/MbrDkYdpmmzvA5LXxn2SpjfOAlgiFKnSIwKSuuuwzW/zCEGdPo1pfBba2VfYAN4y1l863j5ph+eMtlHf7JG8mzIWTo3k+Jx8lQ=
before_install:
- openssl aes-256-cbc -K $encrypted_6059a4f451fd_key -iv $encrypted_6059a4f451fd_iv
-in id_rsa.enc -out deploy_key -d
- echo -e "Host zeus.ugent.be\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- npm install
- echo -e "[zeus.ugent.be]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC87/Q3H8f7ghmA+iCtKGaNyk0fx3Z36Xrn+eGv8a4pD7MXeu6Uwr0aN5HnkcbRWXFtMwnAU3ptoP90vH7qu99w=\n[herbert.ugent.be]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGLnJMh2DgqpVnHxOmeV6KffvzZGEVfniq0NFHRGZoL4f7Uc8xeG9gn3cc7lCL02F9LwWZNwR4gSqhGt/RK2S54=\n" >> ~/.ssh/known_hosts
# Repo for newer Node.js versions
# - curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
# Repo for Yarn
# - sudo apt-key adv --keyserver pgp.mit.edu --recv D101F7899D41F3C3
# - echo "deb http://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
# - sudo apt-get update -qq
# - sudo apt-get install -y -qq yarn
- yarn
script:
- bundle exec nanoc --env=prod
- bundle exec nanoc --env=prod check --deploy
@ -28,5 +46,4 @@ after_success:
- mv deploy_key ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- chmod +x ./deploy.sh
- echo -e "Host $TRAVIS_PULL_REQUEST.zeus.werthen.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- ./deploy.sh

1
.yarnrc Normal file
View file

@ -0,0 +1 @@
--modules-folder content/node_modules

10
Gemfile
View file

@ -3,11 +3,15 @@ source 'https://rubygems.org'
gem 'nanoc'
gem 'uglifier', '>= 4.0.0'
# General filtering
gem 'coffee-script'
gem 'icalendar' # ical files
gem 'kramdown'
gem 'rainpress'
gem 'sass'
gem 'typogruby'
# Needed for atom_feed in blogging helper
gem 'builder'
@ -19,6 +23,9 @@ gem 'therubyracer'
# for reading time
gem 'words_counted'
# Compiling reports from .md to .pdf
gem 'pandoc-ruby'
group :development do
gem 'adsf'
gem 'highline'
@ -29,7 +36,8 @@ end
group :production do
# Autoprefixing for class
gem 'autoprefixer-rails'
gem 'html_press'
gem 'htmlcompressor'
gem 'yui-compressor'
end
group :nanoc do

View file

@ -1,9 +1,11 @@
GEM
remote: https://rubygems.org/
specs:
adsf (1.2.1)
rack (>= 1.0.0)
autoprefixer-rails (7.1.3)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
adsf (1.4.1)
rack (>= 1.0.0, < 3.0.0)
autoprefixer-rails (8.5.0)
execjs
builder (3.2.3)
coderay (1.1.2)
@ -13,94 +15,101 @@ GEM
coffee-script-source (1.12.2)
colored (1.2)
concurrent-ruby (1.0.5)
cri (2.9.1)
cri (2.15.1)
colored (~> 1.2)
css_press (0.3.2)
csspool-st (= 3.1.2)
json
csspool-st (3.1.2)
ddplugin (1.0.1)
ddmemoize (1.0.0)
ddmetrics (~> 1.0)
ref (~> 2.0)
ddmetrics (1.0.1)
ddplugin (1.0.2)
execjs (2.7.0)
ffi (1.9.18)
ffi (1.9.25)
formatador (0.2.5)
guard (2.14.1)
guard (2.14.2)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
lumberjack (~> 1.0)
lumberjack (>= 1.0.12, < 2.0)
nenv (~> 0.1)
notiffany (~> 0.0)
pry (>= 0.9.12)
shellany (~> 0.0)
thor (>= 0.18.1)
guard-compat (1.2.1)
guard-nanoc (2.1.2)
guard-nanoc (2.1.4)
guard (~> 2.8)
guard-compat (~> 1.0)
nanoc (>= 4.3.8, < 5.0)
hamster (3.0.0)
concurrent-ruby (~> 1.0)
highline (1.7.8)
html_press (0.8.2)
htmlentities
multi_css (>= 0.1.0)
multi_js (>= 0.1.0)
htmlentities (4.3.4)
highline (1.7.10)
htmlcompressor (0.4.0)
icalendar (2.4.1)
json (2.1.0)
kramdown (1.14.0)
json_schema (0.19.1)
kramdown (1.16.2)
libv8 (3.16.14.19)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
lumberjack (1.0.12)
method_source (0.8.2)
mini_portile2 (2.2.0)
multi_css (0.1.0)
css_press
multi_js (0.1.0)
uglifier (~> 2)
nanoc (4.8.4)
cri (~> 2.8)
lumberjack (1.0.13)
method_source (0.9.0)
mini_portile2 (2.3.0)
nanoc (4.10.0)
addressable (~> 2.5)
cri (~> 2.15)
ddmemoize (~> 1.0)
ddmetrics (~> 1.0)
ddplugin (~> 1.0)
hamster (~> 3.0)
json_schema (~> 0.19)
parallel (~> 1.12)
ref (~> 2.0)
slow_enumerator_tools (~> 1.0)
tomlrb (~> 1.2)
nenv (0.3.0)
nokogiri (1.8.0)
mini_portile2 (~> 2.2.0)
nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
notiffany (0.1.1)
nenv (~> 0.1)
shellany (~> 0.0)
pry (0.10.4)
pandoc-ruby (2.0.2)
parallel (1.12.1)
pry (0.11.3)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rack (2.0.3)
rb-fsevent (0.10.2)
method_source (~> 0.9.0)
public_suffix (3.0.3)
rack (2.0.5)
rainpress (1.0.1)
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
ref (2.0.0)
ruby_dep (1.5.0)
sass (3.5.1)
rubypants (0.7.0)
sass (3.5.6)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
shellany (0.0.1)
slop (3.6.0)
terminal-notifier (1.8.0)
slow_enumerator_tools (1.1.0)
terminal-notifier (2.0.0)
terminal-notifier-guard (1.7.0)
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
thor (0.20.0)
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
tomlrb (1.2.7)
typogruby (1.0.18)
rubypants
uglifier (4.1.10)
execjs (>= 0.3.0, < 3)
w3c_validators (1.3.3)
json (>= 1.8)
nokogiri (~> 1.6)
words_counted (1.0.2)
yui-compressor (0.12.0)
PLATFORMS
ruby
@ -112,16 +121,21 @@ DEPENDENCIES
coffee-script
guard-nanoc
highline
html_press
htmlcompressor
icalendar
kramdown
nanoc
pandoc-ruby
rainpress
sass
terminal-notifier
terminal-notifier-guard
therubyracer
typogruby
uglifier (>= 4.0.0)
w3c_validators
words_counted
yui-compressor
BUNDLED WITH
1.14.6
1.16.4

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Zeus WPI
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.

104
README.md
View file

@ -4,26 +4,50 @@
[![PageSpeed](https://pagespeed-badges.herokuapp.com/?url=zeus.ugent.be&strat=desktop&showStratLabel=true)](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fzeus.ugent.be&tab=desktop)
[![PageSpeed](https://pagespeed-badges.herokuapp.com/?url=zeus.ugent.be&strat=mobile&showStratLabel=true)](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fzeus.ugent.be&tab=mobile)
## Setup
This repository contains the source code for [zeus.ugent.be](https://zeus.ugent.be), the website of Zeus WPI, the official student association of Informatics at Ghent University. The site is developed using [nanoc](https://github.com/nanoc/nanoc), which is actively developed by ex-Zeus member [ddfreyne](https://github.com/ddfreyne). The CSS framework used is [Bulma](https://bulma.io/). We primarily focus on using markdown for blogposts and events. Feel free to make a Pull Request with a blog post if you feel inspired and need an outlet!
### Installation
Please check the [Wiki](https://github.com/ZeusWPI/zeus.ugent.be/wiki) for questions about structure.
## Getting Started
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
### Prerequisites
You will need Ruby (gem), yarn and pandoc (optional). Installation instructions are listed below.
* [Ruby](https://www.ruby-lang.org/en/documentation/installation/)
* [yarn](yarnpkg.com/en/docs/install)
* [pandoc](https://pandoc.org/installing.html) (optional, install if you want to see the reports)
### Installing
If bundler is not yet installed on your system, make sure to install it using the following command:
```bash
gem install bundler
```
In the root directory of the project, execute following commands
```bash
bundle install
npm install
```
### Developing
You will (momentarily) also need `pandoc` and `latex` to compile the reports from the board meetings. Refer to your OS package manager to install these things.
These will pull in all Ruby and Node.js dependencies. If everything goes well, you should be able to execute the following.
```bash
bundle exec nanoc live
```
This will spawn a webserver, and automatically recompile the site
when files get changed.
Go to <http://localhost:3000> to view the site! When developing, the site gets regenerated when editing files. A simple refresh will show the new changes.
### Deploying
The latest builds on master get deployed automatically using [travis](https://travis-ci.org).
The latest and greatest builds on master get deployed automatically using [travis](https://travis-ci.org).
For manual deployment, run
@ -31,70 +55,22 @@ For manual deployment, run
bundle exec nanoc deploy --target public
```
## Events
If you want to deploy this on your own system for whatever reason, just serve the files using a webserver like nginx or Apache.
Events can be fetched from facebook using `nanoc fetch [facebook event id]`. A file named `.fb_token` containing an app token for facebook must be present.
## Submitting a Pull Request
## Blogposts
Once you've submitted a PR, it will automatically be deployed to (PR#).pr.zeus.gent, for easier reviewing.
Posts should be written in [kramdown](http://kramdown.gettalong.org/index.html), a markdown superset which has a very complete [syntax guide](http://kramdown.gettalong.org/syntax.html).
## Analytics
Meta-tags:
Analytics are powered by [Fathom](https://usefathom.com) and are available on <https://stats.zeus.gent>. These are only available to administrators with proper rights. These analytics are self hosted and provide only simple statistics for our information, without breaching your privacy.
| Name | Type | Required |
|-------------|--------|----------|
| :title | String | yes |
| :created_at | Date | yes |
| :description| String | no |
| :author | String | no |
| :lang | String | no |
## Events
Example structure:
```
content/
assets/
events/
15-16/
16-17/
battlebots/
main.md
intro.md
codenight.md
finale.md
awk.md
sed.md
ruby.md
index.erb
```
### Metadata
Every event is a `.md` file with the following metadata tags:
| Name | Type | Required |
|--------------|--------|----------|
| :title | String | yes |
| :time | Date | yes |
| :location | String | yes |
| :description | String | no |
| :created_at | Date | no |
| :locationlink| String | no |
| :facebook | URL | no |
| :banner | URL | no |
| :image | URL | no |
## Built With
### Grouped events
* [nanoc](https://github.com/nanoc/nanoc), static site generator
* [Bulma](https://bulma.io/), CSS framework
If there's a series of events (for example summer code nights) these can be grouped by creating a folder containing a `main.md`, which will need the following metadata:
## Authors
| Name | Type | Required |
|--------------|--------|----------|
| :title | String | yes |
| :location | String | no |
| :banner | URL | no |
Other `.md` files made in that folder are sub-events which need to fit the [metadata description listed earlier](#metadata)
See the list of [contributors](https://github.com/zeuswpi/zeus.ugent.be/contributors) who participated in this project.

54
Rules
View file

@ -11,14 +11,21 @@ require 'icalendar'
#
preprocess do
`npm install`
`yarn`
# We don't want to compile old blogposts in development
ignore_old_blogposts if development?
ignore_old_content('blog', 'events', 'about/verslagen') if development?
update_blog_attributes
create_yearly_items('Blog')
create_yearly_items('Events')
convert_event_time_to_timestamps
all_events.each do |event|
check_schema(:event, event)
end
add_report_metadata
end
#
@ -38,6 +45,8 @@ compile '/blog/*' do
layout '/generic.*'
layout '/default.*'
filter :erb
filter :html_press if production?
end
#
@ -50,6 +59,8 @@ compile '/events/*' do
layout '/generic.*'
layout '/default.*'
filter :erb
filter :html_press if production?
end
compile '/events/*/*' do
@ -59,6 +70,8 @@ compile '/events/*/*' do
layout '/eventpost.*'
layout '/default.*'
filter :erb
filter :html_press if production?
end
compile '/events/*/*', rep: :text do
@ -74,23 +87,28 @@ end
#
# POSTS
#
compile '/blog/*/*' do
compile '/blog/*/*.md' do
filter :erb
layout '/blogpost.md'
filter :kramdown
filter :typogruby
layout '/blogpost.erb'
layout '/generic.*'
layout '/default.*'
filter :erb
filter :html_press if production?
end
compile '/blog/*/*', rep: :text do
compile '/blog/*/*.md', rep: :text do
filter :erb
filter :kramdown
filter :strip_html
end
compile '/blog/*/*', rep: :html do
compile '/blog/*/*.md', rep: :html do
filter :erb
filter :kramdown
end
@ -99,10 +117,10 @@ end
#
compile '/projects/*' do
filter :kramdown
end
# Don't create specific project pages for now
route '/projects/*' do; end
# Don't write out the projects themselves for now
write nil
end
compile '/*_search.json' do
filter :erb
@ -112,6 +130,15 @@ compile '/**/*.ics' do
filter :erb
end
#
# REPORTS
#
compile '/about/verslagen/*/*.md', rep: :pdf do
filter :pandoc_pdf, args: { f: :markdown } if production?
write ext: (production? ? 'pdf' : 'md')
end
#
# GENERIC ERB PAGES
#
@ -120,6 +147,8 @@ compile '/**/*.erb' do
layout '/generic.*'
layout '/default.*'
filter :html_press if production?
end
compile '/**/*.md' do
@ -140,11 +169,12 @@ compile '/assets/scripts/**/*.coffee' do
end
compile '/assets/scripts/**/*.js' do
filter :uglify_js
filter :uglify_js, harmony: true
end
ignore '/assets/stylesheets/includes/**/*'
ignore '/data/**/*'
ignore '/node_modules/**/*'
compile '/assets/stylesheets/**/*.scss' do
filter :sass, syntax: :scss, style: :compressed
@ -152,6 +182,12 @@ compile '/assets/stylesheets/**/*.scss' do
write ext: 'css'
end
compile '/assets/stylesheets/**/*.css' do
filter :rainpress
filter :autoprefixer if production?
write ext: 'css'
end
#
#
# ROUTES

29
comment.sh Executable file
View file

@ -0,0 +1,29 @@
#!/bin/bash
PR_NR=$TRAVIS_PULL_REQUEST
function performQuery() {
NEW_QUERY_STR="{\"query\":\"$1\"}"
echo $NEW_QUERY_STR
curl -s -H "Authorization: bearer $COMMENT_TOKEN" -X POST -d "$NEW_QUERY_STR" https://api.github.com/graphql
}
RESULT=$(performQuery "{repository(owner:\\\"ZeusWPI\\\",name:\\\"zeus.ugent.be\\\"){pullRequest(number:$PR_NR){id,comments(first:10){nodes{author{login}}}}}}")
if [ $? -ne 0 ]; then
echo "QUERY FAILED, RESULT: $RESULT"
exit 1
fi
# Get the GraphQL ID
PR_ID=$(echo $RESULT | sed 's/.*"id":"\([^"]*\)".*/\1/')
# TODO: Have another user do the commenting
if [[ $RESULT == *"werthen"* ]]; then
echo "User has already commented"
else
ADD_COMMENT_STR="mutation{addComment(input:{subjectId:\\\"$PR_ID\\\",body:\\\"Check out the preview on https://$PR_NR.pr.zeus.gent/\\\"}){clientMutationId}}"
performQuery "$ADD_COMMENT_STR"
fi

View file

@ -27,14 +27,14 @@ narrow_page: true
<h2>The board</h2>
<p id="board">
The board is the oil in the machine and is the driving force behind the organization of events and projects.
The Zeus WPI board for the <%= pretty_year @config[:academic_year] %> academic year is:
The Zeus WPI board in <%= pretty_year @config[:academic_year] %> is:
</p>
<blockquote>
Mail us all at: <a href='mailto:bestuur@zeus.ugent.be'>bestuur@zeus.ugent.be</a>
</blockquote>
<table class="table">
<table class="table board-table">
<thead>
<tr>
<th>Function</th>

View file

@ -18,10 +18,6 @@ contact_links:
link: https://zeuswpi.slack.com/
description: Slack
action: Message us
- icon: commenting
link: irc://wina.ugent.be/#zeus
description: irc
action: Chat with us
- icon: inbox
link: http://lists.zeus.ugent.be/mailman/listinfo/leden
description: Mailinglist
@ -81,7 +77,7 @@ contact_links:
<h1 class='title has-text-centered'>Call us</h1>
<div class='is-divider'></div>
<p id='phone-number' class='is-size-5'>
+32 92 64 47 5</br>
+32 9 264 47 51<br/>
Intern: 4751
</p>
</div>
@ -96,9 +92,9 @@ contact_links:
You can find our hiding place, or what we call <strong>'de kelder'</strong> at the basement level of following address:
</p>
<blockquote id='address' class='is-size-5'>
Krijgslaan 281 </br>
Campus Sterre S9 </br>
9000 Gent </br>
Krijgslaan 281<br/>
Campus Sterre S9<br/>
9000 Gent<br/>
</blockquote>
<div id='contact-location-buttons'>
<a class='button' href='https://www.google.com/maps/place/Zeus+WPI/@51.023115,3.7103,17z/data=!4m5!3m4!1s0x0:0x49fd54f81cafeb5f!8m2!3d51.0231149!4d3.7103?hl=en-US'>
@ -118,7 +114,7 @@ contact_links:
<h1 class='title has-text-centered'>Slack info</h1>
<div class='is-divider'></div>
<p id='slack-info-text' class='is-size-5'>
You can register with any <strong>*.zeus.ugent.be</strong> or even <strong>*.ugent.be</strong> email address.
You can register with any <strong>*@zeus.ugent.be</strong> or even <strong>*@ugent.be</strong> email address.
If you don't have one, try to reach us on one of our other channels and ask for an invitation.
</p>
</div>
@ -126,4 +122,6 @@ contact_links:
</div>
<!-- Embedded Google Maps -->
<iframe id='google-maps' src='https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1156.8611760710044!2d3.7102397000000003!3d51.023149499999995!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47c373c271502d9b%3A0x49fd54f81cafeb5f!2sZeus+WPI!5e0!3m2!1sen!2sbe!4v1481415854540' height='450' style='border:0;width:100%' allowfullscreen></iframe>
<div class="map-wrapper box">
<iframe id='google-maps' src='https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1156.8611760710044!2d3.7102397000000003!3d51.023149499999995!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47c373c271502d9b%3A0x49fd54f81cafeb5f!2sZeus+WPI!5e0!3m2!1sen!2sbe!4v1481415854540' height='450' style='border:0;width:100%' allowfullscreen></iframe>
</div>

View file

@ -75,17 +75,17 @@ narrow_page: true
**Art. 15** - De hierboven vernoemde verantwoordelijkheden van de bestuursleden zijn niet-exhaustief. Ieder bestuurslid draagt o.a. een algemene verwantwoordelijkheid.<br>
</div>
<div class="box" markdown="1">
**Art. 15** - Het bestuur komt regelmatig samen op een daartoe vastgestelde dag, die door de voorzitter wordt vastgelegd en door de secretaris aan alle leden wordt meegedeeld. De bestuursvergadering is slechts geldig wanneer twee derden aanwezig is. De agendapunten moeten behandeld worden. Bij gelijke stemming heeft de voorzitter het laatste woord.<br>
**Art. 16** - Het bestuur komt regelmatig samen op een daartoe vastgestelde dag, die door de voorzitter wordt vastgelegd en door de secretaris aan alle leden wordt meegedeeld. De bestuursvergadering is slechts geldig wanneer twee derden aanwezig is. De agendapunten moeten behandeld worden. Bij gelijke stemming heeft de voorzitter het laatste woord.<br>
</div>
<div class="box" markdown="1">
**Art. 16** - Alle voorstellen die tijdens een bepaalde vergadering werden voorgelegd, worden gebundeld. Een exemplaar hiervan wordt door de secretaris bedeeld aan de bestuursleden. Een exemplaar wordt publiekelijk beschikbaar gesteld via de website van de vereniging.<br>
**Art. 17** - Alle voorstellen die tijdens een bepaalde vergadering werden voorgelegd, worden gebundeld. Een exemplaar hiervan wordt door de secretaris bedeeld aan de bestuursleden. Een exemplaar wordt publiekelijk beschikbaar gesteld via de website van de vereniging.<br>
</div>
# Hoofdstuk IV - Eindbepaling
<div class="box" markdown="1">
**Art. 17** - De statuten kunnen slechts gewijzigd worden op een algemene ledenvergadering waar minstens 1/2 van de leden aanwezig is. Hiervoor is bij stemming een 2/3 meerderheid van alle aanwezige leden vereist.<br>
**Art. 18** - De statuten kunnen slechts gewijzigd worden op een algemene ledenvergadering waar minstens 1/2 van de leden aanwezig is. Hiervoor is bij stemming een 2/3 meerderheid van alle aanwezige leden vereist.<br>
</div>
<div class="box" markdown="1">
**Art. 18** - In geval van ontbinding zal de vereniging beslissen dat het nettoactief zal gestort worden aan een nader te bepalen goed doel.<br>
**Art. 19** - In geval van ontbinding zal de vereniging beslissen dat het nettoactief zal gestort worden aan een nader te bepalen goed doel.<br>
</div>

View file

@ -1,64 +1,15 @@
---
narrow_page: true
---
<%= render '/partials/_about_sub_navbar.*', selected: 'verslagen' %>
<div class="content">
<h1>Verslagen</h1>
<ul>
<li>kdjfsql</li>
<li>kdjfsql</li>
<li>kdjfsql</li>
<li>kdjfsql</li>
<li>kdjfsql</li>
</ul>
</div>
<div class="content">
<h3>Academiejaar 2015-2016</h3>
coming soon: statutenwijzigingen + verkiezingsuitslag (Mei 2016)
<a href="http://zeus.ugent.be/over-zeus-wpi/verslagen/vergadering8/">Bestuursvergadering 8: April 2016</a><br />
<a href="http://zeus.ugent.be/over-zeus-wpi/verslagen/bestuursvergadering7/">Bestuursvergadering 7: Maart 2016</a><br />
<a href="http://zeus.ugent.be/over-zeus-wpi/verslagen/bestuursvergadering6/">Bestuursvergadering 6: Februari 2016</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2015/03/Bestuursvergadering5.pdf">Bestuursvergadering 5: December 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2015/03/Bestuursvergadering4.pdf">Bestuursvergadering 4: November 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2015/03/Bestuursvergadering3.pdf">Bestuursvergadering 3: Oktober 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2015/10/Vergadering7september.pdf"> Bestuursvergadering 2: September 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2015/10/vergadering4augustus.pdf">Bestuursvergadering 1: Augustus 2015</a><br />
<h3>Academiejaar 2014-2015</h3>
<a href="https://zeus.ugent.be/wp-content/uploads/2015/03/Ledenvergaderingmei2015.pdf">Ledenvergadering Mei 5 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2015/03/2015-04-23Bestuursvergadering12.pdf">Bestuursvergadering April 23 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2015/03/2015-03-18Bestuursvergadering11.pdf">Bestuursvergadering Maart 18 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2014/09/2015-03-02Bestuursvergadering10.pdf">Bestuursvergadering Maart 2 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2014/09/2015-02-09Bestuursvergadering9.pdf">Bestuursvergadering Februari 8 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2014/09/2015-02-02Bestuursvergadering8.pdf">Bestuursvergadering Februari 2 2015</a><br />
<a href="https://zeus.ugent.be/wp-content/uploads/2014/09/2014-12-02Bestuursvergadering7.pdf">Bestuursvergadering December 2014</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/09/Bestuursvergadering65november2014.pdf">Bestuursvergadering November 2014</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/09/Bestuursvergadering57oktober2014.pdf">Bestuursvergadering Oktober 2014</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/09/Bestuursvergadering416september2014.pdf">Bestuursvergadering September 16 2014</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/09/Bestuursvergadering38September2014-2.pdf">Bestuursvergadering September 8 2014</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering25augustus2014.pdf">Bestuursvergadering augustus 2014</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering1juli2014.pdf">Bestuursvergadering juli 2014</a><br />
<h3>Academiejaar 2013-2014</h3>
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering18214.pdf">Bestuursvergadering februari 2014</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering29oktober2013.pdf">Bestuursvergadering oktober 2013</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergaderingbegin5913.pdf">Bestuursvergadering september 2013</a><br />
<h3>Academiejaar 2012-2013</h3>
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Ledenvergadering14mei2013.pdf">Ledenvergadering mei 2013</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering2mei.pdf">Bestuursvergadering mei 2013</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering_28_maart_2013.pdf">Bestuursvergadering 28 maart 2013</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering_2013_maart_14.pdf">Bestuursvergadering 14 maart 2013</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering_2013_januari_31.pdf">Bestuursvergadering januari 2013</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/BestuursvergaderingNovember2012.pdf">Bestuursvergadering november 2012</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/BestuursvergaderingOktober2012.pdf">Bestuursvergadering oktober 2012</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/BestuursvergaderingSeptember2012.pdf">Bestuursvergadering september 2012</a><br />
<h3>Vóór 2012</h3>
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/Bestuursvergadering29jun2011.pdf">Bestuursvergadering juni 2011</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/verslag-2010-08-14.pdf">Bestuursvergadering augustus 2010</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/verslag-2010-04-13.pdf">Bestuursvergadering april 2010</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/verslag-2009-12-10.pdf">Bestuursvergadering december 2009</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/verslag-2009-07-30.pdf">Bestuursvergadering 30 juli 2009</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/verslag-2009-07-13.pdf">Bestuursvergadering 13 juli 2009</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/verslag-2009-07-09.pdf">Bestuursvergadering 9 juli 2009</a><br />
<a href="http://zeus.ugent.be/wp-content/uploads/2014/08/ledenvergadering-2006.pdf">Ledenvergadering 2006</a><br />
<h1>Reports</h1>
<% reports.group_by {|r| r[:academic_year]}.each do |year, y_reports| %>
<h2><%= year %></h2>
<% y_reports.each do |report| %>
<a href="<%= report.reps[:pdf]&.path || report.identifier %>">Report <%= report[:date].strftime('%d %B %Y') %></a><br>
<% end %>
<% end %>
</div>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,73 @@
% Bestuursvergadering 6:
%
% Datum: 9 Februari 2016 18h06 tot 19h06
Status: Open
voorgaande wiki pagina:
https://zeus.ugent.be/wiki/doku.php?id=bestuursvergadering:februari_2016
# Verslag vorige vergadering
https://docs.google.com/document/d/1mTGrY02d30t_dgiwgdPumgl8Fj3bh51q-azL7esLJvw/edit?usp=drive_web
1. Venster: repareren zodat het niet volledig open kan, geen rooster plaatsen.
2. Tabp moest in gang treden, maar dit is nog niet gebeurd. Eind deze week zal het systeem beginnen draaien.
3. Verslag goedgekeurd
# Financiën
* Totaal: 2079,2 EUR
waarvan in kassa: 467,9 EUR
waarvan in bank: 722,38
* Te veel cash in de kassa, Kenneth gaat dit naar de bank brengen
* financieel jaarverslag ingediend
# Sysadmin
* Fan op Verne is geïnstalleerd
* Alias pagina aangemaakt
* Minimum wachtwoord lengte verhoogd naar 8
* Maximum file upload via http verhoogd naar 5MB
* SSH keys van Verne en Clarke verwijderd
* Iepoev het root wachtwoord overhandigd
* Graceful shutdown wanneer de stroom uitvalt
* 10GB motion detected cammie footage -> 200GB of 14 dagen alternating continuous/motion detected cammie footage
# Activiteiten
* Google Hash 11 feb
- guest accounts verkregen voor niet UGenters
- goodies zijn er ( 248)
- lokaal is gereserveerd
- Aanraden op voorhand te eten, snacks zullen aanwezig zijn. (hiervoor nog een mail met praktische informatie rondsturen)
* AI avond
1. Voorstellingsavond over een 2 tal weken. Vervolgens nog follow-up avonden (avonden waarop de kelder vooral AI-challenge gericht zal zijn, dient ook om mensen naar de kelder te lokken)
Verder was er sprake van een finale avond
* Waarschijnlijk zouden er prijzen weggegeven worden aan de winnaars
* awk-les
- lokaal A1, op 23 feb 18h (sluit aan op Scriptingstalen)
- gegeven door Professor Dawyndt
* VPW
- ToDo: Op het VPW facebook event delen dat wij een busrit heen en terug van gent organiseren
* Event Brainstorm
- 12 feb 18h
# Projecten updates
* Tabp werkt terug
* Meeting tussen Minerva API team en Zeus wordt georganiseerd
* plannen dit semester:
- 12ul herwerken
- Hydra 2.0 (met API)
- Gamification herwerken
- Projectavond: projecten presenteren met bijkomende avonden (een week later voorbeeld) waar mensen wel kunnen werken, en voorbereid kunnen zijn (zoals talen leren kennen, en platformen leren werken)
# Discussiepunten
* Ereleden: nieuwe omschrijving: ereleden worden genomineerd door het bestuur op het einde van hun bestuursperiode. Iedereen die ooit het recht erelid te zijn heeft gewonnen, behoudt dit recht. Mensen krijgen de privileges van erelid te zijn mits vergoeding nog steeds.
* Opvolger sysadmin
* nieuwe kandidaten: Mehmet en Rien
* Titouan gaat het hier eens over hebben met Mehmet, Rien en Lorin
* leden “inschrijvingsgeld”:
* Nieuwe leden worden vriendelijk gevraagd om cash te betalen. Tapb is pas beschikbaar na een initiële overschrijving van 5 euro instapkrediet.
* Kalmtedagen
* dinsdag en donderdag
* vanaf dinsdag 16 feb
* volgende maand evalueren
# Trivia
AP is in orde, de facturatie details worden doorgestuurd zodat wij een nieuwe kunnen bestellen.

View file

@ -0,0 +1,46 @@
% Bestuursvergadering 7
%
% Datum: 10/03/2016 18h09 - 20h06
Status: Gesloten
voorgaande wiki pagina:
https://zeus.ugent.be/wiki/doku.php?id=bestuursvergadering:maart_2016
# Verslag
1. Verslag vorige vergadering
* verslag
* raam is al gedeeltelijk gerepareerd
* verslag goedgekeurd
# Financiën
* Consumpties: -247,53 EUR
* Kassa: 241,90 EUR
* Waarvan in bank: 2052,19 EUR
* nog in te dienen: 108 EUR
# Sysadmin
* Opgeleiden: Rien, Lorin
# Activiteiten
* Finale ai-challenge: was gepland vlak voor paasvakantie, maar is niet haalbaar.
* spelletjesavond: vlak voor vakantie (poll vrijdag of donderdag)
* veel vraag naar spelletjesavond
* zeus-olympiade
* code-history: nog zoeken naar spreker (eventueel combi met museum der wetenschappen)
# Projecten updates
* hydra komt meer op gang, vraag tot budget voor hydra promotie.
* 12UL: bijna halfweg (stijn ilion felix)
* Saruman: benji
* AI-challenge: veel aan gewerkt, nog veel werk aan, waarschijnlijk af tegen einde van semester
# Discussiepunten
* Statuten: zie
* Gandalf: bigger isue:
1. gandalf + 12UL: Codenights organiseren met maintainers, pair programming? Extra inzet bestuur wordt verwacht hierop
Engagement zoeken (zowel bij ons als bij leden)
2. FK-enrollment: mailen naar FK , wij ondersteunen dit niet meer , FK-ICT moet dit overnemen, ilion is bereid hierbij uitleg te verschaffen indien nodig
# Trivia
* Derp op zeus servers? neen, mag wel op userdirs

View file

@ -0,0 +1,18 @@
% Bestuursvergadering 8
%
% Datum: 26 April 2016 17h- 17h30
Status: Open
# Discussiepunten
1. Sysadmin (1 of 2)
1. 2 sysadmins met 1 stem (idee: 1 stem per functie)
2. 2 sysadmins met 2 stemmen (gelijkwaardige rollen)
3. 1 sysadmin (voordeel: minder bestuursleden voor vergaderingen)
1. event (1 of 2)
1. 2 events met elk een stem (gelijkwaardige rollen)
2. per persoon een event
1. projectleider
1. oorspronkelijk doel: aanspreekpunt en is op de hoogte van alles
2. organiseert codenights samen met events
3. creert hypes rond projecten, zodat er meer aan projecten wordt gewerkt (zie hydra dit jaar)

View file

@ -0,0 +1,105 @@
% Bestuursvergadering 1:
%
% Datum: 13/09/2016 13:01 - 14:30
Status: Gesloten
Aanwezigen: Volledig bestuur
# Verslag vorige vergadering
* https://docs.google.com/document/d/1eRbc1KlB_89AHN3rA6fR5j_Pj1jiFLlR4V9sZcUgFyQ/edit#heading=h.s33rp6ymhlu1
* goedgekeurd
# Financiën
* 300 schulden aan leden zelf
* Bank: ongeveer 1000
* Rechten bank doorgeven
* Vloer: schijven van 125 euro
* Payconiq: nieuwe tafels/frigo
# Sysadmin
* BIJNA ALLES IS KAPOT
* nieuwe VM: Adams, alles migreren naar daar
* King: doet rare dingen, bijna aan limiet -> meer plaats aanvragen
* Zeven is nu Gygax
* Token: ingesteld als router
# Activiteiten
* Volgende vrijdag: introductie
* Mail naar leden: WEES VRIENDELIJK TEGEN MENSEN, TIMO MAG NIE KOMEN
* Reclame voor installparty + SKO
* Draaiboek in orde maken
* SKO
* InstallParty
* usb sticks aankopen (4 + 8GB, ongeveer 50-60 euro, tegen 5 okt) -> TO DO WOUT
* S10
* LanParty: DON DOE DINGEN
# Projecten updates
* Hydra: bijna nieuwe versie
* Gandalf: Payconiq meeting + Tom porren
* FK: geen geklaag
* Tab/tap: bezig aan 2.0, maar SKO dingen, geen deadline
* Bottle bats: tweede semester, werken in eerste semester
* LANA: moet herschreven worden
* Zeus website:
* Goed op weg, heel mooi, wow, niet compleet, projectenpagina nog werk
* Events en blog posts af tegen begin academiejaar?
# Discussiepunten
* Introductiedag
* SKO standje
* Focus op Hydra, internet voorzien voor andere projecten
* Hydra brainstorm: harnassen zijn subsidieerbaar, kartonnen zwaard voor wout
* Verkeerde technische fiche
* Wie komt er? Feli, Wout, (Stijn?)
* Setup: banner, reuzendrakendildo voor don
* Hydra
* SKO: Feedback en functionaliteit vragen
* Enquete (met wedstrijd): gewenste features, keynote op gala-avond DSA, wedstrijd: vat winnen (subsidieerbaar?)
* Harnas huren, fotowedstrijd met Hydra ridder
* Launch party: flop -> gala-avond
* Zoeken in bib naar naslagwerken -> in Hydra integreren
* Epurse integratie(saldo checken)
* Onboarding
* Groepswerklokaaltjes
* Complex, fucnties van app uit kunnen zetten
* Voor sko af?
* Integratie webapp SKO
* Flyers?
* Payconiq
* Geen kosten, geen deadline
* Integratie in Gandalf
* 200 jaar UGent: Gandalf wordt effectief gebruikt
* Thoge erelid: a -oh-kay
* Ereleden fixen
* Nieuwe foto en quote
* Minimum 20 euro
* Bestuursburgers zelf betalen, wel een uitnodiging
* Vloerveiling?
# Trivia
* Sleutel voor Rien
* Jens leent kabel
* LUSTRUMWEEK 6: Fancy kleedijfeestje:
* Lijst van alle leden ooit
* Dresscode!
* Kasteel/artcube/therminal beschikbaar?
* HEEL VEEL DRANK
* Facebookevent maken
* Hapjes?
* Papiertjes invullen voor Lightning talks
* E&F: Exotisch en frustrerende talenavond
* Drank en eten: speciale codenight
* App dev: Feli voor ios, Feli/Niko voor android?
* VPW bus betaling: vragen aan ELIS
# Vrij moment
We gaan sushi eten

View file

@ -0,0 +1,124 @@
% Bestuursvergadering 2:
%
% Datum: 20/10/2016 12:10 - 14:30
Status: Gesloten
Aanwezigen: Volledig bestuur
# Verslag vorige vergadering
* https://docs.google.com/document/d/1dwVBbAg38pyK8uTN3sUrZPk7ygi3M2f2yvoEBP3Gk2g/
# Financiën
* Unixstickers EINDELIJK verzonden! Doorrekenen naar leden
* 450 in kassa, 1360 in bank, 169 aan niet-ingediend subsidies, 550 krediet
* 1400 euro in totaal
* 700 euro over van subsidies
# Sysadmin
* Verne Problemen? STABIEL YEY
* Nieuw serverpark uitstellen tot na lustrumweek
* Nieuwe schijf?
* Netwerkdingen uitgeleend aan Ceneka
# Activiteiten
* LAN party
* Gala avond
* Shiften
1. Inkom (1)
2. Ontvangst (?)
3. Bar (1)
4. Bijvullen (1)
5. Hapjes (1)
6. Zeusvriendjes
* Drinken
1. Drankcentrale wijn en cava aan de Rooigemlaan 12 witte, 6 rode, 6 rose)
2. 50 flessen cava - 7.20 euro
3. 4.5 euro voor witte wijn - 12 witte
4. 6 rode
5. 6 rose
* Prijslijst
1. Cava: 1.5 (1.20 voor ons)
2. Wijn: 1 (0.65)
3. Bier: drankencentrale nevele
4. Fruitsap
5. Frisdrank
6. Duvel
* Hapjes (makro?)
1. Ovenhapjes
2. Chips enzo
3. Croque monsieurs
* Materiaal
1. Bestek, glazen
2. Kartonnen kommetjes/bordjes
3. Frigo
4. Servietten: Makro
5. opdienbladen
* Mails
* Inkleding ruimte
* Serieuze reminder mail naar leden
* Muziek
* Mail sociale raad, RvB en stura, rector en vice-rector, joeri
* 25u Codenight
* Shiften
* Materiaal
* Internet
* verlengkabels/dominos (paddestoel dsa)
* Schermen dict (lorin)?
* Koelbox reserveren
* Nachtvoedsel + ontbijt
* Aiki noedels + waterkoker? microgolf?
* PRIME spelletjesavond:
* ELO: A3 vastleggen
* Drinken: overschotten gala-avond? MAIL WOUWT
* Rustles
* Onderhandelingen zijn bezig, binnenkort een doorbraak
* Alle praktische dingen geregeld
* Kelder reserveren!
* E&F
* A3
* Poster
* wedstrijdjes
* Appweek
* Soort van score-bord app voor spelletjes
# Projecten updates
* Hydra
* Communicatiewetenschappen voor promo
* Epurse integratie: volgende week vergadering met Femke
* Soleway: tijdens 25 uur codenight?
* Volgende week maaltijdproblemen normaal opgelost
* Feli volgend jaar weg, Hydra mag niet doodgaan
Tijdens app week mensen naar Hydra lokken!
Grote persoon + perooon datacenter voor Hydra
* Gandalf
* Payqonic-integratie
* Felix? Tom?
* LANA is dood
* Discord opstellen
* Zeus-site
* Statuten
* Verslagen: markdown yey
* mobile!!
* Saruman: mats zou deze gebruiken voor het DSA uitleensysteem te upgraden (betaald)
# Discussiepunten
* Quivr mail
* Drive assets: assets verspreid over computer, lokaliseren
* Lijst mogelijke uitgaven:
* Kaartje erelid: to do Rien tegen begin november
* Drive opkuisen: to do Isaura
* Mail grafisch designer voor logo
* Werkaanvraag vloervernieuwing: geen respons, jens pingen, voor 1 december kopen
# Trivia
# Vrij moment

View file

@ -0,0 +1,180 @@
% Bestuursvergadering 3:
%
% Datum: 15/11/2016 - 11:24
Status: Gesloten
Aanwezigen: Volledig bestuur
# Verslag vorige vergadering
- https://docs.google.com/document/d/1jkU6QhQaLyaTfYlQn7pme3w_eDDl72SIWXqf9FI5HXk/
# Financiën
* Gala-recap
* Factuur chris union?
* LAN-recap
* Factuur drankstock volgende week
* UNIXstickers in orde? Nee: davit, michilus en felix moeten nog betalen
# Sysadmin
* Dingen lijken kapot, zo kapot
* Verne naar de kloten -> RAID?
* Migratie naar adams hoort te beginnen
* Materiaal nodig? Nuwp
* 8 usb terug?
* Ceneka: site is kak
* Security issues gefixt
* Userdirs: permission issues
* Elo gaat op jeroen gaan staan
# Activiteiten
* Gala-recap
* GROOT SUCCES
* Oud-leden: vroeger beginnen uitnodigen, publieke gastlijst, geen publiek fb-event
* Opkuis beter regelen (+25h codeday)
* Lustrumweken zijn lastig
* Elo gaat op jeroen gaan staan
* LAN-recap
* Trechterzaal beter dan podiumzaal
* Fuck tape
* Bandjesprinter is superhandig of ZEUS STEMPEL kopen
* Iets te laat klaar, minder yoloen
* 25u-codenight-recap
* Elo heeft vreselijke ideeën lorin oook
* Isaura ook
* Mensen zijn effectief tot s ochtends gebleven, tot s middags zelf
* Lijst van to dos voor codenight was wel handig geweest
* “Mensen maken foutjes, Ik voornamelijk” ~Don
* PRIME-spelletjes avond recap
* TOP, veel volk, weinig Zeusers
* Voor herhaling vatbaar, coole spelletjes
* Spelletjes kopen: 50 euro dit jaar? Niet subsidieerbaar, niet dezelfde spelletjes van Prime tho
* Zeus ontspanningsavond planning
* Kelder of V lokaal? V3 reserveren, just to be sure
* Intern houden? Zeusvriendjes
* Kinda een quiz, ma nerdier
* E&F planning
* Poster: elo doet dingen
* A3 reserveren
* Opdrachten maken
* Pannenkoeken en jenevercodenight planning
* Jeroen: doodle maken
* Jenever gaan halen bij dhont
* Hashcode challenge planning
* Hub is geregistreerd
* Elo gaat op jeroen gaan staan
* Httpizza planning
* Ruben moet een datum vastleggen?
1. Wij moeten een aantal voorstellen geven
1. Week van 23 februari is hashcode challenge
2. Week van 6 maart is bottlebats intro
3. 3e of 4e week (27-28 februari, 1 maart)
* Kan vrij groot worden, 3 jaren worden uitgenodigd door ruben
1. Goed voorbereiden
1. Stekkerdozen meenemen en permanentie on standby voor de elektriek terug aan te krijgen
2. Stekkerdozen tafel per tafel insteken om stroomsurge te vermijden
1. Tweede semester zit vol grote evenementen
1. Hashcode
2. Httpizza
3. Bottlebats
4. Lightningtalks
* 250 euro subsidies aangevraagd door ruben bij de werkgroep
1. Integraal besteden aan de pizzas?
1. Pizza verkopen per slice
2. Pizzas op voorhand bestellen, niet met orders werken
# Projecten updates
* Hydra
* Vergadering Femke(epurse/maaltijdmenu)
1. Femke gaat ons verwittigen als de pagina veranderd wordt
2. Femke gaat voorleggen om een epurse API te maken voor hydra (feest)
3. Hydra ging kapot omdat ze een empty list element hadden bij de groeten op iedere maandag (NullPointerException)
4. Wout wil machine learning
* Mail Facultaire Studentenraad van de ComWet
1. Samenwerken met communicatiewetenschappers voor hydra promo
2. Subsidies vrijhouden voor volgend belastingsjaar om promomateriaal te kopen
* Eventueel GSR sponsoring van Hydra
* Gandalf & Payconiq
* Niemand werkt hieraan (TIS TE SAAI EN TE GROOT STUUR HULP)
1. Negeer Tom zijn rewrite?
2. Benji ging evt. Codesprinten met Davit en Illion
1. Wout stelt voor om relaties af te schaffen
* Zeussite
* “Tis cool” ~Wout
* Events die al gepasseerd zijn blijven staan op de frontpage als upcoming event
1. Anders is dat stuk gewoon leeg, en das ook nie cool
2. HERDESIGN FRONTPAGE
* Blogposts gebeuren niet (oeps)
1. 25 jaar zeus post
2. Linux post
3. SKO post
4. Fuck taalconsistentie in posts
* Feliciaan spreekt vreemd
* “Reading time” feature is relatief OK ~Don
* ZeusWPI
* ZeusWPI doet zijn Job
1. Security is fantastisch
2. Absoluut niets mis met security
3. Simpele authenticatie
* Wout wilt fotoalbums
# Discussiepunten
* Netheid kelder
* GRUUTE KUIS
* Afval-awareness campagne
* Opslagruimte plafond: eerst opruimen
* Ereleden
* https://docs.google.com/spreadsheets/d/1cNyYGAqYX9Oui2D7MfCo55sGCdIN4PYOF1S98uAESV4/edit
* Rien is bezig met een fancy shmancy certificaat
* We gaan ereleden per kalenderjaar doen, maar opstart in september
* No vaping @kelder: akkoord
* OpenKnowledge / Apps For Ghent: open data in education, past binnen ethiek van Zeus, codesprint: Hydra?
* Grote schulden
* Geld uitgeven:
* 650 euro te besteden
* Kabels (124.22)
1. Eurostekkers + dominos 50 (48.90)
2. Kabels speakers 20 (11.95)
3. Ethernetkables met aangegoten kopjes 50 (61.80)
* Flyer.be
1. Stickers 100 (104,42)
2. raamsticker 50
3. Zeus stempel 10 (35.09)
* Moderne switches 300 (274.3)
* laserjet (zwart/wit) 100 (69.99)
# Trivia
* TEAMBUILDING AKA ETEN AKA DRINKEN
* Elo heeft met haar hoofd tegen een muur gelopen op de gala avond
* Dinsdag of donderdag
1. Fuck Wout
* Maandag of Woensdag
1. Fuck Elo
* ANDERS GEWOON ZONDAGAVOND?
1. Fuck Rien
* SUSHI???
* Elo wilt eten, niet drinken
* Rien wilt eten en drinken
* Wout is geen voorzitter meer ofzo (MOTIE VAN WANTROUWEN DOOR ELO DON EN RIEN)
1. Wout heeft het lief van elo verkracht blijkbaar
2. Er is een ernstige voorzitter kandidaat
1. Frank?
2. Jos
* Gedichten moeten niet rijmen
1. Maak Zeus Great Again
* Iets van atoombommen en kakkerlakken
* WOUT ZAT OP AIRBNB IN LISSABON EN ER WAREN KAKKERLAKKEN
1. BLIJF VAN MIJN VERSLAG
2. MOTIE VAN WANTROUWEN TEGEN JEROEN
3. ELO TROUWT JEROEN WAN
4. ELO STAAT ER OP DAT DE VERGADERING AFGESLOTEN IS
# Vrij moment

View file

@ -0,0 +1,89 @@
% Bestuursvergadering 4:
%
% Datum: 06/12/2016
Status: Open
Aanwezigen: Volledig bestuur
# Verslag vorige vergadering
* Goedkeuring vorig verslag aight
# Financiën
* Gala & Lan recap
* Dranken: 450 ongeveer
* Extra: 100 ongeveer
* Subsidies: 50 terug
* Totaal: 800 omzet
* Ruwe schatting: max 200 winst
* UNIXstickers in orde? aight
* Spelletjes gaan kopen
* 40-50 euro spelletjes kopen in de fnac
* Brecht gaat spelletjes geven
* Geen cash geld meer in de kassa laten
# Sysadmin
* DINGEN ZIJN NOG STEEDS KAPOT
(UPDATE: dingen zijn iets minder kapot)
* Verne crasht af en toe ne keer
* Rien is boot dingen ah fixen
* Rien is actief en heeft een stappenplan
* Don poept te veel: STOHP MET POEPEN DON
* LDAP migreren naar de clouwd
* Fuck kerberos
# Activiteiten
* E&F
* Opdrachten
* Mensen aanspreken om langs te komen
* Pannenkoeken en jenever codenight
* Da wordt gefixt
* Jenever bij oude dude gaan
* Httpizza brainstorm
* Wouwt heeft 1 idee
* Zelf server opstellen, met enkele versleutelde dingen op en alle deelnemende teams hebben een sleutel om dingen te kunnen decoden. Zelf server hosten om gedecodeerde dingen op te hosten om zo tot een oplossing te komen.
* Codenights 2de semester? Vaste dag?
* Verschillende dagen
* Deftig aankondigen
* Lijst met heel kleine issues maken (op bord)
* Codenights vastleggen op vergaderingen!
# Projecten updates
* Hydra
* Selectie restos
* Release februari: codenights rond die periode extra focus op hydra
* Budgetaanvraag Gentse Studentenraad (+- €2000)
* Eigen inbreng
* Sugestiemenu ( voor bugs enzo)
* Gandalf & Payconiq
* API Update
* NDA
* Contact opnemen voor NDA
* Vragen aan FK of zij de NDA willen aangaan
* * 12urenloop
* Wie? Poef, benji en Isaura
* Teamlead, telsysteem, netwerk en website codenight?
# Discussiepunten
* WVK 12urenloop
* Bespreken om met VVN, Prime en Zeus een loopteam te maken
* To do: mail VVN, Prime en WVK
# Trivia
* GROTE KELDER KUIS
* Boeken: ledenmail om boeken terug te geven
* Macs naar 12urenloop archief
* 12urenloop materiaal naar 12urenloop opslagplaats
* Wouwt gaat mailen naar DICT
* Kapotte dingen wegdoen
* DICT: Shit dumpen en shit schooien
# Vrij moment
* DSA: zeus steunt, maar draagt niet

View file

@ -0,0 +1,152 @@
% Bestuursvergadering 5:
%
% Datum: 06/02/2017 - 14:24
Status: Open
Aanwezigen: Volledig bestuur
# Verslag vorige vergadering
- Goedgekeurd
# Financiën
* Spelletjes
* Nieuw spelletje: Concept
* Financieel verslag (10 februari): Jeroentje
* Financiën: zelfde als vorige keer
# Sysadmin
* (Idee Illion) Eigen GitLab server, naast GitHub? Something something idealen en open saus.
* Komt overeen met ethiek
* Maar dingen gaan nu al kapot
* Als we het zelf niet doen, breken dingen zeker niet en minder ingewikkeld
* IS ALLES NOG KAPOT?? => JA :(
* Dingen (internet en oauth) worden deze week gefixt
* LDAP dingen migreren naar Adams opdat OAuth gefikst wordt
* Dick, nieuwe router wordt ingesteld <3
# Activiteiten
* EnF Recap
* Zelfde vragen per ronde
* Moeilijkheid gelijkhouden
* Jenever codenight Recap
* Weinig gecode
* Gewerkt aan Blokmap, Mozaic en Zeus site
* Maar sfeer <3
* Geen bloemenjenever volgend jaar
* FOSDEM
* Twas a-o-kay
* Bottlebats
* Mozaic: Massive Online Zeus Artificial Intelligence Competition
* Mozaic dit jaar implementeren, niet per se gebruiken
* MMMMMMassas werk, in kleine deeltjes opsplitsen
* generials.io met lokaal scorebord
* Bottlebats van vorig jaar met updates qua spelregels
* Samenwerking met vak AI?
* HTTPizza
* Dingen doen
* Gaat door in de Foundry (technicum), verschillende lokalen
* Servers/pis opzetten
* Ruben heeft protocol + basisserver online gezet
* Wij moeten daar effectief een gameserver van maken
* Posters (-> noctua)
* Pizzas regelen
* Facebookevent
* 250 budget
* Google Hashcode
* Lokaal gereserveerd
* Permanentie contacteren
* UGent Guest aanvragen
* stekkerdozen!
* VPW
* Lorin + Elo: bus regelen
* ELIS
* Lightning talks
* (post)-doctoraat studenten
* Oud zeusleden (Jens Sander Andy)
* onderzoek/werk/projecten
* Elixir/Phoenix (ruby gebaseerde functionele taal met als basis erlang)
* Don ging da doen
* Don gaat da nog steeds doen
* Workshop: maak deze webapp
* App dev sessies
* Feli/Timo: iOS (Swift)
* Feli/Niko: Android
* 2 workshops, op het einde kleine app ontwikkelen
* App-idee: counter voor specifieke spelletjes
* 2-avonden, iOS + Android tegelijkertijd
* Build-server dingen
* Mensen opslorpen;
* WVK 12urenloop
* Facebookgroep
* Mail sturen naar WVK leden
* Karaoke
* Doodle
* Intern
* Voldoende alcohol nodig
* http://kibosh.org/pykaraoke/
# Projecten updates
* Payconiq
* NDA dingen
* Tap/Tab
* Benji heeft tab dingen gedaan
* Integreren met haldis
* Battlebots
* MOZAIC
* Veel werk
* Gandalf
* 200jaar UGent
* Gebruikt voor Groot Dictee
* Feli en Tom: RRRRestyle
* Handig voor FK
* Integratie niet getest
* Site
* Verslagen
* *-*Smooi eh*-*
* Nog een paar issues
* Hydra
* DSA Relaunch
* Minder OAuth inloggen
* Oasis agenda items
* Promo -> Dino
* Helpende handen nodig
* Hulp van bestuur nodig
# Discussiepunten
* Motie van wantrouwen tegen Destro: slechte grappen: goedgekeurd
* Motie van wantrouwen tegen Rien: moties: goedgekeurd
* Wantrouwen van Rien tegen motie: Destro: goedgekeurd
* Vantegen wotie Dien trouwen man: Resto: goedgekeurd
* Vape geur in kelder
* No go
* Algemene evaluatie vorig semester
* Feli: Ik heb steekjes laten vallen
* Isaura: meer helpen <3
* Jeroen: Hydra is niet het enige project, projectondersteuning moet beter
* Rien: rien
* Lorin: projecten weinig docs -> READMEs toevoegen/documentatiecodenight/standaard van documentatie vastleggen, weinig ledenmails, we hebben te weinig
* Elo: is blij, update mails/nieuwsbrief toevoegen
* Destro: is a happy boy :) maaaar servers niet gefixed :( + development voor sommige dingen gestopt en geen nieuwe leden
* Isaura zorgt voor vriendjes avond
* https://docs.google.com/document/d/14keb9yfQBcA7CuUgU1Dw06iVQ0lwA_BZ4P3pZXihLmA/edit#
* Gitiquette
* Hoge drempel (reviews enzo)
* Volgende vergadering
* Hosting GSR
* Vragen we een vergoeding?
* Aan iedereen? (Ceneka, Macht, 12Urenloop …)
* Wie aanvaarden we en wie niet?
* Vergoeding vragen voor iedereen: €50/jaar
* Adverteren, geen garanties, last resort
# Trivia
* Jaarverslag (10 februari)
* Ereledenposters: alles oke
# Vrij moment
Zeus gaat een feministische studentenvereniging oprichten met tetten

View file

@ -0,0 +1,105 @@
% Bestuursvergadering 6:
%
% Datum: 01/03/2017 - 13:20
Status: Closed
Aanwezigen: Volledig bestuur
# Verslag vorige vergadering
- https://docs.google.com/document/d/10Ur1cE9UrPz9DDT1kMPPNkvSc4xehgN7mOD8b0U4n7A/
- Goedgekeurd
# Financiën
* Hashcode
* HTTPizza recap
* 300 euro ongeveer aan pizzas
* Factuur doorsturen
* Server dingen
* 50 euro per kalender/belastingjaar (niet academiejaar)
* GSR wil nu al betalen
* Guidelines opstellen
* Facturen opstellen
# Sysadmin
* Dingen lijken niet meer kapot? Enkel de router en maildingen
* Professionele router? Rien zegt “nah”
* Extra VM aanvragen voor die hosting
* Verantwoordelijke: Bart, Felix, Mats, Dawyndt?
# Activiteiten
* Knowledge transfer template: https://drive.google.com/drive/folders/0B6H1GGAfyze3UzFRMDU3LWMyclE
* Hashcode recap
* Pwetty kewl
* Geen stroomuitval, internetproblemen…
* Volgend jaar meer marketen, testronde organiseren of blogpost voor schrijven
* HTTPizza recap
* Netwerk iets te laat opgezet
* Kleine challenge problemen
* Bonnetjes in twee kleuren waren handig geweest
* Voor de rest a-oh-kay
* Meerdere challenges en met high score werken
* Communicatie ivm voorrang verbeteren
* VPW
* Bellen: danku don <3
* Vast aantal plaatsen: Gandalf?
* Inschrijvingen openstellen (+mailen naar angelique)
* Dawyndt en cicero mailen + facebook + ledenmail
* Bottlebats
* Gaat niet door dit jaar
* Focussen op Mozaic (eerstejaars)
* Lightning talks
* Wie uitnodigen?
* Bart mesuere
* Herman de beukelaer
* Felix vdj
* Ruben verborgh
* Bart coppens
* Jens Timmerman
* Rudy gevaert
* Sanderdemeester
* Andy Georges
* Michiel Camembert vdb
* Relix
* Javache
* Andy van maele
* Bij mail: vragen om toestemming om te filmen
* Breed publiek
* Opnames maken
* Als promo (blogpost) opnames van 2 jaar geleden online zetten na vragen toestemming
# Projecten updates
* Sauron/Saruman
* Benji is bezig aan updates
* Use-cases komen niet volledig overeen
* Jeroen is niet akkoord met de naam DE LOOOOOORE
* HTTPizza
* Volgend jaar uitbreiden
* Mozaic
* Hydra
* Promopersoon: onbereikbaar, verder zoeken
* Campagne: geen promopersoon dus nog niet mogelijk
* Agenda :(
* Buildserver?
* Codenight (projectavonden, …)
* https://docs.google.com/spreadsheets/d/1wx6QHARqcURAKM3C9DyGvQgPDy7a4zO7kKGfFploMGg/
* Geen battlebots, dus casual coding night
* Documentatiefocus
* Applicaties gemakkelijk deploybaar maken
# Discussiepunten
- CenEka: meer samenwerken, redelijk wat overlappingen, event met Sigasi samen organiseren?, samenzitten met beide besturen
# Trivia
* Student Street Soccer mail
* Sure alst zelfde is van vorig jaar, anders niet
* Uniducenti
* Samen met Jochen: Gandalf ging te veel gewijzigd moeten worden voor het Uniducenti event, Feli heeft een nodeJS ding geschreven
* Pulls: 14 momenteel
# Vrij moment
* Elo zegt “miauw”
* Feli vraagt “Komt er iemand naar de werkgroep digitalisering vanavond???”

View file

@ -0,0 +1,106 @@
% Bestuursvergadering 7:
%
% Datum: 03/05/2017 - 14:08
Status: Gesloten
Aanwezigen: Iedereen
# Verslag vorige vergadering
- https://docs.google.com/document/d/1u8ELvmoirJT170eVu-J1H1UXuoqzg0vvLaHnqoQS2og/
# Financiën
* 12urenloop
* Vat met andere verenigingen
* Feli: update moneys van tent
* Pulls
* Betaald, was ongeveer 1000 euro
* Nog enkele pullen op overschot
* 400 euro naar de bank gebracht
* 800 euro op de rekening, 200 in de kassa
* Julien moet nog 2 rollen gaffa teruggeven
* 10 mei: 1ste subsidiedeadline
# Sysadmin
* Respons DICT: geen eigen DNS + mail records meer
* Kopen we zeuswpi.be ? Yes
* Geen geld, subsidieerbaar, handig voor subdomains
* Zomer
* Accountpage
* Slack alternatief
* Backups userdirs en adams
# Activiteiten
* Pieters-thesisding recap
* Vrij complex, niet super geschikt voor eerstejaars
* iOS-lessen recap
* Heel weinig (4-5 man), wat positief bleek te zijn
* Zelfde personen zijn 2de keer ook teruggekomen
* Iedereen heeft de app effectief gemaakt
* Prijzen moet nog beslist worden (30 euro)
* Spelen met FPGAs recap
* Da was cool, voor herhaling vatbaat
* Sigasi was ook tevreden
* Goede opkomst
* 12urenloop recap
* Zeus is taking over
* Dank aan iedereen die is komen helpen
* We hebben wa extra naambekendheid gekregen
* Logs gaan we aan vtk geven, dan krijgen we een nieuwe server?
* Opbouw vrij vlot
* Veel lopers van Ceneka in de voormiddag, VVN in namiddag
* Weinig Zeus lopers
* Minder ambitieus qua drankverbruik
* Maar geslaagd!
* Meer promo(materiaal) na volgend jaar toe
* Lightning talks recap
* Demaks
* Op voorhand timer klaarhouden
* Videos syncen
* Regelmatig/jaarlijks
* Jobbeurs volgend jaar
* Nein, geen resources, geen motivatie
# Projecten updates
* Zeus site is nog altijd cool
* Uitbreidingen:
* Historiek
* Verslagen
* sponsor/partner
* Er zijn nog issues, dus fix ze!
* Gandalf
* Saga 200 jaar UGent continues
* Eerst aparte site
* Nadien eventbrite??
* Uitbreidingen mergen in master branch
* Met mats babbelen
* Hydra
* Gandalf in Hydra?
* SKO: sneller promo
* Feli: koop dingen, dit academiejaar
# Discussiepunten
* Planning en verloop zeusverkiezingen
* Eten al geregeld
* Anoniem stemmen
* Max 3 posities voor ondersteunend bestuursleden
* Teams zijn toegelaten om voor een positie te gaan
# Trivia
* Eetgelegenheid na verkiezingen
* Fixed, Patrick Foleys
* “Zeus sletje doneren”: ok
* Nieuw + oud bestuur meetup/vergadering
* Bestuurssushi met ereleden
* Isaura moet haar juiste naam gebruiken op Slack
* Isaura heeft een identiteitscrisis en dat is haar volste recht
1. No
* Bestuursburgers met sushi
# Vrij moment

View file

@ -0,0 +1,195 @@
% Bestuursvergadering 1:
%
% Datum: 31/07/2017 - 19:30
Status: Gesloten
# Verslag vorige vergadering
- Vergadering 7 - 03/05: goedgekeurd &lt;3
# Financiën
- Bankkaart nieuwe penning?
- Formulieren invullen
- Financiële status: minder goed dan we begonnen zijn
- Niets levensbedreigend
- Rekeningen fixen
- Jeroen gaat nog es bellen
- Sleutels van de kassa zijn overgedragen
- Fix op wiki
# Sysadmin
- Nieuwe sysadmins 'inwijden'
- Documentatie updaten
- Zeuswpi.be
- We hebben een penning nodig die da koopt
- Timo heeft ooit een domeinnaam gekocht
- Gent
- Matrix deftig instellen
- Login platform
- Rien is begonnen met dingen op te zetten
- Wiki updaten
- Sletje
- Mozaic op draaien
- Nieuwe naam nodig: Venus
# Activiteiten
- Gemeenschappelijke kalender WiNA, Prime, VVN, Zeus
- Welke events? Wie?
- Introductiedag
1. Mozaic: Ilion Wout
2. Isaura en don/rien
- SKO standje (Hydra)
1. Wout
- Linux install party -> Weg
1. Dawyndt: Mensen doorverwijzen naar blogpost
2. Assistenten erbij betrekken
3. Naaah, andere unixdingen in de plaats
- Zeus quiz
1. Mensen: Ilion, Elo, Wout, Timpy, Laurens
2. ELOOOOOOOOOOOOOOOOOOOOOo
3. Leutige quiz/talk
- Tiles & Terminals
1. Mensen hun workflow showcasen
- Spelletjes
1. Zie document
- Latex
1. Wout wil gerust eens zien
2. Niet veel werk
3. Andere verenigingen betrekken
- LAN
1. Jeroen en Lorin staan paraat
2. Laurens, Timo, Elo, Alexander Neyt, Safa
3. Sponsoring: Timo en Poef
4. Foodsponsoring
- E&F Talenavond
- Elo, Isaura, Ilion
- Pannekoeken & Jeneever Koodenigt Avont
- Jeroen
- Ceneka talks
- Verantwoordelijk: Laurens
- Ilion, Isaura (geen hard), en de rest
- Ruben verborgh: net neutrality talks
- Event-knowledge transfer dingen afwerken
- Wout (httpizza, bottlebats, sko standje), Rien
- TODO voor alle events => Elo
- 2de semester grote events
- HTTPizza
- Hashcode
- Lightning Talks
- 12urenloop it/loop
- VPW
1. Zeus team
- Elo wenst iedereen veel plezier
- Lasershoot delaware
- Ook een beetje meer promotie op campus Schoonmeersen
- Elo stelt drugs voor
# Projecten updates
- MOZAIC
- Gaat vooruit
- codenight begin juli, relatief veel volk voor een focus codenight
- Wout struikelt over moeilijke dingen, kan geen Rust en ook geen computers :(
- Extra MOZAIC codenight (september of volgende week)
- Nuttige deel van SO II is gebruikt voor documentatie
- JSON schema dat formaat van dingen beschrijft
- GEMAKKELIJKSTE PROJECT OM MEE TE WERKEN!
- Demo proberen tegen introductiedag (geen zekerheid)
- Uw return type kan ook een trait zijn
- Tijdens het jaar ook
- Gamification (Timo)
- TIMO SCHUIFT HET DOOR NAAR ILION
- Timo wilt ML ertegenaan gooien
- Zodat er meer mensen willen gaan coden
- “Timo werkt enkel voor geld” \~~ Wout
- Timo zegt dat Ilion ook gaat meekijken
- Hydra
- € 2000 => Wout koopt harnas
- SKO dingen mee kopen
- Spelletje
- Mail naar mensen restos
- Mail Anneke
- Android
- Niko is bezig aan veel werk, maar vooral architectuur aan het opkuisen
- Bedankingen voor Niko te voorzien
- Hydra T-shirts (semi zeus voorzien)
- Buildserver op sletje draaien
- GSMs bestellen
- Elos kinderen moeten gaan slapen
- Codenights
- Nu al vastleggen? => deftige publieke codenights
- Iedere keer een dinsdag
- Thematische codenights enkel vastleggen, de rest ad-hoc
# Discussiepunten
- Vergaderingen
- Geen event persoon => dus bijvoorbeeld printen lijst verantwoordelijken events in de komende maand (maandelijkse kalender openhangen)
- Vaste dag in de maand?
- Vaker (geen eventpersoon)
- Improvements kelder?
- LED matrix samen met Francis en anderen
- Sirene
- Vloer => DGFB is komen op meten => Pieter De Pauw/Mats vragen
# Trivia
- Overdracht van bestuursdingen
- Badge
1. Aanvragen => 1 voor voorzitter
- Slack owner
1. Toon => wilt dat niet afstaan
2. Opgelost door matrix
- Sleutels
1. Jeroen De Clerck
2. Feliciaan De Palmenaer
3. Lorin Werthen
4. Isaura Claeys
5. Eloïse Piret
6. Rien Maertens
7. Wout Schellaert
8. Tom Naessens
9. Felix van der Jeugt
10. Stijn Seghers
11. Jens Timmerman
- Elo en Feliciaan geven de sleutel af
- …
- Lintjes
1. Misschien Tshirts
- Betaalde facebookreclame
# Vrij moment
- Zouden we geen VZW worden?
# Todo's:
- Rien
- Doedel syssies
- Eventkalender + Eventpersonen fixen
- EKT
- Loginpagina bekijken
- Interesse: Elo, Laurens, Syssies
- Wout pingen voor badge
- Delegeren:
- Volgende vergadering vastleggen
- Begin academiejaar
- Jeroen
- Bankkaart overzet dingen regelen
- Doedel voor met 4 mensen
- Domeinnaam kopen
- Deurwaarder checken
- Timo
- Sponsoring Lanparty
- Wout
- EKT
- Badge: wie?
- ALGEMEEN
- Mails naar leden sturen
- Kalender in kelder uitprinten & hangen (matrixbord)

View file

@ -0,0 +1,64 @@
% Bestuursvergadering 2:
%
% Datum: 02/10/2017 - 14:30
Status: Gesloten
# Verslag vorige vergadering
- <https://docs.google.com/document/d/1rwjfM5vd7YKvjfKCxibOBN45Zv_MfHWA1lFuok1Iju8>
- goedgekeurd
# Financiën
- Zeus heeft geld
- Bank: €243
- Kassa: €305
- Veel te weinig liquide middelen
- Hoge schulden: tap herbekijken (limiet op 0), Rien praat met hoge schuldenaren
- Schuldenmails
- Kaartmoment regelen: volgende maandag (9 okt 11 uur)
- bankformulieren
# Sysadmin
- Digitaal Ledenformulier: zeus.ugent.be/ledenformulier
- Samenzitten voor
- Config mgmt
- Backups
- Algemene dingen
# Activiteiten
- Introdag is gebeurd
- Meer mensen lokken en praten
- Zeus-quiz
- Ledenformulier vermelden
- Elo en ilion volgen dingen op
- Sigasi is cool: in het hoofd houden
- Events verdelen
- Ceneka Talks: hulp nodig
- ANTWOORD OP DELAWARE: ziggy, ilion, laurens
- Poster geeks, attack: Stranger things
# Projecten updates
- Mozaic bestaat
- Hydradingen gebeuren
- Timo gaat nog steeds gamificationdingen doen maar eerst moet hij de financien van zeus redden
- Gandalf: enkel feli doet daar nog dingen mee, we laten het zoals het is
# Discussiepunten
- Zeus sponsoring
- Voor de LAN-party: jeroen gaat daar voor kijken
- Recruiting pagina opzetten
- Sponsoring is ok als we een doel voor ogen hebben
# Trivia
- Sleuteltjes
# Vrij moment
# Todo's:

View file

@ -0,0 +1,97 @@
% Bestuursvergadering 3
% Isaura Claeys
% Datum: 20/11/2017 - 13:00
Status: Gesloten
# Verslag vorige vergadering
- <https://docs.google.com/document/d/1JTZ3PmzZfooRkfUjZCoBqdfzMDKA31XdfpiwaR1qPWE/edit>
# Financiën
- Afronden subsidies dit jaar
- Deadline 1 december
- 130 euro aan subsidies
- 381 euro op rekening + 600 in de kassa
- Verhoging prijzen drank publieke events (bvb Hashcode) voor niet-leden (afronden naar boven)
- Tab
1. fixen codenight + overleggen met benji
2. Mails sturen
- Hydra
1. Veel te veel geld over
2. IPad gekocht (voorgeschoten door timo)
3. T-Shirts
- Terugbetaling Giant Progressbar destro
- Terugbetaling MOZAIC codenight drinks destro
# Sysadmin
- Sysadminis
- Lorin kuist asana op + voegt nieuwe sysadminis toe
# Activiteiten
- Lan: Alles in orde? (competities ed.)
- Sigasi contacteren met winnaars
- Jeroen moet stoppen met tam zijn
- Internet freedom
- <https://docs.google.com/document/d/1zgM6jF2mmNyfXKi_SHFMZYLywnJvLPDq0sLxAxb9Bps/edit#>
- Mensen fixen
- Talk Delaware
- Datum 18/04
- Verantwoordelijke: Laurens, Wout en elo helpen
- Ricing-avond 04/12
- Tiles & Terminals 2
- Ideeën?
1. Blogpost met links
2. Korte demos met workflow tips
3. Oproep om mensen te vinden die hun setup willen showen
4. Felix, Detlev, Ketnet, Rien
- Brainstormavond met Detlev: DOODLE
- Workflow stresstesting
- Contest: om ter snelst typen op een mechanisch toetsenbord
- Feli talk (GDPR)
- Europees dataprotocol
- Via GSR?
- E&F avond
- FP progtalen gebruiken?
- Uitstellen naar 2de semester: 2de week
- Eerstejaars optrommelen
- DOODLE voor brainstorm
- Pannenkoeken en Jenever Codenight-Avond
- HELL YEAH
- 30 november TBD
- Blogposts/Eventposts schrijven voor vastgepinde events!
- Tiles & terminals
- Delaware talk:
1. Poster
2. Blogpost
- Vlaamse Programmeerwedstrijd!
- Jonathan + isaura
- Poke andy
# Projecten updates
- 12Urenloop
- Crew: Ziggy + Jonathan + Tibo
- G2
- Gamification 2
- Project en event management tool
- MOZAIC
- 2de grote mozaic-codenight
- React rewrite gaat vooruit
# Discussiepunten
# Trivia
- Slotmachien was kapot: Jeroen merkt op dat als ge gewoon regelmatig es moet aanduwen, dan kan hij er niet van vallen.
- Heeft Ilion de sleutel van Stijn? -> Neen.
- Wanneer zeuswpi.org gebruiken?
- Komt bij asana taakjes
- Certificaten aanvragen
# Vrij moment
# Todo's

View file

@ -0,0 +1,110 @@
% Bestuursvergadering 4
% Isaura Claeys
% 21/02/2018 - 17:25
# Verslag vorige vergadering
<https://docs.google.com/document/d/1XmpU8lRla56X1osueR8ucaRUP8atVbrJuS4XGRiJd-8/edit?usp=sharing> Check
# Financiën
- WVK Subsidies
- Goedgekeurd: +50 euro extra tov AJ 2016-2017 (1100 in totaal)
- Overzicht
- 650 op de bank
- 220 in de kassa
- Hydra: 1029 terugkrijgen voor Hydra
- Stuw moeten we ook terugkrijgen
- 1800 hebben we atm in totaal
- 839 tab schulden atm
- TV
- Mailen als subsidies bij DSA verwerkt zijn
- Partnerships
- Aparte mailinglijst waar leden zich op kunnen uitschrijven als nodig
- Pakketten aanbieden
1. Evenement (50)
2. Vacature mailinglijst/site
3. Logo op poster/site (enkel bij sponsoring event)
4. Codenights sponsoren
5. Prijzen sponsoren
6. 1 pakket met combinatie van alles
- Wie? Timo
- Ocean Garden en Ocean Garden codenight?
- Timo organiseert aparte vergadering hiervoor
- Lorin is een tomaat, want hij heeft voor de eerste keer in 10 jaar 100 meter gefietst.
- Ereleden
- Kandidaten: pietervdv
- Minimum 50 euro: poster + site (optioneel)
- Dino doet dingen
# Sysadmin
- Deployen MOZAIC
- Met Wout afspreken
- Dingen mogen gebeuren
- Asana
# Activiteiten
- Hashcode
- Delhaizerun vrijdag
- Extra locatie
- 300 euro aan pizzas: Lorin en Rien
- VPW
- We zijn ervoorbij
- In orde!
- Bus zit vol!
- Je bent goed bezig!
- Behalve Lorin en zijn potentieel team van Wout zijn lief
- Ceneka Talks
- 18 april
- Delaware komt
- Maar wie weet waar het over gaat
- Camera bij DICT regelen
- Eten regelen avond zelf
- Barmensen regelen
- Lightning talks
- Komt in orde
- 12Urenloop
- Jeroen wordt teamlead IT
- Volgende vrijdag 12UL codenight
- Tent: Feliciaan vragen hoe subsidieren?
- HTTPizza
- Momenteel afgelast
# Projecten updates
- MOZAIC
- Intel AI ding van maken if need be
- Meer bestuur rond krijgen nu
1. Organiseren + inplannen + promo
- Inplannen introductie (presentatie etc.)
- Rien gaat helpen!
- Volgende donderdagmiddag: 11.30u
- Hydra
- Dingen gaan vooruit
- Feli gaat traag
- Lekker
- G2
- Verschil met gamification: stats zijn een bijzaak, doel is participatie verhogen
# Discussiepunten
- Rien zegt iets: Ik stel voor dat we eventueel toekomstige bestuursleden bij het bestuur beginnen betrekken.
- Niet bij vergaderingen betrekken
# Trivia
- Cegeka antwoorden
- Timo + die andere partnership mail
- VEK antwoorden
- wout
- Wina Antwoorden
- Infodinges voor de master informatica
- Rien
# Vrij moment
Ilion doet een bekentenis: Ik lees mijn mails nooit.
# Todo's:

View file

@ -0,0 +1,196 @@
% Bestuursvergadering 5
% Isaura Claeys
% 20/04/2018 - 16:00
# Bestuursvergadering 5
_Datum: 19/04/2018 - 16:00_
_Status: Gesloten_
**Timetable:**
| Start | Duur | Onderwerp |
| ----- | ---- | ------------ |
| 16:00 | '10 | Intro |
| 16:10 | '5 | Financiën |
| 16:15 | '5 | Sysadmin |
| 16:20 | '5 | Projecten |
| 16:25 | '20 | Events |
| 16:45 | '15 | Pauze |
| 17:00 | '20 | Ereleden |
| 17:20 | '20 | Verkiezingen |
| 17:40 | '20 | Partnerships |
| 18:00 | ... | Trivia, ... |
## 0. Verslagen workflow
Gebruik van hackmd.io: collaboratief verslagen schrijven in markdown. :white_check_mark:
- Goedkeuringen door middel van 'reviews' op PR's
- Verslag op de site: officiëler en permanenter
- Hopelijk een verbetering in de kwaliteit van verslagen tot gevolg
- We vereisen dat elk bestuurslid het verslag goedkeurt op de PR
## 1. Verslag vorige vergadering
[Bestuursvergadering 4](https://drive.google.com/open?id=1l2LuBNQlMPtEKhjJ7ahJC3MRpc3l5fC9H2X7cvaCWQ4) :white_check_mark:
## 2. Financiën
### Status
€1100 + €200 ongeveer aan subsidies, wat vrij degelijk is voor Zeus.
### Kosten 12UL in samenwerking met WVK
Geld **tent**: €475 over 3 verenigingen, €120 per vereniging, mits korting €110 euro per vereniging. De **Espressobins**: €360 in totaal.
*Note: na het event eens evalueren of we dit willen doen volgend jaar, is het de financiële nood waard?*
## 3. Sysadmin
### Jasper als sysadmin-in-training
Jasper heeft sysadmin opleiding intro gekregen om de volgende sysadmin te worden.
### Nieuwe VM
We gaan een nieuwe VM aanvragen voor studentenverenigingen sites die niet bij DSA kunnen. Deze zijn oa Ceneka, macht, cursuscruisen, stuw, ... Zit ook vol met PHP code, wat vaak vulnerable is. Lorin gaat dit regelen.
### Nieuwe domeinnaam:
We gaan zeus.gent kopen en als default gebruiken. Dit kost wat meer geld per jaar, maar is subsidieerbaar. Oogt ook mooier dan zeuswpi.org. Hiervoor moeten we alle applicaties checken voor harcoded locations.
Testrun van site moven (zeus.ugent.be/xxx naar zeuswpi.org/xxx) lukt.
## 4. Projecten updates
### MOZAIC
Er is veel netwerkcode, maar nog geen nieuwe release, komt wel soonish. Wout en Timo gaan voor het vak Datavisualisatie een visualisatie maken voor matchanalyse.
Op donderdag 26 april is een tinkersessie gepland. Daar zorgen we dat de code werkt. We maken een fb event en een zeus site event, en we sturen een mail. **Rien** maakt de reservatie, en **Wout** en **Ilion** doen de mail en eventpost. Ze kijken ook of er Intel sponsorgeld kan gebruikt worden.
## 5. Activiteiten
### Evaluatie
#### Hashcode
We moeten duidelijker communiceren dat we geen eten fixen, of gewoon en masse pizza's bestellen. Dit moeten we op voorhand beslissen. We beslissen ook best wie de verantwoordelijkheid neemt op het event, aangezien veel bestuursleden willen meedoen. Idee: Een bestuursteam kan zo wel handig worden.
#### VPW
We waren Jonathan ter plekke vergeten doordat hij nog wachtte op potentieel andere mensen die meereden. Voor de rest ging het vlot. We moeten op voorhand afspreken wie verantwoordelijk is.
#### Lasershoot
Ging goed, maar we moeten op voorhand meer informatie geven. De opties geven we ook beter op voorhand. Er moet ook meer structuur zijn.
#### Bottlebats intro-event
Was al bij al een succes, maar kon beter georganiseerd zijn. Concept is oke, maar bleef vrij wild en los. Er moet meer documentatie voorzien worden, en het is te veel werk voor te weinig man. Dit gaat een issue blijven.
We geven ook best een demo van een bot te schrijven.
#### Delaware talk
Ging niet door en hier was weinig over gecommuniceerd. Er was een talk-moeheid van iedereen (bestuur en ook attendees) doordat er te veel talks waren dit semester. Er moet meer communicatie zijn tussen Zeus en delaware, en ook meer communicatie mbt promo. Wout had meer begeleiding kunnen geven aan Laurens.
Het was ook een event na de paasvakantie, waardoor er vroeg genoeg met promo moest begonnen worden.
We zouden volgend jaar de Tech talkz niet meer doen.
### Toekomstige events:
#### 12Urenloop
Gyrids zijn gefixed. We zoeken naar de chips, maar worden niet gevonden. Op vrijdag 20 april zou alles af moeten zijn.
Op het evenement zelf gaan er nog mensen nodig zijn om te tellen, en sowieso gaan er mensen nodig zijn om mee te helpen. Iedereen is hierbij welkom.
#### Lightning Talks
Alles is geregeld. We steken €50-€100 in de receptie, wat met het ereleden budget kan. Voor de sprekersbedanking gaat Timo kijken naar de maximale prijs zodat dit gesubsidieerd kan worden.
#### Cybersecurity workshop/CTF/…
Geagendeerd maar niet besproken (te laat in het jaar om dit nog te organiseren, mogelijks event voor volgend jaar)
#### Zeus verkiezingen
We organiseren het op 8 mei 18:00, wat samenvalt met de WiNA shotjesavond! We gaan eten in O'Leary's, maar hier is nog geen beslissing over geveld. We zullen dit bespreken met de leden en daarna tot een beslissing komen.
We sturen zo snel mogelijk een mail (ging gebeuren 19 april). Ook zetten we de kandidatuurform online.
## 6. Discussiepunten
- Werkgroep sponsorships & ereleden: [verslag](https://hackmd.io/yVLl1eV2SLqVNTtern6F3Q)
- Sponsorships
- Ereleden
- Steunend-lid statuut invoeren: afgestudeerde mensen kunnen nog steeds Zeus steunen via vrije bijdrage, en dan worden die leden op de site vermeld. Vermelding op de site vindt plaats vanaf 10 euro?. Daarnaast hebben we dan ereleden, waarvoor we geen geld meer vragen. Poll voor heel Zeus om mensen te selecteren die erelidwaardig zijn, alsook met motivatie. Deze poll is geen finale beslissing. Bestuur beslist dan op basis daar van, ook op basis van een stemming. Geen extra voordeel buiten de erkenning en een poster. Geen burgeravond. Dus ereleden en sponsors splitsen. Op het einde van het academiejaar ereleden beslissen. Poster + foto op de site.
- Alumniwerking
- Alumni-event (receptie of alumni-codenight) voor alle sponsors en ereleden (eventueel ereleden).
- Huidige ereleden: mail sturen. Ereleden kunnen storten tot aan de bestuursverkiezingen.
- Bestuursfuncties '18-'19
Momenteel is mogelijk:
- **Voorzitter (verplicht)**
Het hoofd van het bestuur. Hakt knopen door bij moeilijke beslissingen en zorgt voor een vloeiende werking van het bestuur
- **Penning (verplicht)**
De penningmeester houdt alle financiële zaken bij van de organisatie.
Deze functie is ook verplicht door de DSA, en kan misschien gecombineerd worden met secretaris, wegens het ook een administratieve taak is.
- **Secretaris**
De secretaris onderhoudt de administratie van het bestuur en schrijft de verslagen van de bestuursvergaderingen. Ook reserveert de secretaris de evenementen van Zeus en noteert ze in het DSA-controlepaneel. Deze taak kan door PR opgenomen worden.
- **Project**
De projectverantwoordelijke verzorgt de projecten in Zeus en zorgt voor een goede vooruitgang. Ook zorgt de projectverantwoordelijke voor de definitie van een goed development proces en onderhoudt de repos
- **Sysadmin**
De sysadmin verzorgt de servers, zij het lokaal, zij het in de cloud. Deze moeten altijd up to date gehouden worden zodat er geen security issues op kunnen komen.
- **PR**
De PR verantwoordelijke zorgt voor blogposts, communicatie met externen en onze social media. De PR zal dus ook foto's en dergelijke online zetten en het engagement met niet-Zeusleden verhogen
- **HR**
SHFEERBEHEER. Zorgt voor de algemene sfeer in de kelder en ledenwerking. Probeert actief leden aan te werven. Kennisoverdracht tussen events enzovoorts.
Bestuursfuncties die we niet inrichten:
- **Vicevoorzitter (verplicht)**
Right hand (wo)man van de voorzitter. Wordt commander-in-chief indien de voorzitter niet beschikbaar is.
Deze functie is verplicht door DSA, maar in de realiteit is de vice gewoon secretaris met een fancy titel. In principe kan eender welk bestuurslid de vicevoorzitter zijn, ongeacht hun feitelijke rol.
Het voorstel is om deze rol intern aan te duiden onder de verkozen bestuursleden.
- **Event**
In plaats van één persoon constant te 'belasten' met het organiseren van alle events zouden we blijven bij de formule van dit jaar: nl. events in het begin van het semester te bespreken en een verantwoordelijke per event aan te duiden.
Discussie
- HR samenvoegen met Vice + Vice beter omschrijven
- De functie van projectverantwoordelijke: heeft een voortrekkersrol, waar een niet verwaarloosbare werkdruk komt bij kijken. Er wordt opgemerkt dat deze functie liefst door meerdere personen wordt ingekleed.
## 7. Trivia
### Evaluatie vleor
VLEOR (Dit is Zeusiaans voor: "De vloer ligt er en we zijn blij")
### Blogpost ideeën/evaluatie
We kunnen blogpost maken over:
- bottlebats
- update april
- Datavisualisatie project Isaura, Elo en Lorin. Deze zouden visualisaties bevatten van Haldis, Tab, Tap, Zeus events, ...
We zijn in ieder geval content over de recente stroom van blogposts.
### Engagement bestuursleden.
Is besproken geweest op de vergadering. Deze kon in sommige gevallen beter.
### Opmerkingen Lorin over Linux Install Party volgend jaar
Volgend jaar gaat dit huge zijn, dus meer organisatie (splitsen in 2 avonden bijvoorbeeld).
## 8. Vrij moment
## Todo's:

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -1,61 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 864 312"
width="200">
<path d="m2.3 2.3h859.5v307.5h-859.5z" />
<path d="m4.5 4.5h855v303h-855zm-4.5 307.5h864v-312h-864z" fill="#d2d2d2" />
<path d="m70.5 68.6h83.8v83.8h-83.8z" fill="#f25022" />
<path d="m163 68.6h83.8v83.8h-83.8z" fill="#7fba00" />
<path d="m70.5 161h83.8v83.8h-83.8z" fill="#00a4ef" />
<path d="m163 161h83.8v83.8h-83.8z" fill="#ffb900" />
<path
d="m408.3 163c0-2.5.9-4.5 2.7-6.2 1.8-1.7 3.9-2.5 6.4-2.5 2.6 0 4.8.9 6.5 2.6 1.7 1.7 2.6 3.8 2.6 6.1 0 2.4-.9 4.5-2.7 6.1-1.8 1.7-3.9 2.5-6.5 2.5-2.6 0-4.7-.8-6.5-2.5-1.6-1.7-2.5-3.7-2.5-6.1m16.5 81.8h-14.9v-63.5h14.9z"
fill="#fff" />
<path
d="m470.2 233.9c2.2 0 4.7-.5 7.4-1.5 2.7-1 5.1-2.4 7.4-4.1v13.9c-2.4 1.4-5.1 2.4-8.1 3.1-3 .7-6.4 1.1-10 1.1-9.3 0-16.9-3-22.8-8.9-5.9-5.9-8.8-13.5-8.8-22.6 0-10.2 3-18.6 9-25.2 6-6.6 14.4-9.9 25.4-9.9 2.8 0 5.6.4 8.5 1.1 2.9.7 5.1 1.6 6.8 2.5v14.3c-2.3-1.7-4.7-3-7.1-3.9-2.4-.9-4.9-1.4-7.4-1.4-5.9 0-10.6 1.9-14.3 5.7-3.6 3.8-5.4 9-5.4 15.5 0 6.4 1.7 11.4 5.2 15 3.5 3.6 8.2 5.3 14.2 5.3"
fill="#fff" />
<path
d="m527.5 180.3c1.2 0 2.3.1 3.2.2.9.2 1.8.4 2.4.6v15.1c-.8-.6-1.9-1.1-3.4-1.6-1.5-.5-3.3-.8-5.5-.8-3.7 0-6.8 1.5-9.3 4.6-2.5 3.1-3.8 7.8-3.8 14.3v32.1h-14.9v-63.5h14.9v10h .2c1.4-3.5 3.4-6.2 6.2-8.1 2.8-1.9 6.1-2.9 10-2.9"
fill="#fff" />
<path
d="m533.9 214c0-10.5 3-18.8 8.9-25 5.9-6.1 14.2-9.2 24.7-9.2 9.9 0 17.7 3 23.3 8.9 5.6 5.9 8.4 13.9 8.4 23.9 0 10.3-3 18.5-8.9 24.6-5.9 6.1-14 9.1-24.2 9.1-9.8 0-17.7-2.9-23.4-8.7-5.9-5.7-8.8-13.6-8.8-23.6m15.6-.5c0 6.6 1.5 11.7 4.5 15.2 3 3.5 7.3 5.2 12.9 5.2 5.4 0 9.6-1.7 12.4-5.2s4.3-8.7 4.3-15.6c0-6.8-1.5-12-4.4-15.5-2.9-3.5-7.1-5.2-12.4-5.2-5.5 0-9.7 1.8-12.8 5.5-3 3.7-4.5 8.8-4.5 15.6"
fill="#fff" />
<path
d="m621.4 198c0 2.1.7 3.8 2 5 1.4 1.2 4.4 2.7 9 4.6 6 2.4 10.2 5.1 12.6 8.1 2.4 3 3.6 6.6 3.6 10.8 0 6-2.3 10.8-6.9 14.4-4.6 3.6-10.8 5.4-18.6 5.4-2.6 0-5.5-.3-8.7-1-3.2-.6-5.9-1.5-8.1-2.4v-14.7c2.7 1.9 5.6 3.4 8.8 4.5 3.1 1.1 6 1.7 8.5 1.7 3.4 0 5.9-.5 7.5-1.4 1.6-.9 2.4-2.5 2.4-4.8 0-2.1-.8-3.8-2.5-5.2-1.7-1.4-4.8-3.1-9.5-4.9-5.5-2.3-9.4-4.9-11.7-7.8-2.3-2.9-3.5-6.6-3.5-11 0-5.7 2.3-10.4 6.8-14.1 4.5-3.7 10.4-5.5 17.7-5.5 2.2 0 4.7.2 7.5.7 2.8.5 5.1 1.1 6.9 1.9v14.2c-2-1.3-4.3-2.4-6.9-3.4-2.6-.9-5.3-1.4-7.8-1.4-2.8 0-5.1.6-6.6 1.7-1.7 1.1-2.5 2.7-2.5 4.6"
fill="#fff" />
<path
d="m655.2 214c0-10.5 3-18.8 8.9-25 5.9-6.1 14.2-9.2 24.7-9.2 9.9 0 17.7 3 23.3 8.9 5.6 5.9 8.4 13.9 8.4 23.9 0 10.3-3 18.5-8.9 24.6-5.9 6.1-14 9.1-24.2 9.1-9.8 0-17.7-2.9-23.4-8.7-5.9-5.7-8.8-13.6-8.8-23.6m15.5-.5c0 6.6 1.5 11.7 4.5 15.2 3 3.5 7.3 5.2 12.9 5.2 5.4 0 9.6-1.7 12.4-5.2s4.3-8.7 4.3-15.6c0-6.8-1.5-12-4.4-15.5s-7.1-5.2-12.4-5.2c-5.5 0-9.7 1.8-12.8 5.5-3 3.7-4.5 8.8-4.5 15.6"
fill="#fff" />
<path
d="m769.8 193.6v32.6c0 6.8 1.6 11.8 4.7 15.2 3.1 3.4 7.9 5 14.2 5 2.1 0 4.3-.2 6.5-.7 2.2-.5 3.8-.9 4.7-1.5v-12.4c-.9.6-2 1.1-3.2 1.5-1.2.4-2.3.6-3.1.6-3 0-5.3-.8-6.7-2.4-1.4-1.6-2.1-4.4-2.1-8.3v-29.7h15.2v-12.2h-15.1v-18.8l-15 4.6v14.3h-22.3v-7.7c0-3.8.8-6.7 2.5-8.7 1.7-2 4.1-2.9 7.2-2.9 1.6 0 3 .2 4.3.6 1.2.4 2.1.8 2.6 1.1v-12.9c-1.1-.4-2.3-.6-3.7-.8-1.4-.2-3-.3-4.8-.3-6.8 0-12.4 2.1-16.7 6.4-4.3 4.3-6.5 9.7-6.5 16.4v8.8h-10.6v12.2h10.6v51.3h15.1v-51.3z"
fill="#fff" />
<path
d="m395.5 156.2v88.6h-15.4v-69.4h-.2l-27.5 69.4h-10.2l-28.2-69.4h-.2v69.4h-14.2v-88.6h22l25.5 65.7h.4l26.9-65.7z"
fill="#fff" />
<path
d="m340 117.9c-5.3 3-11.3 4.5-18 4.5-5.1 0-9.6-1.1-13.6-3.4-3.9-2.2-7-5.4-9.1-9.5-2.1-4.1-3.2-8.7-3.2-13.8 0-5.4 1.2-10.3 3.5-14.5s5.6-7.6 9.9-10c4.3-2.4 9.1-3.6 14.5-3.6 2.7 0 5.4.3 8.1.8 2.7.5 4.9 1.2 6.6 2v8c-4-2.7-9.1-4-15.3-4-3.7 0-7 .9-10 2.7-3 1.8-5.3 4.3-6.9 7.4-1.6 3.2-2.4 6.8-2.4 10.8 0 6.3 1.7 11.3 5 15 3.3 3.7 7.9 5.5 13.7 5.5 3.7 0 7-.7 9.8-2.2v-13.7h-11.3v-6.6h18.7z"
fill="#fff" />
<path
d="m383.1 104.6h-26.2c.1 3.8 1.3 6.7 3.3 8.8 2.1 2 4.8 3.1 8.2 3.1 4.5 0 8.4-1.3 11.8-3.9v6.4c-1.5 1-3.4 1.9-5.7 2.5-2.3.6-4.7.9-7.1.9-5.7 0-10.2-1.7-13.3-5.1-3.1-3.4-4.7-8.2-4.7-14.4 0-3.8.8-7.3 2.3-10.3 1.5-3.1 3.7-5.5 6.4-7.2 2.7-1.7 5.8-2.6 9.1-2.6 4.9 0 8.8 1.6 11.6 4.8 2.8 3.2 4.2 7.6 4.2 13.3v3.7zm-7.3-5.7c0-3.3-.8-5.8-2.3-7.5-1.5-1.7-3.6-2.6-6.4-2.6-2.5 0-4.7.9-6.6 2.7s-3 4.3-3.6 7.4z"
fill="#fff" />
<path
d="m411.5 121.1c-.7.4-1.6.7-2.9.9-1.2.2-2.3.3-3.3.3-7 0-10.5-3.9-10.5-11.6v-21h-6.4v-6h6.4v-9l7.3-2.3v11.2h9.3v6h-9.3v19.8c0 2.5.4 4.3 1.2 5.3.8 1 2.2 1.5 4.3 1.5 1.4 0 2.7-.4 3.8-1.2v6.1z"
fill="#fff" />
<path
d="m447.7 70.3c0 1.2-.4 2.2-1.3 3.1-.9.9-2 1.3-3.3 1.3-1.3 0-2.4-.4-3.3-1.3-.9-.8-1.3-1.9-1.3-3.2 0-1.3.5-2.4 1.4-3.2.9-.8 2-1.3 3.2-1.3 1.2 0 2.3.4 3.2 1.3 1 1 1.4 2 1.4 3.3m-1 51.2h-7.3v-37.8h7.3z"
fill="#fff" />
<path
d="m478.4 121.1c-.7.4-1.6.7-2.9.9-1.2.2-2.3.3-3.3.3-7 0-10.5-3.9-10.5-11.6v-21h-6.4v-6h6.4v-9l7.3-2.3v11.2h9.3v6h-9.3v19.8c0 2.5.4 4.3 1.2 5.3.8 1 2.2 1.5 4.3 1.5 1.4 0 2.7-.4 3.8-1.2v6.1z"
fill="#fff" />
<path
d="m526.2 71.7c-1.2-.6-2.5-1-4-1-4.1 0-6.1 2.5-6.1 7.5v5.4h8.6v6h-8.6v31.8h-7.3v-31.7h-6.4v-6h6.4v-5.8c0-4 1.1-7.2 3.4-9.6 2.3-2.4 5.4-3.6 9.4-3.6 2 0 3.5.2 4.7.7v6.3z"
fill="#fff" />
<path
d="m553.1 91c-.4-.3-1.2-.6-2.2-.9-1-.2-1.9-.4-2.6-.4-2.6 0-4.7 1.2-6.3 3.5-1.6 2.3-2.4 5.3-2.4 9v19.3h-7.3v-37.8h7.3v7.6h.2c.8-2.6 2.1-4.6 3.8-6.1 1.7-1.5 3.7-2.2 5.9-2.2 1.5 0 2.7.2 3.5.5v7.5z"
fill="#fff" />
<path
d="m594.8 102.4c0 6.1-1.8 11-5.3 14.6-3.5 3.6-8.2 5.4-14 5.4-5.7 0-10.3-1.8-13.7-5.3-3.4-3.5-5.1-8.2-5.1-14.1 0-6.3 1.8-11.2 5.3-14.8 3.5-3.6 8.3-5.4 14.4-5.4 5.7 0 10.2 1.7 13.4 5.2 3.4 3.5 5 8.3 5 14.4m-7.5.2c0-4.5-1-7.9-2.9-10.2-2-2.3-4.7-3.5-8.3-3.5-3.6 0-6.5 1.2-8.6 3.7-2.1 2.4-3.1 5.9-3.1 10.3 0 4.3 1 7.6 3.1 10 2.1 2.4 4.9 3.6 8.6 3.6 3.7 0 6.5-1.2 8.4-3.5 1.8-2.5 2.8-5.9 2.8-10.4"
fill="#fff" />
<path
d="m660.1 121.5h-7.3v-21.5c0-3.9-.6-6.7-1.8-8.5-1.2-1.8-3.3-2.6-6.2-2.6-2.4 0-4.5 1.1-6.1 3.3-1.7 2.2-2.5 4.9-2.5 7.9v21.4h-7.3v-22.2c0-6.9-2.7-10.4-8-10.4-2.5 0-4.6 1.1-6.2 3.2s-2.4 4.8-2.4 8.1v21.4h-7.3v-37.9h7.3v5.9h.1c2.7-4.6 6.7-6.8 11.8-6.8 2.4 0 4.6.7 6.6 2 1.9 1.3 3.3 3.2 4.2 5.6 1.5-2.6 3.2-4.5 5.3-5.8 2.1-1.2 4.5-1.9 7.3-1.9 8.3 0 12.4 5.1 12.4 15.4v23.4z"
fill="#fff" />
</svg>

Before

Width:  |  Height:  |  Size: 6.2 KiB

View file

@ -0,0 +1,237 @@
// BUBBLEMAP
(function () {
let dayFilter = new Set();
function applyFilter(data) {
if (dayFilter.size > 0) {
return _.filter(data, e => dayFilter.has(moment(e.starttime).day()))
}
return data;
}
function filterData(data, beginTime, endTime) {
data = applyFilter(data);
return _(data).filter(e => beginTime <= moment(e.starttime) && moment(e.starttime) <= endTime).value();
}
d3.csv(`/csvdata/punchcard.csv`).then(data => {
// Sort the data chronologically
data = _.sortBy(data, e => Date.parse(e.starttime));
const chart = bubbleMap();
const selection = d3.select('#leafletmap')
.datum(data)
.call(chart);
const times = _(data).map(e => moment(e.starttime));
const slider = timeSlider()
.domain([times.min().toDate(), times.max().toDate()])
.data(times.value())
.on('slide.hm', domain => {
const beginTime = domain[0];
const endTime = domain[1];
const d = filterData(data, beginTime, endTime);
selection.datum(d).call(chart)
});
const sel2 = d3.select('#slider1').call(slider);
d3.selectAll("#dayButtons .button")
.on("click", function () {
const btn = d3.select(this);
const num = +btn.attr('data-day-idx');
const selected = btn.classed('is-outlined');
if (num >= 0) {
selected ? dayFilter.add(num) : dayFilter.delete(num) ;
btn.classed('is-outlined', !selected)
} else {
dayFilter = new Set();
d3.selectAll("#dayButtons .button").classed('is-outlined', true);
}
const filtered = applyFilter(data);
const sliderData = _(filtered).map(e => moment(e.starttime).toDate()).value();
selection.datum(filtered).call(chart);
slider.data(sliderData);
});
var playing = false;
var interval;
d3.select('#playButton')
.on('click', function () {
if(playing) {
clearInterval(interval);
playing = false;
d3.select(this).text('Play');
return;
}
playing = true;
d3.select(this).text('Pause');
let beginTime = moment(slider.slider()[0]);
let endTime = moment(slider.slider()[1]);
interval = setInterval(() => {
const bt = beginTime.toDate();
const et = endTime.toDate();
if (endTime < times.max()) {
const filtData = filterData(data, bt, et);
selection.datum(filtData).call(chart);
slider.slider([bt, et]);
beginTime.add(1, 'd');
endTime.add(1, 'd');
} else {
clearInterval(interval);
}
}, 20);
d3.select(this).text('Pause');
});
});
})();
// PUNCHCARD
(function () {
d3.csv(`/csvdata/punchcard.csv`, e => { return { ...e, starttime: moment(e.starttime) } }).then(data => {
function prepareData(data) {
let grouped = _(data).groupBy(e => e.name).mapValues(e => _(e).groupBy(e => e.starttime.hour()).mapValues(e => e.length).value()).value();
grouped = _(grouped).toPairs().sortBy(e => -_(e[1]).values().sum()).fromPairs().value();
return grouped;
}
const grouped = prepareData(data);
const pChart = punchCard().data(grouped);
const svg = d3.select('svg#punchcard').call(pChart);
const times = _(data).map(e => e.starttime);
function filterData(data, beginTime, endTime) {
return _(data).filter(e => beginTime <= e.starttime && e.starttime <= endTime).value();
}
const slider = timeSlider()
.domain([times.min(), times.max()])
.data(times.value())
.on('slide.punchcard', domain => {
const beginTime = domain[0];
const endTime = domain[1];
const d = filterData(data, beginTime, endTime);
pChart.data(prepareData(d));
});
const sel2 = d3.select('#slider2').call(slider);
var playing = false;
var interval;
d3.select('#playButton2')
.on('click', function () {
if(playing) {
clearInterval(interval);
playing = false;
d3.select(this).text('Play');
return;
}
playing = true;
d3.select(this).text('Pause');
let beginTime = moment(slider.slider()[0]);
let endTime = moment(slider.slider()[1]);
interval = setInterval(() => {
const bt = beginTime.toDate();
const et = endTime.toDate();
if (endTime < times.max()) {
const filtData = prepareData(filterData(data, bt, et));
pChart.data(filtData);
slider.slider([bt, et]);
beginTime.add(1, 'd');
endTime.add(1, 'd');
} else {
clearInterval(interval);
}
}, 20);
});
});
})();
// INSTANCE CHART
(function () {
d3.csv(`/csvdata/punchcard.csv`, e => {
return { ...e, starttime: moment(e.starttime) }
}).then(data => {
function prepareData(data, interval) {
data = _(data).sortBy(e => e.starttime).groupBy('name').value();
return data
}
const prepped = prepareData(data, d3.timeDay);
let chart = instanceChart().data(prepped);
d3.select('svg#instance').call(chart);
});
})();
// RANKING CHART
(function () {
function prepareData(data, interval) {
let l = data.length;
data = _(data).sortBy(e => e.starttime).value();
let slices = [];
let slice = []
let itv = interval(data[0].starttime);
for (const d of data) {
slice.push(d);
let nItv = interval(d.starttime);
if (itv.getTime() !== nItv.getTime()) {
slices.push({
slice: slice.slice(),
time: itv
});
itv = nItv;
}
}
let res = slices.map(e => {
let r = _(e.slice).countBy('name').toPairs().orderBy('1', 'desc').value();
return { slice: r, time: e.time };
});
res = res.map((l, _) => l.slice.map((e, i) => { return { time: l.time, name: e[0], count: e[1], idx: i }; }));
res = _(res).flatten();
return res.groupBy('name').value();
}
d3.csv(`/csvdata/punchcard.csv`, e => {
return { ...e, starttime: moment(e.starttime) }
}).then(data => {
const prepped = prepareData(data, d3.timeDay.every(1));
let chart = rankingChart()
.data(prepped);
d3.select('svg#rankings').call(chart);
});
})();

View file

@ -0,0 +1,116 @@
(function () {
function bubbleMap() {
// Empty map variable, will init once
var map;
function init(mapId) {
if (map == null) {
map = new L.Map(mapId, { center: [51.023115, 3.710299], zoom: 12 })
.addLayer(new L.TileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png'));
map._initPathRoot();
d3.select(`#${mapId}`)
.select('svg')
.append('g')
.attr("class", "leaflet-zoom-hide")
}
}
function my(sel) {
init(sel.attr('id'));
const g = sel.select('g');
const dt = g.datum();
var div = d3.select(".tooltip").style('opacity', 0);
function vrUpdate() {
let g = d3.select('g');
const selection = g.selectAll('.location');
const data = selection.data();
const lines = g.selectAll('line');
const latlngs = data.map(e => map.latLngToLayerPoint(new L.LatLng(e.lat, e.lon)));
selection
.attr('cx', (e, i) => latlngs[i].x)
.attr('cy', (e, i) => latlngs[i].y)
;
}
const t = d3.transition()
.ease(d3.easeLinear)
.duration(100);
const sizes = _.countBy(dt, 'location_id');
const data = _.uniqBy(dt, 'location_id')
let radius = d3.scaleSqrt()
.range([0, 50])
.domain([0, 177])
;
// JOIN DATA
const selection = g.selectAll('.location').data(data, d => d.location_id);
const lines = g.selectAll('line').data(data, d => d.location_id);
// EXIT
selection.exit()
.transition(t)
.attr('r', 0)
.remove();
// ENTER
selection.enter()
.append('circle')
.style("stroke", "white")
.style("opacity", .4)
.style("fill", "blue")
.attr("r", 0)
.attr('class', 'location')
.each(d => {
const coord = map.latLngToLayerPoint(new L.LatLng(d.lat, d.lon));
g.append('circle')
.attr('r', radius(sizes[d.location_id]))
.attr('fill-opacity', 0)
.style('stroke', 'black')
.attr('transform', e => `translate(${coord.x}, ${coord.y})`)
.attr('opacity', 1)
.transition()
.duration(1000)
.ease(d3.easeLinear)
.attr('r', 75)
.attr('opacity', 0)
.remove();
})
.on("mouseout", _ => {
div.style("opacity", 0);
})
.merge(selection)
// We do the mouseover after the merge so the values update when changing time
.on("mouseover", function (d) {
div.text(`${d.name} (${sizes[d.location_id]})`);
let rect = d3.select(this).node().getBoundingClientRect();
let t_rect = div.node().getBoundingClientRect();
div
.style("opacity", .9)
.style("left", (rect.left + rect.width/2 - t_rect.width/2) + "px")
.style("top", (rect.top - t_rect.height - 5) + "px")
;
})
.transition(t)
.attr("r", d => radius(sizes[d.location_id]))
;
vrUpdate();
map.on("viewreset", vrUpdate);
}
return my;
}
window['bubbleMap'] = bubbleMap;
})();

View file

@ -0,0 +1,172 @@
(function() {
const EMOJI_TYPES = {
chinese: '🥡',
pasta: '🍝',
fries: '🍟',
pizza: '🍕',
pitta: '🥙',
burgers: '🍔',
sandwich: '🥪'
}
function instanceChart() {
var margin = { top: 40, right: 60, bottom: 20, left: 20 };
var data;
var updateData;
function chart(svg) {
let width = svg.attr('width');
let height = svg.attr('height');
width -= margin.left + margin.right;
height -= margin.top + margin.bottom;
const g = svg.append('g')
.attr("transform", `translate(${margin.left}, ${margin.top})`);
updateData = function () {
times = _(data).toPairs().map(1).flatten().map('starttime').value();
const leftPad = 170;
const x = d3.scaleTime()
.domain(d3.extent(times))
.range([0, width - leftPad])
;
console.log(x.domain());
const y = d3.scaleBand()
.domain(d3.keys(data))
.range([0, height])
;
const yLegend = d3.scaleBand()
.domain(d3.keys(EMOJI_TYPES))
.range([0, 170])
.paddingInner(0.4)
;
// const c = d3.scaleOrdinal(d3.schemeCategory10);
const c = d3.scaleOrdinal(d3.schemeCategory10).domain(d3.keys(EMOJI_TYPES));
let axis = d3.axisTop(x);
const selection = g.selectAll('g.instance').data(d3.entries(data));
let instance = selection.enter().append('g')
.classed('instance', true)
.attr('transform', d => `translate(0, ${y(d.key)})`)
;
instance.append('text')
.attr('y', y.bandwidth() / 2)
// .style('fill', d => `${c(d.value[0].type)}`)
.text(d => `${EMOJI_TYPES[d.value[0].type]} ${d.key} (${d.value.length})`)
.style('font-size', '12pt')
;
const iHeightMod = 0.8;
// GRAY BACKGROUND
instance.append('rect')
.attr('x', leftPad)
.attr('width', width - leftPad)
.attr('height', y.bandwidth() * iHeightMod)
.attr('fill-opacity', 0.03)
;
instance.append('g')
.classed('innerInstance', true)
.selectAll('rect.tick').data(d => d.value).enter().append('rect')
.classed('tick', true)
.attr('x', d => leftPad + x(d.starttime))
.attr('width', 2)
.attr('height', y.bandwidth() * iHeightMod)
.attr('fill', d => c(d.type))
.attr('fill-opacity', 0.8)
;
g.append('g')
.attr('transform', `translate(${leftPad}, -5)`)
.call(axis)
;
const text = d3.select('body').append('div')
.style('position', 'fixed')
.style('opacity', 0)
.style('background-color', 'white')
.style('border-radius', '20px')
.style('padding', '5px')
;
const line = g.append('rect')
.attr('y', 0)
.attr('height', height - (y.bandwidth() * (1 - iHeightMod)))
.attr('width', 1)
.attr('opacity', 0)
;
const legendEntry = g.selectAll('g.legendEntry').data(d3.keys(EMOJI_TYPES)).enter().append('g')
.classed('legendEntry', true)
.attr('transform', d => `translate(${20 + leftPad + x.range()[1]}, ${yLegend(d)})`)
;
legendEntry
.append('rect')
.attr('width', yLegend.bandwidth())
.attr('height', yLegend.bandwidth())
.attr('fill', c)
.attr('fill-opacity', 0.8)
;
legendEntry
.append('text')
.attr('x', yLegend.bandwidth() + 5)
.attr('y', 17)
.text(d => EMOJI_TYPES[d])
;
g.append('rect')
.attr('width', x.range()[1])
.attr('height', y.range()[1])
.attr('fill-opacity', 0)
.attr('x', leftPad)
.on('mouseover', () => {
text.style('opacity', 1);
line.attr('opacity', 1);
})
.on('mousemove', function () {
let mouse = d3.mouse(this);
let date = x.invert(mouse[0] - leftPad);
text
.style('left', `${d3.event.x + 15}px`)
.style('top', `${d3.event.y - 20}px`)
;
let fmt = d3.timeFormat('%d/%m/%y');
text.text(fmt(date));
line.attr('x', mouse[0])
})
.on('mouseout', () => {
text.style('opacity', 0);
line.attr('opacity', 0);
})
;
}
updateData();
}
chart.data = function (value) {
if (!arguments.length) return data;
data = value;
if (typeof updateData === 'function') updateData();
return chart;
}
return chart;
}
window['instanceChart'] = instanceChart;
})();

View file

@ -0,0 +1,119 @@
(function () {
function punchCard() {
var margin = { top: 20, right: 20, bottom: 30, left: 150 };
var data;
var updateData;
const tooltip = d3.select('body').append('div')
.classed('tooltip', true)
.attr('id', 'pCardTooltip')
.style("opacity", 0);
;
function chart(svg) {
let width = svg.attr('width');
let height = svg.attr('height');
width -= margin.left + margin.right;
height -= margin.top + margin.bottom;
const g = svg.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const gAxis = g.append('g')
.classed('axis', true);
updateData = function () {
const maxValue = _(data).values().map(e => _(e).values().value()).map(e => _(e).max()).max();
const x = d3.scaleLinear()
.domain([0, 23])
.range([0, width])
;
const y = d3.scaleLinear()
.domain([0, d3.keys(data).length])
.range([0, height])
;
const r = d3.scaleSqrt()
.domain([1, maxValue])
.range([3, 11])
;
let rows = g.selectAll('g.row').data(d3.entries(data), d => d.key);
let erows = rows.enter().append('g')
.classed('row', true)
.attr('opacity', 1)
erows
.append('text')
.attr('x', -10)
.attr('y', 3)
.attr('text-anchor', 'end')
.text(d => d.key);
rows.exit().remove();
rows = erows.merge(rows);
rows.transition().duration(25).attr('transform', (d, i) => `translate(0, ${y(i)})`);
const circles = rows.selectAll('circle.punch').data(d => d3.entries(d.value), d => d.key);
circles.enter().append('circle')
.classed('punch', true)
.attr('cx', d => x(+d.key))
.attr('fill', 'orange')
.attr('r', 0)
.on("mouseover", function (d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html(d.value);
// We calculate the bounding rects after setting the html
let rect = d3.select(this).node().getBoundingClientRect();
let t_rect = tooltip.node().getBoundingClientRect();
tooltip
.style("left", (rect.left + rect.width/2 - t_rect.width/2) + "px")
.style("top", (rect.top - t_rect.height - 5) + "px");
})
.on("mouseout", _ => {
tooltip.transition()
.duration(500)
.style("opacity", 0);
})
.merge(circles)
.transition()
.duration(25)
.attr('r', d => r(d.value))
;
circles.exit().transition()
.attr('r', 0)
.remove();
rows.selectAll('circle.punch').attr('r', d => r(d.value));
const axis = d3.axisBottom(x).ticks(24);
gAxis
.attr('transform', `translate(0, ${y.range()[1]})`)
.call(axis);
}
updateData();
}
chart.data = function (value) {
if (!arguments.length) return data;
data = value;
if (typeof updateData === 'function') updateData();
return chart;
}
return chart;
}
window['punchCard'] = punchCard;
})();

View file

@ -0,0 +1,116 @@
(function() {
function rankingChart() {
var margin = { top: 50, right: 120, bottom: 20, left: 120 };
var data;
var updateData;
function chart(svg) {
let width = $(svg.node()).width();
let height = svg.attr('height');
width -= margin.left + margin.right;
height -= margin.top + margin.bottom;
const g = svg.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
updateData = function () {
let allDates = _(d3.entries(data).map(e => e.value)).flatten().value().map(e => e.time);
let allIdx = _(d3.entries(data).map(e => e.value)).flatten().value().map(e => e.idx);
const x = d3.scaleTime()
.domain(d3.extent(allDates))
.range([0, width])
.nice()
;
let axis = d3.axisTop(x);
g.append('g')
.attr('transform', `translate(0, -20)`)
.call(axis);
const y = d3.scaleLinear()
.domain([0, d3.max(allIdx)])
.range([0, height])
;
const c = d3.scaleOrdinal(d3.schemeCategory10);
const line = d3.line()
.x(d => x(d.time))
.y(d => y(d.idx))
.curve(d3.curveMonotoneX)
;
const minTimes = d3.entries(data).map(e => _(e.value).minBy('time'));
const maxTimes = d3.entries(data).map(e => _(e.value).maxBy('time'));
function mouseover(ident) {
return function inner(d, i, sel) {
const path = g.selectAll('path.rankPath').filter(e => d[ident] === e.key);
const others = g.selectAll('path.rankPath').filter(e => d[ident] !== e.key);
path.attr('stroke-width', 6);
others.attr('stroke', 'gray');
}
}
function mouseout(ident) {
return function inner(d, i, sel) {
const path = g.selectAll('path.rankPath').filter(e => d[ident] === e.key);
const others = g.selectAll('path.rankPath');
path.attr('stroke-width', 3);
others.attr('stroke', (_, i) => c(i));
}
}
g.selectAll('path.rankPath').data(d3.entries(data)).enter().append('path')
.classed('rankPath', true)
.attr('fill-opacity', 0)
.attr('stroke', (_, i) => c(i))
.attr('stroke-width', 3)
.attr('d', d => {
const lastVal = d.value[d.value.length - 1];
const nVal = {...lastVal, time: x.domain()[1]}
return line(d.value.concat([nVal]));
})
.on('mouseover', mouseover('key'))
.on('mouseout', mouseout('key'))
;
g.selectAll('text.begin').data(minTimes).enter().append('text')
.classed('begin', true)
.attr('x', d => x(d.time) - 5)
.attr('y', d => y(d.idx) + 4)
.attr('text-anchor', 'end')
.text(d => d.name)
.on('mouseover', mouseover('name'))
.on('mouseout', mouseout('name'))
;
g.selectAll('text.end').data(maxTimes).enter().append('text')
.classed('end', true)
.attr('x', d => x.range()[1] + 5)
.attr('y', d => y(d.idx) + 4)
.attr('text-anchor', 'begin')
.text(d => d.name)
.on('mouseover', mouseover('name'))
.on('mouseout', mouseout('name'))
;
}
updateData();
}
chart.data = function (value) {
if (!arguments.length) return data;
data = value;
if (typeof updateData === 'function') updateData();
return chart;
}
return chart;
}
window['rankingChart'] = rankingChart;
})();

View file

@ -0,0 +1,334 @@
(function () {
const width = 1000;
const height = 800;
const middle = height / 2;
const barPadding = 1;
const padding = { top: 50, left: 50, right: 40, bottom: 50 };
const formatTime = d3.timeFormat('%b %e %Y');
let prevUpper, prevLower;
let xScale, yScale1, yScale2, xAxis, yAxis1, yAxis2;
let prevUpperButton, prevLowerButton;
var chart, chart2, slider, selection;
var userdata, pricedata, eventdata, tapordersdata, tapusersdata;
d3.csv('/csvdata/haldis-price-time.csv', d => {
return {
date: d3.timeParse('%Y-%m-%d')(d.starttime).setHours(0, 0, 0, 0),
value: parseInt(d.total_price) / 100
};
}).then(function (data) {
pricedata = data;
return d3.csv('/csvdata/haldis-num-users-time.csv', d => {
return {
date: d3.timeParse("%Y-%m-%d")(d.starttime).setHours(0, 0, 0, 0),
value: parseInt(d.num_users)
};
});
}).then(function (data) {
userdata = data;
return d3.csv('/csvdata/eventdata.csv', d => {
return {
date: d3.utcParse("%Y-%m-%dT%H:%M:%S%Z")(d.date).setHours(0, 0, 0, 0),
title: d.title
};
});
}).then(function (data) {
eventdata = data;
return d3.csv('/csvdata/tap-orders-day.csv', d => {
return {
date: d3.timeParse('%Y-%m-%d')(d.created_at).setHours(0, 0, 0, 0),
value: parseInt(d.count)
};
});
}).then(function (data) {
tapordersdata = data;
return d3.csv('/csvdata/tap-orders-users-day.csv', d => {
return {
date: d3.timeParse('%Y-%m-%d')(d.created_at).setHours(0, 0, 0, 0),
value: parseInt(d.count)
};
});
}).then(function (data) {
tapusersdata = data;
xScale = d3.scaleTime().range([padding.left, width - padding.right]);
yScale1 = d3.scaleLinear().range([middle, padding.top]);
yScale2 = d3.scaleLinear().range([padding.bottom, middle]);
xAxis = d3.axisBottom().scale(xScale).ticks().tickFormat('').tickSize(0);
yAxis1 = d3.axisLeft().scale(yScale1).ticks();
yAxis2 = d3.axisLeft().scale(yScale2).ticks();
chart = timeBarChart();
chart.upper = true;
chart.eventdata = eventdata;
chart2 = timeBarChart();
chart2.upper = false;
chart2.eventdata = eventdata;
selection = d3.select('#barchart').append('g');
selection.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0, ${middle})`);
selection.append('g')
.attr('class', 'y axis')
.attr('transform', `translate(${padding.left}, 0)`);
selection.append('g')
.attr('class', 'y axis2')
.attr('transform', `translate(${padding.left}, ${middle - padding.top})`);
slider = timeSlider();
prevUpper = userdata;
prevLower = tapordersdata;
updateData(userdata, true);
updateData(tapordersdata, false);
prevUpperButton = d3.select("#user-button");
prevLowerButton = d3.select("#tap-order-button");
setActiveButton('#haldis-user-button', true);
setActiveButton('#tap-order-button', false);
slider.on('slide', domain => {
chart.domain.start = domain[0];
chart.domain.end = domain[1];
chart2.domain.start = domain[0];
chart2.domain.end = domain[1];
const d1 = filterData(prevUpper, chart.domain.start, chart.domain.end);
const d2 = filterData(prevLower, chart2.domain.start, chart2.domain.end);
selection.datum(d1).call(chart);
selection.datum(d2).call(chart2);
});
d3.select('#slider').call(slider);
});
function setActiveButton(name, upper) {
curButton = d3.select(name);
if (upper) {
prevUpperButton.classed("is-focused", false);
prevUpperButton = curButton;
} else {
prevLowerButton.classed("is-focused", false);
prevLowerButton = curButton;
}
curButton.classed("is-focused", true);
}
function filterData(data, beginTime, endTime) {
return _(data).filter(e => beginTime <= e.date && e.date <= endTime).value();
}
function timeBarChart() {
function my(svg) {
let eventdata = my.eventdata;
var dt = svg.datum();
const t = d3.transition()
.ease(d3.easeLinear)
.duration(100);
xScale.domain([my.domain.start, my.domain.end]);
svg.select('.x.axis')
.transition(t)
.call(xAxis);
if (my.upper) {
yScale1.domain(d3.extent(dt, d => d.value));
svg.select('.y.axis')
.transition(t)
.call(yAxis1);
} else {
yScale2.domain(d3.extent(dt, d => d.value));
svg.select('.y.axis2')
.transition(t)
.call(yAxis2);
}
function update() {
let g = d3.select('svg#barchart > g');
var selection, sellines, eventlines;
if (my.upper) {
selection = g.selectAll('.datacircle');
sellines = g.selectAll('.line');
eventlines = g.selectAll('.eventline');
} else {
selection = g.selectAll('.datacircle2');
sellines = g.selectAll('.line2');
eventlines = g.selectAll('.eventline2');
}
sellines
.attr('x1', d => xScale(d.date))
.attr('y1', () => my.upper ? middle : padding.top)
.attr('x2', d => xScale(d.date))
.attr('y2', d => my.upper ? yScale1(d.value) : yScale2(d.value));
eventlines
.attr('x1', d => xScale(d.date))
.attr('y1', () => my.upper ? middle : padding.top)
.attr('x2', d => xScale(d.date))
.attr('y2', (d) => {
let yValue = 0;
selection.data().forEach(function (el) {
if (el.date === d.date) {
yValue = el.value;
}
})
return my.upper ? yScale1(yValue) : yScale2(yValue);
});
selection
.attr('cx', d => xScale(d.date))
.attr('cy', d => my.upper ? yScale1(d.value) : yScale2(d.value));
}
const fed = filterData(eventdata, my.domain.start, my.domain.end);
var selection, sellines, eventlines;
if (my.upper) {
selection = svg.selectAll('.datacircle').data(dt, d => d.date);
sellines = svg.selectAll('.line').data(dt, d => d.date);
eventlines = svg.selectAll('.eventline').data(fed, d => d.date);
} else {
selection = svg.selectAll('.datacircle2').data(dt, d => d.date);
sellines = svg.selectAll('.line2').data(dt, d => d.date);
eventlines = svg.selectAll('.eventline2').data(fed, d => d.date);
}
const fmtStr = 'DD/MM/YY';
sellines.exit().remove();
sellines.enter()
.append('line')
.attr('stroke', '#ddd')
.attr('stroke-width', 2)
.attr('class', () => my.upper ? 'line' : 'line2')
.attr('transform', () => my.upper ? `translate(0, 0)` : `translate(0, ${middle - padding.bottom})`)
.merge(sellines);
eventlines.exit().remove();
eventlines.enter()
.append('line')
.attr('stroke', '#f4a442')
.attr('stroke-width', 2)
.attr('class', () => my.upper ? 'eventline' : 'eventline2')
.attr('transform', () => my.upper ? `translate(0, 0)` : `translate(0, ${middle - padding.bottom})`)
.on("mouseover", function (d) {
const tooltip = d3.select('.tooltip');
tooltip
.style("opacity", .9)
.html(moment(d.date).format(fmtStr) + ' - ' + d.title);
// We calculate the bounding rects after setting the html
let rect = d3.select(this).node().getBoundingClientRect();
let t_rect = tooltip.node().getBoundingClientRect();
tooltip
.style("left", (rect.left + rect.width / 2 - t_rect.width / 2) + "px")
.style("top", (rect.top - t_rect.height - 5) + "px");
})
.on("mouseout", _ => {
const tooltip = d3.select('.tooltip');
tooltip.style("opacity", 0);
})
.merge(eventlines);
selection.exit().remove();
selection.enter()
.append('circle')
.attr('fill', 'lightblue')
.attr('class', () => my.upper ? 'datacircle' : 'datacircle2')
.attr('transform', () => my.upper ? `translate(0, 0)` : `translate(0, ${middle - padding.bottom})`)
.on("mouseover", function (d) {
const tooltip = d3.select('.tooltip');
tooltip
.style("opacity", .9)
.html(moment(d.date).format(fmtStr) + ' - ' + d.value);
// We calculate the bounding rects after setting the html
let rect = d3.select(this).node().getBoundingClientRect();
let t_rect = tooltip.node().getBoundingClientRect();
tooltip
.style("left", (rect.left + rect.width / 2 - t_rect.width / 2) + "px")
.style("top", (rect.top - t_rect.height - 5) + "px");
})
.on("mouseout", _ => {
const tooltip = d3.select('.tooltip');
tooltip.style("opacity", 0);
})
.merge(selection)
.attr('r', 3)
;
update();
}
return my;
}
function updateData(data, upper) {
domain = d3.extent(data, d => d.date);
chart.domain = {
'start': domain[0],
'end': domain[1]
};
chart2.domain = {
'start': domain[0],
'end': domain[1]
};
const times = _(data).map(e => moment(e.date));
if (upper) {
prevUpper = data;
const fd = filterData(prevLower, chart.domain.start, chart.domain.end);
selection.datum(data).call(chart);
selection.datum(fd).call(chart2);
slider.domain([times.min(), times.max()]).data(times.value(), true);
} else {
prevLower = data;
const fd = filterData(prevUpper, chart.domain.start, chart.domain.end);
selection.datum(data).call(chart2);
selection.datum(fd).call(chart);
slider.domain([times.min(), times.max()]).data(times.value(), true);
}
}
d3.select('#haldis-user-button').on('click', () => {
updateData(userdata, true);
setActiveButton('#haldis-user-button', true);
});
d3.select('#haldis-price-button').on('click', () => {
updateData(pricedata, true);
setActiveButton('#haldis-price-button', true);
});
d3.select('#tap-order-button').on('click', () => {
updateData(tapordersdata, false);
setActiveButton('#tap-order-button', false);
});
d3.select('#tap-user-button').on('click', () => {
updateData(tapusersdata, false);
setActiveButton('#tap-user-button', false);
});
})();

View file

@ -0,0 +1,244 @@
var margin = {top: 20, right: 10, bottom: 30, left: 10};
var width = 700 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
const mat = [];
const interpol = d3.interpolateViridis;
const colorScaleRel = d3.scaleSequential(interpol).domain([0, 100]);
const colorScaleAbs = d3.scaleSequential(interpol).domain([0, 306]); //oeps harcoded
const svg = d3.select('#gridlo')
.append('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const products = [];
const locations = [];
d3.csv("/csvdata/elodata.csv", d => {
d.product_id = +d.product_id;
d.location_id = +d.location_id;
if (!mat[d.product_id]) {
products[d.product_id] = d.name_x;
mat[d.product_id] = Array(...Array(110)).map(Number.prototype.valueOf, 0);
}
// at this point tha array is made d.location_id
if (!mat[d.product_id][d.location_id]) {
locations[d.location_id] = d.name_y;
mat[d.product_id][d.location_id] = 1;
} else {
mat[d.product_id][d.location_id] += 1;
}
return d;
}).then((data) => {
const mat2 = [];
let prod2 = [];
mat.forEach((a, i) => {
prod2.push(products[i]);
mat2.push(a);
});
let mat3 = [];
let loc2 = [];
for (var i = 0; i < prod2.length; i++) {
mat3[i] = [];
}
var i = 0;
let mat_scaled = [];
locations.forEach((l, k) => {
loc2.push(l);
for (let j = 0; j < prod2.length; j++) {
mat3[j][i] = mat2[j][k];
}
i++;
});
//rectangles
let comb = _.sortBy(_.zip(prod2, mat3), e => -_.sum(e[1]));
prod2 = _.unzip(comb)[0];
mat3 = _.unzip(comb)[1];
comb = _.sortBy(_.zip(loc2, _.unzip(mat3)), e => -_.sum(e[1]));
loc2 = _.unzip(comb)[0];
mat3 = _.unzip(_.unzip(comb)[1]);
max = 0;
sums = []
for (var i = 0; i < mat3[0].length; i++) {
sums[i] = 0;
}
mat3.forEach(d => {
d.forEach((e, i) => {
sums[i] += e;
});
});
mat_scaled = mat3.map((r, i) => r.map((e, j) => 100 * e / sums[j]));
relative = false; // 0 is false -> scaled
data = [mat_scaled, mat3];
scales = [colorScaleRel, colorScaleAbs];
const legends = [[0, 20, 40, 60, 80, 100], [0, 60, 120, 180, 240, 300]];
let d = data[+relative];
const top = svg.append("g").attr("id", "top");
const boxScale = d3.scaleBand()
.domain(d3.range(Math.max(d.length, d[0].length)))
.range([0, Math.min(height, width)])
.round(true)
;
d3.select("#switch").on("click", updateData);
function updateData() {
relative = !relative;
d = data[+relative];
scale = scales[+relative]
// ENTER -- Rows
top.selectAll('g').data(d, (_, i) => i).enter().append('g')
.attr('opacity', 0.95)
.attr("transform", (_, i) => `translate(0, ${(boxScale(i))})`)
.attr('data-row-idx', (_, i) => i)
// ENTER -- Boxes
.selectAll('rect').data(d => d, (_, i) => i).enter().append("rect")
.attr('opacity', 0.95)
.attr("class", (_, i) => `id${i}`)
.attr('width', boxScale.bandwidth() * 1.01)
.attr('height', boxScale.bandwidth() * 1.01)
.attr("x", (_, i) => boxScale(i) + 150)
.on("mouseover", mouse_over_rect)
.on("mouseout", mouse_out_rect);
const boxes = top.selectAll('g').data(d, (_, i) => i).selectAll('rect').data(d => d, (_, i) => i);
boxes
.transition()
.attr('fill', d => scale(d));
svg.selectAll(".legend text")
.transition().duration(500)
.text((_, i) => {
const d = legends[+relative][i];
return relative ? d : d + '%';
});
svg.selectAll(".legend rect")
.transition().duration(500)
.style("fill", (d, i) => scale(legends[+relative][i]));
};
updateData();
function mouse_over_rect(d, i, j) { // Add interactivity
const row = d3.select(this.parentNode);
const block = d3.select(this);
const tooltip = d3.select('.tooltip');
//row
row.attr("opacity", 1);
d3.selectAll(`.id${i}`).attr("opacity", 1);
tooltip
.style("opacity", .9)
.html(relative ? d : `${d.toFixed(2)}%`);
// We calculate the bounding rects after setting the html
let rect = block.node().getBoundingClientRect();
let t_rect = tooltip.node().getBoundingClientRect();
tooltip
.style("left", (rect.left + rect.width / 2 - t_rect.width / 2) + "px")
.style("top", (rect.top - t_rect.height - 5) + "px");
//Labels
d3.select(`#rest${i}`)
.attr("fill", scale(d))
.attr("font-weight", "bold")
;
d3.select(`#prod${row.attr('data-row-idx')}`)
.attr("fill", scale(d))
.attr("font-weight", "bold")
;
}
function mouse_out_rect(d, i, j) {
const row = d3.select(this.parentNode);
const block = d3.select(this);
const tooltip = d3.select('.tooltip');
//rm border and text
row.attr("stroke", "none");
row.attr("opacity", 0.95);
d3.selectAll(`.id${i}`).attr("opacity", 0.95);
tooltip.style('opacity', 0);
d3.select(`#rest${i}`)
.attr("fill", "black")
.attr("font-weight", "")
;
d3.select(`#prod${row.attr('data-row-idx')}`)
.attr("fill", "black")
.attr("font-weight", "")
;
}
// product labels
let prodLabels = svg.append("g")
.selectAll("g")
.data(prod2)
.enter()
.append("text")
.text(d => d)
.attr("x", 30)
.attr("y", (_, i) => boxScale(i) + 15)
.attr("id", (_, i) => `prod${i}`)
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "black");
// location labels
let locLabels = svg.append("g")
.selectAll("g")
.data(loc2)
.enter()
.append("text")
.text(d => d)
.attr("text-anchor", "middle")
.attr("transform", (_, i) => `translate(${(boxScale(i) + 150)},${boxScale(prodLabels.size() - 1) + 70}) rotate(-65)`)
.attr("font-family", "sans-serif")
.attr("id", (_, i) => `rest${i}`)
.attr("font-size", "11px")
.attr("fill", "black");
//Legend
let legend = svg.append('g')
.classed('legendWrapper', 'true')
.attr("transform", `translate(${boxScale(locLabels.size() - 1) + boxScale.bandwidth() + 160}, 0)`);
;
let legendAbs = legend.selectAll(".legend")
.data(legends[+relative])
.enter().append("g")
.attr("class", "legend")
.attr("transform", (d, i) => `translate(0 ,${boxScale(i) + 20})`);
legendAbs.append("rect")
.attr("width", 20)
.attr("height", 20)
.style("fill", d => colorScaleAbs(d));
legendAbs.append("text")
.attr("x", 26)
.attr("y", 10)
.attr("dy", ".35em")
.text(d => relative ? d : `${d.toFixed(2)}%`);
legend.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", 10)
.attr("dy", ".35em")
.text("Count");
});

View file

@ -0,0 +1,189 @@
(function() {
function timeSlider() {
var data;
var sliderValue;
var updateSlider;
var updateData;
let width = 50;
let midPoint = width / 2;
let domain = [moment().subtract(1, 'year').toDate(), moment().toDate()]
const dispatch = d3.dispatch('slide');
var margin = { top: 2, right: 40, bottom: 20, left: 40 };
function my(svg) {
let xScale;
let tWidth = $(svg.node()).width();
let tHeight = $(svg.node()).height();
tWidth -= margin.left + margin.right;
tHeight -= margin.top + margin.bottom;
const g = svg.append('g')
.attr("transform", `translate(${margin.left}, ${margin.top})`);
const gAxis = g.append('g');
// Create the svg:defs element and the main gradient definition.
var svgDefs = g.append('defs');
var mainGradient = svgDefs.append('linearGradient')
.attr('id', 'mainGradient');
// Create the stops of the main gradient. Each stop will be assigned
// a class to style the stop using CSS.
mainGradient.append('stop')
.attr('stop-opacity', '0')
.attr('offset', '0%');
mainGradient.append('stop')
.attr('stop-color', 'blue')
.attr('stop-opacity', '1')
.attr('offset', '45%');
mainGradient.append('stop')
.attr('stop-color', 'blue')
.attr('stop-opacity', '1')
.attr('offset', '55%');
mainGradient.append('stop')
.attr('stop-opacity', '0')
.attr('offset', '100%');
updateData = function (data, updateDomain) {
if (updateDomain) {
domain = d3.extent(data);
}
xScale = d3.scaleTime()
.domain(domain)
.range([0, tWidth])
.nice()
;
const xAxis = d3.axisBottom(xScale)
.tickFormat(d3.timeFormat("%b '%y"))
;
gAxis
.attr('transform', 'translate(0,' + 50 + ')')
.classed('x axis', true)
.call(xAxis)
.selectAll("text")
;
const sliderHeatmap = g.selectAll('rect.heatTick').data(data, d => d);
sliderHeatmap.exit().transition().attr('height', 0).remove();
sliderHeatmap.enter().append('rect')
.attr('x', e => xScale(e))
.attr('class', 'heatTick')
.attr('fill', 'blue')
.attr('width', 3)
.attr('height', 0)
.attr('fill-opacity', 0.2)
.transition()
.attr('height', 50)
;
}
updateData(data);
const outer = g.append('rect')
.attr('stroke', 'black')
.attr('fill-opacity', 0)
.attr('stroke-width', 1)
.attr('width', tWidth)
.attr('height', 50);
const t1 = g.append('text')
.attr('font-size', '.6em')
.attr('y', 50);
const t2 = g.append('text')
.attr('font-size', '.6em')
.attr('y', 50);
const inner = g.append('rect')
.attr('stroke', 'black')
.attr('fill-opacity', 0)
.attr('stroke-width', 2)
.attr('width', 50)
.attr('height', width)
.call(d3.drag()
.on("drag", function (d) {
const dx = d3.event.dx;
const dy = d3.event.dy;
let nx = midPoint + dx - width / 2;
width -= 1.5 * dy;
width = Math.max(10, width);
nx += 1.5 * dy / 2;
nx = Math.min(tWidth - width, nx);
nx = Math.max(0, nx);
midPoint = nx + width / 2;
width = Math.min(width, tWidth);
const beginTime = xScale.invert(nx);
const endTime = xScale.invert(nx + width);
sliderValue = [beginTime, endTime];
updateSlider(sliderValue);
dispatch.call('slide', this, sliderValue);
}));
updateSlider = function (value) {
sliderValue = value
nx = xScale(sliderValue[0]);
width = xScale(sliderValue[1]) - xScale(sliderValue[0]);
midPoint = nx + width / 2;
inner.attr('x', nx)
.attr('width', width);
const fmtStr = 'DD/MM/YY'
t1.text(moment(sliderValue[0]).format(fmtStr))
.attr('x', nx)
.attr('transform', `rotate(45 ${nx},50) translate(20,20)`);
t2.text(moment(sliderValue[1]).format(fmtStr))
.attr('x', nx + width)
.attr('transform', `rotate(45 ${nx + width},50) translate(20,20)`);
}
updateSlider(xScale.domain());
}
my.on = function () {
let value = dispatch.on.apply(dispatch, arguments);
return value === dispatch ? my : value;
}
my.domain = function (value) {
if (!arguments.length) return domain;
domain = value;
if (typeof updateData === 'function') updateData(data);
return my;
}
my.slider = function (value) {
if (!arguments.length) return sliderValue;
if (typeof updateSlider === 'function') updateSlider(value);
return my;
}
my.data = function (dt) {
if (!arguments.length) return intensity;
data = dt
if (typeof updateData === 'function') updateData(data);
return my;
}
return my;
}
window['timeSlider'] = timeSlider;
})();

View file

@ -1,20 +1,36 @@
$ ->
$.getJSON 'https://zeus.ugent.be/game/top4/show.json', (data) ->
request = new XMLHttpRequest
request.open 'GET', 'https://zeus.ugent.be/game/top4/show.json', true
request.onload = ->
if request.status >= 200 and request.status < 400
# Success!
data = JSON.parse(request.responseText)
str = "<table>"
for x in data
str += """
str += """
<tr>
<td class="picture">
<td class="picture">
<img class="coder-picture" src="#{x.avatar_url}">
</td>
<td class="name">
</td>
<td class="name">
<a class="coder-name" href="#{x.github_url}">#{x.github_name}</a>
</td>
<td class="score">
</td>
<td class="score">
#{x.score}
</td>
</td>
</tr>
"""
"""
str += "</table>"
$('#gamification-coders').html(str)
el = document.getElementById('gamification-coders')
el.innerHTML = str
else
# We reached our target server, but it returned an error
return
request.onerror = ->
# There was a connection error of some sort
return
request.send()

View file

@ -0,0 +1,10 @@
$ '.send'
.click ->
$context = $ this
$.ajax
url: "https://kelder.zeus.ugent.be/messages/",
contentType: "text/plain",
type: "POST"
data: $('.chatbox').val()
success: -> $('#chat-response').text('Success! :)')
error: -> $('#chat-response').text('Error !1!')

View file

@ -1,9 +1,16 @@
$('#tipue_search_input_field').on 'focusin', ->
$('#tipue_search_input').addClass("focused")
input_field = document.getElementById('tipue_search_input_field')
input = document.getElementById('tipue_search_input')
$('#tipue_search_input_field').on 'focusout', ->
$('#tipue_search_input').removeClass("focused")
input_field.addEventListener 'focusin', ->
input.classList.add('focused')
$('.nav-toggle').on 'click', ->
$('.nav-menu').toggleClass('is-active')
$('.nav-toggle').toggleClass('is-active')
input_field.addEventListener 'focusout', ->
input.classList.remove('focused')
burger = document.getElementsByClassName('navbar-burger')[0]
menu = document.getElementsByClassName('navbar-menu')[0]
burger.addEventListener 'click', ->
s = 'is-active'
if menu.classList.contains(s) then menu.classList.remove(s) else menu.classList.add(s)
if burger.classList.contains(s) then burger.classList.remove(s) else burger.classList.add(s)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,84 @@
/*
Tipue Search 7.0
Copyright (c) 2018 Tipue
Tipue Search is released under the MIT License
http://www.tipue.com/search
*/
/*
Stop words
Stop words list from http://www.ranks.nl/stopwords
*/
var tipuesearch_stop_words = ["a", "above", "after", "again", "against", "all", "am", "an", "and", "any", "are", "aren't", "as", "at", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can't", "cannot", "could", "couldn't", "did", "didn't", "do", "does", "doesn't", "doing", "don't", "down", "during", "each", "few", "for", "from", "further", "had", "hadn't", "has", "hasn't", "have", "haven't", "having", "he", "he'd", "he'll", "he's", "her", "here", "here's", "hers", "herself", "him", "himself", "his", "how", "how's", "i", "i'd", "i'll", "i'm", "i've", "if", "in", "into", "is", "isn't", "it", "it's", "its", "itself", "let's", "me", "more", "most", "mustn't", "my", "myself", "no", "nor", "not", "of", "off", "on", "once", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", "same", "shan't", "she", "she'd", "she'll", "she's", "should", "shouldn't", "so", "some", "such", "than", "that", "that's", "the", "their", "theirs", "them", "themselves", "then", "there", "there's", "these", "they", "they'd", "they'll", "they're", "they've", "this", "those", "through", "to", "too", "under", "until", "up", "very", "was", "wasn't", "we", "we'd", "we'll", "we're", "we've", "were", "weren't", "what", "what's", "when", "when's", "where", "where's", "which", "while", "who", "who's", "whom", "why", "why's", "with", "won't", "would", "wouldn't", "you", "you'd", "you'll", "you're", "you've", "your", "yours", "yourself", "yourselves"];
// Word replace
var tipuesearch_replace = {'words': [
{'word': 'tip', 'replace_with': 'tipue'},
{'word': 'javscript', 'replace_with': 'javascript'},
{'word': 'jqeury', 'replace_with': 'jquery'}
]};
// Weighting
var tipuesearch_weight = {'weight': [
{'url': 'http://www.tipue.com', 'score': 60},
{'url': 'http://www.tipue.com/search', 'score': 60},
{'url': 'http://www.tipue.com/tipr', 'score': 30},
{'url': 'http://www.tipue.com/support', 'score': 20}
]};
// Illogical stemming
var tipuesearch_stem = {'words': [
{'word': 'e-mail', 'stem': 'email'},
{'word': 'javascript', 'stem': 'jquery'},
{'word': 'javascript', 'stem': 'js'}
]};
// Related
var tipuesearch_related = {'Related': [
{'search': 'tipue', 'related': 'Search', 'include': 1},
{'search': 'tipue', 'related': 'jQuery'},
{'search': 'tipue', 'related': 'Features'},
{'search': 'tipue', 'related': 'Support'},
{'search': 'tipue search', 'related': 'Help', 'include': 1},
{'search': 'tipue search', 'related': 'Support'}
]};
// Internal strings
var tipuesearch_string_1 = 'No title';
var tipuesearch_string_2 = 'Showing results for';
var tipuesearch_string_3 = 'Search instead for';
var tipuesearch_string_4 = '1 result';
var tipuesearch_string_5 = 'results';
var tipuesearch_string_6 = '<';
var tipuesearch_string_7 = '>';
var tipuesearch_string_8 = 'Nothing found.';
var tipuesearch_string_9 = 'Common words are largely ignored.';
var tipuesearch_string_10 = 'Related';
var tipuesearch_string_11 = 'Search too short. Should be one character or more.';
var tipuesearch_string_12 = 'Search too short. Should be';
var tipuesearch_string_13 = 'characters or more.';
var tipuesearch_string_14 = 'seconds';
var tipuesearch_string_15 = 'Open Image';
var tipuesearch_string_16 = 'Goto Page';
// Internals
// Timer for showTime
var startTimer = new Date().getTime();

View file

@ -0,0 +1,44 @@
div.tooltip {
position: fixed;
text-align: center;
min-width: 30px;
padding: 4px;
font: 12px sans-serif;
background: black;
color: white;
border: 0px;
border-radius: 8px;
pointer-events: none;
z-index: 10;
opacity: 0;
}
div.tooltip::after {
content: " ";
position: absolute;
top: 100%;
/* At the bottom of the tooltip */
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: black transparent transparent transparent;
}
#instance path.domain {
visibility: hidden;
}
.full-width {
margin-left: -50vw;
margin-right: -50vw;
width: 100vw;
max-width: 100vw;
position: relative;
left: 50%;
right: 50%;
}
text.begin,
text.end {
font-size: 12pt;
}

View file

@ -0,0 +1,16 @@
.viscontainer {
display: flex;
}
.button-container {
padding-top: 50px;
padding-left: 20px;
padding-right: 20px;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.button-item {
margin-bottom: 10px;
}

View file

@ -1,98 +1,153 @@
@include mobile {
table.board-table {
border-collapse: inherit;
thead {
> tr {
visibility: collapse;
}
}
tbody {
> tr {
display: grid;
border-top: 1px solid $box-colour;
grid-template-columns: auto auto;
grid-template-areas:
"func func"
"name name"
"email link";
width: 87vw;
}
> tr > td:nth-child(3) {
grid-area: email;
border: none;
}
> tr > td:nth-child(2) {
grid-area: name;
border: none;
}
> tr > td:nth-child(4) {
display: grid;
justify-items: end;
grid-area: link;
border: none;
}
> tr > td:nth-child(1) {
grid-area: func;
border: none;
}
> tr > td:nth-child(3):before {
content: "E-mail: ";
font-weight: bold;
}
> tr > td:nth-child(2):before {
content: "Name: ";
font-weight: bold;
}
> tr > td:nth-child(1):before {
content: "Function: ";
font-weight: bold;
}
> tr > td:nth-child(4):before {
grid-area: link;
}
}
}
}
#contact-icons {
display: flex;
justify-content: center;
align-items: center;
display: flex;
justify-content: center;
align-items: center;
> .column {
max-width: 70vw;
> .column {
max-width: 70vw;
}
.contact-circle-option {
display: block;
max-width: 200px;
.contact-circle-wrapper {
display: block;
position: relative;
width: 60%;
padding-bottom: 60%;
height: 0;
margin: 0 auto;
.contact-circle-pulse {
position: absolute;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
border: 1px solid $secondary;
margin: 0 auto;
}
.contact-circle {
position: absolute;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: $secondary;
display: flex;
justify-content: center;
align-items: center;
margin: 0 auto;
color: $highlighted-text-colour;
}
}
.contact-circle-option {
display: block;
max-width: 200px;
.contact-circle-wrapper {
display: block;
position: relative;
width: 60%;
padding-bottom: 60%;
height: 0;
margin: 0 auto;
.contact-circle-pulse {
position: absolute;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
border: 1px solid $secondary;
margin: 0 auto;
}
.contact-circle {
position: absolute;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: $secondary;
display: flex;
justify-content: center;
align-items: center;
margin: 0 auto;
color: $highlighted-text-colour;
}
}
.contact-circle-wrapper:hover, .contact-circle-wrapper:focus {
.grow {
transition: all .2s ease-in-out;
-moz-transform: scale(1.2);
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
.contact-description {
display: block;
text-align: center;
margin-top: 20px;
color: $primary;
}
.contact-text-link {
color: $text;
border-bottom: 1px solid $secondary;
margin-top: 7px;
//font-size: 1.5em;
}
.contact-text-link:hover {
color: $secondary;
}
.contact-circle-wrapper:hover,
.contact-circle-wrapper:focus {
.grow {
transition: all 0.2s ease-in-out;
-moz-transform: scale(1.2);
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
.contact-description {
display: block;
text-align: center;
margin-top: 20px;
color: $primary;
}
.contact-text-link {
color: $text;
border-bottom: 1px solid $secondary;
margin-top: 7px;
//font-size: 1.5em;
}
.contact-text-link:hover {
color: $secondary;
}
}
}
#contact-info {
h1 {
margin-bottom: 0.3em;
}
h1 {
margin-bottom: 0.3em;
}
.is-divider {
margin-bottom: 0.7em;
margin-top: 0.7em;
}
.is-divider {
margin-bottom: 0.7em;
margin-top: 0.7em;
}
#contact-location-buttons {
width: 100%;
text-align: center;
}
#contact-location-buttons {
width: 100%;
text-align: center;
}
.button:hover, .button:focus {
border-color: $primary;
}
.button:hover,
.button:focus {
border-color: $primary;
}
}

View file

@ -55,6 +55,13 @@ $sel: '';
.subtitle {
position: absolute;
@include mobile {
text-align: center;
margin-top: 0;
position: relative;
margin-bottom: .2em;
}
}
.details {
@ -63,6 +70,12 @@ $sel: '';
margin-top: -1.1rem;
line-height: 1;
text-align: right;
@include mobile {
text-align: center;
margin-top: 0;
position: relative;
}
}
}
@ -93,8 +106,26 @@ $sel: '';
position: absolute;
bottom: 20px;
left: 0;
background: linear-gradient(to bottom, transparent, white);
/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ffffff+100&0+0,1+100;White+to+Transparent */
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ffffff',GradientType=0 ); /* IE6-9 */
height: 100px;
width: 100%;
}
}
.content figure.full-width {
margin-left: -50vw;
margin-right: -50vw;
width: 100vw;
max-width: 100vw;
position: relative;
left: 50%;
right: 50%;
}
.footnotes {
font-size: 80%;
}

View file

@ -50,19 +50,19 @@
}
}
#cammie-section {
.nav-center{
width:100%;
}
button{
background-color: $orange;
color: white;
margin-top: 5px;
border-radius: 0;
border: none;
width: 33.333333333333333333333333333333333333333333333333333%;
&:not(:last-child){
margin-right: 5px;
width: 100%;
&:hover{
color: #363636;
}
&:active{
background-color: #b36b00; //dark orange
color: #363636;
}
}

View file

@ -42,6 +42,26 @@
}
}
.nav-menu {
background: none;
.map-wrapper {
border-radius: 5px;
overflow: hidden;
position: relative;
height: 400px;
padding: 0;
iframe {
height: 100%;
width: 100%;
}
}
.event-tile-image {
// For now, don't show the event tile image on mobile, takes too much space
@include mobile {
display: none;
}
max-width:200px;
max-height:200px;
}

View file

@ -3,10 +3,31 @@
text-align: justify;
}
pre .line-numbers {
margin-right: 10px;
margin-left: -10px;
}
.caps {
text-transform: uppercase;
font-size: 85%;
letter-spacing: 1px;
}
// Override box styling without round corners
.box {
margin-bottom:10px;
border-radius: 0 !important;
transition: all .15s ease;
box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);
}
a.box:hover {
color: $blue;
transform: translateY(-1px);
box-shadow: 0 7px 14px rgba(50,50,93,.1), 0 3px 6px rgba(0,0,0,.08);
}
// Add some hero attributes to make backgrounds prettier
@ -214,3 +235,11 @@ footer.footer {
font-size: $size-small;
}
}
.has-all-small-caps {
font-variant: all-small-caps;
}
.has-small-caps {
font-variant: small-caps;
}

View file

@ -1,85 +1,72 @@
#navbar {
align-items: flex-end;
z-index: 100;
margin-bottom: 10px;
.logo-wrapper {
padding-bottom: 0;
position: relative;
#santa {
position: absolute;
z-index: 300;
left: 5px;
top: 10px;
width: 60px;
}
}
.nav-menu {
z-index: 20;
}
.actual-nav-bar {
padding: 0;
margin: 10px;
margin-bottom: 0;
border-bottom: 1px solid #eee;
}
#inline-logo {
min-width: 38.703px;
}
#logo-link {
#logo {
padding-left: 10px;
width: 100px;
}
}
//Height of the line underneath when hovering over a menu item
$border-height: 3px;
.nav {
height: 100%;
align-items: flex-end;
z-index: auto;
margin-bottom: 10px;
z-index: 100;
.nav-item {
transition: 0.2s;
.logo-wrapper {
padding-bottom: 0;
position: relative;
font-variant: small-caps;
font-size: 1.15em;
&:not(.nav-search) {
border-bottom: $border-height solid transparent;
border-top: 3px solid transparent;
}
&:hover {
transition: 0.2s;
}
&.social-icon {
padding-left: 5px;
padding-right: 5px;
}
&:not(.nav-search):hover, &.is-active {
border-bottom-color: $zeus-orange;
}
#santa {
bottom: 0;
left: 5px;
position: absolute;
width: 60px;
z-index: 300;
}
}
}
}
.hero {
#logo {
padding-top: 25px;
}
.nav-right {
padding-right: 10px;
}
.navbar:not(.is-transparent) #logo-link {
@include desktop {
border-bottom: 2px solid $body-background;
margin-bottom: -2px;
width: 124px;
}
#logo {
@include desktop {
max-width: none;
max-height: none;
left: 0;
bottom: 5px;
width: 100px;
position: absolute;
}
}
}
.navbar-item {
font-variant: small-caps;
font-size: 1.15em;
}
@include touch {
.navbar-menu {
position: absolute;
width: 100%;
}
}
.navbar:not(.is-transparent) {
.navbar-item {
&:not(.is-active) {
color: #7a7a7a;
}
&.is-active {
color: $primary;
border-bottom: 2px solid;
margin-bottom: -2px;
}
}
}
#ledenformulier {
color: $zeus-orange;
@include desktop {
transform: rotate(10deg);
}
}
}

View file

@ -4,6 +4,10 @@
font: inherit;
color: inherit;
// For border
border: 1px solid #e2e2e2;
border-color: transparent;
width: 40px;
border-color: rgba(0, 0, 0, 0);

View file

@ -1,15 +1,7 @@
$top_coder_size: 80px;
a.box {
&:hover {
box-shadow: 0 2px 3px rgba($black, 0.1), 0 0 0 1px $blue
}
}
#homepage {
.box {
border-radius: 0;
img {
width: 100%;
}
@ -27,7 +19,7 @@ a.box {
color: $text;
height: 100%;
width: 100%;
background: rgba($tertiary, 0.2);
// background: rgba($tertiary, 0.2);
display: flex;
align-items: center;
justify-content: center;
@ -37,7 +29,7 @@ a.box {
font-size: 1.1em;
margin-left: 10px;
margin-right: 10px;
.event-time-loc {
margin-left: 10px;
margin-right: 10px;
@ -77,6 +69,7 @@ a.box {
}
#gamification-coders {
font-variant: all-small-caps;
display: flex;
justify-content: center;
@ -119,10 +112,10 @@ a.box {
}
#blokmap-tile {
position: relative;
height: 200px;
//background-image: url("https://i.imgur.com/PMaIG7X.jpg");
background-image: url("https://cldup.com/-FmSDFbd07.jpg");
background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, .2)), url("https://cldup.com/-FmSDFbd07.jpg");
background-position: center;
.overlay {
@ -158,3 +151,23 @@ a.box {
.backgroundimg{
background-position: center;
}
.gamification-tile {
overflow: hidden;
padding: 0;
.tile-header {
background-color: $primary;
padding: 20px;
h1 {
margin: 0;
}
a, a:visited {
color: white;
}
}
#gamification-coders {
padding: 20px;
}
}

View file

@ -1,30 +1,29 @@
// Colours
$zeus-orange: #FF7F00;
$zeus-blue: #00C4FF;
$zeus-orange: #ff7f00;
$zeus-blue: #00c4ff;
$body-background: white;
$body-background: #fff;
$tile-orange: #ff9f1a;
$tile-orange: $zeus-orange;
$navbar-border-color: #CCC;
$event-border-color: #DDD;
$navbar-border-color: #ccc;
$event-border-color: #ddd;
$orange: $zeus-orange;
$blue: $zeus-blue;
$turquoise: #30D1B2;
$turquoise: #30d1b2;
$family-sans-serif: 'Lato', sans-serif;
$link-visited: $orange;
$link: $orange;
$link-visited: $link;
$border-hover: $blue;
$box-colour: #EEE;
$box-colour: #eee;
$highlighted-box-colour: $zeus-orange;
$highlighted-text-colour: white;
$highlighted-text-colour: #fff;
$highlighted-link-colour: #222324;
$cammie-controls-color: rgba(0, 0, 0, 0.60);
$cammie-controls-color: rgba(0, 0, 0, .60);
$event-padding: 10px;
@ -32,5 +31,5 @@ $primary: $orange;
$secondary: $zeus-blue;
$tertiary: $box-colour;
// Default font size
// $size-normal: 15px;
// Let's trust the font the user chose
$family-sans-serif: sans-serif;

View file

@ -1,22 +1,23 @@
@import 'https://fonts.googleapis.com/css?family=Lato:300,400';
@import "includes/variables";
@import "../../../node_modules/bulma/bulma";
@import "../../../node_modules/bulma-divider/divider";
@import "../../node_modules/bulma/bulma";
@import "../../node_modules/bulma-divider/divider";
.nav-right {
flex: none;
}
// Sticky footer
body.site {
overflow-x: hidden;
body {
hyphens: auto;
display: flex;
min-height: 100vh;
flex-direction: column;
&.site {
overflow-x: hidden;
display: flex;
min-height: 100vh;
flex-direction: column;
}
.wrapper {
flex: 1;
@ -34,4 +35,4 @@ body.site {
@import "includes/projects";
@import "includes/navbar";
@import "includes/search";
@import "includes/about"
@import "includes/about";

View file

@ -0,0 +1,337 @@
/*
Tipue Search 7.0
Copyright (c) 2018 Tipue
Tipue Search is released under the MIT License
http://www.tipue.com/search
*/
/* basics */
.tipue_search_group:after
{
content: "";
display: table;
clear: both;
}
/* fonts, colors */
.tipue_search_icon
{
font: 300 24px/1 sans-serif;
color: #777;
}
#tipue_search_results_count, .tipue_search_related, .tipue_search_note
{
font: 12px/1.3 monospace;
text-transform: uppercase;
color: #999;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
#tipue_search_replace, #tipue_search_error, .tipue_search_content_text
{
font: 300 16px/1.6 sans-serif;
color: #666;
}
#tipue_search_replace a
{
color: #339e41;
text-decoration: none;
}
#tipue_search_replace a:hover
{
color: #666;
}
.tipue_search_related_btn
{
font: 11px/1 monospace;
color: #666;
text-transform: uppercase;
letter-spacing: 1px;
background-color: #f7f7f7;
}
.tipue_search_content_title
{
font: 300 30px/1.2 sans-serif;
color: #333;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.tipue_search_content_title a
{
color: #333;
text-decoration: none;
}
.tipue_search_content_url, .tipue_search_content_debug
{
font: 300 15px/1.7 sans-serif;
color: #333;
}
.tipue_search_content_url a
{
color: #339e41;
text-decoration: none;
}
.tipue_search_content_url a:hover
{
color: #666;
}
.tipue_search_content_bold
{
font-weight: 400;
color: #333;
}
.tipue_search_note a
{
color: #999;
text-decoration: none;
}
.tipue_search_image_close
{
font: 22px/1 monospace;
color: #ccc;
}
#tipue_search_zoom_text
{
font: 11px/1.7 monospace;
color: #ccc;
text-transform: uppercase;
letter-spacing: 1px;
}
#tipue_search_zoom_text a
{
color: #ccc;
text-decoration: none;
border-bottom: 2px solid #f7f7f7;
}
#tipue_search_zoom_text a:hover
{
border: 0;
}
#tipue_search_foot_boxes
{
font: 13px/1 sans-serif;
text-transform: uppercase;
color: #333;
}
#tipue_search_foot_boxes li a
{
background-color: #f7f7f7;
color: #666;
}
#tipue_search_foot_boxes li.current
{
background: #252525;
color: #ccc;
}
#tipue_search_foot_boxes li a:hover, .tipue_search_related_btn:hover
{
background: #252525;
color: #ccc;
}
/* search box */
.tipue_search_button
{
position: relative;
float: left;
width: 47px;
height: 56px;
margin-left: -3px;
background-color: #f3f3f3;
border: none;
border-radius: 3px;
box-sizing: border-box;
cursor: pointer;
outline: 0;
}
.tipue_search_icon
{
float: left;
transform: rotate(-45deg);
-moz-appearance: none;
-webkit-appearance: none;
box-sizing: border-box;
box-shadow: none;
outline: 0;
margin: -1px 0 0 8px;
}
/* search results */
#tipue_search_content
{
max-width: 100%;
margin: 0;
}
.tipue_search_result
{
padding-top: 21px;
}
#tipue_search_results_count
{
padding-top: 9px;
}
.tipue_search_related
{
padding-top: 13px;
}
.tipue_search_related_block
{
padding-bottom: 6px;
}
#tipue_search_warning
{
padding-top: 10px;
}
.tipue_search_related_btn
{
display: inline-block;
padding: 9px 10px;
text-decoration: none;
text-align: center;
border-radius: 3px;
margin: 9px 9px 0 0;
outline: 0;
transition: 0.2s;
cursor: pointer;
}
#tipue_search_replace
{
padding-top: 13px;
}
#tipue_search_error
{
padding-top: 13px;
}
.tipue_search_content_url
{
padding-top: 3px;
word-wrap: break-word;
hyphens: auto;
}
.tipue_search_content_text
{
word-wrap: break-word;
hyphens: auto;
margin-top: 1px;
}
.tipue_search_note
{
padding-top: 5px;
}
.tipue_search_content_debug
{
margin: 5px 0;
}
/* images */
.tipue_search_image
{
padding: 9px 0 6px 0;
}
.tipue_search_img
{
width: 200px;
max-width: 100%;
height: auto;
transition: 0.5s;
border-radius: 1px;
}
.tipue_search_img:hover
{
opacity: 0.7;
}
.tipue_search_image_zoom
{
cursor: pointer;
}
#tipue_search_image_modal
{
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.9);
}
.tipue_search_image_close
{
position: absolute;
top: 0;
right: 0;
padding: 25px 30px;
cursor: pointer;
}
.tipue_search_image_block
{
margin: 0 auto;
max-width: 900px;
padding: 73px 30px 30px 30px;
box-sizing: border-box;
color: #fff;
}
#tipue_search_zoom_img
{
max-width: 100%;
height: auto;
}
#tipue_search_zoom_text, .tipue_search_zoom_options
{
padding-top: 9px;
}
/* footer */
#tipue_search_foot
{
margin: 51px 0 21px 0;
}
#tipue_search_foot_boxes
{
padding: 0;
margin: 0;
cursor: pointer;
}
#tipue_search_foot_boxes li
{
display: inline;
list-style: none;
margin: 0;
padding: 0;
}
#tipue_search_foot_boxes li a
{
padding: 10px 17px 11px 17px;
border-radius: 3px;
margin-right: 7px;
text-decoration: none;
text-align: center;
transition: 0.2s;
}
#tipue_search_foot_boxes li.current
{
padding: 10px 17px 11px 17px;
border-radius: 3px;
margin-right: 7px;
text-align: center;
}

View file

@ -78,7 +78,7 @@ The problem here was that we only could put cables _around_ the circuit, we coul
## count-von-count
Now, I will elaborate on the software which interpolates the data received from the Gyrid nodes in order to count laps<sup><a href="#fn1" class="footnoteRef" id="fnref1">1</a></sup>. `count-von-count` is a robust system written in the [Haskell](https://haskell.org/) programming language.
Now, I will elaborate on the software which interpolates the data received from the Gyrid nodes in order to count laps[^1]. `count-von-count` is a robust system written in the [Haskell](https://haskell.org/) programming language.
At this point, we have a central node which receives 4-tuples from the Gyrid nodes:
@ -140,4 +140,6 @@ When the contest started, both Gyrid, `count-von-count` and `dr.beaker` turned o
Initially, we were able to swap the broken relay batons for the few spare ones we had, and then quickfix the broken ones using some duct tape. After about five hours, however, they really started breaking -- at a rate that was hard to keep up with using quickfixing.
Hence, this is the main goal for next year: build reliable, solid relay batons. We need to be able to throw them down from a four-story building. Beth Dido needs to be able to use them as a dildo, and they should come out unharmed. Feel free to [contact us](https://zeus.ugent.be/contact/) if you're interested in making this happen!
Hence, this is the main goal for next year: build reliable, solid relay batons. We need to be able to throw them down from a four-story building. Beth Dido needs to be able to use them as a dildo, and they should come out unharmed. Feel free to [contact us](https://zeus.ugent.be/about/contact/) if you're interested in making this happen!
[^1]: Because the author of this blogpost is also the author of `count-von-count`, this component is explained in a little more detail.

View file

@ -1,13 +0,0 @@
---
title: LaTeX en Django-les
created_at: 18-10-2010
---
Ben je het ook beu dat je opmaak in Word verprutst wordt telkens je een wijziging maakt. Vloek je wanneer je een wiskundige formule, inhoudstabel, referentietabel,... moet invoegen? Dan is LaTeX zeker iets voor jou!
Daarom organiseert de WVS (Werkgroep Vrije Software) een LaTeX-les. Deze zal doorgaan op dinsdag 19/10 om 19u in Auditorium A van de plateau. Meer info vind je op [latex.ugent.be](https://latex.ugent.be). Wij raden in ieder geval aan om je thesis in LaTeX te maken.
Donderdag 21/10 organiseren we met WVS een Django-les. Django is een webapplicatie-framework geschreven in Python. Het is zeker een goede start als je wilt beginnen met web-development in Python. Meer info over Django vind je op [djangoproject.com](https://www.djangoproject.com/). Deze zal doorgaan op de Plateau in PC-klas A vanaf 19u. Inschrijven kan op [vtk.ugent.be](https://vtk.ugent.be/activities/2010/10/21/djangoles/).
![latexles](https://zeus.ugent.be/wp-content/uploads/2010/10/latexles-212x300.jpg){:class="alignleft"}
![djanglos](https://zeus.ugent.be/wp-content/uploads/2010/10/djanglos-212x300.png){:class="alignleft"}

View file

@ -1,6 +1,7 @@
---
title: ANSIBLE IS AF
created_at: 16-08-2015
author: FlashYoshi
---
Aan het einde van het vorige academiejaar liet onze belangrijkste server, genaamd King, zijn leeftijd zien: zijn RAID-controller had het namelijk begeven, met een hoop corrupte data als gevolg. Na wat spannende momenten (blijkbaar had onze backupserver het ook begeven) kon Silox de data herstellen en wist hij ook aan reserveonderdelen te raken (bedankt Ruben!). De schade bleef dus gelukkig beperkt tot een week downtime.

View file

@ -14,8 +14,7 @@ Deze blogpost dient als een leidraad voor de dappersten onder hen: zij die het p
# Enkele tips voor je begint
## Probeer eerst in een virtuele machine
Als je nog geen ervaring hebt met het installeren van Linux start je best door eens te oefenen op een VM (virtuele machine) zoals [VirtualBox](https://www.virtualbox.org/). Op die manier komt niet alles in één keer op je af en kan je het installatieproces onder de knie krijgen zonder dat je jezelf in de problemen kunt brengen doordat je (naast het OS installeren) ook rekening moet houden met andere obstakels zoals het opzetten van een dualboot systeem. Hou er wel rekening mee dat een VM iets trager is. Het resultaat zal dus iets minder responsief aanvoelen dan een rechtstreekse installatie.
Als je nog geen ervaring hebt met het installeren van Linux start je best door eens te oefenen op een VM (virtuele machine) zoals [VirtualBox](https://www.virtualbox.org/). Op die manier komt niet alles in één keer op je af en kan je het installatieproces onder de knie krijgen zonder dat je jezelf in de problemen kunt brengen doordat je (naast het OS installeren) ook rekening moet houden met andere obstakels zoals het opzetten van een dual-boot systeem. Hou er wel rekening mee dat een VM iets trager is. Het resultaat zal dus iets minder responsief aanvoelen dan een rechtstreekse installatie.
## Zit je vast? RTFM!
@ -43,7 +42,7 @@ Er zijn veel verschillende Linux-distributies, elk met een verschillende _look &
## Fix windows
Als je van plan bent een dualboot te doen (Linux en Windows op één machine) moet je rekening houden met het volgende:
Als je van plan bent een dual-boot te doen (Linux en Windows op één machine) moet je rekening houden met het volgende:
- Maak ruimte vrij op je harde schijf. Voor Linux is 20GB een goed begin. Als je zeker wilt zijn is 50GB zeker genoeg.
- [Schakel fast startup uit](https://www.tenforums.com/tutorials/4189-fast-startup-turn-off-windows-10-a.html). Dit geeft op meerdere manieren problemen met Linux. Als je Windows-installatie op een SSD staat is het verschil in opstartsnelheid toch verwaarloosbaar.
@ -58,8 +57,8 @@ Als je Linux installeert naast Windows (of andere belangrijke data op dezelfde m
Kies een installatietutorial voor de distributie die je gekozen hebt. Probeer steeds alles te snappen voor je iets effectief doet.
- **Fedora:** [wikihow](http://www.wikihow.com/Install-Fedora), de [officiële installatiegids](https://docs.fedoraproject.org/en-US/Fedora/25/html/Installation_Guide/chap-introduction.html) of [een tutorial specifiek voor dualboot](http://linuxbsdos.com/2016/12/01/dualboot-fedora-25-windows-10-on-a-computer-with-uefi-firmware/)
- **Linux Mint:** [dualboot tutorial](http://www.tecmint.com/install-linux-mint-18-alongside-windows-10-or-8-in-dualboot-uefi-mode/) of de [offiële user guide](https://www.linuxmint.com/documentation/user-guide/Cinnamon/english_18.0.pdf)
- **Fedora:** [wikihow](http://www.wikihow.com/Install-Fedora), de [officiële installatiegids](https://docs.fedoraproject.org/en-US/Fedora/25/html/Installation_Guide/chap-introduction.html) of [een tutorial specifiek voor dual-boot](http://linuxbsdos.com/2016/12/01/dual-boot-fedora-25-windows-10-on-a-computer-with-uefi-firmware/)
- **Linux Mint:** [dual-boot tutorial](http://www.tecmint.com/install-linux-mint-18-alongside-windows-10-or-8-in-dual-boot-uefi-mode/) of de [officiële user guide](https://www.linuxmint.com/documentation/user-guide/Cinnamon/english_18.0.pdf)
- **Arch Linux:** de [installation guide](https://wiki.archlinux.org/index.php/installation_guide) is erg uitgebreid.
## Enkele concepten die vaak aan bod komen

View file

@ -0,0 +1,23 @@
---
author: Lorin Werthen
title: "Bestuur '18-'19"
created_at: 08-05-2018
description: Het bestuur voor academiejaar '18-'19 is verkozen.
---
Na een strijd tussen vicevoorzitters, een nagelbijtende keuzeronde tussen de kandidaat-projectverantwoordelijken, en een staande ovatie die een minuut lang duurde voor een ontroerende, ijzersterke doch bescheiden motivatiespeech, zijn we tot een bestuur gekomen waar we u kunnen tegen zeggen. We wensen ze enorm veel succes!
| Rol | Naam |
| -------------- | --------------- |
| Voorzitter | Robbe Van Herck |
| Vicevoorzitter | Rien Maertens |
| Project | Arne Bertrand |
| PR | Wout Schellaert |
| Penningmeester | Timo De Waele |
| Sysadmin | Jasper Devreker |
Kusjes en knuffels van jullie (bijna oud-)bestuur 😘
> Hallo mijn naam is Jasper en ik zou graag sysadmin worden.
>
> _\*langstdurende staande ovatie in de geschiedenis van staande ovaties\*_

View file

@ -0,0 +1,16 @@
---
author: Lorin Werthen
title: "Summer Codenights 2018"
created_at: 19-05-2018
description: Coden tot de zon op komt, de hele zomer lang!
---
Het academiejaar komt tot een einde, de dagen worden terug korter en de tweede zit is nog ver, ver weg. Betekent dit dat je de kelder een hele zomer hoeft te missen? Natuurlijk niet! Elke dinsdag komen we samen om te werken aan de verschillende [Zeus projecten](/projects/), persoonlijke projectjes, of om gewoon de keldersfeer nog eens te ervaren!
De codenights zijn ook een ideaal moment om Zeus te leren kennen! Er zal wel altijd een Zeuslid aanwezig zijn die kennis heeft van een bepaald project en je kan helpen om het project op te zetten.
# Waar en Wanneer??
De codenights gaan officieel van start op **Dinsdag 3 juli 17:00**, en gaan de hele zomervakantie door op dinsdagen (uitgezonderd op dinsdag 17 juli, tijdens de Gentse Feesten). Deze blogpost zal een update krijgen indien er een codenight niet door gaat, en bekijk zeker onze [Slack](https://zeuswpi.slack.com/) in de #zeus en #codenight kanalen.
Alle codenights gaan door in de [Zeus kelder](/about/contact/)!

View file

@ -0,0 +1,97 @@
---
author: David Vandorpe
title: 'Cyber Security Challenge 2018: Radium'
created_at: 08-03-2018
description: A writeup of one of the Cyber Security Challenge's more difficult tasks
toc: true
---
**Category:** Network Security
**Points:** 150
**Description:**
Someone implemented a protocol to execute (privileged) commands on a server. After months of analysis, our word-class TAO team didn't find a single buffer overflow.. However, they were able to compromise a router between a communicating client and server.
To perform a man-in-the-middle attack through this router, forward data between 52.210.242.66:8023 (this represents the server) and 52.210.242.66:8024 (this represents the client).
See client.c for an example command to do this. Abuse the resulting man-in-the-middle position to somehow obtain the ability to execute privileged commands!
*Hint*: When is the authenticity of a packet verified? When is the data payload of a packet decrypted?
[Source code](https://zeus.ugent.be/zeuswpi/jaWQQLqU.zip)
## Introduction
This challenge proved to be possibly the hardest challenge, going unsolved until the organisers decided to reveal a hint near the end of the competition. Even then, our team was the only one to solve it.
## Write-up
The zip file contains the code ran on the server and the client. The client and server share a secret password and a secret key. The flow to request the flag is as follow:
* Client sends the randomly generated client nonce to the server
* Server replies with a randomly generated server nonce.
- The session key (all following communications will use this key) is now `HMAC_SHA256(secret_key, "CSCBE18 Session Key Generation" || client_nonce || server_nonce)`
* The client sends a flag request to the server, which requires a password. Unfortunately this password is encrypted.
* The server responds with the (encrypted) flag
The same routine was also available without encryption if the client didn't pass a NONCE in it's handshake.
So, how do we get our flag? Let's list some ideas:
* Find an attack on the encryption algorithm (AES in OFB mode)
* Try to trick client and server to use the flow without encryption
* Try to set the key to a known value
* Try to trick the server into dumping the flag without a password
* Try to trick the server into using a known encryption key
* Try to generate an error message on the server that includes (a part of) the flag or encryption key
* Try to generate an error message on the client that includes (a part of) the flag or encryption key
Let's see what these ideas lead to.
We found a [writeup](https://shrikantadhikarla.wordpress.com/2016/03/08/des-ofb-writeup-boston-key-party-ctf/) from another CTF that cracks DES encryption in OFB mode. The key weakness here is using a weak DES key (guaranteeing `x == DES(DES(x))`), in combination with OFB. But wait a second, the program uses the same function to encrypt and decrypt as well! So basically we would expect the second block of ciphertext to just be the plaintext XOR'd with the IV. Some testing proved that our logic was flawed: using the same function worked because of the symmetry of the XOR operation in OFB mode, and not because `IV == AES(AES(IV))` which would break AES OFB.
Setting the encryption key to NULL on the server seemed easy enough, but sadly this would also mean that the server couldn't decrypt the messages from the client (as this key was used for both encryption and decryption by both sides).
To understand the next step, let's see how the plaintext is formatted. It consists of some header bytes (including IV and HMAC sign) followed by data. The data is the only part that gets encrypted if encryption is used. This data is essentially an array of different data blocks. The first two bytes of each block are the "TlvType" (an enum in `packets.h`) and the length of the data block (excluding these two bytes). The rest of block is the actual data. It is also essential to understand that AES+OFB generates a bytestream which only depends on the IV and the encryption key. This stream does then get XOR'd with the plaintext. Changing a byte in the plain/ciphertext only changes the corresponding byte in the cipher/plaintext. If we know a byte P from the plaintext, it is easy to substitute it with another byte P': simply change C to C'=C XOR P XOR P'.
Let's dive back into the code. When trying to dump the flag through an error message (which never gets encrypted) on the client side, we stumbled across some interesting code.
~~~ c
size_t pos = 0;
while (pos < len && len - pos >= 2)
{
// Assure there is enough length for the element
if (data[pos + 1] > len - pos - 2) {
send_error(session, "%s: not enough data left for element type %d (need %d bytes but only %d left)\n",
__FUNCTION__, data[pos], data[pos + 1], len - pos - 2);
return -1;
}
~~~
This is were our attack will happen. We let the flow described earlier proceed as normal, except we intercept the final message returning the flag to the client. Assume we want to decrypt the fifth byte of the flag. If we manage to set the length of the first datablock to 3, the fifth byte of the flag will be interpreted as the length of the second data block. If this length is greater than the amount of remaining bytes, then our byte will get sent back to the server unencrypted! To do this, we need to know the original length of the flag, which is hardcoded and 39. So we replace the second byte with `C' = C XOR 0x27 XOR 0x3` and this should print the correct byte and the preceding byte.
However, we're not there yet. All ciphertexts get signed with HMAC_SHA256. At this point, we got stuck for a bit. Around 2.5 hours before the competition ended a hint was posted (see challenge description) which led to the solution.
~~~ c
static int radium_check_authenticity(struct radium_session *session, struct pkt_header *hdr)
{
// Nothing to do if no encryption is used, or if it's not an authenticated message
if (!session->using_encryption || hdr->msgtype < Packet_Command)
return 0;
// We need a session key to verify all the other packets
else if (!session->using_encryption || !session->handshake_done) {
fprintf(stderr, "%s: no session key available to check authenticity\n", __FUNCTION__);
return -1;
}
static int radium_decrypt_data(struct radium_session *session, struct pkt_header *hdr)
{
// Nothing to do if not encrypted
if (!hdr->encrypted)
return 0;
~~~
Basically, the solution was to set the msgtype byte to 0x1 (ServerHello). This wasn't according to our protocol flow, but that didn't matter as we intended to already produce an error during the parsing of the message. Throwing this together revealed that the fifth byte was 'E', which matched our expectation of flag format "CSCBE{.................................}". Jackpot! Now we just had to repeat for all other bytes. A simple [python script](https://zeus.ugent.be/zeuswpi/GotPD6yg.py) solved this.
Flag: CSCBE{1FFCD19C964D3E5DF5B4CFF490583AC1}

Some files were not shown because too many files have changed in this diff Show more