mumuki-gobstones-runner 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/assets_server.rb +1 -0
- data/lib/gobstones/batch_parser.rb +1 -0
- data/lib/gobstones_runner.rb +1 -1
- data/lib/metadata_hook.rb +1 -1
- data/lib/render/editor/editor.css +46 -0
- data/lib/render/editor/editor.html +401 -24
- data/lib/render/editor/editor.js +19 -0
- data/lib/render/editor/hammer.min.js +7 -0
- data/lib/test_hook.rb +3 -1
- data/lib/version_hook.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa7b7f5ce0edeb711911bfb8b886cf7906a681245a7ef022295fec265e040676
|
4
|
+
data.tar.gz: 90f1de72bd66bca95a19ad1121be9e50122f3f03767f65df396842d33a8ca2de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc3a0620556c87d876921446152faaf0f94456c8af1ef551f76a37c2cef19528cb8d05c16a0eb631715339abbf42224e4082117d02c37b99aa4097fa3f392c2b
|
7
|
+
data.tar.gz: a2730718e9268c56fcf4661f4a41f98b3617029c999faedca678bf66d484427f789159d9901972abc3de8ea55c88af71bfded410f500cfacbcac6cb1a6ee062f
|
data/lib/assets_server.rb
CHANGED
@@ -43,6 +43,7 @@ class Mumukit::Server::App < Sinatra::Base
|
|
43
43
|
get_local_asset 'editor/editor.js', 'lib/render/editor/editor.js', 'application/javascript'
|
44
44
|
get_local_asset 'editor/editor.css', 'lib/render/editor/editor.css', 'text/css'
|
45
45
|
get_local_asset 'editor/editor.html', 'lib/render/editor/editor.html', 'text/html'
|
46
|
+
get_local_asset 'editor/hammer.min.js', 'lib/render/editor/hammer.min.js', 'application/javascript'
|
46
47
|
get_local_asset 'boom.png', 'lib/public/boom.png', 'image/png'
|
47
48
|
['red', 'blue', 'green', 'black', 'attires_enabled', 'attires_disabled'].each { |name|
|
48
49
|
get_local_asset "editor/#{name}.svg", "lib/public/#{name}.svg", 'image/svg+xml'
|
@@ -45,6 +45,7 @@ module Gobstones::BatchParser
|
|
45
45
|
struct(key: :show_final_board, default: true),
|
46
46
|
struct(key: :check_head_position, default: false),
|
47
47
|
struct(key: :expect_endless_while, default: false),
|
48
|
+
struct(key: :interactive, default: false),
|
48
49
|
struct(key: :subject, default: nil)
|
49
50
|
].map { |it| [
|
50
51
|
it.key,
|
data/lib/gobstones_runner.rb
CHANGED
@@ -5,7 +5,7 @@ I18n.load_translations_path File.join(__dir__, 'locales', '*.yml')
|
|
5
5
|
|
6
6
|
Mumukit.runner_name = 'gobstones'
|
7
7
|
Mumukit.configure do |config|
|
8
|
-
config.docker_image = 'mumuki/mumuki-gobstones-worker:
|
8
|
+
config.docker_image = 'mumuki/mumuki-gobstones-worker:4.0'
|
9
9
|
config.content_type = 'html'
|
10
10
|
config.structured = true
|
11
11
|
end
|
data/lib/metadata_hook.rb
CHANGED
@@ -63,6 +63,52 @@
|
|
63
63
|
outline: 1px solid #cc0000 !important;
|
64
64
|
}
|
65
65
|
|
66
|
+
.mu-kids-interactive #mu-initial-state-text {
|
67
|
+
display: none;
|
68
|
+
}
|
69
|
+
|
70
|
+
.mu-kids-interactive #mu-final-state-text {
|
71
|
+
display: none;
|
72
|
+
}
|
73
|
+
|
74
|
+
.mu-kids-interactive .mu-initial-state {
|
75
|
+
height: 70%;
|
76
|
+
}
|
77
|
+
|
78
|
+
.mu-kids-interactive gs-keyboard {
|
79
|
+
height: 100%;
|
80
|
+
}
|
81
|
+
|
82
|
+
.mu-kids-interactive .mu-final-state {
|
83
|
+
height: 30%;
|
84
|
+
}
|
85
|
+
|
86
|
+
.mu-kids-interactive .mu-scenario-control {
|
87
|
+
z-index: -1;
|
88
|
+
}
|
89
|
+
|
90
|
+
.mu-kids-interactive.play-mode .blocklyToolboxDiv {
|
91
|
+
display: none;
|
92
|
+
}
|
93
|
+
|
94
|
+
.mu-kids-interactive .mu-kids-interactive-submit-button paper-fab {
|
95
|
+
cursor: default;
|
96
|
+
opacity: 0.5;
|
97
|
+
}
|
98
|
+
|
99
|
+
.mu-kids-interactive.play-mode .mu-kids-interactive-submit-button paper-fab {
|
100
|
+
cursor: pointer;
|
101
|
+
opacity: 1;
|
102
|
+
}
|
103
|
+
|
104
|
+
.mu-kids-interactive.play-mode .mu-kids-exercise-description {
|
105
|
+
width: 65% !important;
|
106
|
+
}
|
107
|
+
|
108
|
+
.mu-kids-interactive.play-mode .mu-kids-states {
|
109
|
+
width: 35% !important;
|
110
|
+
}
|
111
|
+
|
66
112
|
@-moz-document url-prefix() {
|
67
113
|
.mu-kids-exercise gs-board table.gbs_board {
|
68
114
|
position: absolute;
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
<link href="./gs-element-blockly.html" rel="import"/>
|
4
4
|
<link href="./gobstones-code-runner.html" rel="import"/>
|
5
|
+
<script src="./hammer.min.js"></script>
|
5
6
|
|
6
7
|
<dom-module id="mu-gobstones-custom-editor">
|
7
8
|
|
@@ -136,6 +137,8 @@
|
|
136
137
|
}
|
137
138
|
};
|
138
139
|
|
140
|
+
this.$exerciseContainer = $('.mu-kids-exercise');
|
141
|
+
|
139
142
|
const setTrashPosition = () => {
|
140
143
|
var width = $('#blocklyDiv').width() - 68;
|
141
144
|
var height = $('#blocklyDiv').height() - 210;
|
@@ -153,7 +156,7 @@
|
|
153
156
|
};
|
154
157
|
|
155
158
|
const triggerResizeOnContextModalClose = () => {
|
156
|
-
$('
|
159
|
+
$('.mu-kids-context, .mu-kids-results').on('hidden.bs.modal shown.bs.modal', function () {
|
157
160
|
localOnResize();
|
158
161
|
})
|
159
162
|
};
|
@@ -176,6 +179,8 @@
|
|
176
179
|
|
177
180
|
this.setTeacherActions(blockly);
|
178
181
|
this._setInitialXml(blockly);
|
182
|
+
this.interactiveMode = blockly.initialXml.indexOf("block type=\"InteractiveProgram\"") !== -1;
|
183
|
+
if (this.interactiveMode) this.setInteractiveLayout();
|
179
184
|
this._initializeWorkspace(blockly, () => {
|
180
185
|
localOnResize();
|
181
186
|
blockly._onresize();
|
@@ -189,6 +194,27 @@
|
|
189
194
|
initialize();
|
190
195
|
},
|
191
196
|
|
197
|
+
toggleInteractiveMode() {
|
198
|
+
this.$exerciseContainer.toggleClass('play-mode');
|
199
|
+
this.triggerResize();
|
200
|
+
},
|
201
|
+
|
202
|
+
triggerResize() {
|
203
|
+
let event = document.createEvent('HTMLEvents');
|
204
|
+
event.initEvent('resize', true, false);
|
205
|
+
document.dispatchEvent(event);
|
206
|
+
},
|
207
|
+
|
208
|
+
setInteractiveLayout() {
|
209
|
+
this.$exerciseContainer.addClass('mu-kids-interactive');
|
210
|
+
$('.mu-final-state').html('<gs-keyboard/>');
|
211
|
+
$('.mu-editor').append($('<kids-interactive-submit-button/>'));
|
212
|
+
// In order to avoid triggering click on enter or space
|
213
|
+
$('#gbsPlayButton')[0].addEventListener('focus', function () {
|
214
|
+
this.blur();
|
215
|
+
})
|
216
|
+
},
|
217
|
+
|
192
218
|
setTeacherActions(blockly) {
|
193
219
|
const teacherCode = this.getTeacherCode();
|
194
220
|
if (teacherCode) {
|
@@ -332,6 +358,54 @@
|
|
332
358
|
</script>
|
333
359
|
</dom-module>
|
334
360
|
|
361
|
+
<dom-module id="kids-interactive-submit-button">
|
362
|
+
<style>
|
363
|
+
.mu-kids-interactive-submit-button {
|
364
|
+
position: absolute;
|
365
|
+
right: 80px;
|
366
|
+
width: 56px;
|
367
|
+
height: 56px;
|
368
|
+
bottom: 15px;
|
369
|
+
z-index: 70;
|
370
|
+
}
|
371
|
+
|
372
|
+
.mu-kids-interactive-submit-button paper-fab {
|
373
|
+
background-color: #0B456D;
|
374
|
+
}
|
375
|
+
|
376
|
+
</style>
|
377
|
+
|
378
|
+
<template>
|
379
|
+
<div class="mu-kids-interactive-submit-button">
|
380
|
+
<paper-fab icon="av:skip-next"
|
381
|
+
on-click="_onButtonClick"
|
382
|
+
></paper-fab>
|
383
|
+
</div>
|
384
|
+
</template>
|
385
|
+
|
386
|
+
<script>
|
387
|
+
Polymer({
|
388
|
+
is: 'kids-interactive-submit-button',
|
389
|
+
|
390
|
+
ready: function () {
|
391
|
+
this.submitButton = $("kids-submit-button")[0];
|
392
|
+
this.codeRunner = this.submitButton.$.runner;
|
393
|
+
},
|
394
|
+
|
395
|
+
_onButtonClick: function () {
|
396
|
+
const currentPromise = this.submitButton.serverPromise;
|
397
|
+
if(!currentPromise) return;
|
398
|
+
currentPromise.always(() => {
|
399
|
+
const currentResponse = this.submitButton.serverResponse;
|
400
|
+
this.codeRunner.stop();
|
401
|
+
mumuki.kids.showResult(currentResponse);
|
402
|
+
this.codeRunner.isDirty = true;
|
403
|
+
})
|
404
|
+
},
|
405
|
+
});
|
406
|
+
</script>
|
407
|
+
</dom-module>
|
408
|
+
|
335
409
|
<dom-module id="kids-reset-button">
|
336
410
|
<template>
|
337
411
|
<div>
|
@@ -407,13 +481,13 @@
|
|
407
481
|
|
408
482
|
ready: function () {
|
409
483
|
const resetStatusAfterAborted = () => {
|
410
|
-
$('
|
484
|
+
$('.mu-kids-results-aborted').on('hidden.bs.modal', () => {
|
411
485
|
this.$.runner.isDirty = false;
|
412
486
|
this._onResetState();
|
413
487
|
})
|
414
488
|
};
|
415
489
|
const _getScenarioSelector = function (scenario) {
|
416
|
-
return `.mu
|
490
|
+
return `.mu-${scenario}-state .mu-kids-state-image > *`;
|
417
491
|
};
|
418
492
|
|
419
493
|
const _createMultipleScenarios = () => {
|
@@ -433,6 +507,7 @@
|
|
433
507
|
|
434
508
|
_createMultipleScenarios();
|
435
509
|
setInitialState();
|
510
|
+
this.$editor = $("mu-gobstones-custom-editor")[0];
|
436
511
|
},
|
437
512
|
|
438
513
|
_boardToState : function ({size, table, header, boom}) {
|
@@ -442,7 +517,7 @@
|
|
442
517
|
_onRunRequest: function (event) {
|
443
518
|
const {detail: controller} = event;
|
444
519
|
|
445
|
-
const editor = this
|
520
|
+
const editor = this.$editor;
|
446
521
|
const xml = editor.getStudentXml();
|
447
522
|
const code = editor.getStudentCode();
|
448
523
|
const teacherCode = editor.getTeacherCode() || "";
|
@@ -453,19 +528,23 @@
|
|
453
528
|
this._cleanState();
|
454
529
|
this._cleanErrors(finalBoard);
|
455
530
|
|
456
|
-
|
531
|
+
const targetStateIndex = this.multipleScenarios.currentScenarioIndex;
|
532
|
+
this.targetState = this.initialState[targetStateIndex];
|
533
|
+
|
457
534
|
const promise = new mumuki.bridge.Laboratory()
|
458
535
|
.runTests(solution)
|
459
536
|
.then((results) => {
|
460
537
|
if (promise !== this.serverPromise) return;
|
461
538
|
|
462
|
-
this._onRemoteExecutionStop(results)
|
539
|
+
this._onRemoteExecutionStop(results);
|
463
540
|
})
|
464
541
|
.catch(() => {
|
465
542
|
mumuki.kids.showResult({status: 'aborted'})
|
466
543
|
});
|
467
544
|
this.serverPromise = promise;
|
468
545
|
|
546
|
+
editor.toggleInteractiveMode();
|
547
|
+
|
469
548
|
controller.start({
|
470
549
|
initialState: this.targetState,
|
471
550
|
code: {
|
@@ -490,12 +569,32 @@
|
|
490
569
|
_onStop: function (event) {
|
491
570
|
const reason = event.detail;
|
492
571
|
|
572
|
+
const editor = this.$editor;
|
573
|
+
|
493
574
|
if (reason === "end") {
|
575
|
+
this._onExecutionEnd(editor);
|
576
|
+
}
|
577
|
+
else if (reason === "cancel" && editor.interactiveMode) {
|
578
|
+
this._onInteractiveStop(editor);
|
579
|
+
}
|
580
|
+
else this.serverPromise = undefined;
|
581
|
+
},
|
582
|
+
|
583
|
+
_onExecutionEnd: function (editor) {
|
584
|
+
if(editor.interactiveMode) {
|
585
|
+
editor.toggleInteractiveMode();
|
586
|
+
} else {
|
494
587
|
this._onLocalExecutionStop();
|
495
588
|
this._toggleInitialState();
|
496
|
-
this.$.runner.isDirty = true;
|
497
589
|
}
|
498
|
-
|
590
|
+
this.$.runner.isDirty = true;
|
591
|
+
},
|
592
|
+
|
593
|
+
_onInteractiveStop: function (editor) {
|
594
|
+
this._removeBlockErrors();
|
595
|
+
this._cleanState();
|
596
|
+
this._resetBoards();
|
597
|
+
editor.toggleInteractiveMode();
|
499
598
|
},
|
500
599
|
|
501
600
|
_onLocalExecutionStop: function () {
|
@@ -505,8 +604,9 @@
|
|
505
604
|
|
506
605
|
_onRemoteExecutionStop: function (serverResponse) {
|
507
606
|
this.serverResponse = serverResponse;
|
508
|
-
|
509
|
-
|
607
|
+
if (!this.$.runner.isRunning && !this.$editor.interactiveMode) {
|
608
|
+
this._onExecutionStop(serverResponse);
|
609
|
+
}
|
510
610
|
},
|
511
611
|
|
512
612
|
_onExecutionStop: function (data) {
|
@@ -541,12 +641,13 @@
|
|
541
641
|
},
|
542
642
|
|
543
643
|
_updateBoardFromResult: function (originalBoard, resultBoard) {
|
544
|
-
|
545
|
-
if (
|
546
|
-
const boardAttrs = gbbReader.fromString(
|
547
|
-
originalBoard.update(boardAttrs.table, boardAttrs.
|
644
|
+
const resultGbb = resultBoard.textContent;
|
645
|
+
if (resultGbb) {
|
646
|
+
const boardAttrs = gbbReader.fromString(resultGbb);
|
647
|
+
originalBoard.update(boardAttrs.table, boardAttrs.head);
|
548
648
|
}
|
549
649
|
else {
|
650
|
+
resultBoard = resultBoard.cloneNode(); // To force initialization
|
550
651
|
originalBoard.boom = resultBoard.boom;
|
551
652
|
}
|
552
653
|
},
|
@@ -572,7 +673,7 @@
|
|
572
673
|
|
573
674
|
_showError: function (region, error) {
|
574
675
|
const expectsTimeout = /expect_endless_while *: *true/.test(
|
575
|
-
this.
|
676
|
+
this.$editor.getEditorTest().value
|
576
677
|
);
|
577
678
|
|
578
679
|
const isExpectedTimeout = (
|
@@ -592,25 +693,25 @@
|
|
592
693
|
},
|
593
694
|
|
594
695
|
_cleanErrors: function (finalBoard) {
|
595
|
-
this.
|
696
|
+
this._removeBlockErrors();
|
596
697
|
finalBoard.boom = false;
|
597
698
|
},
|
598
699
|
|
700
|
+
_removeBlockErrors: function () {
|
701
|
+
this._getBlockly().workspace.removeBlockErrors();
|
702
|
+
},
|
703
|
+
|
599
704
|
_getLastRegion: function (context = {}) {
|
600
705
|
const {regionStack} = context;
|
601
706
|
return regionStack && regionStack.filter(it => it).slice(-1)[0];
|
602
707
|
},
|
603
708
|
|
604
709
|
_getBlockly: function () {
|
605
|
-
return this.
|
606
|
-
},
|
607
|
-
|
608
|
-
_getEditor: function () {
|
609
|
-
return $("mu-gobstones-custom-editor")[0];
|
710
|
+
return this.$editor.getBlockly();
|
610
711
|
},
|
611
712
|
|
612
713
|
_getInitialBoards: function () {
|
613
|
-
return $(".mu-
|
714
|
+
return $(".mu-initial-state gs-board");
|
614
715
|
},
|
615
716
|
|
616
717
|
_getTargetBoard: function () {
|
@@ -643,6 +744,7 @@
|
|
643
744
|
},
|
644
745
|
|
645
746
|
_toggleInitialState: function () {
|
747
|
+
if(this.$editor.interactiveMode) return;
|
646
748
|
$("#mu-initial-state-text").toggle();
|
647
749
|
$("#mu-actual-state-text").toggle();
|
648
750
|
}
|
@@ -701,6 +803,276 @@
|
|
701
803
|
</script>
|
702
804
|
</dom-module>
|
703
805
|
|
806
|
+
<dom-module id="gs-keyboard-arrow-keys">
|
807
|
+
<template>
|
808
|
+
<div class="gs-keyboard-arrow-keys-container">
|
809
|
+
<svg class="keys-svg" viewBox="0 0 100 100" height="100%">
|
810
|
+
<path d="M50,0 60,10 60,26 40,26 40,10Z" data-direction="DIRECTION_UP" on-tap="dispatchArrowPressed"></path>
|
811
|
+
<path d="M50,100 60,90 60,74 40,74 40,90Z" data-direction="DIRECTION_DOWN" on-tap="dispatchArrowPressed"></path>
|
812
|
+
<path d="M0,50 10,60 26,60 26,40 10,40Z" data-direction="DIRECTION_LEFT" on-tap="dispatchArrowPressed"></path>
|
813
|
+
<path d="M100,50 90,60 74,60 74,40 90,40Z" data-direction="DIRECTION_RIGHT" on-tap="dispatchArrowPressed"></path>
|
814
|
+
</svg>
|
815
|
+
</div>
|
816
|
+
</template>
|
817
|
+
|
818
|
+
<style>
|
819
|
+
.gs-keyboard-arrow-keys path {
|
820
|
+
fill: #0B456D;
|
821
|
+
cursor: pointer;
|
822
|
+
}
|
823
|
+
|
824
|
+
.gs-keyboard-arrow-keys-container {
|
825
|
+
height: 100%;
|
826
|
+
width: 100%;
|
827
|
+
position: relative;
|
828
|
+
}
|
829
|
+
|
830
|
+
.keys-svg {
|
831
|
+
display: block;
|
832
|
+
margin: 0 auto;
|
833
|
+
padding-left: 10px;
|
834
|
+
overflow: visible;
|
835
|
+
}
|
836
|
+
|
837
|
+
.keys-svg path {
|
838
|
+
filter: drop-shadow(2px 2px 2px rgba(11, 70, 93, .4));
|
839
|
+
-webkit-filter: drop-shadow(2px 2px 2px rgba(11, 70, 93, .4));
|
840
|
+
}
|
841
|
+
|
842
|
+
.keys-svg path.pressed {
|
843
|
+
filter: drop-shadow(1px 1px 1px rgba(11, 70, 93, .4));
|
844
|
+
-webkit-filter: drop-shadow(1px 1px 1px rgba(11, 70, 93, .4));
|
845
|
+
transform: translate(1px, 1px);
|
846
|
+
}
|
847
|
+
</style>
|
848
|
+
|
849
|
+
<script>
|
850
|
+
Polymer({
|
851
|
+
is: 'gs-keyboard-arrow-keys',
|
852
|
+
properties: {
|
853
|
+
dispatchKeydown: {
|
854
|
+
type: Object
|
855
|
+
}
|
856
|
+
},
|
857
|
+
ready: function () {
|
858
|
+
},
|
859
|
+
clickTransition: function (direction) {
|
860
|
+
const arrow = $(this).find('path[data-direction=' + direction +']');
|
861
|
+
arrow.toggleClass('pressed');
|
862
|
+
setTimeout(() => arrow.toggleClass('pressed'), 300);
|
863
|
+
},
|
864
|
+
dispatchArrowPressed: function (event) {
|
865
|
+
const direction = event.target.dataset.direction;
|
866
|
+
this.dispatchKeydown(Hammer[direction]);
|
867
|
+
this.clickTransition(direction);
|
868
|
+
}
|
869
|
+
})
|
870
|
+
</script>
|
871
|
+
</dom-module>
|
872
|
+
|
873
|
+
<dom-module id="gs-keyboard-key">
|
874
|
+
<template>
|
875
|
+
<button class="gs-keyboard-button" on-tap="dispatch" type="button" class="btn btn-secondary gs-keyboard-key">
|
876
|
+
{{ key }}
|
877
|
+
</button>
|
878
|
+
</template>
|
879
|
+
|
880
|
+
<style>
|
881
|
+
.gs-keyboard-key {
|
882
|
+
background-color: #ecf0f1;
|
883
|
+
border: 1px solid #dce4ec;
|
884
|
+
border-radius: 4px;
|
885
|
+
cursor: pointer;
|
886
|
+
margin-bottom: 3px;
|
887
|
+
}
|
888
|
+
|
889
|
+
.gs-keyboard-key {
|
890
|
+
height: 100%;
|
891
|
+
width: 100%;
|
892
|
+
}
|
893
|
+
|
894
|
+
.gs-keyboard-key:hover {
|
895
|
+
color: unset;
|
896
|
+
}
|
897
|
+
|
898
|
+
.gs-keyboard-key:focus {
|
899
|
+
outline-color: #0B456D;
|
900
|
+
}
|
901
|
+
</style>
|
902
|
+
|
903
|
+
<script>
|
904
|
+
Polymer({
|
905
|
+
is: 'gs-keyboard-key',
|
906
|
+
properties: {
|
907
|
+
key: {
|
908
|
+
type: String
|
909
|
+
},
|
910
|
+
keyCode: {
|
911
|
+
type: String,
|
912
|
+
},
|
913
|
+
dispatchKeydown: {
|
914
|
+
type: Object
|
915
|
+
}
|
916
|
+
},
|
917
|
+
ready: function () {
|
918
|
+
if(!this.keyCode) {
|
919
|
+
this.keyCode = this.key;
|
920
|
+
}
|
921
|
+
},
|
922
|
+
dispatch: function () {
|
923
|
+
this.dispatchKeydown(this.keyCode)
|
924
|
+
}
|
925
|
+
})
|
926
|
+
</script>
|
927
|
+
</dom-module>
|
928
|
+
|
929
|
+
<dom-module id="gs-keyboard">
|
930
|
+
<style>
|
931
|
+
.gs-keyboard-container {
|
932
|
+
display: flex;
|
933
|
+
flex-direction: row;
|
934
|
+
justify-content: center;
|
935
|
+
height: 100%;
|
936
|
+
}
|
937
|
+
|
938
|
+
.gs-keyboard-container .section {
|
939
|
+
flex-grow: 4;
|
940
|
+
height: 100%;
|
941
|
+
width: 100%;
|
942
|
+
}
|
943
|
+
|
944
|
+
.arrow-keys {
|
945
|
+
padding: 15px 0;
|
946
|
+
}
|
947
|
+
|
948
|
+
.gs-keyboard-key-container.small {
|
949
|
+
flex-basis: 33%;
|
950
|
+
}
|
951
|
+
|
952
|
+
.gs-keyboard-key-container {
|
953
|
+
flex-grow: 1;
|
954
|
+
padding: 1px;
|
955
|
+
}
|
956
|
+
|
957
|
+
.gs-keyboard-keys-container {
|
958
|
+
display: flex;
|
959
|
+
flex-wrap: wrap;
|
960
|
+
}
|
961
|
+
|
962
|
+
</style>
|
963
|
+
|
964
|
+
<template>
|
965
|
+
<template is="dom-if" if="{{configLoaded}}">
|
966
|
+
<div class="gs-keyboard-container">
|
967
|
+
<div class="section gs-keyboard-keys-container">
|
968
|
+
<template is="dom-repeat" items="{{keyboardConfig.keys}}" as="key">
|
969
|
+
<gs-keyboard-key class="gs-keyboard-key-container small" dispatch-keydown="{{dispatchKeydown}}" key="{{key}}"></gs-keyboard-key>
|
970
|
+
</template>
|
971
|
+
<!-- Should definitely internationalize the space key below -->
|
972
|
+
<gs-keyboard-key class="gs-keyboard-key-container" dispatch-keydown="{{dispatchKeydown}}" key="ESPACIO" key-code="space"></gs-keyboard-key>
|
973
|
+
</div>
|
974
|
+
<template is="dom-if" if="[[_shouldDisplayArrows(keyboardConfig)]]">
|
975
|
+
<div class="section arrow-keys">
|
976
|
+
<gs-keyboard-arrow-keys dispatch-keydown="{{dispatchKeydown}}">
|
977
|
+
</gs-keyboard-arrow-keys>
|
978
|
+
</div>
|
979
|
+
</template>
|
980
|
+
</div>
|
981
|
+
</template>
|
982
|
+
</template>
|
983
|
+
|
984
|
+
<script>
|
985
|
+
Polymer({
|
986
|
+
is: 'gs-keyboard',
|
987
|
+
properties: {
|
988
|
+
keyboardConfig: {
|
989
|
+
type: Object
|
990
|
+
},
|
991
|
+
dispatchKeydown: {
|
992
|
+
type: Object,
|
993
|
+
value: function () {
|
994
|
+
return function (key) {
|
995
|
+
const keyCode = GobstonesKeyboard.keyboardMap[key] || key.charCodeAt(0);
|
996
|
+
const event = new KeyboardEvent('keydown', {'keyCode': keyCode, 'which': keyCode});
|
997
|
+
document.dispatchEvent(event);
|
998
|
+
};
|
999
|
+
}
|
1000
|
+
},
|
1001
|
+
configLoaded: {
|
1002
|
+
type: Boolean,
|
1003
|
+
value: false,
|
1004
|
+
observer: '_onConfigLoaded'
|
1005
|
+
}
|
1006
|
+
},
|
1007
|
+
ready: function () {
|
1008
|
+
document.addEventListener('gs-keyboard-config-changed', this._loadConfig.bind(this));
|
1009
|
+
this._loadConfig();
|
1010
|
+
},
|
1011
|
+
_onConfigLoaded: function () {
|
1012
|
+
if(this.configLoaded) this._createSwipeListener();
|
1013
|
+
},
|
1014
|
+
_createSwipeListener: function () {
|
1015
|
+
if(typeof Hammer === "undefined") return postpone(this._createSwipeListener);
|
1016
|
+
const $swipeListenerArea = $('.mu-initial-state gs-board')[0];
|
1017
|
+
const hammer = new Hammer($swipeListenerArea);
|
1018
|
+
hammer.get('swipe').set({direction: Hammer.DIRECTION_ALL});
|
1019
|
+
hammer.on('swipe', (event) => {
|
1020
|
+
this.dispatchKeydown(event.direction)
|
1021
|
+
});
|
1022
|
+
},
|
1023
|
+
_loadConfig: function () {
|
1024
|
+
if (typeof GobstonesKeyboard !== "undefined") {
|
1025
|
+
this.keyboardConfig = GobstonesKeyboard.config;
|
1026
|
+
this.configLoaded = true;
|
1027
|
+
}
|
1028
|
+
},
|
1029
|
+
_shouldDisplayArrows: function (keyboardConfig) {
|
1030
|
+
return keyboardConfig && keyboardConfig.showArrows;
|
1031
|
+
}
|
1032
|
+
})
|
1033
|
+
</script>
|
1034
|
+
</dom-module>
|
1035
|
+
|
1036
|
+
<dom-module id="gs-keyboard-config">
|
1037
|
+
<script>
|
1038
|
+
Polymer({
|
1039
|
+
is: 'gs-keyboard-config',
|
1040
|
+
properties: {
|
1041
|
+
keyboardUrl: Object,
|
1042
|
+
observer: '_keyboardChanged'
|
1043
|
+
},
|
1044
|
+
|
1045
|
+
attached: function () {
|
1046
|
+
this._createKeyboardConfig();
|
1047
|
+
this._setKeyboard();
|
1048
|
+
},
|
1049
|
+
|
1050
|
+
_createKeyboardConfig: function () {
|
1051
|
+
if(typeof GobstonesKeyboard === 'undefined') GobstonesKeyboard = {};
|
1052
|
+
if(typeof Hammer === "undefined") return postpone(this._createKeyboardConfig);
|
1053
|
+
GobstonesKeyboard.keyboardMap = {
|
1054
|
+
[Hammer.DIRECTION_LEFT]: 37,
|
1055
|
+
[Hammer.DIRECTION_UP]: 38,
|
1056
|
+
[Hammer.DIRECTION_RIGHT]: 39,
|
1057
|
+
[Hammer.DIRECTION_DOWN]: 40,
|
1058
|
+
'space': 32
|
1059
|
+
}
|
1060
|
+
},
|
1061
|
+
|
1062
|
+
_keyboardChanged: function () {
|
1063
|
+
this._setKeyboard();
|
1064
|
+
},
|
1065
|
+
|
1066
|
+
_setKeyboard: function () {
|
1067
|
+
$.getJSON(this.keyboardUrl, (keyboardConfig) => {
|
1068
|
+
GobstonesKeyboard.config = keyboardConfig;
|
1069
|
+
this.fire('gs-keyboard-config-changed');
|
1070
|
+
})
|
1071
|
+
}
|
1072
|
+
});
|
1073
|
+
</script>
|
1074
|
+
</dom-module>
|
1075
|
+
|
704
1076
|
<dom-module id="gs-attire-toggle-button">
|
705
1077
|
<style>
|
706
1078
|
.button {
|
@@ -756,17 +1128,22 @@
|
|
756
1128
|
});
|
757
1129
|
},
|
758
1130
|
|
1131
|
+
_getEditor: function () {
|
1132
|
+
return $("mu-gobstones-custom-editor")[0];
|
1133
|
+
},
|
1134
|
+
|
759
1135
|
_relocateButton: function () {
|
760
1136
|
const $container = $('.mu-kids-gbs-board-initial');
|
761
|
-
if(!$container.length) return;
|
1137
|
+
if(!$container.length || this._getEditor().interactiveMode) return;
|
762
1138
|
const $header = $('.mu-initial-state-header');
|
1139
|
+
const headerWidth = $header.width() || $container.width();
|
763
1140
|
const $attireToggle = $container.find('.button.gs-attire-toggle-button');
|
764
1141
|
if(!$attireToggle.length) return setTimeout(() => this._relocateButton());
|
765
1142
|
const margin = 4; // Leave a margin between text and image
|
766
1143
|
const maxSize = 65.75; // Original width
|
767
1144
|
mumuki.resize(() => {
|
768
1145
|
$attireToggle.css('transform', 'scale(1)');
|
769
|
-
let buttonSize = (($container.width() -
|
1146
|
+
let buttonSize = (($container.width() - headerWidth) / 2) - margin;
|
770
1147
|
let scaleX = Math.min(buttonSize, maxSize) / $attireToggle.width();
|
771
1148
|
$attireToggle.css('transform', `scale(${scaleX})`);
|
772
1149
|
});
|
data/lib/render/editor/editor.js
CHANGED
@@ -2,4 +2,23 @@ $(document).ready(function () {
|
|
2
2
|
$(".mu-kids-submit-button").html("<kids-submit-button></kids-submit-button>");
|
3
3
|
$(".mu-kids-reset-button").html("<kids-reset-button></kids-reset-button>");
|
4
4
|
$(".mu-initial-state-header").append("<gs-attire-toggle-button></gs-attire-toggle-button>");
|
5
|
+
|
6
|
+
mumuki.kids.registerStateScaler(($state, fullMargin, preferredWidth, preferredHeight) => {
|
7
|
+
const $table = $state.find('.active gs-board > table');
|
8
|
+
if(!$table.length) return setTimeout(() => mumuki.kids.scaleState($state, fullMargin));
|
9
|
+
|
10
|
+
$table.css('transform', 'scale(1)');
|
11
|
+
$table.css('transform', 'scale(' + Math.min(preferredWidth / $table.width(), preferredHeight / $table.height()) + ')');
|
12
|
+
});
|
13
|
+
|
14
|
+
mumuki.kids.registerBlocksAreaScaler(($blocks) => {
|
15
|
+
const $blockArea = $blocks.find('#blocklyDiv');
|
16
|
+
const $blockSvg = $blocks.find('.blocklySvg');
|
17
|
+
|
18
|
+
$blockArea.width($blocks.width());
|
19
|
+
$blockArea.height($blocks.height());
|
20
|
+
|
21
|
+
$blockSvg.width($blocks.width());
|
22
|
+
$blockSvg.height($blocks.height());
|
23
|
+
});
|
5
24
|
});
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/*! Hammer.JS - v2.0.8 - 2016-04-23
|
2
|
+
* http://hammerjs.github.io/
|
3
|
+
*
|
4
|
+
* Copyright (c) 2016 Jorik Tangelder;
|
5
|
+
* Licensed under the MIT license */
|
6
|
+
!function(a,b,c,d){"use strict";function e(a,b,c){return setTimeout(j(a,c),b)}function f(a,b,c){return Array.isArray(a)?(g(a,c[b],c),!0):!1}function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function h(b,c,d){var e="DEPRECATED METHOD: "+c+"\n"+d+" AT \n";return function(){var c=new Error("get-stack-trace"),d=c&&c.stack?c.stack.replace(/^[^\(]+?[\n$]/gm,"").replace(/^\s+at\s+/gm,"").replace(/^Object.<anonymous>\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",f=a.console&&(a.console.warn||a.console.log);return f&&f.call(a.console,e,d),b.apply(this,arguments)}}function i(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.constructor=a,d._super=e,c&&la(d,c)}function j(a,b){return function(){return a.apply(b,arguments)}}function k(a,b){return typeof a==oa?a.apply(b?b[0]||d:d,b):a}function l(a,b){return a===d?b:a}function m(a,b,c){g(q(b),function(b){a.addEventListener(b,c,!1)})}function n(a,b,c){g(q(b),function(b){a.removeEventListener(b,c,!1)})}function o(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function p(a,b){return a.indexOf(b)>-1}function q(a){return a.trim().split(/\s+/g)}function r(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function s(a){return Array.prototype.slice.call(a,0)}function t(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];r(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function u(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g<ma.length;){if(c=ma[g],e=c?c+f:b,e in a)return e;g++}return d}function v(){return ua++}function w(b){var c=b.ownerDocument||b;return c.defaultView||c.parentWindow||a}function x(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){k(a.options.enable,[a])&&c.handler(b)},this.init()}function y(a){var b,c=a.options.inputClass;return new(b=c?c:xa?M:ya?P:wa?R:L)(a,z)}function z(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&Ea&&d-e===0,g=b&(Ga|Ha)&&d-e===0;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,A(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function A(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=D(b)),e>1&&!c.firstMultiple?c.firstMultiple=D(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=E(d);b.timeStamp=ra(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=I(h,i),b.distance=H(h,i),B(c,b),b.offsetDirection=G(b.deltaX,b.deltaY);var j=F(b.deltaTime,b.deltaX,b.deltaY);b.overallVelocityX=j.x,b.overallVelocityY=j.y,b.overallVelocity=qa(j.x)>qa(j.y)?j.x:j.y,b.scale=g?K(g.pointers,d):1,b.rotation=g?J(g.pointers,d):0,b.maxPointers=c.prevInput?b.pointers.length>c.prevInput.maxPointers?b.pointers.length:c.prevInput.maxPointers:b.pointers.length,C(c,b);var k=a.element;o(b.srcEvent.target,k)&&(k=b.srcEvent.target),b.target=k}function B(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};b.eventType!==Ea&&f.eventType!==Ga||(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function C(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStamp;if(b.eventType!=Ha&&(i>Da||h.velocity===d)){var j=b.deltaX-h.deltaX,k=b.deltaY-h.deltaY,l=F(i,j,k);e=l.x,f=l.y,c=qa(l.x)>qa(l.y)?l.x:l.y,g=G(j,k),a.lastInterval=b}else c=h.velocity,e=h.velocityX,f=h.velocityY,g=h.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g}function D(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:pa(a.pointers[c].clientX),clientY:pa(a.pointers[c].clientY)},c++;return{timeStamp:ra(),pointers:b,center:E(b),deltaX:a.deltaX,deltaY:a.deltaY}}function E(a){var b=a.length;if(1===b)return{x:pa(a[0].clientX),y:pa(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:pa(c/b),y:pa(d/b)}}function F(a,b,c){return{x:b/a||0,y:c/a||0}}function G(a,b){return a===b?Ia:qa(a)>=qa(b)?0>a?Ja:Ka:0>b?La:Ma}function H(a,b,c){c||(c=Qa);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function I(a,b,c){c||(c=Qa);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function J(a,b){return I(b[1],b[0],Ra)+I(a[1],a[0],Ra)}function K(a,b){return H(b[0],b[1],Ra)/H(a[0],a[1],Ra)}function L(){this.evEl=Ta,this.evWin=Ua,this.pressed=!1,x.apply(this,arguments)}function M(){this.evEl=Xa,this.evWin=Ya,x.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function N(){this.evTarget=$a,this.evWin=_a,this.started=!1,x.apply(this,arguments)}function O(a,b){var c=s(a.touches),d=s(a.changedTouches);return b&(Ga|Ha)&&(c=t(c.concat(d),"identifier",!0)),[c,d]}function P(){this.evTarget=bb,this.targetIds={},x.apply(this,arguments)}function Q(a,b){var c=s(a.touches),d=this.targetIds;if(b&(Ea|Fa)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=s(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return o(a.target,i)}),b===Ea)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Ga|Ha)&&delete d[g[e].identifier],e++;return h.length?[t(f.concat(h),"identifier",!0),h]:void 0}function R(){x.apply(this,arguments);var a=j(this.handler,this);this.touch=new P(this.manager,a),this.mouse=new L(this.manager,a),this.primaryTouch=null,this.lastTouches=[]}function S(a,b){a&Ea?(this.primaryTouch=b.changedPointers[0].identifier,T.call(this,b)):a&(Ga|Ha)&&T.call(this,b)}function T(a){var b=a.changedPointers[0];if(b.identifier===this.primaryTouch){var c={x:b.clientX,y:b.clientY};this.lastTouches.push(c);var d=this.lastTouches,e=function(){var a=d.indexOf(c);a>-1&&d.splice(a,1)};setTimeout(e,cb)}}function U(a){for(var b=a.srcEvent.clientX,c=a.srcEvent.clientY,d=0;d<this.lastTouches.length;d++){var e=this.lastTouches[d],f=Math.abs(b-e.x),g=Math.abs(c-e.y);if(db>=f&&db>=g)return!0}return!1}function V(a,b){this.manager=a,this.set(b)}function W(a){if(p(a,jb))return jb;var b=p(a,kb),c=p(a,lb);return b&&c?jb:b||c?b?kb:lb:p(a,ib)?ib:hb}function X(){if(!fb)return!1;var b={},c=a.CSS&&a.CSS.supports;return["auto","manipulation","pan-y","pan-x","pan-x pan-y","none"].forEach(function(d){b[d]=c?a.CSS.supports("touch-action",d):!0}),b}function Y(a){this.options=la({},this.defaults,a||{}),this.id=v(),this.manager=null,this.options.enable=l(this.options.enable,!0),this.state=nb,this.simultaneous={},this.requireFail=[]}function Z(a){return a&sb?"cancel":a&qb?"end":a&pb?"move":a&ob?"start":""}function $(a){return a==Ma?"down":a==La?"up":a==Ja?"left":a==Ka?"right":""}function _(a,b){var c=b.manager;return c?c.get(a):a}function aa(){Y.apply(this,arguments)}function ba(){aa.apply(this,arguments),this.pX=null,this.pY=null}function ca(){aa.apply(this,arguments)}function da(){Y.apply(this,arguments),this._timer=null,this._input=null}function ea(){aa.apply(this,arguments)}function fa(){aa.apply(this,arguments)}function ga(){Y.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function ha(a,b){return b=b||{},b.recognizers=l(b.recognizers,ha.defaults.preset),new ia(a,b)}function ia(a,b){this.options=la({},ha.defaults,b||{}),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=a,this.input=y(this),this.touchAction=new V(this,this.options.touchAction),ja(this,!0),g(this.options.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function ja(a,b){var c=a.element;if(c.style){var d;g(a.options.cssProps,function(e,f){d=u(c.style,f),b?(a.oldCssProps[d]=c.style[d],c.style[d]=e):c.style[d]=a.oldCssProps[d]||""}),b||(a.oldCssProps={})}}function ka(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var la,ma=["","webkit","Moz","MS","ms","o"],na=b.createElement("div"),oa="function",pa=Math.round,qa=Math.abs,ra=Date.now;la="function"!=typeof Object.assign?function(a){if(a===d||null===a)throw new TypeError("Cannot convert undefined or null to object");for(var b=Object(a),c=1;c<arguments.length;c++){var e=arguments[c];if(e!==d&&null!==e)for(var f in e)e.hasOwnProperty(f)&&(b[f]=e[f])}return b}:Object.assign;var sa=h(function(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a},"extend","Use `assign`."),ta=h(function(a,b){return sa(a,b,!0)},"merge","Use `assign`."),ua=1,va=/mobile|tablet|ip(ad|hone|od)|android/i,wa="ontouchstart"in a,xa=u(a,"PointerEvent")!==d,ya=wa&&va.test(navigator.userAgent),za="touch",Aa="pen",Ba="mouse",Ca="kinect",Da=25,Ea=1,Fa=2,Ga=4,Ha=8,Ia=1,Ja=2,Ka=4,La=8,Ma=16,Na=Ja|Ka,Oa=La|Ma,Pa=Na|Oa,Qa=["x","y"],Ra=["clientX","clientY"];x.prototype={handler:function(){},init:function(){this.evEl&&m(this.element,this.evEl,this.domHandler),this.evTarget&&m(this.target,this.evTarget,this.domHandler),this.evWin&&m(w(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&n(this.element,this.evEl,this.domHandler),this.evTarget&&n(this.target,this.evTarget,this.domHandler),this.evWin&&n(w(this.element),this.evWin,this.domHandler)}};var Sa={mousedown:Ea,mousemove:Fa,mouseup:Ga},Ta="mousedown",Ua="mousemove mouseup";i(L,x,{handler:function(a){var b=Sa[a.type];b&Ea&&0===a.button&&(this.pressed=!0),b&Fa&&1!==a.which&&(b=Ga),this.pressed&&(b&Ga&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:Ba,srcEvent:a}))}});var Va={pointerdown:Ea,pointermove:Fa,pointerup:Ga,pointercancel:Ha,pointerout:Ha},Wa={2:za,3:Aa,4:Ba,5:Ca},Xa="pointerdown",Ya="pointermove pointerup pointercancel";a.MSPointerEvent&&!a.PointerEvent&&(Xa="MSPointerDown",Ya="MSPointerMove MSPointerUp MSPointerCancel"),i(M,x,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=Va[d],f=Wa[a.pointerType]||a.pointerType,g=f==za,h=r(b,a.pointerId,"pointerId");e&Ea&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Ga|Ha)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var Za={touchstart:Ea,touchmove:Fa,touchend:Ga,touchcancel:Ha},$a="touchstart",_a="touchstart touchmove touchend touchcancel";i(N,x,{handler:function(a){var b=Za[a.type];if(b===Ea&&(this.started=!0),this.started){var c=O.call(this,a,b);b&(Ga|Ha)&&c[0].length-c[1].length===0&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:za,srcEvent:a})}}});var ab={touchstart:Ea,touchmove:Fa,touchend:Ga,touchcancel:Ha},bb="touchstart touchmove touchend touchcancel";i(P,x,{handler:function(a){var b=ab[a.type],c=Q.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:za,srcEvent:a})}});var cb=2500,db=25;i(R,x,{handler:function(a,b,c){var d=c.pointerType==za,e=c.pointerType==Ba;if(!(e&&c.sourceCapabilities&&c.sourceCapabilities.firesTouchEvents)){if(d)S.call(this,b,c);else if(e&&U.call(this,c))return;this.callback(a,b,c)}},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var eb=u(na.style,"touchAction"),fb=eb!==d,gb="compute",hb="auto",ib="manipulation",jb="none",kb="pan-x",lb="pan-y",mb=X();V.prototype={set:function(a){a==gb&&(a=this.compute()),fb&&this.manager.element.style&&mb[a]&&(this.manager.element.style[eb]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return g(this.manager.recognizers,function(b){k(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),W(a.join(" "))},preventDefaults:function(a){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return void b.preventDefault();var d=this.actions,e=p(d,jb)&&!mb[jb],f=p(d,lb)&&!mb[lb],g=p(d,kb)&&!mb[kb];if(e){var h=1===a.pointers.length,i=a.distance<2,j=a.deltaTime<250;if(h&&i&&j)return}return g&&f?void 0:e||f&&c&Na||g&&c&Oa?this.preventSrc(b):void 0},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var nb=1,ob=2,pb=4,qb=8,rb=qb,sb=16,tb=32;Y.prototype={defaults:{},set:function(a){return la(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(f(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=_(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return f(a,"dropRecognizeWith",this)?this:(a=_(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(f(a,"requireFailure",this))return this;var b=this.requireFail;return a=_(a,this),-1===r(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(f(a,"dropRequireFailure",this))return this;a=_(a,this);var b=r(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function b(b){c.manager.emit(b,a)}var c=this,d=this.state;qb>d&&b(c.options.event+Z(d)),b(c.options.event),a.additionalEvent&&b(a.additionalEvent),d>=qb&&b(c.options.event+Z(d))},tryEmit:function(a){return this.canEmit()?this.emit(a):void(this.state=tb)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(tb|nb)))return!1;a++}return!0},recognize:function(a){var b=la({},a);return k(this.options.enable,[this,b])?(this.state&(rb|sb|tb)&&(this.state=nb),this.state=this.process(b),void(this.state&(ob|pb|qb|sb)&&this.tryEmit(b))):(this.reset(),void(this.state=tb))},process:function(a){},getTouchAction:function(){},reset:function(){}},i(aa,Y,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(ob|pb),e=this.attrTest(a);return d&&(c&Ha||!e)?b|sb:d||e?c&Ga?b|qb:b&ob?b|pb:ob:tb}}),i(ba,aa,{defaults:{event:"pan",threshold:10,pointers:1,direction:Pa},getTouchAction:function(){var a=this.options.direction,b=[];return a&Na&&b.push(lb),a&Oa&&b.push(kb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&Na?(e=0===f?Ia:0>f?Ja:Ka,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?Ia:0>g?La:Ma,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return aa.prototype.attrTest.call(this,a)&&(this.state&ob||!(this.state&ob)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=$(a.direction);b&&(a.additionalEvent=this.options.event+b),this._super.emit.call(this,a)}}),i(ca,aa,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[jb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&ob)},emit:function(a){if(1!==a.scale){var b=a.scale<1?"in":"out";a.additionalEvent=this.options.event+b}this._super.emit.call(this,a)}}),i(da,Y,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function(){return[hb]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Ga|Ha)&&!f)this.reset();else if(a.eventType&Ea)this.reset(),this._timer=e(function(){this.state=rb,this.tryEmit()},b.time,this);else if(a.eventType&Ga)return rb;return tb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===rb&&(a&&a.eventType&Ga?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=ra(),this.manager.emit(this.options.event,this._input)))}}),i(ea,aa,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[jb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&ob)}}),i(fa,aa,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:Na|Oa,pointers:1},getTouchAction:function(){return ba.prototype.getTouchAction.call(this)},attrTest:function(a){var b,c=this.options.direction;return c&(Na|Oa)?b=a.overallVelocity:c&Na?b=a.overallVelocityX:c&Oa&&(b=a.overallVelocityY),this._super.attrTest.call(this,a)&&c&a.offsetDirection&&a.distance>this.options.threshold&&a.maxPointers==this.options.pointers&&qa(b)>this.options.velocity&&a.eventType&Ga},emit:function(a){var b=$(a.offsetDirection);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),i(ga,Y,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return[ib]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime<b.time;if(this.reset(),a.eventType&Ea&&0===this.count)return this.failTimeout();if(d&&f&&c){if(a.eventType!=Ga)return this.failTimeout();var g=this.pTime?a.timeStamp-this.pTime<b.interval:!0,h=!this.pCenter||H(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,h&&g?this.count+=1:this.count=1,this._input=a;var i=this.count%b.taps;if(0===i)return this.hasRequireFailures()?(this._timer=e(function(){this.state=rb,this.tryEmit()},b.interval,this),ob):rb}return tb},failTimeout:function(){return this._timer=e(function(){this.state=tb},this.options.interval,this),tb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==rb&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),ha.VERSION="2.0.8",ha.defaults={domEvents:!1,touchAction:gb,enable:!0,inputTarget:null,inputClass:null,preset:[[ea,{enable:!1}],[ca,{enable:!1},["rotate"]],[fa,{direction:Na}],[ba,{direction:Na},["swipe"]],[ga],[ga,{event:"doubletap",taps:2},["tap"]],[da]],cssProps:{userSelect:"none",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var ub=1,vb=2;ia.prototype={set:function(a){return la(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?vb:ub},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&rb)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===vb||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(ob|pb|qb)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof Y)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(f(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(f(a,"remove",this))return this;if(a=this.get(a)){var b=this.recognizers,c=r(b,a);-1!==c&&(b.splice(c,1),this.touchAction.update())}return this},on:function(a,b){if(a!==d&&b!==d){var c=this.handlers;return g(q(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this}},off:function(a,b){if(a!==d){var c=this.handlers;return g(q(a),function(a){b?c[a]&&c[a].splice(r(c[a],b),1):delete c[a]}),this}},emit:function(a,b){this.options.domEvents&&ka(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&ja(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},la(ha,{INPUT_START:Ea,INPUT_MOVE:Fa,INPUT_END:Ga,INPUT_CANCEL:Ha,STATE_POSSIBLE:nb,STATE_BEGAN:ob,STATE_CHANGED:pb,STATE_ENDED:qb,STATE_RECOGNIZED:rb,STATE_CANCELLED:sb,STATE_FAILED:tb,DIRECTION_NONE:Ia,DIRECTION_LEFT:Ja,DIRECTION_RIGHT:Ka,DIRECTION_UP:La,DIRECTION_DOWN:Ma,DIRECTION_HORIZONTAL:Na,DIRECTION_VERTICAL:Oa,DIRECTION_ALL:Pa,Manager:ia,Input:x,TouchAction:V,TouchInput:P,MouseInput:L,PointerEventInput:M,TouchMouseInput:R,SingleTouchInput:N,Recognizer:Y,AttrRecognizer:aa,Tap:ga,Pan:ba,Swipe:fa,Pinch:ca,Rotate:ea,Press:da,on:m,off:n,each:g,merge:ta,extend:sa,assign:la,inherit:i,bindFn:j,prefixed:u});var wb="undefined"!=typeof a?a:"undefined"!=typeof self?self:{};wb.Hammer=ha,"function"==typeof define&&define.amd?define(function(){return ha}):"undefined"!=typeof module&&module.exports?module.exports=ha:a[c]=ha}(window,document,"Hammer");
|
7
|
+
//# sourceMappingURL=hammer.min.js.map
|
data/lib/test_hook.rb
CHANGED
@@ -2,7 +2,9 @@ class GobstonesTestHook < Mumukit::Defaults::TestHook
|
|
2
2
|
def run!(request)
|
3
3
|
output, status = request.result
|
4
4
|
|
5
|
-
if
|
5
|
+
if request.batch.options[:interactive]
|
6
|
+
['', :passed]
|
7
|
+
elsif status == :passed
|
6
8
|
request.batch.run_tests! output
|
7
9
|
else
|
8
10
|
request.result
|
data/lib/version_hook.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mumuki-gobstones-runner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Alfonso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mumukit
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/render/editor/editor.css
|
185
185
|
- lib/render/editor/editor.html
|
186
186
|
- lib/render/editor/editor.js
|
187
|
+
- lib/render/editor/hammer.min.js
|
187
188
|
- lib/render/html_board.rb
|
188
189
|
- lib/render/html_renderer.rb
|
189
190
|
- lib/render/with_renderer.rb
|