refactored for team play

main
Ugo Finnendahl 1 week ago
parent 0dc5eb5226
commit 6d0654ac14
  1. 216
      assets/css/src/style.scss
  2. 2
      assets/css/style.min.css
  3. 4
      assets/js/components/init.js
  4. 3
      assets/js/components/list.js
  5. 40
      assets/js/components/scorerElem.js
  6. 14
      assets/js/components/select.js
  7. 36
      assets/js/components/teamElem.js
  8. 17
      assets/js/views/home.js
  9. 514
      assets/js/views/xoi/logic.js
  10. 308
      assets/js/views/xoi/main.js
  11. 6
      content/1_members/18_todo3/member.txt
  12. 2
      content/1_members/24_230/member.txt
  13. 6
      content/2_seasons/1_2024/1_summer-slam/54kd4kbk/xoi.txt
  14. 6
      content/2_seasons/1_2024/1_summer-slam/7nykca7i/xoi.txt
  15. 6
      content/2_seasons/1_2024/1_summer-slam/her1fj3r/xoi.txt
  16. 7
      content/2_seasons/1_2024/1_summer-slam/jm4ju7pi/xoi.txt
  17. 7
      content/2_seasons/1_2024/1_summer-slam/l0j8jkts/xoi.txt
  18. 7
      content/2_seasons/1_2024/1_summer-slam/lsng5wlg/xoi.txt
  19. 7
      content/2_seasons/1_2024/1_summer-slam/m7tb5bac/xoi.txt
  20. 7
      content/2_seasons/1_2024/1_summer-slam/mxkfs1yq/xoi.txt
  21. 7
      content/2_seasons/1_2024/1_summer-slam/osbkse46/xoi.txt
  22. 7
      content/2_seasons/1_2024/1_summer-slam/rtjuyvsv/xoi.txt
  23. 0
      content/2_seasons/1_2024/1_summer-slam/tnmbrackets.txt
  24. 7
      content/2_seasons/1_2024/1_summer-slam/z7nvffvf/xoi.txt
  25. 7
      content/2_seasons/1_2024/2_spring-break/13tntlfj/xoi.txt
  26. 7
      content/2_seasons/1_2024/2_spring-break/3flmnq6b/xoi.txt
  27. 7
      content/2_seasons/1_2024/2_spring-break/cbwvnzxm/xoi.txt
  28. 7
      content/2_seasons/1_2024/2_spring-break/cutywjod/xoi.txt
  29. 7
      content/2_seasons/1_2024/2_spring-break/kkchbr4a/xoi.txt
  30. 7
      content/2_seasons/1_2024/2_spring-break/ovcmf1c0/xoi.txt
  31. 7
      content/2_seasons/1_2024/2_spring-break/sbggpar6/xoi.txt
  32. 0
      content/2_seasons/1_2024/2_spring-break/tnmbrackets.txt
  33. 7
      content/2_seasons/1_2024/2_spring-break/utbpew7l/xoi.txt
  34. 7
      content/2_seasons/1_2024/2_spring-break/zxlkihnz/xoi.txt
  35. 7
      content/2_seasons/1_2024/3_wm/1_1-runde/xoi.txt
  36. 7
      content/2_seasons/1_2024/3_wm/2_2-runde/xoi.txt
  37. 7
      content/2_seasons/1_2024/3_wm/3_3-runde/xoi.txt
  38. 0
      content/2_seasons/1_2024/3_wm/tnmbrackets.txt
  39. 6
      content/2_seasons/1_2024/4_liga/0tdcwlko/xoi.txt
  40. 6
      content/2_seasons/1_2024/4_liga/1csevwpm/xoi.txt
  41. 6
      content/2_seasons/1_2024/4_liga/4jujnos9/xoi.txt
  42. 6
      content/2_seasons/1_2024/4_liga/5s62p5jp/xoi.txt
  43. 41
      content/2_seasons/1_2024/4_liga/_drafts/template/xoi.txt
  44. 6
      content/2_seasons/1_2024/4_liga/a4iulyd5/xoi.txt
  45. 6
      content/2_seasons/1_2024/4_liga/a9z1tmvh/xoi.txt
  46. 6
      content/2_seasons/1_2024/4_liga/anobo58l/xoi.txt
  47. 7
      content/2_seasons/1_2024/4_liga/as5ijioi/xoi.txt
  48. 7
      content/2_seasons/1_2024/4_liga/bx8cct6r/xoi.txt
  49. 7
      content/2_seasons/1_2024/4_liga/cien2e5y/xoi.txt
  50. 7
      content/2_seasons/1_2024/4_liga/cqeaezmg/xoi.txt
  51. 7
      content/2_seasons/1_2024/4_liga/eiwqlmue/xoi.txt
  52. 7
      content/2_seasons/1_2024/4_liga/eqwdsia4/xoi.txt
  53. 7
      content/2_seasons/1_2024/4_liga/exgzkzyy/xoi.txt
  54. 7
      content/2_seasons/1_2024/4_liga/gcysu6ge/xoi.txt
  55. 7
      content/2_seasons/1_2024/4_liga/gp3pj38u/xoi.txt
  56. 7
      content/2_seasons/1_2024/4_liga/iat8cs7j/xoi.txt
  57. 7
      content/2_seasons/1_2024/4_liga/ix1srhrk/xoi.txt
  58. 7
      content/2_seasons/1_2024/4_liga/jajnvwbu/xoi.txt
  59. 7
      content/2_seasons/1_2024/4_liga/kdcqpxs1/xoi.txt
  60. 7
      content/2_seasons/1_2024/4_liga/lziuhybw/xoi.txt
  61. 7
      content/2_seasons/1_2024/4_liga/mcjcgkbg/xoi.txt
  62. 7
      content/2_seasons/1_2024/4_liga/olf1bjdm/xoi.txt
  63. 7
      content/2_seasons/1_2024/4_liga/ovasmz7s/xoi.txt
  64. 7
      content/2_seasons/1_2024/4_liga/rxwuanez/xoi.txt
  65. 7
      content/2_seasons/1_2024/4_liga/sfln9xej/xoi.txt
  66. 7
      content/2_seasons/1_2024/4_liga/sgl9kqvo/xoi.txt
  67. 7
      content/2_seasons/1_2024/4_liga/tk69oajx/xoi.txt
  68. 0
      content/2_seasons/1_2024/4_liga/tnmfreeforall.txt
  69. 7
      content/2_seasons/1_2024/4_liga/u3wssk4j/xoi.txt
  70. 7
      content/2_seasons/1_2024/4_liga/uslfpwja/xoi.txt
  71. 7
      content/2_seasons/1_2024/4_liga/ut3juonn/xoi.txt
  72. 7
      content/2_seasons/1_2024/4_liga/vmxmfxxs/xoi.txt
  73. 7
      content/2_seasons/1_2024/4_liga/wksontke/xoi.txt
  74. 7
      content/2_seasons/1_2024/4_liga/wovzm0jh/xoi.txt
  75. 7
      content/2_seasons/1_2024/4_liga/wuhzwter/xoi.txt
  76. 7
      content/2_seasons/1_2024/4_liga/xdadumtb/xoi.txt
  77. 7
      content/2_seasons/1_2024/4_liga/ypt4e90v/xoi.txt
  78. 7
      content/2_seasons/1_2024/4_liga/yw8a9zsz/xoi.txt
  79. 7
      content/2_seasons/1_2024/4_liga/zavij0ox/xoi.txt
  80. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/256lip8t/xoi.txt
  81. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/cvmylohu/xoi.txt
  82. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/hkz96vt7/xoi.txt
  83. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/ihap3lgd/xoi.txt
  84. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/bux8rpm6/xoi.txt
  85. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/ce4fqjwm/xoi.txt
  86. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/guuanotg/xoi.txt
  87. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/ivwhmdoe/xoi.txt
  88. 6
      content/2_seasons/1_2024/5_autumn-grand-prix/jfyjddui/xoi.txt
  89. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/jzc8jx4x/xoi.txt
  90. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/miuxwlp4/xoi.txt
  91. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/ngdfd5sd/xoi.txt
  92. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/pnyxwihz/xoi.txt
  93. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/q42hp0bn/xoi.txt
  94. 0
      content/2_seasons/1_2024/5_autumn-grand-prix/tnmbrackets.txt
  95. 7
      content/2_seasons/1_2024/5_autumn-grand-prix/yrb4yey6/xoi.txt
  96. 42
      content/2_seasons/1_2024/6_christmas/tnmteambrackets.txt
  97. 2
      content/2_seasons/1_2024/season.txt
  98. 2
      content/3_templates/_drafts/dido301/xoi.txt
  99. 2
      content/3_templates/_drafts/dodo501bof6/xoi.txt
  100. 2
      content/3_templates/_drafts/dodo501bof7/xoi.txt
  101. Some files were not shown because too many files have changed in this diff Show More

