sciolyff-duosmium 0.13.0 → 0.13.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -9
- data/bin/sciolyff +1 -1
- data/lib/sciolyff/interpreter.rb +6 -6
- data/lib/sciolyff/interpreter/html/main.js +1 -1
- data/lib/sciolyff/interpreter/html/template.html.erb +266 -304
- data/lib/sciolyff/interpreter/placing.rb +5 -5
- data/lib/sciolyff/interpreter/team.rb +7 -7
- data/lib/sciolyff/interpreter/tournament.rb +4 -4
- data/lib/sciolyff/interpreter/{subdivisions.rb → tracks.rb} +10 -10
- data/lib/sciolyff/validator.rb +2 -2
- data/lib/sciolyff/validator/teams.rb +10 -10
- data/lib/sciolyff/validator/top_level.rb +1 -1
- data/lib/sciolyff/validator/tracks.rb +64 -0
- data/sciolyff.gemspec +1 -1
- metadata +4 -4
- data/lib/sciolyff/validator/subdivisions.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a7b4a31efaca54ca04e7eb901a3681f3f66545a1830a909b8a362aa95b7180c
|
4
|
+
data.tar.gz: 347bde8ec63fb0bee0d82fd0ddb20af7004ce17aa3d12e77bd74a80e81a20d00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0119ec1439da52ad630dd29c28233f4b266b42c0e2bc5ee8e514274854c10f2e145406b45f946cabeafb5857c124abc90aad7a75bbcacc83dcf57646b0010829'
|
7
|
+
data.tar.gz: 69a80f6ec3c9d1eac8bfe3fd17de028eb999ac29db7630c5c859cd92f9263f1eaf4e0ae64bc6932b28791adf5daa56c9efb802bbcfdeec5649b009aa98405ec0
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SciolyFF (Science Olympiad File Format)
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/sciolyff.svg)](https://badge.fury.io/rb/sciolyff)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/sciolyff-duosmium.svg)](https://badge.fury.io/rb/sciolyff-duosmium)
|
4
4
|
|
5
5
|
We propose a standardized file format called SciolyFF to represent Science
|
6
6
|
Olympiad tournament results. This will allow for a more universal record of
|
@@ -9,8 +9,8 @@ other fun stuff. The format is a subset of YAML for easy implementation of
|
|
9
9
|
parsers across many programming languages.
|
10
10
|
|
11
11
|
A website that generates results tables based off SciolyFF files can be found
|
12
|
-
[here](https://
|
13
|
-
[here](https://github.com/
|
12
|
+
[here](https://duosmium.org/results/) and the source code for the website
|
13
|
+
[here](https://github.com/Duosmium/duosmium).
|
14
14
|
|
15
15
|
## Specification
|
16
16
|
|
@@ -22,16 +22,16 @@ outlined in the comments of the demo file should be respected.
|
|
22
22
|
## Installation
|
23
23
|
|
24
24
|
```
|
25
|
-
gem install sciolyff
|
25
|
+
gem install sciolyff-duosmium
|
26
26
|
```
|
27
27
|
|
28
28
|
This gem is currently in an alpha stage. To get the latest changes before
|
29
29
|
official releases, build from source:
|
30
30
|
|
31
31
|
```
|
32
|
-
git clone https://github.com/
|
32
|
+
git clone https://github.com/Duosmium/sciolyff.git && cd sciolyff
|
33
33
|
gem build sciolyff.gemspec
|
34
|
-
gem install ./sciolyff-0.
|
34
|
+
gem install ./sciolyff-duosmium-0.13.1.gem
|
35
35
|
```
|
36
36
|
|
37
37
|
## Usage
|
@@ -84,9 +84,9 @@ team_one.points #=> 448
|
|
84
84
|
i.teams #=> [#<...{:school=>"Troy H.S.", :number=>3, :state=>"CA"}>, ... ]
|
85
85
|
```
|
86
86
|
|
87
|
-
A fuller example can be found here in the code for the
|
87
|
+
A fuller example can be found here in the code for the Duosmium Results website,
|
88
88
|
found
|
89
|
-
[here](https://github.com/
|
89
|
+
[here](https://github.com/Duosmium/duosmium/blob/master/source/results/template.html.erb).
|
90
90
|
There is also of course the
|
91
|
-
[documentation](https://www.rubydoc.info/gems/sciolyff/0.
|
91
|
+
[documentation](https://www.rubydoc.info/gems/sciolyff-duosmium/0.13.1), a bit sparse
|
92
92
|
currently.
|
data/bin/sciolyff
CHANGED
data/lib/sciolyff/interpreter.rb
CHANGED
@@ -11,7 +11,7 @@ module SciolyFF
|
|
11
11
|
require 'sciolyff/interpreter/penalty'
|
12
12
|
|
13
13
|
require 'sciolyff/interpreter/tiebreaks'
|
14
|
-
require 'sciolyff/interpreter/
|
14
|
+
require 'sciolyff/interpreter/tracks'
|
15
15
|
require 'sciolyff/interpreter/html'
|
16
16
|
|
17
17
|
attr_reader :tournament, :events, :teams, :placings, :penalties
|
@@ -29,12 +29,12 @@ module SciolyFF
|
|
29
29
|
sort_teams_by_rank
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
@
|
34
|
-
teams.map(&:
|
32
|
+
def tracks
|
33
|
+
@tracks ||=
|
34
|
+
teams.map(&:track)
|
35
35
|
.uniq
|
36
36
|
.compact
|
37
|
-
.map { |sub| [sub, Interpreter.new(
|
37
|
+
.map { |sub| [sub, Interpreter.new(track_rep(sub))] }
|
38
38
|
.to_h
|
39
39
|
end
|
40
40
|
|
@@ -83,7 +83,7 @@ module SciolyFF
|
|
83
83
|
end
|
84
84
|
|
85
85
|
include Interpreter::Tiebreaks
|
86
|
-
include Interpreter::
|
86
|
+
include Interpreter::Tracks
|
87
87
|
include Interpreter::HTML
|
88
88
|
end
|
89
89
|
end
|
@@ -28,7 +28,7 @@ function(e){var t,n,r,i,o,a,s,l,u,c,f,d,p,h,m,g,v,y,b,w="sizzle"+1*new Date,x=e.
|
|
28
28
|
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
29
29
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
30
30
|
*/
|
31
|
-
e.exports=function(e){"use strict";function t(t){var r=this,i=!1;return e(this).one(n.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||n.triggerTransitionEnd(r)}),t),this}e=e&&e.hasOwnProperty("default")?e.default:e;var n={TRANSITION_END:"bsTransitionEnd",getUID:function(e){do{e+=~~(1e6*Math.random())}while(document.getElementById(e));return e},getSelectorFromElement:function(e){var t=e.getAttribute("data-target");if(!t||"#"===t){var n=e.getAttribute("href");t=n&&"#"!==n?n.trim():""}try{return document.querySelector(t)?t:null}catch(e){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),r=e(t).css("transition-delay"),i=parseFloat(n),o=parseFloat(r);return i||o?(n=n.split(",")[0],r=r.split(",")[0],1e3*(parseFloat(n)+parseFloat(r))):0},reflow:function(e){return e.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(e){return(e[0]||e).nodeType},typeCheckConfig:function(e,t,r){for(var i in r)if(Object.prototype.hasOwnProperty.call(r,i)){var o=r[i],a=t[i],s=a&&n.isElement(a)?"element":(l=a,{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase());if(!new RegExp(o).test(s))throw new Error(e.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var l},findShadowRoot:function(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var t=e.getRootNode();return t instanceof ShadowRoot?t:null}return e instanceof ShadowRoot?e:e.parentNode?n.findShadowRoot(e.parentNode):null},jQueryDetection:function(){if(void 0===e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};return n.jQueryDetection(),e.fn.emulateTransitionEnd=t,e.event.special[n.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}},n}(n(0))},function(e,t,n){},function(e,t,n){(function(e){e(document).ready((function(){var t,n=e("div.results-classic-wrapper");window.onresize=function(){e(window).height()<n.height()?n.height(e(window).height()):n.css("height","")},window.onresize(),e("a.js-back-button").on("click",(function(e){e.preventDefault(),document.referrer===this.href&&window.history.length>1?window.history.back():window.location=this.href})),e("button#share-button").on("click",(function(){var n=window.location.href;if(navigator.share)navigator.share({url:n});else{let i=document.createElement("input");document.body.append(i),i.value=n,i.select(),document.execCommand("copy"),document.body.removeChild(i),window.clearTimeout(t);var r=function(){e("div#share-snack div.snackbar-body").html("Link copied! "+n),e("div#share-snack").addClass("show"),t=window.setTimeout((function(){e("div#share-snack").removeClass("show")}),2e3)};e("div#share-snack").hasClass("show")?(e("div#share-snack").removeClass("show"),window.setTimeout(r,200)):r()}})),e("div#filters input:checkbox").prop("checked",!0);var r=function(t){let n=2*e("colgroup.event-columns col").length+28+t,r=n+.5;e("div.results-classic-thead-background").css("min-width",r+"em"),e("div.results-classic-header").css("width",n+"em"),e("div.results-classic-footnotes").css("width",n+"em")};e("table.results-classic td, table.results-classic th").hover((function(){e("colgroup col").eq(e(this).index()).addClass("hover")}),(function(){e("colgroup col").eq(e(this).index()).removeClass("hover")}));var i=function(){let t=e("#sort-select option:selected").val();var n=function(t,n){return parseInt(e(t).find("td.number").text())-parseInt(e(n).find("td.number").text())};switch(t){case"number":var r=n;break;case"school":r=function(t,r){let i=e(t).find("td.team").text(),o=e(r).find("td.team").text();return i>o?1:i<o?-1:n(t,r)};break;case"rank":r=function(t,r){let i=e("#event-select option:selected").val();if("all"===i)var o=parseInt(e(t).find("td.rank").text()),a=parseInt(e(r).find("td.rank").text());else o=parseInt(e(t).find("td.event-points").eq(i).attr("data-sortable-place")),a=parseInt(e(r).find("td.event-points").eq(i).attr("data-sortable-place"));let s=o-a;return 0!==s?s:n(t,r)};break;case"state":r=function(t,r){let i=e(t).find("td.team small").text(),o=e(r).find("td.team small").text();return i>o?1:i<o?-1:n(t,r)};break;default:return}let i=e("table.results-classic tbody tr").get();i.sort(r),e.each(i,(function(t,n){e("table.results-classic tbody").append(n)}))};i(),e("#sort-select").change(i);var o=function(){let t=e("#event-select option:selected").val();if("rank"===e("#sort-select option:selected").val()&&i(),"all"!==t){e("div.results-classic-wrapper").addClass("event-focused"),e("th.event-points-focus div").text(e("#event-select option:selected").text());let n=e("table.results-classic tbody tr").get();e.each(n,(function(n,r){let i=e(r).find("td.event-points").eq(t),o=i.html(),a=i.attr("data-points"),s=e(r).find("td.event-points-focus");s.children("div").html(o),s.attr("data-points",a)})),r(4)}else e("div.results-classic-wrapper").removeClass("event-focused"),e("th.event-points-focus div").text(""),e("td.event-points-focus div").text(""),r(0)};if(o(),e("#event-select").change(o),e("th.event-points").on("click",(function(t){if(t.target!==this)return;let n=Array.prototype.indexOf.call(this.parentNode.children,this);e("#event-select").val(n-5),e("#event-select").change()})),e("th.rank, th.total-points").on("click",(function(){e("#event-select").val("all"),e("#event-select").change(),e("#sort-select").val("rank"),e("#sort-select").change()})),e("th.number").on("click",(function(){e("#sort-select").val("number"),e("#sort-select").change()})),e("th.team").on("click",(function(){e("#sort-select").val("school"),e("#sort-select").change()})),e("th.event-points-focus").on("click",(function(){e("#sort-select").val("rank"),e("#sort-select").change()})),null!==document.getElementById("
|
31
|
+
e.exports=function(e){"use strict";function t(t){var r=this,i=!1;return e(this).one(n.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||n.triggerTransitionEnd(r)}),t),this}e=e&&e.hasOwnProperty("default")?e.default:e;var n={TRANSITION_END:"bsTransitionEnd",getUID:function(e){do{e+=~~(1e6*Math.random())}while(document.getElementById(e));return e},getSelectorFromElement:function(e){var t=e.getAttribute("data-target");if(!t||"#"===t){var n=e.getAttribute("href");t=n&&"#"!==n?n.trim():""}try{return document.querySelector(t)?t:null}catch(e){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),r=e(t).css("transition-delay"),i=parseFloat(n),o=parseFloat(r);return i||o?(n=n.split(",")[0],r=r.split(",")[0],1e3*(parseFloat(n)+parseFloat(r))):0},reflow:function(e){return e.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(e){return(e[0]||e).nodeType},typeCheckConfig:function(e,t,r){for(var i in r)if(Object.prototype.hasOwnProperty.call(r,i)){var o=r[i],a=t[i],s=a&&n.isElement(a)?"element":(l=a,{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase());if(!new RegExp(o).test(s))throw new Error(e.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var l},findShadowRoot:function(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var t=e.getRootNode();return t instanceof ShadowRoot?t:null}return e instanceof ShadowRoot?e:e.parentNode?n.findShadowRoot(e.parentNode):null},jQueryDetection:function(){if(void 0===e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};return n.jQueryDetection(),e.fn.emulateTransitionEnd=t,e.event.special[n.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}},n}(n(0))},function(e,t,n){},function(e,t,n){(function(e){e(document).ready((function(){var t,n=e("div.results-classic-wrapper");window.onresize=function(){e(window).height()<n.height()?n.height(e(window).height()):n.css("height","")},window.onresize(),e("a.js-back-button").on("click",(function(e){e.preventDefault(),document.referrer===this.href&&window.history.length>1?window.history.back():window.location=this.href})),e("button#share-button").on("click",(function(){var n=window.location.href;if(navigator.share)navigator.share({url:n});else{let i=document.createElement("input");document.body.append(i),i.value=n,i.select(),document.execCommand("copy"),document.body.removeChild(i),window.clearTimeout(t);var r=function(){e("div#share-snack div.snackbar-body").html("Link copied! "+n),e("div#share-snack").addClass("show"),t=window.setTimeout((function(){e("div#share-snack").removeClass("show")}),2e3)};e("div#share-snack").hasClass("show")?(e("div#share-snack").removeClass("show"),window.setTimeout(r,200)):r()}})),e("div#filters input:checkbox").prop("checked",!0);var r=function(t){let n=2*e("colgroup.event-columns col").length+28+t,r=n+.5;e("div.results-classic-thead-background").css("min-width",r+"em"),e("div.results-classic-header").css("width",n+"em"),e("div.results-classic-footnotes").css("width",n+"em")};e("table.results-classic td, table.results-classic th").hover((function(){e("colgroup col").eq(e(this).index()).addClass("hover")}),(function(){e("colgroup col").eq(e(this).index()).removeClass("hover")}));var i=function(){let t=e("#sort-select option:selected").val();var n=function(t,n){return parseInt(e(t).find("td.number").text())-parseInt(e(n).find("td.number").text())};switch(t){case"number":var r=n;break;case"school":r=function(t,r){let i=e(t).find("td.team").text(),o=e(r).find("td.team").text();return i>o?1:i<o?-1:n(t,r)};break;case"rank":r=function(t,r){let i=e("#event-select option:selected").val();if("all"===i)var o=parseInt(e(t).find("td.rank").text()),a=parseInt(e(r).find("td.rank").text());else o=parseInt(e(t).find("td.event-points").eq(i).attr("data-sortable-place")),a=parseInt(e(r).find("td.event-points").eq(i).attr("data-sortable-place"));let s=o-a;return 0!==s?s:n(t,r)};break;case"state":r=function(t,r){let i=e(t).find("td.team small").text(),o=e(r).find("td.team small").text();return i>o?1:i<o?-1:n(t,r)};break;default:return}let i=e("table.results-classic tbody tr").get();i.sort(r),e.each(i,(function(t,n){e("table.results-classic tbody").append(n)}))};i(),e("#sort-select").change(i);var o=function(){let t=e("#event-select option:selected").val();if("rank"===e("#sort-select option:selected").val()&&i(),"all"!==t){e("div.results-classic-wrapper").addClass("event-focused"),e("th.event-points-focus div").text(e("#event-select option:selected").text());let n=e("table.results-classic tbody tr").get();e.each(n,(function(n,r){let i=e(r).find("td.event-points").eq(t),o=i.html(),a=i.attr("data-points"),s=e(r).find("td.event-points-focus");s.children("div").html(o),s.attr("data-points",a)})),r(4)}else e("div.results-classic-wrapper").removeClass("event-focused"),e("th.event-points-focus div").text(""),e("td.event-points-focus div").text(""),r(0)};if(o(),e("#event-select").change(o),e("th.event-points").on("click",(function(t){if(t.target!==this)return;let n=Array.prototype.indexOf.call(this.parentNode.children,this);e("#event-select").val(n-5),e("#event-select").change()})),e("th.rank, th.total-points").on("click",(function(){e("#event-select").val("all"),e("#event-select").change(),e("#sort-select").val("rank"),e("#sort-select").change()})),e("th.number").on("click",(function(){e("#sort-select").val("number"),e("#sort-select").change()})),e("th.team").on("click",(function(){e("#sort-select").val("school"),e("#sort-select").change()})),e("th.event-points-focus").on("click",(function(){e("#sort-select").val("rank"),e("#sort-select").change()})),null!==document.getElementById("track")){let t=function(){let t=e("input[type=radio][name=track]:checked").attr("id").substring(4),n=e("tr[data-track]");"combined"===t?(n.show(),e.each(e("td.event-points"),(function(t,n){e(n).attr("data-points",e(n).attr("data-o-points")),e(n).attr("data-true-points",e(n).attr("data-o-true-points")),e(n).attr("data-notes",e(n).attr("data-o-notes")),e(n).attr("data-place",e(n).attr("data-o-place"));let r=e(n).attr("data-o-sup-tag")||"",i=e(n).attr("data-points")+r;e(n).children("div").html(i)})),e.each(e("td.rank"),(function(t,n){e(n).attr("data-points",e(n).attr("data-o-points"));let r=e(n).attr("data-o-sup-tag")||"";e(n).children("div").html(e(n).attr("data-points")+r)})),e.each(e("td.total-points"),(function(t,n){e(n).html(e(n).attr("data-o-points"))})),e("#track").html("Combined")):(e.each(n,(function(n,r){e(r).attr("data-track")===t?e(r).show():e(r).hide()})),e.each(e("td.event-points"),(function(t,n){e(n).attr("data-points",e(n).attr("data-sub-points")),e(n).attr("data-true-points",e(n).attr("data-sub-true-points")),e(n).attr("data-notes",e(n).attr("data-sub-notes")),e(n).attr("data-place",e(n).attr("data-sub-place"));let r=e(n).attr("data-sub-sup-tag")||"",i=e(n).attr("data-points")+r;e(n).children("div").html(i)})),e.each(e("td.rank"),(function(t,n){e(n).attr("data-points",e(n).attr("data-sub-points")),e(n).children("div").html(e(n).attr("data-sub-points"))})),e.each(e("td.total-points"),(function(t,n){e(n).html(e(n).attr("data-sub-points"))})),e("#track").html(t));let r=document.querySelector("#track-style"),i=document.querySelector(`#sub-${CSS.escape(t)}-style`);r.innerHTML=i.innerHTML,o()};e("input[type=radio][name=track]").change(t),t()}function a(e){let t=["th","st","nd","rd"],n=parseInt(e.match(/\d+/))%100;return e+(t[(n-20)%10]||t[n]||t[0])}e("div#team-filter input").change((function(){let t=e(this).attr("id"),n=e("div#team-filter input#allTeams"),r=e("div#team-filter input").not("#allTeams");if("allTeams"===t)e(this).prop("checked")?r.not(":checked").trigger("click"):r.filter(":checked").trigger("click"),n.prop("indeterminate",!1);else{let i="table.results-classic tr[data-team-number='"+t.slice("team".length)+"']";e(this).prop("checked")?e(i).show():e(i).hide(),0===r.not(":checked").length?(n.prop("indeterminate",!1),n.prop("checked",!0)):0===r.filter(":checked").length?(n.prop("indeterminate",!1),n.prop("checked",!1)):n.prop("indeterminate",!0)}})),e("td.number a").on("click",(function(){let t=e(this).closest("tr"),n=t.children("td.total-points").text(),r=t.children("td.rank").attr("data-points");e("div#team-detail span#number").html(e(this).text()),e("div#team-detail span#points").html(n),e("div#team-detail span#place").html(a(r)),e("div#team-detail span#team").html(t.attr("data-team-name")),e("div#team-detail span#school").html(t.attr("data-school"));let i="https://unosmium.org/results/schools.html#"+t.attr("data-school").replace(/ /g,"_");window.location.href.startsWith("https://unosmium.org")&&(i=i.replace(".html","")),e("a#other-results").attr("href",i);let o=e("div#team-detail table tbody").children();e.each(t.children("td.event-points"),(function(t,n){let r=o.eq(t);r.attr("data-points",e(n).attr("data-points")),r.children().eq(1).html(e(n).attr("data-true-points"));let i=e(n).attr("data-place"),s=""===i?"n/a":a(i);r.children().eq(2).html(s),r.children().eq(3).html(e(n).attr("data-notes"))}))})),e("td.number, td.team, td.team > small").on("click",(function(t){t.target===this&&e(this).closest("tr").find("td.number a").click()})),e((function(){e('[data-toggle="popover"]').popover()}))}))}).call(this,n(0))},function(e,t,n){
|
32
32
|
/*!
|
33
33
|
* Bootstrap modal.js v4.4.1 (https://getbootstrap.com/)
|
34
34
|
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
@@ -1,20 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<meta name="viewport"
|
7
|
-
content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
8
|
-
<title><%=
|
9
|
-
"#{i.tournament.year} "\
|
1
|
+
---
|
2
|
+
custom_colors: true
|
3
|
+
---
|
4
|
+
<% current_page.data.title =
|
5
|
+
"#{i.tournament.year} "\
|
10
6
|
"#{tournament_title_short(i.tournament)} " \
|
11
|
-
"(Div. #{i.tournament.division}) |
|
12
|
-
|
13
|
-
<% if i.tournament.teams.count > 1 %>
|
7
|
+
"(Div. #{i.tournament.division}) | Duosmium Results" %>
|
8
|
+
|
14
9
|
<% champion = i.tournament.teams[0] %>
|
15
10
|
<% runnerup = i.tournament.teams[1] %>
|
16
|
-
|
17
|
-
|
11
|
+
<% current_page.data.description =
|
12
|
+
"Full results for the #{i.tournament.year} "\
|
18
13
|
"#{tournament_title(i.tournament)} "\
|
19
14
|
"(Division #{i.tournament.division}), "\
|
20
15
|
"Champion: #{champion.school} "\
|
@@ -24,232 +19,217 @@
|
|
24
19
|
"#{runnerup.suffix ? runnerup.suffix + " " : ""}"\
|
25
20
|
"(#{runnerup.points} pts), "\
|
26
21
|
"Total non-exhibition teams: #{i.tournament.nonexhibition_teams_count}" %>
|
27
|
-
%>">
|
28
|
-
<% end %>
|
29
|
-
<link href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAQAAAD9CzEMAAACDElEQVR4Ae3VA8wcURhG4VPbtm03qK3oj1lEbVTbtm3bbsPatm3bfeve7M3Ozt2t8Zx4zI/fVUV+sBU05ofqgOjFD1QVITrxwyRHH2vED3MDId5Qjx9kE/rYXVLxQ8xHn1vLDzESfa0hEYlBCbz1R1+7SyIiMIIWeBuKMA0lbNUQw32egek1OQlLQi4jDuLtGgpoFmHpij5WmuAqIKtXpMFZQu6jj+0lHmCLxW6EXS+ctUJfW499iOjMQkG6TQycROMiMrGb/BipWYk8Ko+T6sjqLWdZTn9mso/XyLMBOJmEIuw4DmLwEDm3BAWUEV8lkHNriM4tZKIevpohxyYQD1iMTHTC11Tk0EmqAgCtkYlFroPEuwfMprL1zzLtxNeFEGfdlwrEJFBxax1f91GQDlGY4LIiEzfx9RbZsZ74eElsfZK+HgX5xyTFWzSE6RG+TiGrJoSSCmE6ha+NyKoIoZREmDbiayyyik0oXRCmcfiqjazi4y0W5xCm2viKzRMUUCW8dUCYnhIbB+NRQDPxUtaaDhNwkoZnKKCaBFOAGwjTM1LjqD8K6B4VCBSTBthzoz/O4nEAe2guogGFiQGkph2XkdUe4oG7tFxCuHeZlIQpN2eQY+fIRQSSsR05tJNkRCg2HXiKQvSUDsTmm6RhgsdBnjKBNHwX8YhiHnu5yHOecYl9zCGKuPwR/nsHqpaOEAqfQCAAAAAASUVORK5CYII=" rel="icon" type="image/png" />
|
30
|
-
<style>
|
31
|
-
.results-classic-thead-background {
|
32
|
-
background-color: <%= color %> !important;
|
33
|
-
}
|
34
|
-
.btn, .custom-control-label::after {
|
35
|
-
color: <%= color %> !important;
|
36
|
-
}
|
37
|
-
<%= css_file_content %>
|
38
|
-
<% if i.tournament.subdivisions? %>
|
39
|
-
</style>
|
40
|
-
<style id="subdivision-style">
|
41
|
-
<% end %>
|
42
|
-
<%= trophy_and_medal_css(i.tournament.trophies, i.tournament.medals) %>
|
43
|
-
</style>
|
44
|
-
</head>
|
45
|
-
<body>
|
46
22
|
|
47
23
|
<div class="results-classic-wrapper">
|
48
|
-
<div class="results-classic-thead-background shadow-sm"
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
<
|
63
|
-
</
|
64
|
-
<
|
65
|
-
<
|
66
|
-
|
67
|
-
|
68
|
-
<
|
69
|
-
|
70
|
-
|
71
|
-
<
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
<
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
24
|
+
<div class="results-classic-thead-background shadow-sm"
|
25
|
+
style="min-width: <%= 2*(i.events.count + 1) + 28.5 %>em;">
|
26
|
+
<div class="results-classic-header"
|
27
|
+
style="width: <%= 2*(i.events.count + 1) + 28 %>em">
|
28
|
+
<div class="tournament-info">
|
29
|
+
<h1>
|
30
|
+
<%= i.tournament.year %>
|
31
|
+
<%= tournament_title(i.tournament) %> (Div. <%= i.tournament.division %><%= ' <span id="track">Combined</span>' if i.tournament.tracks? %>)
|
32
|
+
</h1>
|
33
|
+
<% if i.tournament.start_date.strftime('%A, %B %-d, %Y') == i.tournament.end_date.strftime('%A, %B %-d, %Y')%>
|
34
|
+
<p><%= i.tournament.date.strftime('%A, %B %-d, %Y') %></p>
|
35
|
+
<% else %>
|
36
|
+
<p><%= i.tournament.start_date.strftime('%A, %B %-d, %Y') %> - <%= i.tournament.end_date.strftime('%A, %B %-d, %Y') %></p>
|
37
|
+
<% end %>
|
38
|
+
<p>@ <span style="white-space: nowrap;"><%= i.tournament.location %></span></p>
|
39
|
+
</div>
|
40
|
+
<div class="actions">
|
41
|
+
<a href="../results/index.html" class="js-back-button">
|
42
|
+
<svg viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>
|
43
|
+
</a>
|
44
|
+
<button type="button" data-toggle="modal" data-target="#download-info">
|
45
|
+
<svg viewBox="0 0 24 24"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg>
|
46
|
+
</button>
|
47
|
+
<button type="button" data-toggle="modal" data-target="#print-instructions">
|
48
|
+
<svg viewBox="0 0 24 24"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></svg>
|
49
|
+
</button>
|
50
|
+
<button type="button" id="share-button">
|
51
|
+
<svg viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/></svg>
|
52
|
+
</button>
|
53
|
+
<select id="event-select" class="custom-select custom-select-sm"
|
54
|
+
aria-label="Select Event Filter">
|
55
|
+
<option value="all" selected>All Events</option>
|
56
|
+
<% i.events.each.with_index do |e, i| %>
|
57
|
+
<option value="<%= i %>">
|
58
|
+
<%= e.name %>
|
59
|
+
<% if e.trial? %>
|
60
|
+
(Trial)
|
61
|
+
<% elsif e.trialed? %>
|
62
|
+
(Trialed)
|
63
|
+
<% end %>
|
64
|
+
</option>
|
83
65
|
<% end %>
|
84
|
-
</
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
<
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
66
|
+
</select>
|
67
|
+
<select id="sort-select" class="custom-select custom-select-sm"
|
68
|
+
aria-label="Select Sort Method">
|
69
|
+
<option value="number">by Number</option>
|
70
|
+
<option value="school">by School</option>
|
71
|
+
<option value="state">by State</option>
|
72
|
+
<option value="rank" selected>by Rank</option>
|
73
|
+
</select>
|
74
|
+
<button type="button" data-toggle="modal" data-target="#filters" class="settings">
|
75
|
+
<svg viewBox="0 0 24 24"><path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/></svg>
|
76
|
+
</button>
|
77
|
+
</div>
|
78
|
+
<p class="source">
|
79
|
+
Source:
|
80
|
+
<a href="https://duosmium.org<%= current_page.url %>">
|
81
|
+
Duosmium Results
|
82
|
+
</a>
|
83
|
+
</p>
|
97
84
|
</div>
|
98
|
-
<p class="source">
|
99
|
-
Generated using
|
100
|
-
<a href="https://github.com/unosmium/sciolyff">
|
101
|
-
SciolyFF
|
102
|
-
</a>
|
103
|
-
</p>
|
104
85
|
</div>
|
105
|
-
|
106
|
-
<
|
107
|
-
<
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
<
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
data-content="Placings in this event did not count towards total
|
86
|
+
<table class="results-classic table-hover">
|
87
|
+
<colgroup>
|
88
|
+
<col>
|
89
|
+
<col>
|
90
|
+
<col>
|
91
|
+
<col>
|
92
|
+
<col>
|
93
|
+
</colgroup>
|
94
|
+
<colgroup class="event-columns">
|
95
|
+
<% i.events.count.times do %>
|
96
|
+
<col>
|
97
|
+
<% end %>
|
98
|
+
<col> <%# for team penalties, which kinda act like an additional event %>
|
99
|
+
</colgroup>
|
100
|
+
<thead>
|
101
|
+
<tr>
|
102
|
+
<th class="number">#</th>
|
103
|
+
<th class="team">Team</th>
|
104
|
+
<th class="event-points-focus"><div></div></th>
|
105
|
+
<th class="rank"><div>Overall</div></th>
|
106
|
+
<th class="total-points">Total</th>
|
107
|
+
<% i.events.each do |e| %>
|
108
|
+
<th class="event-points">
|
109
|
+
<%= e.name %>
|
110
|
+
<% if e.trial? %>
|
111
|
+
<a tabindex="0" role="button"
|
112
|
+
data-toggle="popover" data-trigger="focus"
|
113
|
+
title="Trial Event"
|
114
|
+
data-content="Placings in this event did not count towards total
|
135
115
|
team score">
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
116
|
+
<span class="badge badge-info"><small>T</small></span>
|
117
|
+
</a>
|
118
|
+
<% elsif e.trialed? %>
|
119
|
+
<a tabindex="0" role="button"
|
120
|
+
data-toggle="popover" data-trigger="focus"
|
121
|
+
title="Trialed Event"
|
122
|
+
data-content="Placings in this event did not count towards total
|
143
123
|
team score because of unforseen circumstances during
|
144
124
|
the competition">
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
</thead>
|
153
|
-
<tbody>
|
154
|
-
<% i.teams.each do |tm| %>
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
125
|
+
<span class="badge badge-danger"><small>Td</small></span>
|
126
|
+
</a>
|
127
|
+
<% end %>
|
128
|
+
</th>
|
129
|
+
<% end %>
|
130
|
+
<th class="team-penalties">Team Penalties</th>
|
131
|
+
</tr>
|
132
|
+
</thead>
|
133
|
+
<tbody>
|
134
|
+
<% i.teams.each do |tm| %>
|
135
|
+
<tr data-team-number="<%= tm.number %>"
|
136
|
+
data-school="<%= full_school_name(tm) %>"
|
137
|
+
data-team-name="<%= full_team_name(tm) %>"<%= " data-track=\"#{tm.track}\"" if i.tournament.tracks? %>>
|
138
|
+
<td class="number">
|
139
|
+
<a href="?team=<%= tm.number %>"
|
140
|
+
data-toggle="modal" data-target="#team-detail">
|
141
|
+
<%= tm.number %>
|
142
|
+
</a>
|
143
|
+
</td>
|
144
|
+
<td class="team">
|
145
|
+
<%= format_school(tm) %>
|
146
|
+
<%= tm.suffix %>
|
147
|
+
<%= "(#{tm.city})" if tm.city %>
|
148
|
+
<small><%= tm.state %></small>
|
149
|
+
<% if tm.disqualified? %>
|
150
|
+
<a tabindex="0" role="button"
|
151
|
+
data-toggle="popover" data-trigger="focus"
|
152
|
+
title="Disqualified Team"
|
153
|
+
data-content="This team is ranked behind all other teams that were not
|
174
154
|
disqualified">
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
155
|
+
<span class="badge badge-danger"><small>Dq</small></span>
|
156
|
+
<% elsif tm.exhibition? %>
|
157
|
+
<a tabindex="0" role="button"
|
158
|
+
data-toggle="popover" data-trigger="focus"
|
159
|
+
<% if team_attended?(tm) %>
|
160
|
+
title="Exhibition Team"
|
161
|
+
data-content="Placings by this team did not affect the ranks of other
|
182
162
|
teams (except in Trial Events)">
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
163
|
+
<span class="badge badge-warning"><small>Ex</small></span>
|
164
|
+
<% else %>
|
165
|
+
title="Absent Team"
|
166
|
+
data-content="This team registered but did not compete, and so was
|
167
|
+
treated as an Exhibition Team">
|
168
|
+
<span class="badge badge-light"><small>Ab</small></span>
|
169
|
+
<% end %>
|
170
|
+
</a>
|
171
|
+
<% end %>
|
172
|
+
</td>
|
173
|
+
<td class="event-points-focus" data-points=""><div></div></td>
|
174
|
+
<td class="rank" data-points="<%= tm.rank %>"<%= " data-o-points=\"#{tm.rank}\" data-o-sup-tag=\"#{bids_sup_tag(tm)}\" data-sub-points=\"#{tm.track_team.rank}\"" if tm.track %>><div><%= tm.rank %><%= bids_sup_tag(tm) %></div></td>
|
175
|
+
<td class="total-points"<%= " data-o-points=\"#{tm.points}\" data-sub-points=\"#{tm.track_team.points}\"" if tm.track %>><%= tm.points %></td>
|
176
|
+
<% i.events.each do |e| %>
|
177
|
+
<% placing = e.placing_for(tm) %>
|
178
|
+
<% points = placing.isolated_points %>
|
179
|
+
<% place = placing.place %>
|
180
|
+
<% unknown = placing.unknown? %>
|
181
|
+
<td class="event-points"
|
182
|
+
data-true-points="<%= placing.points %>"
|
183
|
+
data-notes="<%= placing_notes(placing) %>"
|
184
|
+
data-points="<%= unknown ? '??' : points %>"
|
185
|
+
data-place="<%= unknown && placing.points_limited_by_maximum_place? ? "≥#{i.tournament.maximum_place}" : place %>"
|
186
|
+
<% if tm.track %>
|
187
|
+
data-o-true-points="<%= placing.points %>"
|
188
|
+
data-o-notes="<%= placing_notes(placing) %>"
|
189
|
+
data-o-points="<%= unknown ? '??' : points %>"
|
190
|
+
data-o-place="<%= unknown && placing.points_limited_by_maximum_place? ? "≥#{i.tournament.maximum_place}" : place %>"
|
191
|
+
data-o-sup-tag="<%= sup_tag(placing) %>"
|
192
|
+
<% sp = placing.track_placing %>
|
193
|
+
data-sub-true-points="<%= sp.points %>"
|
194
|
+
data-sub-notes="<%= placing_notes(sp) %>"
|
195
|
+
data-sub-points="<%= sp.unknown? ? '??' : sp.isolated_points %>"
|
196
|
+
data-sub-place="<%= sp.place %>"
|
197
|
+
data-sub-sup-tag="<%= sup_tag(sp) %>"
|
198
|
+
<% end %>
|
199
|
+
data-sortable-place="<%= place ? place : (unknown ? 998000 + points : 999000 + points) %>">
|
200
|
+
<div><%= unknown && !placing.points_limited_by_maximum_place? ? '??' : points %><%= sup_tag(placing) %></div>
|
201
|
+
</td>
|
202
|
+
<% end %>
|
203
|
+
<% pen_points = tm.penalties.sum(&:points) %>
|
204
|
+
<td class="team-penalties text-muted" data-points="<%= pen_points %>">
|
205
|
+
<%= pen_points.zero? ? "00" : "+#{pen_points}" %>
|
206
|
+
</td>
|
207
|
+
</tr>
|
208
|
+
<% end %>
|
209
|
+
</tbody>
|
210
|
+
</table>
|
211
|
+
<div class="results-classic-footnotes"
|
212
|
+
style="width: <%= 2*(i.events.count + 1) + 28 %>em">
|
213
|
+
<% if i.tournament.ties? || i.tournament.exempt_placings? || i.tournament.worst_placings_dropped? || i.tournament.bids.nonzero? %>
|
214
|
+
<div class="wrapper">
|
215
|
+
<% if i.tournament.bids.nonzero? %>
|
216
|
+
<p class="footnote">
|
217
|
+
<sup>✧</sup><%= bids_sup_tag_note(i.tournament) %>
|
218
|
+
</p>
|
219
|
+
<% end %>
|
220
|
+
<% if i.tournament.exempt_placings? || i.tournament.worst_placings_dropped? %>
|
221
|
+
<p class="footnote">
|
222
|
+
<sup>◊</sup>Result was not counted as part of total score
|
223
|
+
</p>
|
224
|
+
<% end %>
|
225
|
+
<% if i.tournament.ties_outside_of_maximum_places? %>
|
226
|
+
<p class="footnote">
|
227
|
+
<sup>*</sup>Tied with another team
|
228
|
+
</p>
|
229
|
+
<% end %>
|
230
|
+
</div>
|
191
231
|
<% end %>
|
192
|
-
</td>
|
193
|
-
<td class="event-points-focus" data-points=""><div></div></td>
|
194
|
-
<td class="rank" data-points="<%= tm.rank %>"<%= " data-o-points=\"#{tm.rank}\" data-o-sup-tag=\"#{bids_sup_tag(tm)}\" data-sub-points=\"#{tm.subdivision_team.rank}\"" if tm.subdivision %>><div><%= tm.rank %><%= bids_sup_tag(tm) %></div></td>
|
195
|
-
<td class="total-points"<%= " data-o-points=\"#{tm.points}\" data-sub-points=\"#{tm.subdivision_team.points}\"" if tm.subdivision %>><%= tm.points %></td>
|
196
|
-
<% i.events.each do |e| %>
|
197
|
-
<% placing = e.placing_for(tm) %>
|
198
|
-
<% points = placing.isolated_points %>
|
199
|
-
<% place = placing.place %>
|
200
|
-
<% unknown = placing.unknown? %>
|
201
|
-
<td class="event-points"
|
202
|
-
data-true-points="<%= placing.points %>"
|
203
|
-
data-notes="<%= placing_notes(placing) %>"
|
204
|
-
data-points="<%= unknown ? '??' : points %>"
|
205
|
-
data-place="<%= unknown && placing.points_limited_by_maximum_place? ? "≥#{i.tournament.maximum_place}" : place %>"
|
206
|
-
<% if tm.subdivision %>
|
207
|
-
data-o-true-points="<%= placing.points %>"
|
208
|
-
data-o-notes="<%= placing_notes(placing) %>"
|
209
|
-
data-o-points="<%= unknown ? '??' : points %>"
|
210
|
-
data-o-place="<%= unknown && placing.points_limited_by_maximum_place? ? "≥#{i.tournament.maximum_place}" : place %>"
|
211
|
-
data-o-sup-tag="<%= sup_tag(placing) %>"
|
212
|
-
<% sp = placing.subdivision_placing %>
|
213
|
-
data-sub-true-points="<%= sp.points %>"
|
214
|
-
data-sub-notes="<%= placing_notes(sp) %>"
|
215
|
-
data-sub-points="<%= sp.unknown? ? '??' : sp.isolated_points %>"
|
216
|
-
data-sub-place="<%= sp.place %>"
|
217
|
-
data-sub-sup-tag="<%= sup_tag(sp) %>"
|
218
|
-
<% end %>
|
219
|
-
data-sortable-place="<%= place ? place : (unknown ? 998000 + points : 999000 + points) %>">
|
220
|
-
<div><%= unknown && !placing.points_limited_by_maximum_place? ? '??' : points %><%= sup_tag(placing) %></div>
|
221
|
-
</td>
|
222
|
-
<% end %>
|
223
|
-
<% pen_points = tm.penalties.sum(&:points) %>
|
224
|
-
<td class="team-penalties text-muted" data-points="<%= pen_points %>">
|
225
|
-
<%= pen_points.zero? ? "00" : "+#{pen_points}" %>
|
226
|
-
</td>
|
227
|
-
</tr>
|
228
|
-
<% end %>
|
229
|
-
</tbody>
|
230
|
-
</table>
|
231
|
-
<div class="results-classic-footnotes"
|
232
|
-
style="width: <%= 2*(i.events.count + 1) + 28 %>em">
|
233
|
-
<% if i.tournament.ties? || i.tournament.exempt_placings? || i.tournament.worst_placings_dropped? || i.tournament.bids.nonzero? %>
|
234
|
-
<div class="wrapper">
|
235
|
-
<% if i.tournament.bids.nonzero? %>
|
236
|
-
<p class="footnote">
|
237
|
-
<sup>✧</sup><%= bids_sup_tag_note(i.tournament) %>
|
238
|
-
</p>
|
239
|
-
<% end %>
|
240
|
-
<% if i.tournament.exempt_placings? || i.tournament.worst_placings_dropped? %>
|
241
|
-
<p class="footnote">
|
242
|
-
<sup>◊</sup>Result was not counted as part of total score
|
243
|
-
</p>
|
244
|
-
<% end %>
|
245
|
-
<% if i.tournament.ties_outside_of_maximum_places? %>
|
246
|
-
<p class="footnote">
|
247
|
-
<sup>*</sup>Tied with another team
|
248
|
-
</p>
|
249
|
-
<% end %>
|
250
232
|
</div>
|
251
|
-
<% end %>
|
252
|
-
</div>
|
253
233
|
</div>
|
254
234
|
<div class="modal" id="filters" tabindex="-1" role="dialog"
|
255
235
|
aria-labelledby="filters-label" aria-hidden="true">
|
@@ -265,24 +245,24 @@
|
|
265
245
|
</button>
|
266
246
|
</div>
|
267
247
|
<div class="modal-body">
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
248
|
+
<% if i.tournament.tracks? %>
|
249
|
+
<h6>Select which track to show</h6>
|
250
|
+
<div>
|
251
|
+
<input type="radio" id="sub-combined" name="track" checked>
|
252
|
+
<label class="custom-control-label" for="sub-combined">
|
253
|
+
Combined (all teams)
|
254
|
+
</label>
|
255
|
+
</div>
|
256
|
+
<% i.tournament.tracks.each do |s, _| %>
|
257
|
+
<div>
|
258
|
+
<input type="radio" id="sub-<%= s %>" name="track">
|
259
|
+
<label class="custom-control-label" for="sub-<%= s %>">
|
260
|
+
<%= s %>
|
261
|
+
</label>
|
262
|
+
</div>
|
263
|
+
<% end %>
|
264
|
+
<hr>
|
265
|
+
<% end %>
|
286
266
|
<h6>Select which teams to show</h6>
|
287
267
|
<div id="team-filter">
|
288
268
|
<div>
|
@@ -292,18 +272,18 @@
|
|
292
272
|
All Teams
|
293
273
|
</label>
|
294
274
|
</div>
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
275
|
+
<% i.teams.sort_by(&:number).each do |tm| %>
|
276
|
+
<div>
|
277
|
+
<input type="checkbox"
|
278
|
+
id="team<%= tm.number %>" checked>
|
279
|
+
<label class="custom-control-label" for="team<%= tm.number %>">
|
280
|
+
<%= tm.number %> <%= format_school(tm) %>
|
281
|
+
<%= tm.suffix %>
|
282
|
+
<%= "(#{tm.city})" if tm.city %>
|
283
|
+
<small><%= tm.state %></small>
|
284
|
+
</label>
|
285
|
+
</div>
|
286
|
+
<% end %>
|
307
287
|
</div>
|
308
288
|
</div>
|
309
289
|
<div class="modal-footer">
|
@@ -375,10 +355,10 @@
|
|
375
355
|
) instead.
|
376
356
|
</p>
|
377
357
|
<p>
|
378
|
-
The results will be downloaded as a
|
379
|
-
|
380
|
-
|
381
|
-
<a href="https://github.com/
|
358
|
+
The results will be downloaded as a YAML file, specifically in the
|
359
|
+
SciolyFF, and can be opened with any text editor or parsed with your
|
360
|
+
favorite programming language. For more info about SciolyFF, see its
|
361
|
+
<a href="https://github.com/smayya337/sciolyff">GitHub repository</a>.
|
382
362
|
</p>
|
383
363
|
<p>
|
384
364
|
If you really want a CSV file, select CANCEL, copy the whole table
|
@@ -392,7 +372,7 @@
|
|
392
372
|
Cancel
|
393
373
|
</button>
|
394
374
|
<a role="button" class="btn btn-secondary"
|
395
|
-
href="
|
375
|
+
href="../data/<%= File.basename(current_page.path, '.html') + '.yaml' %>">
|
396
376
|
Download
|
397
377
|
</a>
|
398
378
|
</div>
|
@@ -415,31 +395,31 @@
|
|
415
395
|
<div class="modal-body">
|
416
396
|
<h6>Summary</h6>
|
417
397
|
<p><span id="team">[team]</span> placed <span id="place">[place]</span>
|
418
|
-
|
398
|
+
overall with a total score of <span id="points">[points]</span> points.
|
419
399
|
<hr>
|
420
400
|
<div class="table-responsive-md">
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
401
|
+
<table class="table-striped">
|
402
|
+
<thead>
|
403
|
+
<tr>
|
404
|
+
<th class="event">Event</th>
|
405
|
+
<th class="points">Points</th>
|
406
|
+
<th class="place">Place</th>
|
407
|
+
<th class="notes">Notes</th>
|
408
|
+
</tr>
|
409
|
+
</thead>
|
410
|
+
<tbody>
|
411
|
+
<% i.events.each do |e| %>
|
412
|
+
<tr>
|
413
|
+
<td class="event">
|
414
|
+
<%= e.name %>
|
415
|
+
</td>
|
416
|
+
<td class="points"></td>
|
417
|
+
<td class="place"></td>
|
418
|
+
<td class="notes"></td>
|
419
|
+
</tr>
|
420
|
+
<% end %>
|
421
|
+
</tbody>
|
422
|
+
</table>
|
443
423
|
</div>
|
444
424
|
<hr>
|
445
425
|
<h6>Other Results</h6>
|
@@ -460,21 +440,3 @@
|
|
460
440
|
<%# populated using JS %>
|
461
441
|
</div>
|
462
442
|
</div>
|
463
|
-
<script>
|
464
|
-
<%= js_file_content %>
|
465
|
-
</script>
|
466
|
-
<% if i.tournament.subdivisions? %>
|
467
|
-
<x-st id="sub-combined-style">
|
468
|
-
<%= trophy_and_medal_css(i.tournament.trophies, i.tournament.medals) %>
|
469
|
-
</x-st>
|
470
|
-
<% i.subdivisions.each do |sub, sub_i| %>
|
471
|
-
<x-st id="sub-<%= sub %>-style">
|
472
|
-
<%= trophy_and_medal_css(sub_i.tournament.trophies, sub_i.tournament.medals) %>
|
473
|
-
</x-st>
|
474
|
-
<% end %>
|
475
|
-
<% end %>
|
476
|
-
<sciolyff-yaml hidden>
|
477
|
-
<%= i.to_yaml(hide_raw: hide_raw) %>
|
478
|
-
</sciolyff-yaml>
|
479
|
-
</body>
|
480
|
-
</html>
|
@@ -12,10 +12,10 @@ module SciolyFF
|
|
12
12
|
@event = interpreter.events.find { |e| e.name == @rep[:event] }
|
13
13
|
@team = interpreter.teams .find { |t| t.number == @rep[:team] }
|
14
14
|
|
15
|
-
|
15
|
+
link_to_placing_in_track_interpreter(interpreter)
|
16
16
|
end
|
17
17
|
|
18
|
-
attr_reader :event, :team, :
|
18
|
+
attr_reader :event, :team, :track_placing
|
19
19
|
|
20
20
|
def participated?
|
21
21
|
@rep[:participated] || @rep[:participated].nil?
|
@@ -116,10 +116,10 @@ module SciolyFF
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
-
def
|
120
|
-
return @
|
119
|
+
def link_to_placing_in_track_interpreter(interpreter)
|
120
|
+
return @track_placing = nil unless (sub = team.track)
|
121
121
|
|
122
|
-
@
|
122
|
+
@track_placing = interpreter.tracks[sub].placings.find do |p|
|
123
123
|
p.event.name == event.name && p.team.number == team.number
|
124
124
|
end
|
125
125
|
end
|
@@ -12,10 +12,10 @@ module SciolyFF
|
|
12
12
|
@placings_by_event =
|
13
13
|
@placings.group_by(&:event).transform_values!(&:first)
|
14
14
|
|
15
|
-
|
15
|
+
link_to_team_in_track_interpreter(interpreter)
|
16
16
|
end
|
17
17
|
|
18
|
-
attr_reader :placings, :penalties, :
|
18
|
+
attr_reader :placings, :penalties, :track_team
|
19
19
|
|
20
20
|
def school
|
21
21
|
@rep[:school]
|
@@ -29,8 +29,8 @@ module SciolyFF
|
|
29
29
|
@rep[:suffix]
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
@rep[:
|
32
|
+
def track
|
33
|
+
@rep[:track]
|
34
34
|
end
|
35
35
|
|
36
36
|
def exhibition?
|
@@ -100,10 +100,10 @@ module SciolyFF
|
|
100
100
|
|
101
101
|
private
|
102
102
|
|
103
|
-
def
|
104
|
-
return @
|
103
|
+
def link_to_team_in_track_interpreter(interpreter)
|
104
|
+
return @track_team = nil unless (sub = track)
|
105
105
|
|
106
|
-
@
|
106
|
+
@track_team = interpreter.tracks[sub].teams.find do |t|
|
107
107
|
t.number == number
|
108
108
|
end
|
109
109
|
end
|
@@ -15,10 +15,10 @@ module SciolyFF
|
|
15
15
|
@teams = interpreter.teams
|
16
16
|
@placings = interpreter.placings
|
17
17
|
@penalties = interpreter.penalties
|
18
|
-
@
|
18
|
+
@tracks = interpreter.tracks
|
19
19
|
end
|
20
20
|
|
21
|
-
attr_reader :events, :teams, :placings, :penalties, :
|
21
|
+
attr_reader :events, :teams, :placings, :penalties, :tracks
|
22
22
|
|
23
23
|
undef tournament
|
24
24
|
|
@@ -171,8 +171,8 @@ module SciolyFF
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
def
|
175
|
-
!@
|
174
|
+
def tracks?
|
175
|
+
!@tracks.empty?
|
176
176
|
end
|
177
177
|
|
178
178
|
def nonexhibition_teams_count
|
@@ -1,37 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SciolyFF
|
4
|
-
#
|
5
|
-
module Interpreter::
|
4
|
+
# Track logic, to be used in the Interpreter class
|
5
|
+
module Interpreter::Tracks
|
6
6
|
private
|
7
7
|
|
8
|
-
def
|
8
|
+
def track_rep(sub)
|
9
9
|
# make a deep copy of rep
|
10
10
|
rep = Marshal.load(Marshal.dump(@rep))
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
remove_teams_not_in_track(rep, sub)
|
13
|
+
fix_track_tournament_fields(rep, sub)
|
14
14
|
limit_maximum_place(rep)
|
15
15
|
fix_placings_for_existing_teams(rep) unless raws?
|
16
16
|
rep
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
rep[:Teams].select! { |t| t.delete(:
|
19
|
+
def remove_teams_not_in_track(rep, sub)
|
20
|
+
rep[:Teams].select! { |t| t.delete(:track) == sub }
|
21
21
|
|
22
22
|
team_numbers = rep[:Teams].map { |t| t[:number] }
|
23
23
|
rep[:Placings].select! { |p| team_numbers.include? p[:team] }
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def fix_track_tournament_fields(rep, sub)
|
27
27
|
tournament_rep = rep[:Tournament]
|
28
|
-
sub_rep = rep[:
|
28
|
+
sub_rep = rep[:Tracks].find { |s| s[:name] == sub }
|
29
29
|
|
30
30
|
replace_tournament_fields(tournament_rep, sub_rep)
|
31
31
|
|
32
32
|
tournament_rep.delete(:bids)
|
33
33
|
tournament_rep.delete(:'bids per school')
|
34
|
-
rep.delete(:
|
34
|
+
rep.delete(:Tracks)
|
35
35
|
end
|
36
36
|
|
37
37
|
def replace_tournament_fields(tournament_rep, sub_rep)
|
data/lib/sciolyff/validator.rb
CHANGED
@@ -10,7 +10,7 @@ module SciolyFF
|
|
10
10
|
|
11
11
|
require 'sciolyff/validator/top_level'
|
12
12
|
require 'sciolyff/validator/tournament'
|
13
|
-
require 'sciolyff/validator/
|
13
|
+
require 'sciolyff/validator/tracks'
|
14
14
|
require 'sciolyff/validator/events'
|
15
15
|
require 'sciolyff/validator/teams'
|
16
16
|
require 'sciolyff/validator/placings'
|
@@ -65,7 +65,7 @@ module SciolyFF
|
|
65
65
|
def check_all(rep, logger)
|
66
66
|
check(TopLevel, rep, rep, logger) &&
|
67
67
|
check(Tournament, rep, rep[:Tournament], logger) &&
|
68
|
-
[
|
68
|
+
[Tracks, Events, Teams, Placings, Penalties].all? do |klass|
|
69
69
|
check_list(klass, rep, logger)
|
70
70
|
end &&
|
71
71
|
rep[:Placings].map { |p| p[:raw] }.compact.all? do |r|
|
@@ -17,7 +17,7 @@ module SciolyFF
|
|
17
17
|
|
18
18
|
OPTIONAL = {
|
19
19
|
'school abbreviation': String,
|
20
|
-
|
20
|
+
track: String,
|
21
21
|
suffix: String,
|
22
22
|
city: String,
|
23
23
|
disqualified: [true, false],
|
@@ -26,7 +26,7 @@ module SciolyFF
|
|
26
26
|
|
27
27
|
def initialize(rep)
|
28
28
|
initialize_teams_info(rep[:Teams])
|
29
|
-
@
|
29
|
+
@tracks = rep[:Tracks]&.map { |s| s[:name] } || []
|
30
30
|
@placings = rep[:Placings].group_by { |p| p[:team] }
|
31
31
|
@exempt = rep[:Tournament][:'exempt placings'] || 0
|
32
32
|
end
|
@@ -74,18 +74,18 @@ module SciolyFF
|
|
74
74
|
"exempt placings (#{count} insteand of #{@exempt})"
|
75
75
|
end
|
76
76
|
|
77
|
-
def
|
78
|
-
sub = team[:
|
79
|
-
return true if sub.nil? || @
|
77
|
+
def matching_track?(team, logger)
|
78
|
+
sub = team[:track]
|
79
|
+
return true if sub.nil? || @tracks.include?(sub)
|
80
80
|
|
81
|
-
logger.error "'
|
82
|
-
'section
|
81
|
+
logger.error "'track: #{sub}' does not match any name in "\
|
82
|
+
'section Tracks'
|
83
83
|
end
|
84
84
|
|
85
|
-
def
|
86
|
-
return true unless !@
|
85
|
+
def in_a_track_if_possible?(team, logger)
|
86
|
+
return true unless !@tracks.empty? && !team[:track]
|
87
87
|
|
88
|
-
logger.warn "missing
|
88
|
+
logger.warn "missing track for 'team: #{team[:number]}'"
|
89
89
|
end
|
90
90
|
|
91
91
|
include Validator::Canonical
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sciolyff/validator/checker'
|
4
|
+
require 'sciolyff/validator/sections'
|
5
|
+
require 'sciolyff/validator/range'
|
6
|
+
|
7
|
+
module SciolyFF
|
8
|
+
# Checks for one track in the Tracks section of a SciolyFF file
|
9
|
+
class Validator::Tracks < Validator::Checker
|
10
|
+
include Validator::Sections
|
11
|
+
|
12
|
+
REQUIRED = {
|
13
|
+
name: String
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
OPTIONAL = {
|
17
|
+
medals: Integer,
|
18
|
+
trophies: Integer,
|
19
|
+
'maximum place': Integer
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
def initialize(rep)
|
23
|
+
@names = rep[:Tracks].map { |s| s[:name] }
|
24
|
+
@teams = rep[:Teams].group_by { |t| t[:track] }
|
25
|
+
end
|
26
|
+
|
27
|
+
def unique_name?(track, logger)
|
28
|
+
return true if @names.count(track[:name]) == 1
|
29
|
+
|
30
|
+
logger.error "duplicate track name: #{track[:name]}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def matching_teams?(track, logger)
|
34
|
+
name = track[:name]
|
35
|
+
return true if @teams[name]
|
36
|
+
|
37
|
+
logger.error "track with 'name: #{name}' has no teams"
|
38
|
+
end
|
39
|
+
|
40
|
+
include Validator::Range
|
41
|
+
|
42
|
+
def maximum_place_within_range?(track, logger)
|
43
|
+
max = team_count(track)
|
44
|
+
within_range?(track, :'maximum place', logger, 1, max)
|
45
|
+
end
|
46
|
+
|
47
|
+
def medals_within_range?(track, logger)
|
48
|
+
max = [team_count(track), track[:'maximum place']].compact.min
|
49
|
+
within_range?(track, :medals, logger, 1, max)
|
50
|
+
end
|
51
|
+
|
52
|
+
def trophies_within_range?(track, logger)
|
53
|
+
within_range?(track, :trophies, logger, 1, team_count(track))
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def team_count(track)
|
59
|
+
@teams[track[:name]].count do |t|
|
60
|
+
t[:track] == track[:name] && !t[:exhibition]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/sciolyff.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.license = 'MIT'
|
10
10
|
s.name = 'sciolyff-duosmium'
|
11
11
|
s.summary = 'A file format for Science Olympiad tournament results.'
|
12
|
-
s.version = '0.13.
|
12
|
+
s.version = '0.13.1'
|
13
13
|
s.executables << 'sciolyff'
|
14
14
|
s.add_runtime_dependency 'erubi', '~> 1.9'
|
15
15
|
s.add_runtime_dependency 'optimist', '~> 3.0'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sciolyff-duosmium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.13.
|
4
|
+
version: 0.13.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Em Zhan
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-01-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: erubi
|
@@ -76,10 +76,10 @@ files:
|
|
76
76
|
- lib/sciolyff/interpreter/penalty.rb
|
77
77
|
- lib/sciolyff/interpreter/placing.rb
|
78
78
|
- lib/sciolyff/interpreter/raw.rb
|
79
|
-
- lib/sciolyff/interpreter/subdivisions.rb
|
80
79
|
- lib/sciolyff/interpreter/team.rb
|
81
80
|
- lib/sciolyff/interpreter/tiebreaks.rb
|
82
81
|
- lib/sciolyff/interpreter/tournament.rb
|
82
|
+
- lib/sciolyff/interpreter/tracks.rb
|
83
83
|
- lib/sciolyff/validator.rb
|
84
84
|
- lib/sciolyff/validator/canonical.rb
|
85
85
|
- lib/sciolyff/validator/checker.rb
|
@@ -90,10 +90,10 @@ files:
|
|
90
90
|
- lib/sciolyff/validator/range.rb
|
91
91
|
- lib/sciolyff/validator/raws.rb
|
92
92
|
- lib/sciolyff/validator/sections.rb
|
93
|
-
- lib/sciolyff/validator/subdivisions.rb
|
94
93
|
- lib/sciolyff/validator/teams.rb
|
95
94
|
- lib/sciolyff/validator/top_level.rb
|
96
95
|
- lib/sciolyff/validator/tournament.rb
|
96
|
+
- lib/sciolyff/validator/tracks.rb
|
97
97
|
- sciolyff.gemspec
|
98
98
|
homepage: https://github.com/duosmium/sciolyff
|
99
99
|
licenses:
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'sciolyff/validator/checker'
|
4
|
-
require 'sciolyff/validator/sections'
|
5
|
-
require 'sciolyff/validator/range'
|
6
|
-
|
7
|
-
module SciolyFF
|
8
|
-
# Checks for one subdivision in the Subdivisions section of a SciolyFF file
|
9
|
-
class Validator::Subdivisions < Validator::Checker
|
10
|
-
include Validator::Sections
|
11
|
-
|
12
|
-
REQUIRED = {
|
13
|
-
name: String
|
14
|
-
}.freeze
|
15
|
-
|
16
|
-
OPTIONAL = {
|
17
|
-
medals: Integer,
|
18
|
-
trophies: Integer,
|
19
|
-
'maximum place': Integer
|
20
|
-
}.freeze
|
21
|
-
|
22
|
-
def initialize(rep)
|
23
|
-
@names = rep[:Subdivisions].map { |s| s[:name] }
|
24
|
-
@teams = rep[:Teams].group_by { |t| t[:subdivision] }
|
25
|
-
end
|
26
|
-
|
27
|
-
def unique_name?(subdivision, logger)
|
28
|
-
return true if @names.count(subdivision[:name]) == 1
|
29
|
-
|
30
|
-
logger.error "duplicate subdivision name: #{subdivision[:name]}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def matching_teams?(subdivision, logger)
|
34
|
-
name = subdivision[:name]
|
35
|
-
return true if @teams[name]
|
36
|
-
|
37
|
-
logger.error "subdivision with 'name: #{name}' has no teams"
|
38
|
-
end
|
39
|
-
|
40
|
-
include Validator::Range
|
41
|
-
|
42
|
-
def maximum_place_within_range?(subdivision, logger)
|
43
|
-
max = team_count(subdivision)
|
44
|
-
within_range?(subdivision, :'maximum place', logger, 1, max)
|
45
|
-
end
|
46
|
-
|
47
|
-
def medals_within_range?(subdivision, logger)
|
48
|
-
max = [team_count(subdivision), subdivision[:'maximum place']].compact.min
|
49
|
-
within_range?(subdivision, :medals, logger, 1, max)
|
50
|
-
end
|
51
|
-
|
52
|
-
def trophies_within_range?(subdivision, logger)
|
53
|
-
within_range?(subdivision, :trophies, logger, 1, team_count(subdivision))
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def team_count(subdivision)
|
59
|
-
@teams[subdivision[:name]].count do |t|
|
60
|
-
t[:subdivision] == subdivision[:name] && !t[:exhibition]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|