@ -12,8 +12,8 @@ $bgcolor: #2f6f2a;
$line: 0.2rem;
@mixin border {
border-radius: 0.25em;
border: 0.3em black solid;
border-radius: 0.5rem;
border: 0.3rem black solid;
}
@mixin button {
@ -193,49 +193,12 @@ h1,h2,h3,h4,h5,h6{
}
}
body.home{
header{
display: flex;
justify-content: center;
align-items: center;
height: 42%;
&>img{
display: block;
width: 50%;
height: auto;
}
}
h1{
text-align: center;
color: white;
font-size: 2.6rem;
text-shadow: $shadow;
}
.menu{
flex-grow: 1;
display: flex;
align-items: center;
padding-bottom: 7.5rem;
.mainmenu{
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
h1{
margin-bottom: 1em;
}
}
}
}
nav.list{
display: flex;
justify-content: center;
flex-grow: 1;
width: 100%;
&.horizontal{
flex-direction: row;
@ -257,12 +220,12 @@ nav.list{
// Elements
////////////////////////////////////////////////////////////////////////////////
.element{
@include border;
border-width: 0.3rem;
background-color: $bg;
cursor: pointer;
box-shadow: 0.25rem 0.25rem 1rem rgba(0,0,0, 0.3);
&:focus, &:hover{
outline: none;
@ -283,6 +246,7 @@ nav.list{
justify-content: flex-start;
align-items: center;
padding: 0.7em;
height: 4.5em;
h2{
font-size: 1.3em;
@ -300,13 +264,48 @@ nav.list{
}
}
&.scorer{
@include button-text;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.7em;
height: 4.5em;
.player{
display: flex;
justify-content: flex-start;
align-items: center;
min-width: 0;
flex-basis: 0;
flex-grow: 1;
text-align: left;
h2{
font-size: 1.3em;
}
&>*{
margin-right: 1em;
}
img{
height: 3em;
aspect-ratio: 1/1;
object-position: top;
object-fit: cover;
}
}
}
&.plain{
@include button-text;
padding: 1rem 2rem;
justify-content: center;
align-items: center;
box-shadow: 0.25rem 0.25rem 1rem rgba(0,0,0, 0.3);
font-size: 1.6em;
&:hover,&:focus{
background-color: rgba(0, 0, 0, 0.2);
border-color: $orange;
@ -319,9 +318,7 @@ nav.list{
background-color: darken($bg, 5%);
}
}
&.player {
height: 4.5em;
}
&.square{
font-size: 1rem;
width: 20em;
@ -365,9 +362,52 @@ nav.list{
}
}
////////////////////////////////////////////////////////////////////////////////
// Home
////////////////////////////////////////////////////////////////////////////////
body.home{
header{
display: flex;
justify-content: center;
align-items: center;
height: 42%;
&>img{
display: block;
width: 50%;
height: auto;
}
}
h1{
text-align: center;
color: white;
font-size: 2.6rem;
text-shadow: $shadow;
}
.menu{
flex-grow: 1;
display: flex;
align-items: center;
padding-bottom: 7.5rem;
.mainmenu{
width: 60%;
margin: 0 auto;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
h1{
margin-bottom: 1em;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Game Setup
// Game
////////////////////////////////////////////////////////////////////////////////
body.xoi{
@ -402,8 +442,8 @@ body.xoi{
grid-template-columns: 3fr 3fr 2fr 3fr 3fr;
grid-template-rows: 11.5rem 52rem 4rem;
grid-template-areas:
"player1 toGo1 score toGo2 player2"
"player1 game game game player2"
"scorer1 toGo1 score toGo2 scorer2"
"scorer1 game game game scorer2"
"navi navi navi navi navi"
;
background-color: black;
@ -460,19 +500,77 @@ body.xoi{
}
.player{
background-color: $bgcolor;
margin-bottom: $line/2;
margin-bottom: calc($line/2);
&.team{
$anim: 0.3s linear;
.images{
position: relative;
left: 0;
top: 0;
width: 100%;
padding-bottom: 128.5714286%;
background-color: #737373;
img{
transform: translate(24%,0) scale(0.42);
position: absolute;
left: 0;
top: 0;
transition: transform $anim, box-shadow $anim, z-index $anim;
z-index: 10;
box-shadow: 0.6rem 0.6rem 0.6rem rgba(0, 0, 0, 0.4);
}
img:nth-child(1){
transform: translate(-24%,0) scale(0.42);
}
img:nth-child(1).inactive{
transform: translate(-25%,25%) scale(0.35);
}
img.inactive{
transform: translate(25%,25%) scale(0.35);
}
img.active{
box-shadow: 0rem 0rem 0rem #000;
transform: scale(1);
z-index: 1;
}
}
.titles{
display: grid;
& > *{
grid-column: 1;
grid-row: 1;
}
.title{
display: flex;
flex-direction: column;
justify-content: center;
h2, h3{
opacity: 0;
}
&.active{
h2, h3{
transition: opacity $anim;
opacity: 1;
}
}
}
}
}
&.player1{
grid-area: player1;
&.scorer1{
grid-area: scorer1;
}
&.player2{
grid-area: player2;
&.scorer2{
grid-area: scorer2;
}
img{
width: 100%;
aspect-ratio: 35/45;
object-fit: cover;
}
h2, h3{
text-align: center;
margin: 0.2em;
@ -524,8 +622,6 @@ body.xoi{
background: white;
color: black;
margin: 0 0 $line $line;
width: calc(100% - $line);
height: calc(100% - $line);
border: 0.15em transparent solid;
display: flex;
justify-content: center;
@ -541,17 +637,17 @@ body.xoi{
color: white;
text-shadow: $text-shadow;
}
&.player1.points{
&.scorer1.points{
grid-column: 1;
}
&.player1.toGo{
&.scorer1.toGo{
grid-column: 2;
font-size: 1.6rem;
}
&.player2.points{
&.scorer2.points{
grid-column: 4;
}
&.player2.toGo{
&.scorer2.toGo{
grid-column: 5;
margin-right: $line;
// width: calc(100% - 2*$line);
@ -586,7 +682,7 @@ body.xoi{
.nav{
grid-area: navi;
background-color: $bgcolor;
margin-top: $line/2;
margin-top: calc($line/2);
display: flex;
justify-content: space-evenly;
align-items: center;

File diff suppressed because one or more lines are too long

@ -1,11 +1,11 @@
import list from "./list.js";
import playerElem from "./playerElem.js";
import scorerElem from "./scorerElem.js";
import plainElem from "./plainElem.js";
import squareElem from "./squareElem.js";
import inputElem from "./inputElem.js";
import playerSelect from "./playerSelect.js";
import select from "./select.js";
// import overlay from "./overlay.js";
import dialog from "./dialog.js";
@ -14,11 +14,11 @@ export default (app) => {
app.component("d-list", list);
app.component("d-playerElem", playerElem);
app.component("d-scorerElem", scorerElem);
app.component("d-plainElem", plainElem);
app.component("d-squareElem", squareElem);
app.component("d-inputElem", inputElem);
app.component("d-select", select);
app.component("d-playerSelect", playerSelect);
app.component("d-dialog", dialog);
}

@ -4,11 +4,12 @@ import { getId } from "../handlers.js";
const html = (v) => { return v[0] };
export default {
props: ['elements', 'type', "withshortkey"],
props: ['elements', 'title', 'type', "withshortkey"],
setup(props) {
return { }
},
template: html`
<h2 v-if="!!title">{{ title }}</h2>
<nav class="list" :class="{ horizontal: type == 'horizontal', vertical: type != 'horizontal'}">
<component :is="item.component" v-for="(item, index) in elements" v-index :withshortkey="withshortkey" @click="item.onClick" v-bind="item.props">
</component>

@ -0,0 +1,40 @@
import { onMounted, ref, computed, watch, nextTick } from "vue";
const html = (v) => { return v[0] };
export default {
props: ['scorer', 'id'],
setup(props) {
return { }
},
template: html`
<div class="scorer element">
<div class="player" v-if="scorer === undefined">
<h2 class="name">No Player</h2>
<h3 class="nickname">&nbsp;</h3>
</div>
<div class="player" v-if="scorer !== undefined">
<template v-if="scorer.member[0] !== undefined">
<img :src="scorer.member[0].img ? scorer.member[0].img : '/assets/img/placeholder_person.png'">
<h2 class="name">{{ scorer.member[0].forename }} {{ scorer.member[0].surname }}</h2>
<!-- <h3 class="nickname">{{ scorer.member[0].nickname }}</h3> -->
</template>
<template v-if="scorer.member[0] === undefined">
<h2 class="name">No Player</h2>
<h3 class="nickname">&nbsp;</h3>
</template>
</div>
<div class="player" v-if="scorer !== undefined && scorer.member[1] !== undefined">
<template v-if="scorer.member[1] !== undefined">
<img :src="scorer.member[1].img ? scorer.member[1].img : '/assets/img/placeholder_person.png'">
<h2 class="name">{{ scorer.member[1].forename }} {{ scorer.member[1].surname }}</h2>
<!-- <h3 class="nickname">{{ scorer.member[1].nickname }}</h3> -->
</template>
<template v-if="scorer.member[1] === undefined">
<h2 class="name">No Player</h2>
<h3 class="nickname">&nbsp;</h3>
</template>
</div>
</div>
`
}

@ -3,15 +3,21 @@ import { handleActive, ArrowVerticalKeyHandler, ArrowHorizontalKeyHandler, Numbe
const html = (v) => { return v[0] };
const mappings = {
"player": ["d-playerElem", (p) => {return {"player": p} }],
"scorer": ["d-scorerElem", (p) => {return {"scorer": p} }],
"plain": ["d-plainElem", (p) => {return {"text": p} }],
}
export default {
props: ['options', 'title', 'stack', 'active', 'input'],
props: ['options', 'type', 'title', 'stack', 'active', 'input'],
setup(props, context) {
handleActive(props, [ArrowVerticalKeyHandler]);
handleActive(props, [ArrowVerticalKeyHandler, NumberKeyHandler]);
const children = computed(() => {
return props.options.map((o) => {
return {
component: "d-plainElem",
props: {"text": o},
component: props.type ? mappings[props.type][0] : "d-plainElem",
props: props.type ? mappings[props.type][1](o) : {"text": o},
onClick: () => {
context.emit('resolve', o);
}

@ -0,0 +1,36 @@
import { onMounted, ref, computed, watch, nextTick } from "vue";
const html = (v) => { return v[0] };
export default {
props: ['team', 'id'],
setup(props) {
return { }
},
template: html`
<div class="team element">
<div class="player">
<template v-if="team.member[0] !== undefined">
<img :src="team.member[0].img ? team.member[0].img : '/assets/img/placeholder_person.png'">
<h2 class="name">{{ team.member[0].forename }} {{ team.member[0].surname }}</h2>
<!-- <h3 class="nickname">{{ team.member[0].nickname }}</h3> -->
</template>
<template v-if="team.member[0] === undefined">
<h2 class="name">No Player</h2>
<h3 class="nickname">&nbsp;</h3>
</template>
</div>
<div class="player">
<template v-if="team.member[1] !== undefined">
<img :src="team.member[1].img ? team.member[1].img : '/assets/img/placeholder_person.png'">
<h2 class="name">{{ team.member[1].forename }} {{ team.member[1].surname }}</h2>
<!-- <h3 class="nickname">{{ team.member[1].nickname }}</h3> -->
</template>
<template v-if="team.member[1] === undefined">
<h2 class="name">No Player</h2>
<h3 class="nickname">&nbsp;</h3>
</template>
</div>
</div>
`
}

@ -100,7 +100,7 @@ export const selectGame = {
items.push({
component: "d-plainElem",
props: {
text: game.player[0]?.forename + " vs. " + game.player[1]?.forename,
text: game.scorers[0]?.member[0]?.forename + " vs. " + game.scorers[1]?.member[0]?.forename,
},
onClick: () => {
emit("resolve", game.id);
@ -164,15 +164,24 @@ const stateMachine = (stack) => {
return [2, result];
},
2: async (input, reGet) => {
const playerInfo = {
forename: "page.forename",
surname: "page.surname",
uuid: "page.uuid",
// img: "page.pic.toFile?.thumbnail(350).url"
};
const games = await getQuery(`site.find('${input}').getRunningGames`, {
select: {
title: "page.title",
id: "page.id",
uuid: "page.uuid",
player: {
query: "page.players.toPages",
scorers: {
query: "page.scorers.toStructure",
select: {
forename: "page.forename"
member: {
query: "structureItem.member.toPages",
select: playerInfo
}
}
}
}

@ -1,5 +1,9 @@
import { computed } from "vue";
/////////////////////////////////////////
// Helper
/////////////////////////////////////////
function setPoints(page, set){
let points = [0, 0]; // need to get updated for more player
let ret;
@ -40,157 +44,6 @@ function legPoints(page, set, leg){
return points;
}
export const getFinalWinner = (page) => {
const points = setPoints(page, page.sets[page.sets.length-1]);
return getWinner(points, page.sets);
};
export function getGameProps(page, current_set, current_leg) {
const ret = {};
if (current_set === undefined) {
current_set = computed(() => {
if (page.game != undefined) {
return page.game.sets[page.game.sets.length - 1]
}
return undefined;
});
}
ret.current_set = current_set;
if (current_leg === undefined) {
current_leg = computed(() => {
if (current_set.value != undefined) {
return current_set.value.legs[current_set.value.legs.length - 1]
}
return undefined;
});
}
ret.current_leg = current_leg;
const current_toGo = computed(() => {
if (current_leg.value != undefined) {
if (current_leg.value.visits.length < 2) {
return [page.modus, page.modus]
} else {
const end = current_leg.value.visits[current_leg.value.visits.length - 1].toGo;
if (end) return end;
return current_leg.value.visits[current_leg.value.visits.length - 2].toGo;
}
}
return [0, 0]; // need to get updated for more player
});
ret.current_toGo = current_toGo;
const current_set_points = computed(() => {
if (current_set.value != undefined) {
return setPoints(page, current_set.value);
}
return undefined;
});
ret.current_set_points = current_set_points;
const current_leg_points = computed(() => {
if (current_set.value != undefined || current_leg.value != undefined) {
return legPoints(page, current_set.value, current_leg.value);
}
return undefined;
});
ret.current_leg_points = current_leg_points;
const current_player = computed(() => {
if (current_leg.value != undefined) {
const len = current_leg.value.visits.length;
return current_leg.value.visits[len - 1].player == page.players[1].uuid;
}
return undefined;
});
ret.current_player = current_player;
const breaks = computed(() => {
let b = [0,0];
for (const j in page.game.sets) {
const set = page.game.sets[j];
for (const i in set.legs) {
const l = set.legs[i];
if (l.visits[l.visits.length-1].toGo === undefined) {
return b;
}
if (l.visits[l.visits.length-1].toGo[0] == 0 && i%2 == 1)
b[0] += 1;
else if (l.visits[l.visits.length-1].toGo[1] == 0 && i%2 == 0)
b[1] += 1;
}
}
return b;
});
ret.breaks = breaks;
const getVal = (tr) => {
const val = tr.trim();
if (val == "") {
return 0;
}
if (val == "SB") {
return 25;
}
if (val == "DB") {
return 50;
}
if (val[0] == "S" || val[0] == "O" || val[0] == "I") {
return parseFloat(val.substring(1));
}
if (val[0] == "D") {
return 2 * parseFloat(val.substring(1));
}
if (val[0] == "T") {
return 3 * parseFloat(val.substring(1));
}
if (val[0] == "M") {
return 0;
} else {
// TODO: Check for Na
return parseFloat(val);
}
}
const verifySum = (sum) => {
if (sum > 180 || [179, 178, 176, 175, 173, 172, 169, 166, 163].indexOf(sum) > -1) {
return -1;
} else if (current_toGo.value[current_player.value * 1] - sum < 0) {
return -2;
} if (current_toGo.value[current_player.value * 1] - sum == 0) {
// bogey numbers
if (page.out == "Double" && (sum > 170 || [169, 168, 166, 165, 163, 162, 159].indexOf(sum) > -1)) {
return -1;
}
return 0;
} else if (current_toGo.value[current_player.value * 1] - sum <= 50) {
return 1;
} else if (page.in != "Straight" && current_toGo.value[current_player.value * 1] == page.modus && sum != 0) {
return 3;
}
return 2;
}
const checkVisit = (throws) => {
const tr = throws.split(",");
let sum = 0;
tr.forEach((t, i) => {
sum += getVal(t);
});
const res = verifySum(sum);
return [res, sum];
}
ret.checkVisit = checkVisit;
return ret;
}
function newPlayerStats(player) {
return {
player: player.uuid,
@ -207,36 +60,30 @@ function newPlayerStats(player) {
};
}
function addNewSetStats(stats, players) {
stats["sets"].push(newStats(players));
function addNewSetStats(stats, scorers) {
stats["sets"].push(newStats(scorers));
stats["sets"][0]["legs"] = [];
return stats;
}
function addNewLegStats(stats, players) {
stats["sets"].at(-1)["legs"].push(newStats(players));
function addNewLegStats(stats, scorers) {
stats["sets"].at(-1)["legs"].push(newStats(scorers));
return stats;
}
function newStats(players) {
function newStats(scorers) {
const stats = {
stats: []
}
players.forEach((player, i) => {
scorers.forEach((scorer) => {
scorer.member.forEach((player) => {
const n = newPlayerStats(player);
stats.stats.push(n);
});
});
return stats;
}
export function initStats(page) {
const stats = newStats(page.players);
stats.sets = [];
addNewSetStats(stats, page.players);
addNewLegStats(stats, page.players);
page.stats = stats;
}
function newVisit(playerUUID, round) {
return {
player: playerUUID,
@ -245,23 +92,101 @@ function newVisit(playerUUID, round) {
checkoutTries: 0,
checkinTries: 0,
numDarts: 0,
}
}
function clearLastVisit(page){
const set = page.game.sets[page.game.sets.length-1];
const leg = set.legs[set.legs.length-1];
const visit = leg.visits[leg.visits.length-1];
const ret = visit["throws"];
visit["throws"] = [];
visit["checkoutTries"] = 0;
visit["checkinTries"] = 0;
visit["numDarts"] = 0;
delete visit["sum"];
delete visit["toGo"];
return ret;
}
function getWinner(points, mode) {
const sorted = [...points].map((e,i) => [e,i]).sort((a, b) => b[0] - a[0]);
const k = points.length;
const sum = points.reduce((a,c) => a+c, 0);
if (sum < mode && sorted[0][0] <= mode/k){
// not over yet
return -1;
}
if (sorted[0][0] == sorted[1][0]){
// Draw
return -2;
}
// winner id
return sorted[0][1];
}
function addNewSet(page){
const set = page.game.sets[page.game.sets.length-1];
const k = player2scorer(page)[set.legs[0].visits[0].player];
const p = page.scorers[(k+1)%2].member[0].uuid;
page.game.sets.push({
// points: [...points],
legs: [{
points: Array(2).fill(0),
visits: [newVisit(p, 1)]
}]
});
}
function addNewLeg(page){
const set = page.game.sets[page.game.sets.length-1];
const leg = set.legs[set.legs.length-1];
const k = player2scorer(page)[leg.visits[0].player];
console.log(k, k+1);
const p = page.scorers[(k+1)%2].member[0].uuid;
page.game.sets[page.game.sets.length-1].legs.push({
// points: [...points],
visits: [newVisit(p, 1)]
});
}
/////////////////////////////////////////
// Exports
/////////////////////////////////////////
export function playerFromUUID(uuid, players){
return players[players.map((p) => p.uuid).indexOf(uuid)];
}
export const getFinalWinner = (page) => {
const points = setPoints(page, page.sets[page.sets.length-1]);
return getWinner(points, page.sets);
};
export function initStats(page) {
const stats = newStats(page.scorers);
stats.sets = [];
addNewSetStats(stats, page.scorers);
addNewLegStats(stats, page.scorers);
page.stats = stats;
}
export function initGame(page) {
page.game = {
sets: [{
points: new Array(page.players.length).fill(0),
points: new Array(2).fill(0),
legs: [{
points: new Array(page.players.length).fill(0),
visits: [newVisit(page.players[0].uuid, 1)]
points: new Array(2).fill(0),
visits: [newVisit(page.scorers[0].member[0].uuid, 1)]
}]
}]
}
}
function updateStats(page, visit){
const playerUUIDs = page.players.map((p) => p.uuid);
const playerUUIDs = allPlayers(page).map((p) => p.uuid);
const k = playerUUIDs.indexOf(visit.player);
const todos = [page.stats["stats"][k]];
@ -297,69 +222,43 @@ function updateStats(page, visit){
});
}
function getWinner(points, mode) {
const sorted = [...points].map((e,i) => [e,i]).sort((a, b) => b[0] - a[0]);
const k = points.length;
const sum = points.reduce((a,c) => a+c, 0);
if (sum < mode && sorted[0][0] <= mode/k){
// not over yet
return -1;
}
if (sorted[0][0] == sorted[1][0]){
// Draw
return -2;
}
// winner id
return sorted[0][1];
}
export const formatDate = (d) => {
return `${d.getFullYear()}-${(d.getMonth()+1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
};
function addNewSet(page, points){
const playerUUIDs = page.players.map((p) => p.uuid);
function getNextPlayer(page, visit) {
const set = page.game.sets[page.game.sets.length-1];
const leg = set.legs[set.legs.length-1];
const k = playerUUIDs.indexOf(set.legs[0].visits[0].player);
const p = playerUUIDs[(k+1)%playerUUIDs.length];
page.game.sets.push({
// points: [...points],
legs: [{
points: Array(playerUUIDs.length).fill(0),
visits: [newVisit(p, 1)]
}]
});
const offset = 1*(leg.visits[0].player == page.scorers[0].member[0].uuid);
const order = [];
for (let index = 0; index < page.scorers[0].member.length; index++) {
order.push(page.scorers[1-offset].member[index].uuid);
order.push(page.scorers[offset].member[index].uuid);
}
const nextid = (order.indexOf(visit.player)+1);
return [order[nextid%order.length], (nextid == order.length)];
}
function addNewLeg(page){
const playerUUIDs = page.players.map((p) => p.uuid);
const set = page.game.sets[page.game.sets.length-1];
const leg = set.legs[set.legs.length-1];
const k = playerUUIDs.indexOf(leg.visits[0].player);
const p = playerUUIDs[(k+1)%playerUUIDs.length];
page.game.sets[page.game.sets.length-1].legs.push({
// points: [...points],
visits: [newVisit(p, 1)]
export function player2scorer(page){
return Object.entries(page.scorers).reduce((result, [scorersId, scorer]) => {
// Use the map method to create an array of key-value pairs for each "member"
scorer.member.forEach(player => {
result[player.uuid] = parseInt(scorersId);
});
return result;
}, {});
}
function clearLastVisit(page){
const set = page.game.sets[page.game.sets.length-1];
const leg = set.legs[set.legs.length-1];
const visit = leg.visits[leg.visits.length-1];
const ret = visit["throws"];
visit["throws"] = [];
visit["checkoutTries"] = 0;
visit["checkinTries"] = 0;
visit["numDarts"] = 0;
delete visit["sum"];
delete visit["toGo"];
return ret;
export function allPlayers(page){
return Object.entries(page.scorers).reduce((result, [scorersId, scorer]) => {
return result.concat(scorer.member);
}, []);
}
export const formatDate = (d) => {
return `${d.getFullYear()}-${(d.getMonth()+1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
};
export function recalcStats(page){
const set = page.game.sets[page.game.sets.length-1];
// const set = page.game.sets[page.game.sets.length-1];
// const leg = set.legs[set.legs.length-1];
// const visit = leg.visits[leg.visits.length-1];
initStats(page);
@ -373,11 +272,11 @@ export function recalcStats(page){
updateStats(page, visit);
}
if (k == lastvisit && j != lastleg) {
addNewLegStats(page.stats, page.players);
addNewLegStats(page.stats, page.scorers);
}
});
if (j == lastleg && i != lastset) {
addNewSetStats(page.stats, page.players);
addNewSetStats(page.stats, page.scorers);
}
});
});
@ -386,7 +285,7 @@ export function recalcStats(page){
export function removeLastVisit(page){
const set = page.game.sets[page.game.sets.length-1];
const leg = set.legs[set.legs.length-1];
const visit = leg.visits[leg.visits.length-1];
// const visit = leg.visits[leg.visits.length-1];
// delete last visit.
leg["visits"].pop();
@ -417,11 +316,10 @@ export function storeVisit(page, throws, sum, numDarts, outTries, inTries=0) {
visit["checkinTries"] = inTries;
visit["sum"] = sum
const playerUUIDs = page.players.map((p) => p.uuid);
const k = playerUUIDs.indexOf(visit["player"]);
const k = player2scorer(page)[visit["player"]];
let toGo;
if (leg["visits"].length-2 < 0) {
toGo = Array(playerUUIDs.length).fill(page.modus);
toGo = Array(2).fill(page.modus);
} else {
toGo = [...leg["visits"][leg["visits"].length-2]["toGo"]];
}
@ -441,8 +339,8 @@ export function storeVisit(page, throws, sum, numDarts, outTries, inTries=0) {
let update = [];
if (rest != 0) {
// Normal case...next players turn
const nextPlayer = playerUUIDs[(k+1)%playerUUIDs.length];
const nVisit = newVisit(nextPlayer, visit["visit"]+1*(leg.visits[0]["player"] == nextPlayer));
const [nextPlayer, newRound] = getNextPlayer(page, visit);
const nVisit = newVisit(nextPlayer, visit["visit"]+1*newRound);
leg.visits.push(nVisit);
}
else {
@ -452,7 +350,7 @@ export function storeVisit(page, throws, sum, numDarts, outTries, inTries=0) {
if (winner == -1) {
// new Leg
addNewLeg(page);
addNewLegStats(page.stats, page.players);
addNewLegStats(page.stats, page.scorers);
} else {
// new set?
const newsetp = setPoints(page, set);
@ -460,8 +358,8 @@ export function storeVisit(page, throws, sum, numDarts, outTries, inTries=0) {
if (winner == -1) {
// new Set
addNewSet(page);
addNewSetStats(page.stats, page.players);
addNewLegStats(page.stats, page.players);
addNewSetStats(page.stats, page.scorers);
addNewLegStats(page.stats, page.scorers);
} else {
// ask for continue or game over
if (winner == -2) {
@ -490,8 +388,156 @@ export function endGame(page){
export function extension(page){
const set = page.game.sets[page.game.sets.length-1];
const leg = set.legs[set.legs.length-1];
page.enddate = undefined;
// leg["points"] = newlegp;
// new Leg
addNewLeg(page);
addNewLegStats(page.stats, page.players);
addNewLegStats(page.stats, page.scorers);
}
/////////////////////////////////////////
// GameProps
/////////////////////////////////////////
export function getGameProps(page, current_set, current_leg) {
const ret = {};
if (current_set === undefined) {
current_set = computed(() => {
if (page.game != undefined) {
return page.game.sets[page.game.sets.length - 1]
}
return undefined;
});
}
ret.current_set = current_set;
if (current_leg === undefined) {
current_leg = computed(() => {
if (current_set.value != undefined) {
return current_set.value.legs[current_set.value.legs.length - 1]
}
return undefined;
});
}
ret.current_leg = current_leg;
const current_toGo = computed(() => {
if (current_leg.value != undefined) {
if (current_leg.value.visits.length < 2) {
return [page.modus, page.modus]
} else {
const end = current_leg.value.visits[current_leg.value.visits.length - 1].toGo;
if (end) return end;
return current_leg.value.visits[current_leg.value.visits.length - 2].toGo;
}
}
return [0, 0]; // need to get updated for more player
});
ret.current_toGo = current_toGo;
const current_set_points = computed(() => {
if (current_set.value != undefined) {
return setPoints(page, current_set.value);
}
return undefined;
});
ret.current_set_points = current_set_points;
const current_leg_points = computed(() => {
if (current_set.value != undefined || current_leg.value != undefined) {
return legPoints(page, current_set.value, current_leg.value);
}
return undefined;
});
ret.current_leg_points = current_leg_points;
const current_scorer_idx = computed(() => {
if (current_leg.value != undefined) {
const len = current_leg.value.visits.length;
return player2scorer(page)[current_leg.value.visits[len - 1].player];
}
return undefined;
});
ret.current_scorer_idx = current_scorer_idx;
const breaks = computed(() => {
let b = [0,0];
for (const j in page.game.sets) {
const set = page.game.sets[j];
for (const i in set.legs) {
const l = set.legs[i];
if (l.visits[l.visits.length-1].toGo === undefined) {
return b;
}
if (l.visits[l.visits.length-1].toGo[0] == 0 && i%2 == 1)
b[0] += 1;
else if (l.visits[l.visits.length-1].toGo[1] == 0 && i%2 == 0)
b[1] += 1;
}
}
return b;
});
ret.breaks = breaks;
const getVal = (tr) => {
const val = tr.trim();
if (val == "") {
return 0;
}
if (val == "SB") {
return 25;
}
if (val == "DB") {
return 50;
}
if (val[0] == "S" || val[0] == "O" || val[0] == "I") {
return parseFloat(val.substring(1));
}
if (val[0] == "D") {
return 2 * parseFloat(val.substring(1));
}
if (val[0] == "T") {
return 3 * parseFloat(val.substring(1));
}
if (val[0] == "M") {
return 0;
} else {
// TODO: Check for Na
return parseFloat(val);
}
}
const verifySum = (sum) => {
if (sum > 180 || [179, 178, 176, 175, 173, 172, 169, 166, 163].indexOf(sum) > -1) {
return -1;
} else if (current_toGo.value[current_scorer_idx.value] - sum < 0) {
return -2;
} if (current_toGo.value[current_scorer_idx.value] - sum == 0) {
// bogey numbers
if (page.out == "Double" && (sum > 170 || [169, 168, 166, 165, 163, 162, 159].indexOf(sum) > -1)) {
return -1;
}
return 0;
} else if (current_toGo.value[current_scorer_idx.value] - sum <= 50) {
return 1;
} else if (page.in != "Straight" && current_toGo.value[current_scorer_idx.value] == page.modus && sum != 0) {
return 3;
}
return 2;
}
const checkVisit = (throws) => {
const tr = throws.split(",");
let sum = 0;
tr.forEach((t, i) => {
sum += getVal(t);
});
const res = verifySum(sum);
return [res, sum];
}
ret.checkVisit = checkVisit;
return ret;
}

@ -1,10 +1,9 @@
import { nextTick, watch, reactive, ref, computed, onMounted, onUnmounted } from "vue";
import { reactive, ref, computed, onMounted, toRaw } from "vue";
import { getQuery, setKirby } from "../../kirby.js";
import { state } from "../../stateMgr.js";
import { handleActive, ArrowVerticalKeyHandler, ArrowHorizontalKeyHandler, NumberKeyHandler } from "../../handlers.js";
import { overlayAndGet, powerStateMachine, overlayAndPop, popLastElem } from "../../componentPromise.js";
import { getGameProps, initGame, initStats, storeVisit, formatDate, removeLastVisit, extension, getFinalWinner } from "./logic.js";
import { getGameProps, initGame, initStats, storeVisit, formatDate, removeLastVisit, extension, getFinalWinner, playerFromUUID } from "./logic.js";
const html = (v) => { return v[0] };
@ -19,13 +18,29 @@ const pregame = {
const selectPlayer = async (i) => {
if (props.active) {
const [result, error] = await overlayAndPop("d-playerSelect", { players: props.page.participants, class:"overlay"}, props.stack);
let [result, error] = await overlayAndPop("d-select", { type: "player", options: props.page.participants, class:"overlay"}, props.stack);
if (error === undefined) {
props.page.players[i] = result;
}
}
}
const selectScorer = async (i) => {
if (props.active) {
const [scorer, error] = await overlayAndPop("d-select", { type: "scorer", options: props.page.participants, class:"overlay"}, props.stack);
if (error === undefined) {
if (scorer.member.length > 1){
const [captain, err] = await overlayAndPop("d-select", { type: "player", title: "Team Captain", options: [scorer.member[0],scorer.member[1]], class:"overlay"}, props.stack);
if (err !== undefined){
return selectScorer(i);
}
scorer.member = [captain, scorer.member[0] == captain ? scorer.member[1] : scorer.member[0]];
}
props.page.scorers[i] = scorer;
}
}
}
const selectX01 = async () => {
if (props.active) {
const [result, error] = await overlayAndPop("d-select", { options: [ "301", "501" ], class:"overlay"}, props.stack);
@ -44,15 +59,16 @@ const pregame = {
}
}
return { selectPlayer, selectX01, selectIn }
return { selectX01, selectIn, selectScorer }
},
template: html`
<nav class="gamesetup" :disabled="!active">
<h1>Game Setup</h1>
<div class="menu">
<!-- <div><span class="label">Name:</span><d-inputElem v-index="active" v-model="game.title"></d-inputElem></div> -->
<div><span class="label">Player 1:</span><d-playerElem v-index="active" @click="selectPlayer(0)" :player="page.players[0]"></d-playerElem></div>
<div><span class="label">Player 2:</span><d-playerElem v-index="active" @click="selectPlayer(1)" :player="page.players[1]"></d-playerElem></div>
<div><span class="label">Scorer 1:</span><d-scorerElem v-index="active" @click="selectScorer(0)" :scorer="page.scorers[0]"></d-scorerElem></div>
<div><span class="label">Scorer 2:</span><d-scorerElem v-index="active" @click="selectScorer(1)" :scorer="page.scorers[1]"></d-scorerElem></div>
<div><span class="label">X01:</span><d-plainElem v-index="active" @click="selectX01()" :text="page.modus"></d-plainElem></div>
<div><span class="label">In:</span><d-plainElem v-index="active" @click="selectIn()" :text="page.in"></d-plainElem></div>
<!-- <div><span class="label">Best of Sets:</span><d-inputElem v-index="active" v-model="page.sets"></d-inputElem></div> -->
@ -64,14 +80,15 @@ const pregame = {
}
export const bullselect = {
props: ['players','active', 'stack'],
props: ['scorers', 'active', 'stack'],
setup(props, { emit }) {
handleActive(props, [ArrowHorizontalKeyHandler, NumberKeyHandler]);
const children = computed(() => {
const items = [];
for (let i in props.players){
const player = props.players[i];
for (let i in props.scorers){
const player = props.scorers[i].member[0];
items.push({
component: "d-squareElem",
props: {
@ -79,7 +96,7 @@ export const bullselect = {
icon: player.img ? player.img : '/assets/img/placeholder_person.png'
},
onClick: () => {
emit("resolve", player);
emit("resolve", props.scorers[i]);
}
})
}
@ -123,8 +140,8 @@ const score = {
`
}
const player = {
props: ['page', 'id', 'current_stat'],
const scorer = {
props: ['page', 'id', 'current_stat', 'current_leg'],
setup(props) {
const addStats = (stat1, stat2) => {
let res = {
@ -146,23 +163,17 @@ const player = {
}
const inspect = !!props.page.enddate;
const tourStats = computed(() => {
if (props.page.tournamentStats.length != 2){
return [
props.page.stats.stats[0],
props.page.stats.stats[1]
];
}
if (inspect) {
return [
props.page.tournamentStats[0],
props.page.tournamentStats[1]
];
}
return [
addStats(props.page.tournamentStats[0], props.page.stats.stats[0]),
addStats(props.page.tournamentStats[1], props.page.stats.stats[1])
];
return props.page.tournamentStats;
}
return props.page.tournamentStats.map((s,i) => {
if (s.length == 0){
return props.page.stats.stats[i];
}
return addStats(s,props.page.stats.stats[i])
});
});
const getAverage = (avg) => {
return avg && avg[1] != 0 ? ((3*avg[0])/avg[1]).toFixed(1) : "-";
}
@ -175,59 +186,113 @@ const player = {
}
return "-"
}
const player = computed(() => props.page.players[props.id])
return { tourStats, getAverage, getCheckout, getMax, player }
const scorer = ref(props.page.scorers[props.id]);
const allScorerIndices = computed(() => scorer.value.member.map((p) => props.page.stats.stats.map((s) => s.player).indexOf(p.uuid)));
const currentScorerIdx = computed(() => {
if (scorer.value.member.length == 1){
return 0;
}
const idx = props.page.scorers[props.id].member.map((p) => p.uuid).indexOf(props.current_leg.visits.at(-1).player);
return idx;
});
const tnmStats = computed(() => {
if (currentScorerIdx.value == -1){
return addStats(tourStats.value[allScorerIndices.value[0]], tourStats.value[allScorerIndices.value[1]]);
}
return tourStats.value[allScorerIndices.value[currentScorerIdx.value]];
});
const matchStats = computed(() => {
if (currentScorerIdx.value == -1){
return addStats(props.page.stats.stats[allScorerIndices.value[0]], props.page.stats.stats[allScorerIndices.value[1]]);
}
return props.page.stats.stats[allScorerIndices.value[currentScorerIdx.value]];
});
const legStats = computed(() => {
if (currentScorerIdx.value == -1){
return addStats(props.current_stat.stats[allScorerIndices.value[0]], props.current_stat.stats[allScorerIndices.value[1]]);
}
return props.current_stat.stats[allScorerIndices.value[currentScorerIdx.value]];
});
return { tnmStats, matchStats, legStats, getAverage, getCheckout, getMax, scorer, currentScorerIdx }
},
template: html`
<div class="player">
<img style="width: 100%" :src="player.img ? player.img : '/assets/img/placeholder_person.png'">
<h2 class="name">{{ player.forename }} {{ player.surname }}</h2>
<h3 class="nickname">{{ player.nickname }}</h3>
<div class="player" :class="{ 'team': scorer.member.length == 2 }">
<template v-if="scorer.member.length == 1">
<img style="width: 100%" :src="scorer.member[0].img ? scorer.member[0].img : '/assets/img/placeholder_person.png'">
<h2 class="name">{{ scorer.member[0].forename }} {{ scorer.member[0].surname }}</h2>
<h3 class="nickname">{{ scorer.member[0].nickname }}</h3>
</template>
<template v-if="scorer.member.length == 2">
<div class="team images">
<img :class="{ 'active': currentScorerIdx == 0, 'inactive': currentScorerIdx == 1 }" :src="scorer.member[0].img ? scorer.member[0].img : '/assets/img/placeholder_person.png'">
<img :class="{ 'active': currentScorerIdx == 1, 'inactive': currentScorerIdx == 0 }" :src="scorer.member[1].img ? scorer.member[1].img : '/assets/img/placeholder_person.png'">
</div>
<div class="team titles">
<div class="title" :class="{ 'active': currentScorerIdx == -1 }">
<h2 class="name">{{ scorer.member[0].forename }} + {{ scorer.member[1].forename }}</h2>
</div>
<div class="title" :class="{ 'active': currentScorerIdx == 0 }">
<h2 class="name">{{ scorer.member[0].forename }} {{ scorer.member[0].surname }}</h2>
<h3 class="nickname">{{ scorer.member[0].nickname }}</h3>
</div>
<div class="title" :class="{ 'active': currentScorerIdx == 1 }">
<h2 class="name">{{ scorer.member[1].forename }} {{ scorer.member[1].surname }}</h2>
<h3 class="nickname">{{ scorer.member[1].nickname }}</h3>
</div>
</div>
</template>
<div class="stats">
<div class="row header">
<div>Stat</div><div>Tnm</div><div>Match</div><div>Leg</div>
</div>
<div class="row">
<div>Avg:</div><div>
{{ getAverage(tourStats[id].average) }}
{{ getAverage(tnmStats.average) }}
</div><div>
{{ getAverage(page.stats.stats[id].average) }}
{{ getAverage(matchStats.average) }}
</div><div>
{{ getAverage(current_stat.stats[id].average) }}
{{ getAverage(legStats.average) }}
</div>
</div>
<div class="row">
<div>First 9:</div><div>
{{ getAverage(tourStats[id].first9) }}
{{ getAverage(tnmStats.first9) }}
</div><div>
{{ getAverage(page.stats.stats[id].first9) }}
{{ getAverage(matchStats.first9) }}
</div><div>
{{ getAverage(current_stat.stats[id].first9) }}
{{ getAverage(legStats.first9) }}
</div>
</div>
<div class="row">
<div>60+:</div><div>{{ tourStats[id]["60+"] }}</div><div>{{ page.stats.stats[id]["60+"] }}</div><div>{{ current_stat.stats[id]["60+"] }}</div>
<div>60+:</div><div>{{ tnmStats["60+"] }}</div><div>{{ matchStats["60+"] }}</div><div>{{ legStats["60+"] }}</div>
</div>
<div class="row">
<div>100+:</div><div>{{ tourStats[id]["100+"] }}</div><div>{{ page.stats.stats[id]["100+"] }}</div><div>{{ current_stat.stats[id]["100+"] }}</div>
<div>100+:</div><div>{{ tnmStats["100+"] }}</div><div>{{ matchStats["100+"] }}</div><div>{{ legStats["100+"] }}</div>
</div>
<div class="row">
<div>140+:</div><div>{{ tourStats[id]["140+"] }}</div><div>{{ page.stats.stats[id]["140+"] }}</div><div>{{ current_stat.stats[id]["140+"] }}</div>
<div>140+:</div><div>{{ tnmStats["140+"] }}</div><div>{{ matchStats["140+"] }}</div><div>{{ legStats["140+"] }}</div>
</div>
<div class="row">
<div>180:</div><div>{{ tourStats[id]["180"] }}</div><div>{{ page.stats.stats[id]["180"] }}</div><div>{{ current_stat.stats[id]["180"] }}</div>
<div>180:</div><div>{{ tnmStats["180"] }}</div><div>{{ matchStats["180"] }}</div><div>{{ legStats["180"] }}</div>
</div>
<div class="row" v-if="page.in == 'Double'">
<div>Ch. I. %:</div><div>{{ getCheckout(tourStats[id].checkins) }}%</div><div>{{ getCheckout(page.stats.stats[id].checkins) }}%</div><div>{{ getCheckout(current_stat.stats[id].checkins) }}%</div>
<div>Ch. I. %:</div><div>{{ getCheckout(tnmStats.checkins) }}%</div><div>{{ getCheckout(matchStats.checkins) }}%</div><div>{{ getCheckout(legStats.checkins) }}%</div>
</div>
<div class="row" v-if="page.in == 'Double'">
<div>Best Ch.:</div><div>{{ getMax(tourStats[id].checkinPoints) }}</div><div>{{ getMax(page.stats.stats[id].checkinPoints) }}</div><div>{{ getMax(current_stat.stats[id].checkinPoints) }}</div>
<div>Best Ch.:</div><div>{{ getMax(tnmStats.checkinPoints) }}</div><div>{{ getMax(matchStats.checkinPoints) }}</div><div>{{ getMax(legStats.checkinPoints) }}</div>
</div>
<div class="row">
<div>Ch. O. %:</div><div>{{ getCheckout(tourStats[id].checkouts) }}%</div><div>{{ getCheckout(page.stats.stats[id].checkouts) }}%</div><div></div>
<div>Ch. O. %:</div><div>{{ getCheckout(tnmStats.checkouts) }}%</div><div>{{ getCheckout(matchStats.checkouts) }}%</div><div></div>
</div>
<div class="row">
<div>Best Ch.:</div><div>{{ getMax(tourStats[id].checkoutPoints) }}</div><div>{{ getMax(page.stats.stats[id].checkoutPoints) }}</div><div></div>
<div>Best Ch.:</div><div>{{ getMax(tnmStats.checkoutPoints) }}</div><div>{{ getMax(matchStats.checkoutPoints) }}</div><div></div>
</div>
</div>
</div>
@ -236,11 +301,15 @@ const player = {
const game = {
props: ['active', 'stack', 'players','current_leg', 'max'],
props: ['active', 'stack', 'scorers', 'current_leg', 'max'],
setup(props, context) {
const visits = computed(() => props.current_leg ? props.current_leg.visits : undefined );
const getPlayerVisits = (uuid) => {
const vs = visits.value.filter((v) => v.player == uuid);
const getScorersVisits = (scorer) => {
// const vs = visits.value.filter((v,i) => i % 2 == props.scorers.map((p) => p.uuid).indexOf(uuid) % 2);
const vs = visits.value.filter((v,i) => scorer.member.map((p) => p.uuid).indexOf(v.player) != -1);
if (vs.length < 9) {
for (var i = vs.length; i < 9; i++) {
vs.push({ "sum": "", "toGo":["",""]})
@ -251,34 +320,34 @@ const game = {
}
return vs;
}
return { getPlayerVisits }
return { getScorersVisits }
},
template: html`
<div class="game">
<div class="headding">
<div class="headding points player1">Points</div>
<div class="headding toGo player1">ToGo</div>
<div class="headding points scorer1">Points</div>
<div class="headding toGo scorer1">ToGo</div>
<div class="headding rounds">Round</div>
<div class="headding points player2">Points</div>
<div class="headding toGo player2">ToGo</div>
<div class="headding points scorer2">Points</div>
<div class="headding toGo scorer2">ToGo</div>
</div>
<div class="body">
<div class="points player1"></div>
<div class="toGo player1">{{ max }}</div>
<div class="points scorer1"></div>
<div class="toGo scorer1">{{ max }}</div>
<div class="rounds">0</div>
<div class="points player2"></div>
<div class="toGo player2">{{ max }}</div>
<template v-for="j in [1,2]" v-if="players">
<template v-for="visit, i in getPlayerVisits(players[j-1].uuid)">
<div class="points scorer2"></div>
<div class="toGo scorer2">{{ max }}</div>
<template v-for="j in [1,2]" v-if="scorers">
<template v-for="visit, i in getScorersVisits(scorers[j-1])">
<template v-if="visit.toGo === undefined">
<div :class="'points player'+j+' input'">
<div :class="'points scorer'+j+' input'">
<slot />
</div>
<div :class="'toGo player'+j"></div>
<div :class="'toGo scorer'+j"></div>
</template>
<template v-if="visit.toGo !== undefined">
<div :class="'points player'+j">{{ visit.sum }}</div>
<div :class="'toGo player'+j">{{ visit.toGo[j-1] }}</div>
<div :class="'points scorer'+j">{{ visit.sum }}</div>
<div :class="'toGo scorer'+j">{{ visit.toGo[j-1] }}</div>
</template>
<div class="rounds" v-if="j == 1">{{ (i+1)*3 }}</div>
</template>
@ -328,7 +397,7 @@ const gameinput = {
const xoi = {
props: ['page', 'active', 'stack', 'inspect', 'watch'],
components: {
"d-player": player,
"d-scorer": scorer,
"d-score": score,
"d-game": game
},
@ -352,6 +421,7 @@ const xoi = {
}, 2000);
}
const computedProps = getGameProps(props.page, current_set, current_leg);
if (!props.inspect) {
current_stat = computed( () => props.page.stats?.sets[props.page.stats.sets.length-1].legs[computedProps.current_set.value.legs.length-1]);
}
@ -360,21 +430,25 @@ const xoi = {
if (props.inspect || props.watch) {
} else {
const winner = await gameHandler(gamestack, props.stack, props.page, computedProps)
if (winner === undefined){
context.emit('reject', winner);
} else {
context.emit('resolve', winner);
}
}
})
return { ...computedProps, set_id, leg_id, gamestack, inspectstack, current_stat }
},
template: html`
<div class="xoi">
<div class="bigToGo one" :class="{'active' : current_player==0 }">{{ current_toGo[0] }}</div>
<div class="bigToGo one" :class="{'active' : current_scorer_idx==0 }">{{ current_toGo[0] }}</div>
<d-score :page="page" :justlegs="page && page.sets == 1" :current_set_points="current_set_points" :current_leg_points="current_leg_points"></d-score>
<div class="bigToGo two" :class="{'active' : current_player==1 }">{{ current_toGo[1] }}</div>
<d-player class="player1" :page="page" :id="0" :current_stat="current_stat"></d-player>
<d-game :active="active" :stack="stack" :players="page.players" :max="page.modus" :current_leg="current_leg" >
<div class="bigToGo two" :class="{'active' : current_scorer_idx==1 }">{{ current_toGo[1] }}</div>
<d-scorer class="scorer1" :page="page" :id="0" :current_stat="current_stat" :current_leg="current_leg"></d-scorer>
<d-game :active="active" :stack="stack" :scorers="page.scorers" :max="page.modus" :current_leg="current_leg" >
<d-renderer :stack="gamestack"></d-renderer>
</d-game>
<d-player class="player2" :page="page" :id="1" :current_stat="current_stat"></d-player>
<d-scorer class="scorer2" :page="page" :id="1" :current_stat="current_stat" :current_leg="current_leg"></d-scorer>
<div class="nav" v-if="inspect">
<span class="label" v-if="page.sets != 1">Set:</span><d-plainElem :text="set_id+1" v-if="page.sets != 1" v-index="active" @click="set_id = (set_id+1)%page.game.sets.length; leg_id=0"></d-plainElem><span class="label">Leg:</span><d-plainElem style="padding:0.2em 0.5em" :text="leg_id+1" v-index="active" v-autofocus="true" @click="leg_id = (leg_id+1)%current_set.legs.length"></d-plainElem>
</div>
@ -494,12 +568,27 @@ function refreshGame(id){
return getQuery(`site.find('${id}')`, {
select: {
game: "page.rounds.parseJSON",
stats: "page.stats.parseJSON"
stats: "page.stats.parseJSON",
tournamentStats: "page.tournamentStats"
}
})
}
async function reloadGame(page){
let gs = await refreshGame(page.id);
page.game = gs.game;
page.stats = gs.stats;
page.tournamentStats = gs.tournamentStats;
}
function getGame(id){
const playerInfo = {
forename: "page.forename",
surname: "page.surname",
nickname: "page.nickname",
uuid: "page.uuid",
img: "page.pic.toFile?.thumbnail(350).url"
};
return getQuery(`site.find('${id}')`, {
select: {
title: "page.title",
@ -515,23 +604,21 @@ function getGame(id){
enddate: "page.Enddate",
tournamentStats: "page.tournamentStats",
participants: {
query: "page.parent.participants.toPages.sortBy('forename')",
query: "page.parent.scorers",
select: {
forename: "page.forename",
surname: "page.surname",
nickname: "page.nickname",
uuid: "page.uuid",
img: "page.pic.toFile?.url"
member: {
query: "structureItem.member.toPages",
select: playerInfo
}
}
},
players: {
query: "page.players.toPages",
scorers: {
query: "page.scorers.toStructure",
select: {
forename: "page.forename",
surname: "page.surname",
nickname: "page.nickname",
uuid: "page.uuid",
img: "page.pic.toFile?.thumbnail(350).url"
member: {
query: "structureItem.member.toPages",
select: playerInfo
}
}
}
}
@ -544,8 +631,12 @@ function savePregame(page){
legs: page.legs,
max: page.modus,
in: page.in,
players: page.players.map((p) => p.uuid),
startdate: page.startdate,
scorers: page.scorers.map((s) => {
const copy = Object.assign({},s);
copy.member = copy.member.map((p) => p.uuid)
return copy
}),
startdate: page.startdate ? page.startdate : "",
rounds: page.game ? JSON.stringify(page.game) : "",
stats: page.stats ? JSON.stringify(page.stats) : ""
});
@ -555,7 +646,7 @@ function saveGame(page){
return setKirby(page.id, {
rounds: page.game ? JSON.stringify(page.game) : "",
stats: page.stats ? JSON.stringify(page.stats) : "",
enddate: page.enddate,
enddate: page.enddate ? page.enddate : "",
});
}
@ -616,11 +707,14 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => {
let [visit, error] = await overlayAndPop("d-gameinput", { input: input }, gamestack);
if (parseFloat(visit) < 0 ){
visit = ""+(computedProps.current_toGo.value[computedProps.current_player.value * 1] - parseFloat(visit)*-1);
visit = ""+(computedProps.current_toGo.value[computedProps.current_scorer_idx.value * 1] - parseFloat(visit)*-1);
}
// back/delete last throw
if (error != undefined) {
const val = removeLastVisit(page);
if (val === undefined) {
return [undefined, undefined];
}
saveGame(page);
if (val == undefined) return [1, val];
return [1, val.join(",")];
@ -651,9 +745,7 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => {
storeVisit(page, visit.split(","), sum, 3, 0);
saveGame(page);
return [1, undefined]
}
// checkout:
if (ret == 0) {
} else if (ret == 0) {
// Checkout: Ask for num Darts
[numDarts, tries] = await powerStateMachine(checkoutPipeline(stack), stack, /*initState=*/0, /*initInput=*/sum);
} else if (ret == 1) {
@ -671,9 +763,16 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => {
const winner = getFinalWinner(page);
let name = "DRAW"
if (winner != -2){
name = page.players[winner].forename;
name = page.scorers[winner].member.map((p) => p.forename).join(" + ");
}
const [answer, error] = await overlayAndPop("d-dialog", gameOverDialog(name, points[1], computedProps.breaks.value), stack);
if (error != undefined) {
extension(page);
const val = removeLastVisit(page);
saveGame(page);
if (val == undefined) return [1, val];
return [1, val.join(",")];
}
if (answer == "end") {
saveGame(page);
return [undefined, page.stats.winner];
@ -709,7 +808,7 @@ const stateMachine = (stack, page) => {
// Dispatcher
// Check if in watchmode
// Check Game State:
if (page.players.length != 2 || page.startdate === undefined || page.startdate === ""){
if ( page.scorers.length != 2 || page.startdate === undefined || page.startdate === ""){
// Pre Game
return [1, page];
} else if (page.enddate === undefined || page.enddate === ""){
@ -750,23 +849,34 @@ const stateMachine = (stack, page) => {
},
2: async (page, reGet) => {
// Ask for Bull
const [result, error] = await overlayAndPop("d-bullselect", { players: page.players}, stack);
const [scorer, error] = await overlayAndPop("d-bullselect", { scorers: page.scorers}, stack);
if (error != undefined) {
page.startdate = undefined;
const ret = await savePregame(page);
return [1, page];
}
// reorderPlayer
if (result !== page.players[0]){
page.players = [page.players[1], page.players[0]];
// reorder Scorer
if (scorer !== page.scorers[0]){
page.scorers = [page.scorers[1], page.scorers[0]];
}
// Setup Game
initGame(page);
initStats(page);
const ret = await savePregame(page);
await reloadGame(page);
return [3, page];
},
3: async (page, reGet) => {
// In Game
const [result, error] = await overlayAndPop("d-xoi", { page: page, inspect: false }, stack);
if (error) {
page.game = undefined;
page.stats = undefined;
const ret = await savePregame(page);
return [2, page];
}
return [4, result];
},
4: async (winnerUUID, reGet) => {

@ -10,7 +10,7 @@ Surname: Motzek
----
Nickname: ?
Nickname: TODO
----
@ -22,4 +22,8 @@ Pic:
----
Files:
----
Uuid: 9S2pH2C0vG8XUrye

@ -10,7 +10,7 @@ Surname: Ouakili-Bilan
----
Nickname:
Nickname: TODO
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://aHO5FUnIphBwYEjS
-
member:
- page://XDZibCkgJ9repYEx
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://XDZibCkgJ9repYEx
-
member:
- page://UkQNJytohCGIXySl
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://XDZibCkgJ9repYEx
-
member:
- page://90CUYLfokdOm9Gw0
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://fShTMgFob20fogyr
-
member:
- page://9S2pH2C0vG8XUrye
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://90CUYLfokdOm9Gw0
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://aHO5FUnIphBwYEjS
-
member:
- page://5qeooGppOFqpprW5
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://XDZibCkgJ9repYEx
-
member:
- page://TbZF36aHK27hZvnK
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://4CPpeIGeeK8UHTf8
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://7GAUHPdaKdD2sHm9
-
member:
- page://5qeooGppOFqpprW5
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://9S2pH2C0vG8XUrye
-
member:
- page://ZUPj0Nw2DcaIQ1H1
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://aHO5FUnIphBwYEjS
-
member:
- page://fShTMgFob20fogyr
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://UkQNJytohCGIXySl
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://x8tm8FzBBY95HqIi
-
member:
- page://TbZF36aHK27hZvnK
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://Ue0F1SstBqE7xVKr
-
member:
- page://8TlbKlF7fVBwS24c
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://x8tm8FzBBY95HqIi
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://Ue0F1SstBqE7xVKr
-
member:
- page://fShTMgFob20fogyr
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://7GAUHPdaKdD2sHm9
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://aHO5FUnIphBwYEjS
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://x8tm8FzBBY95HqIi
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://fShTMgFob20fogyr
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://TbZF36aHK27hZvnK
-
member:
- page://Ue0F1SstBqE7xVKr
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://UkQNJytohCGIXySl
-
member:
- page://TbZF36aHK27hZvnK
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://TbZF36aHK27hZvnK
-
member:
- page://xRomcRk5I5n4gkq5
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://5qeooGppOFqpprW5
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://fShTMgFob20fogyr
-
member:
- page://UkQNJytohCGIXySl
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://XDZibCkgJ9repYEx
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://aHO5FUnIphBwYEjS
----

@ -1,41 +0,0 @@
Title: Template
----
Max: 501
----
Sets: 1
----
Legs: 6
----
In: Straight
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: qXIhukwbcsAF6tuD

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://TbZF36aHK27hZvnK
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://UkQNJytohCGIXySl
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://4CPpeIGeeK8UHTf8
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://Ue0F1SstBqE7xVKr
-
member:
- page://xRomcRk5I5n4gkq5
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://XDZibCkgJ9repYEx
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://fShTMgFob20fogyr
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://aHO5FUnIphBwYEjS
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://7GAUHPdaKdD2sHm9
-
member:
- page://5qeooGppOFqpprW5
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://4CPpeIGeeK8UHTf8
-
member:
- page://TbZF36aHK27hZvnK
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://x8tm8FzBBY95HqIi
-
member:
- page://XDZibCkgJ9repYEx
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://90CUYLfokdOm9Gw0
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://aHO5FUnIphBwYEjS
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://Ue0F1SstBqE7xVKr
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://9S2pH2C0vG8XUrye
-
member:
- page://90CUYLfokdOm9Gw0
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://TbZF36aHK27hZvnK
-
member:
- page://90CUYLfokdOm9Gw0
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://x8tm8FzBBY95HqIi
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://7GAUHPdaKdD2sHm9
-
member:
- page://8TlbKlF7fVBwS24c
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://8TlbKlF7fVBwS24c
-
member:
- page://aHO5FUnIphBwYEjS
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://9S2pH2C0vG8XUrye
-
member:
- page://TbZF36aHK27hZvnK
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://GZaBDcKmbMICoNZ8
-
member:
- page://4CPpeIGeeK8UHTf8
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://4CPpeIGeeK8UHTf8
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://9S2pH2C0vG8XUrye
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://GZaBDcKmbMICoNZ8
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://7GAUHPdaKdD2sHm9
-
member:
- page://90CUYLfokdOm9Gw0
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://UkQNJytohCGIXySl
-
member:
- page://XDZibCkgJ9repYEx
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://Ue0F1SstBqE7xVKr
-
member:
- page://aHO5FUnIphBwYEjS
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://fShTMgFob20fogyr
-
member:
- page://TbZF36aHK27hZvnK
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://TbZF36aHK27hZvnK
-
member:
- page://UkQNJytohCGIXySl
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://x8tm8FzBBY95HqIi
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://5qeooGppOFqpprW5
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://7GAUHPdaKdD2sHm9
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5qeooGppOFqpprW5
-
member:
- page://9S2pH2C0vG8XUrye
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://GZaBDcKmbMICoNZ8
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://9S2pH2C0vG8XUrye
-
member:
- page://5bw1wQY8DAfxUVAw
----

@ -1,41 +0,0 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: aH5scdKjvS0IS3Jo

@ -1,41 +0,0 @@
Title: Template
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: yPPt29M3WHOZO7u1

@ -1,41 +0,0 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: pKzyBEjOUz9c8ibP

@ -1,41 +0,0 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: z35XfckvPvetLXWA

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://5bw1wQY8DAfxUVAw
-
member:
- page://Ue0F1SstBqE7xVKr
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://fShTMgFob20fogyr
-
member:
- page://90CUYLfokdOm9Gw0
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://XDZibCkgJ9repYEx
-
member:
- page://x8tm8FzBBY95HqIi
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://90CUYLfokdOm9Gw0
-
member:
- page://GZaBDcKmbMICoNZ8
----

@ -22,9 +22,13 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://fShTMgFob20fogyr
-
member:
- page://x8tm8FzBBY95HqIi
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://Ue0F1SstBqE7xVKr
-
member:
- page://fShTMgFob20fogyr
----

@ -1,41 +0,0 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: p3POP6ilQfWDlSUX

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://xRomcRk5I5n4gkq5
-
member:
- page://XDZibCkgJ9repYEx
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://x8tm8FzBBY95HqIi
-
member:
- page://4CPpeIGeeK8UHTf8
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://XDZibCkgJ9repYEx
-
member:
- page://TbZF36aHK27hZvnK
----

@ -22,9 +22,12 @@ Out: Double
----
Players:
Scorers:
-
member:
- page://7GAUHPdaKdD2sHm9
-
member:
- page://GZaBDcKmbMICoNZ8
----

@ -0,0 +1,42 @@
Title: Christmas
----
Participants:
-
member:
- page://7GAUHPdaKdD2sHm9
- page://Jz127lCNtxHgUj2b
-
member:
- page://90CUYLfokdOm9Gw0
- page://CRQRBY9Ac3tXXQse
-
member:
- page://GZaBDcKmbMICoNZ8
- page://5bw1wQY8DAfxUVAw
-
member:
- page://fShTMgFob20fogyr
- page://xRomcRk5I5n4gkq5
-
member:
- page://5qeooGppOFqpprW5
- page://XDZibCkgJ9repYEx
----
Date: 2024-12-14
----
Default: - page://caLr6s1GrTQpYNvj
----
Duo: true
----
Uuid: BQqZYReH6e489II3

@ -1,4 +1,4 @@
Title: Season 2024
Title: 2024
----

@ -22,7 +22,7 @@ Out: Double
----
Players:
Scorers:
----

@ -22,7 +22,7 @@ Out: Double
----
Players:
Scorers:
----

@ -26,7 +26,7 @@ Out: Double
----
Players:
Scorers:
----

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

Loading…
Cancel
Save