From 68cc91f95d0e129ced4137b86f519135db59a293 Mon Sep 17 00:00:00 2001 From: Haifeng Luo Date: Sun, 11 Apr 2021 20:33:16 +0800 Subject: [PATCH] Translate 12 tasks. --- _common/modules/bundles/bebras-interface.js | 3164 ++++++++--------- .../pemFioi/buttonsAndMessages.js | 92 +- .../official/miniPlatform.js | 2 +- .../official/miniPlatform_M.js | 4 +- _common/modules/pemFioi/quickAlgo/doc.js | 2 +- bebras/2018/2018-FR-05-treasure/index_en.html | 8 +- .../2018/2018-FR-05-treasure/index_en2.html | 12 +- bebras/2019/FR-2019-01-poles/index_en.html | 18 +- .../2019/FR-2019-02-registers/index_en.html | 36 +- .../2019/FR-2019-03-prediction/index_en.html | 40 +- .../2019/FR-2019-06-inclusions/index_en.html | 26 +- .../2019/FR-2019-07-two-connect/index_en.html | 24 +- bebras/2019/FR-2019-08-patterns/index_en.html | 24 +- .../FR-2019-09-hidden-words/index_en.html | 54 +- bebras/2019/FR-2019-10-lighting/index_en.html | 42 +- bebras/2019/FR-2019-12-roller/index_en.html | 38 +- .../FR-2019-13-align-strips/index_en.html | 32 +- .../index_en.html | 36 +- .../FR-2019-17-base-4-encoding/index_en.html | 20 +- bebras/2019/contents.js | 24 +- 20 files changed, 1849 insertions(+), 1849 deletions(-) diff --git a/_common/modules/bundles/bebras-interface.js b/_common/modules/bundles/bebras-interface.js index 2c3b109..b2fd703 100644 --- a/_common/modules/bundles/bebras-interface.js +++ b/_common/modules/bundles/bebras-interface.js @@ -1,267 +1,267 @@ -(function () { - -'use strict'; - -function getUrlParameterByName(name) { - name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); - var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), - results = regex.exec(location.href); - return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); -} - -function isCrossDomain() { - function isInIframe() { - try { - return window.self !== window.top; - } catch (e) { - return false; - } - } - function isSameDomain() { - var res = false; - function doNothing(document){} - try{ - res = !! parent.document; - } catch(e){ - res = false; - } - return res; - } - return isInIframe() && !isSameDomain(); -} - -var platform; - -if (!isCrossDomain()) { - - /* Implementation of a platform proxy for the task iframe. This object is always - * available, but is effective only when setPlatform is called with a true - * platform object. - */ - - platform = { - registered_objects: [], - parent_platform: null, - initFailed: false, - setPlatform: function(platformArg) { - platform.parent_platform = platformArg; - }, - trigger: function(event, content) { - for (var i = 0; i < platform.registered_objects.length; i++) { - var object = platform.registered_objects[i]; - if (typeof (object[event]) != "undefined") { - object[event].apply(object, content); - } - } - }, - subscribe: function(object) { - this.registered_objects.push(object); - }, - unsubscribe: function(object) { - var index = this.registered_objects.indexOf(object); - if (index != -1) { - this.registered_objects.splice(index, 1); - } - }, - validate: function(mode, success, error) { - // TODO: this case is a bit blur... - var res = platform.parent_platform.validate(mode, success, error); - this.trigger('validate', [mode]); - return res; - }, - showView: function(views, success, error) { - return platform.parent_platform.showView(views, success, error); - }, - askHint: function(platformToken, success, error) { - return platform.parent_platform.askHint(platformToken, success, error); - }, - updateHeight: function(height, success, error) { - return platform.parent_platform.updateDisplay({height: height}, success, error); - }, - updateDisplay: function(data, success, error) { - return platform.parent_platform.updateDisplay(data, success, error); - }, - getTaskParams: function(key, defaultValue, success, error) { - return platform.parent_platform.getTaskParams(key, defaultValue, success, error); - }, - openUrl: function(url, success, error) { - return platform.parent_platform.openUrl(url, success, error); - }, - initCallback: function(callback) { - this.initCallbackFun = callback; - if (platform.initDone) { - callback(); - } - }, - initWithTask: function(task) { - platform.task = task; - window.task = task; - platform.initDone = true; - if (platform.initCallbackFun) { - platform.initCallbackFun(); - } - } - }; - -} else { - - // cross-domain version, depends on jschannel - platform = {}; - var callAndTrigger = function(fun, triggerName, error, args) { - return function() { - try { - platform.trigger(triggerName, args); - fun(arguments); - } catch(e) { - error(e.toString()+'\n'+e.stack); - } - }; - }; - platform.ready = false; - platform.initFailed = false; - platform.initWithTask = function(task) { - if (typeof Channel === 'undefined') { - platform.initFailed = true; - console.error('cannot init task if jschannel is not present'); - return; - } - - var previousHeights = []; - var getHeightFiltered = function(success, error) { - // If the new height has already been returned just before the current - // height, we're in a loop between two heights, possibly because of a - // scrollbar. - // In that case we want to keep the largest of the two heights. - if(!task.getHeight) { error('task.getHeight not defined yet'); } - task.getHeight(function(h) { - if((previousHeights.length == 2) && - (previousHeights[0] == h) && - (previousHeights[1] >= h)) { - success(previousHeights[1]); - return; - } - previousHeights.push(h); - previousHeights = previousHeights.slice(-2); - success(h); - }, error); - } - - var gradeAnswer = function(params, success, error) { - var newSuccess = function(score, message, scoreToken) { - success([score, message, scoreToken]); - }; - if (typeof task.gradeAnswer === 'function') { - task.gradeAnswer(params[0], params[1], newSuccess, error); - } else { - window.grader.gradeTask(params[0], params[1], newSuccess, error); - } - }; - var channelId = getUrlParameterByName('channelId'); - var chan = Channel.build({window: window.parent, origin: "*", scope: channelId, onReady: function() {platform.ready = true;}}); - platform.chan = chan; - platform.task = task; - platform.channelId = channelId; - chan.bind('task.load', function(trans, views) {task.load(views, callAndTrigger(trans.complete, 'load', trans.error, [views]), trans.error);trans.delayReturn(true);}); - chan.bind('task.unload', function(trans) {task.unload(callAndTrigger(trans.complete, 'unload', trans.error, null), trans.error);trans.delayReturn(true);}); - chan.bind('task.getHeight', function(trans) {getHeightFiltered(trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.getMetaData', function(trans) {task.getMetaData(trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.getViews', function(trans) {task.getViews(trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.showViews', function(trans, views) {task.showViews(views, callAndTrigger(trans.complete, 'showViews', trans.error, [views]), trans.error);trans.delayReturn(true);}); - chan.bind('task.updateToken', function(trans, token) {task.updateToken(token, trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.reloadAnswer', function(trans, answer) {task.reloadAnswer(answer, callAndTrigger(trans.complete, 'reloadAnswer', trans.error, [answer]), trans.error);trans.delayReturn(true);}); - chan.bind('task.getAnswer', function(trans) {task.getAnswer(trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.getState', function(trans) {task.getState(trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.getResources', function(trans) {task.getResources(trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.reloadState', function(trans, state) {task.reloadState(state, callAndTrigger(trans.complete, 'reloadState', trans.error, [state]), trans.error);trans.delayReturn(true);}); - chan.bind('grader.gradeTask', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);}); - chan.bind('task.gradeAnswer', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);}); - }; - - platform.registered_objects = []; - platform.trigger = function(event, content) { - for (var i = 0; i < platform.registered_objects.length; i++) { - var object = platform.registered_objects[i]; - if (typeof object[event] !== "undefined") { - object[event].apply(object, content); - } - } - }; - platform.subscribe = function(object) { - platform.registered_objects.push(object); - }; - platform.unsubscribe = function(object) { - var index = platform.registered_objects.indexOf(object); - if (index != -1) { - platform.registered_objects.splice(index, 1); - } - }; - platform.stop = function() { - platform.chan.destroy(); - }; - platform.validate = function (sMode, success, error) { - if (!success) success = function(){}; // not mandatory, as most code doesn't use it - if (!error) error = function() {console.error(arguments);}; - platform.chan.call({method: "platform.validate", - params: sMode, - error: error, - success: callAndTrigger(success, 'validate', error, [sMode]) - }); - }; - platform.getTaskParams = function(key, defaultValue, success, error) { - if (!success) success = function(){}; - if (!error) error = function() {console.error(arguments);}; - platform.chan.call({method: "platform.getTaskParams", - params: [key, defaultValue], - error: error, - success: success - }); - }; - platform.showView = function(views, success, error) { - if (!success) success = function(){}; - if (!error) error = function() {console.error(arguments);}; - platform.chan.call({method: "platform.showView", - params: views, - error: error, - success: success - }); - }; - platform.askHint = function(platformToken, success, error) { - if (!success) success = function(){}; - if (!error) error = function() {console.error(arguments);}; - platform.chan.call({method: "platform.askHint", - params: platformToken, - error: error, - success: success - }); - }; - platform.updateHeight = function(height, success, error) { - // Legacy - platform.updateDisplay({height: height}, success, error); - }; - platform.updateDisplay = function(data, success, error) { - if (!success) success = function(){}; - if (!error) error = function() {console.error(arguments);}; - platform.chan.call({method: "platform.updateDisplay", - params: data, - error: error, - success: success - }); - }; - platform.openUrl = function(url, success, error) { - if (!success) success = function(){}; - if (!error) error = function() {console.error(arguments);}; - platform.chan.call({method: "platform.openUrl", - params: url, - error: error, - success: success - }); - }; -} - -window.platform = platform; - -}()); - +(function () { + +'use strict'; + +function getUrlParameterByName(name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), + results = regex.exec(location.href); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); +} + +function isCrossDomain() { + function isInIframe() { + try { + return window.self !== window.top; + } catch (e) { + return false; + } + } + function isSameDomain() { + var res = false; + function doNothing(document){} + try{ + res = !! parent.document; + } catch(e){ + res = false; + } + return res; + } + return isInIframe() && !isSameDomain(); +} + +var platform; + +if (!isCrossDomain()) { + + /* Implementation of a platform proxy for the task iframe. This object is always + * available, but is effective only when setPlatform is called with a true + * platform object. + */ + + platform = { + registered_objects: [], + parent_platform: null, + initFailed: false, + setPlatform: function(platformArg) { + platform.parent_platform = platformArg; + }, + trigger: function(event, content) { + for (var i = 0; i < platform.registered_objects.length; i++) { + var object = platform.registered_objects[i]; + if (typeof (object[event]) != "undefined") { + object[event].apply(object, content); + } + } + }, + subscribe: function(object) { + this.registered_objects.push(object); + }, + unsubscribe: function(object) { + var index = this.registered_objects.indexOf(object); + if (index != -1) { + this.registered_objects.splice(index, 1); + } + }, + validate: function(mode, success, error) { + // TODO: this case is a bit blur... + var res = platform.parent_platform.validate(mode, success, error); + this.trigger('validate', [mode]); + return res; + }, + showView: function(views, success, error) { + return platform.parent_platform.showView(views, success, error); + }, + askHint: function(platformToken, success, error) { + return platform.parent_platform.askHint(platformToken, success, error); + }, + updateHeight: function(height, success, error) { + return platform.parent_platform.updateDisplay({height: height}, success, error); + }, + updateDisplay: function(data, success, error) { + return platform.parent_platform.updateDisplay(data, success, error); + }, + getTaskParams: function(key, defaultValue, success, error) { + return platform.parent_platform.getTaskParams(key, defaultValue, success, error); + }, + openUrl: function(url, success, error) { + return platform.parent_platform.openUrl(url, success, error); + }, + initCallback: function(callback) { + this.initCallbackFun = callback; + if (platform.initDone) { + callback(); + } + }, + initWithTask: function(task) { + platform.task = task; + window.task = task; + platform.initDone = true; + if (platform.initCallbackFun) { + platform.initCallbackFun(); + } + } + }; + +} else { + + // cross-domain version, depends on jschannel + platform = {}; + var callAndTrigger = function(fun, triggerName, error, args) { + return function() { + try { + platform.trigger(triggerName, args); + fun(arguments); + } catch(e) { + error(e.toString()+'\n'+e.stack); + } + }; + }; + platform.ready = false; + platform.initFailed = false; + platform.initWithTask = function(task) { + if (typeof Channel === 'undefined') { + platform.initFailed = true; + console.error('cannot init task if jschannel is not present'); + return; + } + + var previousHeights = []; + var getHeightFiltered = function(success, error) { + // If the new height has already been returned just before the current + // height, we're in a loop between two heights, possibly because of a + // scrollbar. + // In that case we want to keep the largest of the two heights. + if(!task.getHeight) { error('task.getHeight not defined yet'); } + task.getHeight(function(h) { + if((previousHeights.length == 2) && + (previousHeights[0] == h) && + (previousHeights[1] >= h)) { + success(previousHeights[1]); + return; + } + previousHeights.push(h); + previousHeights = previousHeights.slice(-2); + success(h); + }, error); + } + + var gradeAnswer = function(params, success, error) { + var newSuccess = function(score, message, scoreToken) { + success([score, message, scoreToken]); + }; + if (typeof task.gradeAnswer === 'function') { + task.gradeAnswer(params[0], params[1], newSuccess, error); + } else { + window.grader.gradeTask(params[0], params[1], newSuccess, error); + } + }; + var channelId = getUrlParameterByName('channelId'); + var chan = Channel.build({window: window.parent, origin: "*", scope: channelId, onReady: function() {platform.ready = true;}}); + platform.chan = chan; + platform.task = task; + platform.channelId = channelId; + chan.bind('task.load', function(trans, views) {task.load(views, callAndTrigger(trans.complete, 'load', trans.error, [views]), trans.error);trans.delayReturn(true);}); + chan.bind('task.unload', function(trans) {task.unload(callAndTrigger(trans.complete, 'unload', trans.error, null), trans.error);trans.delayReturn(true);}); + chan.bind('task.getHeight', function(trans) {getHeightFiltered(trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.getMetaData', function(trans) {task.getMetaData(trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.getViews', function(trans) {task.getViews(trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.showViews', function(trans, views) {task.showViews(views, callAndTrigger(trans.complete, 'showViews', trans.error, [views]), trans.error);trans.delayReturn(true);}); + chan.bind('task.updateToken', function(trans, token) {task.updateToken(token, trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.reloadAnswer', function(trans, answer) {task.reloadAnswer(answer, callAndTrigger(trans.complete, 'reloadAnswer', trans.error, [answer]), trans.error);trans.delayReturn(true);}); + chan.bind('task.getAnswer', function(trans) {task.getAnswer(trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.getState', function(trans) {task.getState(trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.getResources', function(trans) {task.getResources(trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.reloadState', function(trans, state) {task.reloadState(state, callAndTrigger(trans.complete, 'reloadState', trans.error, [state]), trans.error);trans.delayReturn(true);}); + chan.bind('grader.gradeTask', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);}); + chan.bind('task.gradeAnswer', function(trans, params) {gradeAnswer(params, trans.complete, trans.error);trans.delayReturn(true);}); + }; + + platform.registered_objects = []; + platform.trigger = function(event, content) { + for (var i = 0; i < platform.registered_objects.length; i++) { + var object = platform.registered_objects[i]; + if (typeof object[event] !== "undefined") { + object[event].apply(object, content); + } + } + }; + platform.subscribe = function(object) { + platform.registered_objects.push(object); + }; + platform.unsubscribe = function(object) { + var index = platform.registered_objects.indexOf(object); + if (index != -1) { + platform.registered_objects.splice(index, 1); + } + }; + platform.stop = function() { + platform.chan.destroy(); + }; + platform.validate = function (sMode, success, error) { + if (!success) success = function(){}; // not mandatory, as most code doesn't use it + if (!error) error = function() {console.error(arguments);}; + platform.chan.call({method: "platform.validate", + params: sMode, + error: error, + success: callAndTrigger(success, 'validate', error, [sMode]) + }); + }; + platform.getTaskParams = function(key, defaultValue, success, error) { + if (!success) success = function(){}; + if (!error) error = function() {console.error(arguments);}; + platform.chan.call({method: "platform.getTaskParams", + params: [key, defaultValue], + error: error, + success: success + }); + }; + platform.showView = function(views, success, error) { + if (!success) success = function(){}; + if (!error) error = function() {console.error(arguments);}; + platform.chan.call({method: "platform.showView", + params: views, + error: error, + success: success + }); + }; + platform.askHint = function(platformToken, success, error) { + if (!success) success = function(){}; + if (!error) error = function() {console.error(arguments);}; + platform.chan.call({method: "platform.askHint", + params: platformToken, + error: error, + success: success + }); + }; + platform.updateHeight = function(height, success, error) { + // Legacy + platform.updateDisplay({height: height}, success, error); + }; + platform.updateDisplay = function(data, success, error) { + if (!success) success = function(){}; + if (!error) error = function() {console.error(arguments);}; + platform.chan.call({method: "platform.updateDisplay", + params: data, + error: error, + success: success + }); + }; + platform.openUrl = function(url, success, error) { + if (!success) success = function(){}; + if (!error) error = function() {console.error(arguments);}; + platform.chan.call({method: "platform.openUrl", + params: url, + error: error, + success: success + }); + }; +} + +window.platform = platform; + +}()); + (function() { 'use strict'; @@ -390,7 +390,7 @@ window.displayHelper = { enemyWarning: "Attention : dans ce défi, l'ordinateur vous empêchera de trouver la solution par hasard." }, en: { - version: "Version", + version: "版本", levelVersionName_easy: "easy version", levelVersionName_medium: "medium version", levelVersionName_hard: "hard version", @@ -419,21 +419,21 @@ window.displayHelper = { tryToDoBetterOrChangeTask: "Try to do even better, or move on to another task.", tryToDoBetterOrMoveToNextLevel: "Try to do even better, or move on to a more difficult version.", bestPossibleScoreCongrats: "This is the best possible score on this task, congratulations!", - forMorePointsMoveToNextLevel: "To obtain more points, move on to a harder version of this task.", + forMorePointsMoveToNextLevel: "要想获得更多的分数,请进入更难的版本。", youDidBetterBefore: "You did better before.", - scoreStays2: "Your score stays the same.", - reloadBestAnswer: "Reload your best answer.", - noAnswerSaved: "No answer saved so far for this version.", + scoreStays2: "你的得分保持不变", + reloadBestAnswer: "重新加载你的最佳答案。", + noAnswerSaved: "到目前为止,这个版本还没有答案。", validate: "Validate", - restart: "Restart", + restart: "重新开始", harderLevelSolved: "Warning: you already solved a harder version of this task. You won't be able to obtain extra points with this version.", showLevelAnyway: "Show it to me anyways.", - scoreObtained: "Obtained score:", + scoreObtained: "得分:", hardVersionTakesTime: "Solving a {0} can take a lot of time. Consider working on the {1} to gain points quickly.", illKeepThatInMind: "I'll consider it.", harderLevelAvailable: "Note that for this task, you may try to directly work on a harder version than this one.", lockedLevel: "This version is locked. Solve the previous version to display it!", - gradeThisAnswer: "Grade this answer", + gradeThisAnswer: "验证一下", // The following messages are used for tasks with no feedback saveAnswer: "Save this answer", @@ -456,7 +456,7 @@ window.displayHelper = { scoreWouldStay: "With this answer, your score would stay the same:", answerNotSavedContestOver: "The contest being over, your answer was not saved. You may {0}.", reloadSubmittedAnswer: "reload the validated answer", - difficultyWarning: "Warning: solving this version takes time.
You would solve the 2 or 3 star versions of other tasks more quickly.", + difficultyWarning: "提醒: 解决这个版本很耗费时间。
解决2星或3星版本的任务可以更快哦。", enemyWarning: "Warning: in this challenge, the computer will make sure you don't find the solution by chance." }, sv: { @@ -2120,1312 +2120,1312 @@ function drawStars(id, nbStars, starWidth, rate, mode) { window.platform.subscribe(displayHelper); })(); - -var Beav = new Object(); - - -/**********************************************************************************/ -/* Object */ - -Beav.Object = new Object(); - -Beav.Object.eq = function eq(x, y) { - // assumes arguments to be of same type - var tx = typeof(x); - var ty = typeof(y); - if (tx != ty) { - throw "Beav.Object.eq incompatible types"; - } - if (tx == "boolean" || tx == "number" || tx == "string" || tx == "undefined") { - return x == y; - } - if ($.isArray(x)) { - if (! $.isArray(y)) - throw "Beav.Object.eq incompatible types"; - if (x.length != y.length) - return false; - for (var i = 0; i < x.length; i++) - if (! eq(x[i], y[i])) - return false; - return true; - } - if (tx == "object") { - var kx = []; - for (var key in x) { - kx.push(key); - } - var ky = []; - for (var key in y) { - ky.push(key); - } - var sort_keys = function(n1,n2) { return (n1 < n2) ? -1 : ((n1 > n2) ? 1 : 0); }; - kx.sort(sort_keys); - ky.sort(sort_keys); - if (kx.length != ky.length) - return false; - for (var i = 0; i < kx.length; i++) { - var ex = kx[i]; - var ey = ky[i]; - if (ex != ey) - return false; - if (! eq(x[ex], y[ex])) - return false; - } - return true; - } - throw "Beav.Object.eq unsupported types"; -}; - - -/**********************************************************************************/ -/* Array */ - -Beav.Array = new Object(); - -Beav.Array.make = function(nb, initValue) { - var t = []; - for (var i = 0; i < nb; i++) - t[i] = initValue; - return t; -}; - -Beav.Array.init = function(nb, initFct) { - var t = []; - for (var i = 0; i < nb; i++) - t.push(initFct(i)); - return t; -}; - -Beav.Array.indexOf = function(t, v, eq) { - if (eq === undefined) - eq = Beav.Object.eq; - for (var i = 0; i < t.length; i++) - if (eq(t[i], v)) - return i; - return -1; -}; - -Beav.Array.has = function(t, v, eq) { - return Beav.Array.indexOf(t, v, eq) != -1; -}; - -Beav.Array.filterCount = function(t, filterFct) { - var count = 0; - for (var i = 0; i < t.length; i++) - if (filterFct(t[i], i)) - count++; - return count; -}; - -Beav.Array.stableSort = function(t, compFct) { - var swap = function(a, b) { - var v = t[a]; - t[a] = t[b]; - t[b] = v; - }; - var insert = function (i, j, v) { - while(i+1 < j && compFct(t[i+1], v) < 0) { - swap(i, i+1); - i++; - } - t[i] = v; - }; - var merge = function(i, k, j) { - for ( ; i": ">", - '"': '"', - "'": ''', - "/": '/' }; - return String(stringToEncode).replace(/[&<>"'\/]/g, function (s) { - return entityMap[s]; - }); -}; - - -/**********************************************************************************/ -/* Raphael */ - -Beav.Raphael = new Object(); - -Beav.Raphael.line = function(paper, x1, y1, x2, y2) { - return paper.path([ "M", x1, y1, "L", x2, y2 ]); -}; - -Beav.Raphael.lineRelative = function(paper, x1, y1, dx, dy) { - return Beav.Raphael.line(paper, x1, y1, x1+dx, y1+dy); -}; - - -/**********************************************************************************/ -/* Random */ - -Beav.Random = new Object(); - -Beav.Random.bit = function(randomSeed, idBit) { - return (randomSeed & (1 << idBit)) ? 1 : 0; -}; - - -/**********************************************************************************/ -/* Task */ - -Beav.Task = new Object(); - -Beav.Task.scoreInterpolate = function(minScore, maxScore, minResult, maxResult, result) { - // requires minResult <= result <= maxResult and minScore <= maxScore - return Math.round(minScore + (maxScore - minScore) * (result - minResult) / (maxResult - minResult)); -}; - - -/**********************************************************************************/ -/* Geometry */ - -Beav.Geometry = new Object(); - -Beav.Geometry.distance = function(x1,y1,x2,y2) { - return Math.sqrt(Math.pow(x2 - x1,2) + Math.pow(y2 - y1,2)); -}; - -/* - This is used to handle drag on devices that have both a touch screen and a mouse. - Can be tested on chrome by loading a task in desktop mode, then switching to tablet mode. - To call instead of element.drag(onMove, onStart, onEnd); -*/ -Beav.dragWithTouch = function(element, onMove, onStart, onEnd) { - var touchingX = 0; - var touchingY = 0; - var disabled = false; - - function onTouchStart(evt) { - if (disabled) { - return; - } - var touches = evt.changedTouches; - touchingX = touches[0].pageX; - touchingY = touches[0].pageY; - onStart(touches[0].pageX, touches[0].pageY, evt); - } - - function onTouchEnd(evt) { - if (disabled) { - return; - } - onEnd(null); - } - - function onTouchMove(evt) { - if (disabled) { - return; - } - var touches = evt.changedTouches; - var dx = touches[0].pageX - touchingX; - var dy = touches[0].pageY - touchingY; - onMove(dx, dy, touches[0].pageX, touches[0].pageY, evt); - } - - function callOnStart(x,y,event) { - disabled = true; - onStart(x,y,event); - } - - function callOnMove(dx,dy,x,y,event) { - disabled = true; - onMove(dx,dy,x,y,event); - } - - function callOnEnd(event) { - disabled = false; - onEnd(event); - } - - // element.undrag(); - element.drag(callOnMove,callOnStart,callOnEnd); - if (element.touchstart) { - element.touchstart(onTouchStart); - element.touchend(onTouchEnd); - element.touchcancel(onTouchEnd); - element.touchmove(onTouchMove); - } -} -(function() { - -'use strict'; - -// requires jQuery, and a task object in the global scope. - -// this should be called before the task loads, because the task can modify -// its html at load, and we want to return unmodified html in getTaskResources. -var res = {}; - -var taskResourcesLoaded = false; - -window.implementGetResources = function(task) { - task.getResources = function(callback) - { - if (taskResourcesLoaded) { - callback(res); - return; - } - res.task = ('task' in res) ? res.task : [{ type: 'html', content: $('#task').html() }]; - res.solution = ('solution' in res) ? res.solution : [{ type: 'html', content: $('#solution').html() }]; - res.grader = []; - res.task_modules = []; - res.solution_modules = []; - res.grader_modules = []; - if (!res.hints) { - res.hints = []; - $('.hint').each(function(index) { - res.hints[res.hints.length] = [{type: 'html', content: $(this).html() }]; - $(this).attr('hint-Num', res.hints.length-1); - }); - } - res.proxy = []; - res.proxy_modules = []; - res.display = []; - res.display_modules = []; - res.sat = []; - res.sat_modules = []; - res.files = []; - if (!res.title) { - res.title = $('title').text(); - } - - // Resources - var curDest = 'task'; - var curType = 'javascript'; - $('script, style, link').each(function() { - if ($(this).hasClass('remove')) { - return; - } - if ($(this).hasClass('solution') && $(this).hasClass('module')) { - curDest = res.solution_modules; - } - else if ($(this).hasClass('solution')) { - curDest = res.solution; - } - else if ($(this).hasClass('grader') && $(this).hasClass('module')) { - curDest = res.grader_modules; - } - else if ($(this).hasClass('grader')) { - curDest = res.grader; - } - else if ($(this).hasClass('hint')) { - res.hints.push([{ type: 'html', content: $(this).html() }]); - return; - } - else if ($(this).hasClass('proxy') && $(this).hasClass('module')) { - curDest = res.proxy_modules; - } - else if ($(this).hasClass('proxy')) { - curDest = res.proxy; - } - else if ($(this).hasClass('stdButtonsAndMessages') && $(this).hasClass('module')) { - curDest = res.display_modules; - } - else if ($(this).hasClass('stdButtonsAndMessages')) { - curDest = res.display; - } - else if ($(this).hasClass('stdAnswerTypes') && $(this).hasClass('module')) { - curDest = res.sat_modules; - } - else if ($(this).hasClass('stdAnswerTypes')) { - curDest = res.sat; - } - else if ($(this).hasClass('module')) { - curDest = res.task_modules; - } - else { - curDest = res.task; - } - - if ($(this).is('script')) { - curType = 'javascript'; - } - else if ($(this).is('style') || $(this).is('link')) { - curType = 'css'; - } - - if ($(this).attr('src')) { - curDest.push({ type: curType, url: $(this).attr('src'), id: $(this).attr('id') }); - } - else if ($(this).attr('href')) { - curDest.push({ type: curType, url: $(this).attr('href'), id: $(this).attr('id') }); - } - else { - curDest.push({ type: curType, id: $(this).attr('id'), content: $(this).html() }); - } - }); - - // Images - var images = []; - var image = ''; - $('#task img').each(function() { - var src = $(this).attr('src'); - if (src) { - image = src.toString(); - if ($.inArray(image, images) === -1) { - res.task.push({ type: 'image', url: image }); - images.push(image); - } - } - }); - fillImages($('#task').html(), images, res.task); - $('script').each(function() { - if ($(this).hasClass('remove') || $(this).attr('src') || $(this).attr('href')) { - return; - } - fillImages($(this).html(), images, res.task); - }); - $('#solution img').each(function() { - image = $(this).attr('src').toString(); - if ($.inArray(image, images) === -1) { - res.solution.push({ type: 'image', url: image }); - images.push(image); - } - }); - fillImages($('#solution').html(), images, res.solution); - $('.hint').each(function() { - var hintnum = $(this).attr('hint-num'); - $('[hint-num='+hintnum+'] img').each(function() { - image = $(this).attr('src').toString(); - if ($.inArray(image, images) === -1) { - res.hints[hintnum].push({ type: 'image', url: image }); - images.push(image); - } - }); - fillImages($(this).html(), images, res.hints[hintnum]); - }); - - // Links - $('iframe').each(function () { - var curUrl = $(this).attr('src'); - if(curUrl.indexOf('://') == -1 && curUrl.charAt(0) != '/') { - res.files.push({ type: this.tagName, url: $(this).attr('src') }); - } - }); - - // Other resources - $('source, track').each(function() { - res.files.push({ type: this.tagName, url: $(this).attr('src') }); - }); - $('fioi-video-player').each(function() { - var fileAttributes = ["data-source", "data-image", "data-subtitles"]; - for(var i=0; i\ - \ - \ - \ - \ -
Concours castorLe concours Castor
\ - ' - }, - laptop: { - 'header' : '\ -
\ - \ - \ - \ - \ -
Concours AlkindiLe concours Alkindi
\ -
' - }, - none: { - 'header' : '' - } - }; - - function inIframe() { - try { - return window.self !== window.top; - } catch (e) { - return false; - } - } - - - - if(typeof window.jwt == 'undefined') { - window.jwt = { - isDummy: true, - sign: function() { return null; }, - decode: function(token) { return token; } - }; - } - - function TaskToken(data, key) { - - this.data = data - this.data.sHintsRequested = "[]"; - this.key = key - - var query = document.location.search.replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0]; - this.queryToken = query.sToken; - - this.addHintRequest = function(hint_params, callback) { - try { - hint_params = jwt.decode(hint_params).askedHint; - } catch(e) {} - var hintsReq = JSON.parse(this.data.sHintsRequested); - var exists = hintsReq.find(function(h) { - return h == hint_params; - }); - if(!exists) { - hintsReq.push(hint_params); - this.data.sHintsRequested = JSON.stringify(hintsReq); - } - return this.get(callback); - } - - this.update = function(newData, callback) { - for(var key in newData) { - this.data[key] = newData[key]; - } - } - - this.getToken = function(data, callback) { - var res = jwt.sign(data, this.key) - if(callback) { - // imitate async req - setTimeout(function() { - callback(res) - }, 0); - } - return res; - } - - this.get = function(callback) { - if(window.jwt.isDummy && this.queryToken) { - var token = this.queryToken; - if(callback) { - // imitate async req - setTimeout(function() { - callback(token) - }, 0); - } - return token; - } - return this.getToken(this.data, callback); - } - - this.getAnswerToken = function(answer, callback) { - var answerData = {}; - for(var key in this.data) { - answerData[key] = this.data[key]; - } - answerData.sAnswer = answer; - return this.getToken(answerData, callback); - } - } - - - function AnswerToken(key) { - this.key = key - this.get = function(answer, callback) { - var res = jwt.sign(answer, this.key) - if(callback) { - // imitate async req - setTimeout(function() { - callback(res) - }, 0) - } - return res; - } - } - - - -var taskMetaData; - -// important for tracker.js -var compiledTask = true; - -window.miniPlatformShowSolution = function() { - $("#showSolutionButton").hide(); - task.getAnswer(function(answer) { - task.showViews({"task": true, "solution": true}, function() { - // For tasks with no feedback / older tasks - // miniPlatformPreviewGrade(answer); - platform.trigger('showViews', [{"task": true, "solution": true}]); - }); - }); -} - -function miniPlatformPreviewGrade(answer) { - var minScore = -3; - if (taskMetaData.fullFeedback) { - minScore = 0; - } - var maxScore = 40; - var score; - var showGrade = function(score) { - if ($("#previewScorePopup").length === 0) { - $("
" + - "
" + - "


").insertBefore("#solution"); - } - $("#previewScorePopup").show(); - $("#previewScoreMessage").html("" + getLanguageString('showSolution') + " " + score + "/" + maxScore + "
" + getLanguageString('showSolution')); - }; - // acceptedAnswers is not documented, but necessary for old Bebras tasks - if (taskMetaData.acceptedAnswers && taskMetaData.acceptedAnswers[0]) { - if ($.inArray("" + answer, taskMetaData.acceptedAnswers) > -1) { - score = maxScore; - } - else { - score = minScore; - } - showGrade(score); - } else { - score = grader.gradeTask(answer, null, showGrade); - } -} - -var alreadyStayed = false; - -var miniPlatformValidate = function(task) { return function(mode, success, error) { - //$.post('updateTestToken.php', {action: 'showSolution'}, function(){}, 'json'); - if (mode == 'nextImmediate' || mode == 'log') { - return; - } - if (mode == 'stay') { - if (alreadyStayed) { - platform.trigger('validate', [mode]); - if (success) { - success(); - } - } else { - alreadyStayed = true; - } - } - if (mode == 'cancel') { - alreadyStayed = false; - } - if(platform.registered_objects && platform.registered_objects.length > 0) { - platform.trigger('validate', [mode]); - } else { - // Try to validate - task.getAnswer(function(answer) { - task.gradeAnswer(answer, task_token.getAnswerToken(answer), function(score, message) { - if(success) { success(); } - }) - }); - } - if (success) { - success(); - } -}}; - -function getUrlParameter(sParam) -{ - var sPageURL = window.location.search.substring(1); - var sURLVariables = sPageURL.split('&'); - for (var i = 0; i < sURLVariables.length; i++) - { - var sParameterName = sURLVariables[i].split('='); - if (sParameterName[0] == sParam) - { - return decodeURIComponent(sParameterName[1]); - } - } -} - -function getHashParameter(sParam) -{ - var sPageURL = window.location.hash.substring(1); - var sURLVariables = sPageURL.split('&'); - for (var i = 0; i < sURLVariables.length; i++) - { - var sParameterName = sURLVariables[i].split('='); - if (sParameterName[0] == sParam) - { - return decodeURIComponent(sParameterName[1]); - } - } -} - -var chooseView = (function () { - // Manages the buttons to choose the view - return { - doubleEnabled: false, - isDouble: false, - lastShownViews: {}, - - init: function(views) { - if (! $("#choose-view").length) - $(document.body).append('
'); - $("#choose-view").html(""); - // Display buttons to select task view or solution view - /* - for(var viewName in views) { - if (!views[viewName].requires) { - var btn = $('') - $("#choose-view").append(btn); - btn.click(this.selectFactory(viewName)); - } - } - */ - $("#grade").remove(); - var btnGradeAnswer = $('
'); - // display grader button only if dev mode by adding URL hash 'dev' - if (getHashParameter('dev')) { - $(document.body).append(btnGradeAnswer); - } - btnGradeAnswer.click(function() { - task.getAnswer(function(answer) { - answer_token.get(answer, function(answer_token) { - task.gradeAnswer(answer, answer_token, function(score, message, scoreToken) { - alert("Score : " + score + ", message : " + message); - }); - }) - }, function() { - alert("error"); - }); - }) - }, - - reinit: function(views) { - this.init(views); - var newShownViews = {}; - for(var viewName in this.lastShownViews) { - if(!this.lastShownViews[viewName]) { continue; } - if(views[viewName] && !views[viewName].requires) { - newShownViews[viewName] = true; - } - } - for(var viewName in views) { - if(views[viewName].includes) { - for(var i=0; i'); - var platformLoad = function(task) { - window.task_token.update({id: taskMetaData.id}); - window.answer_token = new AnswerToken(demo_key) - - platform.validate = miniPlatformValidate(task); - platform.updateHeight = function(height,success,error) {if (success) {success();}}; - platform.updateDisplay = function(data,success,error) { - if(data.views) { - chooseView.reinit(data.views); - } - if (success) {success();} - }; - var taskOptions = {}; - try { - var strOptions = getUrlParameter("options"); - if (strOptions !== undefined) { - taskOptions = $.parseJSON(strOptions); - } - } catch(exception) { - alert("Error: invalid options"); - } - var minScore = -3; - if (taskMetaData.fullFeedback) { - minScore = 0; - } - platform.getTaskParams = function(key, defaultValue, success, error) { - var res = {'minScore': minScore, 'maxScore': 40, 'noScore': 0, 'readOnly': false, 'randomSeed': "0", 'options': taskOptions}; - if (key) { - if (key !== 'options' && key in res) { - res = res[key]; - } else if (res.options && key in res.options) { - res = res.options[key]; - } else { - res = (typeof defaultValue !== 'undefined') ? defaultValue : null; - } - } - if (success) { - success(res); - } else { - return res; - } - }; - platform.askHint = function(hint_params, success, error) { - /* - $.post('updateTestToken.php', JSON.stringify({action: 'askHint'}), function(postRes){ - if (success) {success();} - }, 'json'); - */ - task_token.addHintRequest(hint_params, function(token) { - task.updateToken(token, function() {}) - success(token) - }) - }; - - - var loadedViews = {'task': true, 'solution': true, 'hints': true, 'editor': true, 'grader': true, 'metadata': true, 'submission': true}; - var shownViews = {'task': true}; - // TODO: modifs ARTHUR à relire - if (taskOptions.showSolutionOnLoad) { - shownViews.solution = true; - } - if (!taskOptions.hideTitle) { - $("#task h1").show(); - } - - if (taskMetaData.fullFeedback) { - loadedViews.grader = true; - } - - task.load( - loadedViews, - function() { - platform.trigger('load', [loadedViews]); - task.getViews(function(views) { - chooseView.init(views); - }); - task.showViews(shownViews, function() { - chooseView.update(shownViews); - platform.trigger('showViews', [{"task": true}]); - }); - if ($("#solution").length) { - $("#task").append("
"); - } - - // add branded header to platformless task depending on avatarType - // defaults to beaver platform branding - if(window.displayHelper) { - if (miniPlatformWrapping[displayHelper.avatarType].header) { - $('body').prepend(miniPlatformWrapping[displayHelper.avatarType].header); - } else { - $('body').prepend(miniPlatformWrapping[beaver].header); - } - } - }, - function(error) { - console.error(error) - } - ); - - - task_token.get(function(token) { - task.updateToken(token, function() {}) - }) - - - /* For the 'resize' event listener below, we use a cross-browser - * compatible version for "addEventListener" (modern) and "attachEvent" (old). - * Source: https://stackoverflow.com/questions/6927637/addeventlistener-in-internet-explorer - */ - function addEvent(evnt, elem, func) { - if (elem.addEventListener) // W3C DOM - elem.addEventListener(evnt,func,false); - else if (elem.attachEvent) { // IE DOM - elem.attachEvent("on"+evnt, func); - } - else { // No much to do - elem[evnt] = func; - } - } - - addEvent('resize', window, function() { - task.getViews(function(views) { - chooseView.reinit(views); - }); - }); - }; - var getMetaDataAndLoad = function(task) { - task.getMetaData(function(metaData) { - taskMetaData = metaData; - platformLoad(task); - }); - }; - if (window.platform.task || platform.initFailed) { - // case everything went fine with task loading, or task loading failed - // (due to missing jschannel and file:// protocol... - getMetaDataAndLoad(window.task ? window.task : window.platform.task); - } else { - // task is not loaded yet - var oldInit = platform.initWithTask; - platform.initWithTask = function(task) { - oldInit(task); - getMetaDataAndLoad(task); - }; - } - } -}); - -})(); + +var Beav = new Object(); + + +/**********************************************************************************/ +/* Object */ + +Beav.Object = new Object(); + +Beav.Object.eq = function eq(x, y) { + // assumes arguments to be of same type + var tx = typeof(x); + var ty = typeof(y); + if (tx != ty) { + throw "Beav.Object.eq incompatible types"; + } + if (tx == "boolean" || tx == "number" || tx == "string" || tx == "undefined") { + return x == y; + } + if ($.isArray(x)) { + if (! $.isArray(y)) + throw "Beav.Object.eq incompatible types"; + if (x.length != y.length) + return false; + for (var i = 0; i < x.length; i++) + if (! eq(x[i], y[i])) + return false; + return true; + } + if (tx == "object") { + var kx = []; + for (var key in x) { + kx.push(key); + } + var ky = []; + for (var key in y) { + ky.push(key); + } + var sort_keys = function(n1,n2) { return (n1 < n2) ? -1 : ((n1 > n2) ? 1 : 0); }; + kx.sort(sort_keys); + ky.sort(sort_keys); + if (kx.length != ky.length) + return false; + for (var i = 0; i < kx.length; i++) { + var ex = kx[i]; + var ey = ky[i]; + if (ex != ey) + return false; + if (! eq(x[ex], y[ex])) + return false; + } + return true; + } + throw "Beav.Object.eq unsupported types"; +}; + + +/**********************************************************************************/ +/* Array */ + +Beav.Array = new Object(); + +Beav.Array.make = function(nb, initValue) { + var t = []; + for (var i = 0; i < nb; i++) + t[i] = initValue; + return t; +}; + +Beav.Array.init = function(nb, initFct) { + var t = []; + for (var i = 0; i < nb; i++) + t.push(initFct(i)); + return t; +}; + +Beav.Array.indexOf = function(t, v, eq) { + if (eq === undefined) + eq = Beav.Object.eq; + for (var i = 0; i < t.length; i++) + if (eq(t[i], v)) + return i; + return -1; +}; + +Beav.Array.has = function(t, v, eq) { + return Beav.Array.indexOf(t, v, eq) != -1; +}; + +Beav.Array.filterCount = function(t, filterFct) { + var count = 0; + for (var i = 0; i < t.length; i++) + if (filterFct(t[i], i)) + count++; + return count; +}; + +Beav.Array.stableSort = function(t, compFct) { + var swap = function(a, b) { + var v = t[a]; + t[a] = t[b]; + t[b] = v; + }; + var insert = function (i, j, v) { + while(i+1 < j && compFct(t[i+1], v) < 0) { + swap(i, i+1); + i++; + } + t[i] = v; + }; + var merge = function(i, k, j) { + for ( ; i": ">", + '"': '"', + "'": ''', + "/": '/' }; + return String(stringToEncode).replace(/[&<>"'\/]/g, function (s) { + return entityMap[s]; + }); +}; + + +/**********************************************************************************/ +/* Raphael */ + +Beav.Raphael = new Object(); + +Beav.Raphael.line = function(paper, x1, y1, x2, y2) { + return paper.path([ "M", x1, y1, "L", x2, y2 ]); +}; + +Beav.Raphael.lineRelative = function(paper, x1, y1, dx, dy) { + return Beav.Raphael.line(paper, x1, y1, x1+dx, y1+dy); +}; + + +/**********************************************************************************/ +/* Random */ + +Beav.Random = new Object(); + +Beav.Random.bit = function(randomSeed, idBit) { + return (randomSeed & (1 << idBit)) ? 1 : 0; +}; + + +/**********************************************************************************/ +/* Task */ + +Beav.Task = new Object(); + +Beav.Task.scoreInterpolate = function(minScore, maxScore, minResult, maxResult, result) { + // requires minResult <= result <= maxResult and minScore <= maxScore + return Math.round(minScore + (maxScore - minScore) * (result - minResult) / (maxResult - minResult)); +}; + + +/**********************************************************************************/ +/* Geometry */ + +Beav.Geometry = new Object(); + +Beav.Geometry.distance = function(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(x2 - x1,2) + Math.pow(y2 - y1,2)); +}; + +/* + This is used to handle drag on devices that have both a touch screen and a mouse. + Can be tested on chrome by loading a task in desktop mode, then switching to tablet mode. + To call instead of element.drag(onMove, onStart, onEnd); +*/ +Beav.dragWithTouch = function(element, onMove, onStart, onEnd) { + var touchingX = 0; + var touchingY = 0; + var disabled = false; + + function onTouchStart(evt) { + if (disabled) { + return; + } + var touches = evt.changedTouches; + touchingX = touches[0].pageX; + touchingY = touches[0].pageY; + onStart(touches[0].pageX, touches[0].pageY, evt); + } + + function onTouchEnd(evt) { + if (disabled) { + return; + } + onEnd(null); + } + + function onTouchMove(evt) { + if (disabled) { + return; + } + var touches = evt.changedTouches; + var dx = touches[0].pageX - touchingX; + var dy = touches[0].pageY - touchingY; + onMove(dx, dy, touches[0].pageX, touches[0].pageY, evt); + } + + function callOnStart(x,y,event) { + disabled = true; + onStart(x,y,event); + } + + function callOnMove(dx,dy,x,y,event) { + disabled = true; + onMove(dx,dy,x,y,event); + } + + function callOnEnd(event) { + disabled = false; + onEnd(event); + } + + // element.undrag(); + element.drag(callOnMove,callOnStart,callOnEnd); + if (element.touchstart) { + element.touchstart(onTouchStart); + element.touchend(onTouchEnd); + element.touchcancel(onTouchEnd); + element.touchmove(onTouchMove); + } +} +(function() { + +'use strict'; + +// requires jQuery, and a task object in the global scope. + +// this should be called before the task loads, because the task can modify +// its html at load, and we want to return unmodified html in getTaskResources. +var res = {}; + +var taskResourcesLoaded = false; + +window.implementGetResources = function(task) { + task.getResources = function(callback) + { + if (taskResourcesLoaded) { + callback(res); + return; + } + res.task = ('task' in res) ? res.task : [{ type: 'html', content: $('#task').html() }]; + res.solution = ('solution' in res) ? res.solution : [{ type: 'html', content: $('#solution').html() }]; + res.grader = []; + res.task_modules = []; + res.solution_modules = []; + res.grader_modules = []; + if (!res.hints) { + res.hints = []; + $('.hint').each(function(index) { + res.hints[res.hints.length] = [{type: 'html', content: $(this).html() }]; + $(this).attr('hint-Num', res.hints.length-1); + }); + } + res.proxy = []; + res.proxy_modules = []; + res.display = []; + res.display_modules = []; + res.sat = []; + res.sat_modules = []; + res.files = []; + if (!res.title) { + res.title = $('title').text(); + } + + // Resources + var curDest = 'task'; + var curType = 'javascript'; + $('script, style, link').each(function() { + if ($(this).hasClass('remove')) { + return; + } + if ($(this).hasClass('solution') && $(this).hasClass('module')) { + curDest = res.solution_modules; + } + else if ($(this).hasClass('solution')) { + curDest = res.solution; + } + else if ($(this).hasClass('grader') && $(this).hasClass('module')) { + curDest = res.grader_modules; + } + else if ($(this).hasClass('grader')) { + curDest = res.grader; + } + else if ($(this).hasClass('hint')) { + res.hints.push([{ type: 'html', content: $(this).html() }]); + return; + } + else if ($(this).hasClass('proxy') && $(this).hasClass('module')) { + curDest = res.proxy_modules; + } + else if ($(this).hasClass('proxy')) { + curDest = res.proxy; + } + else if ($(this).hasClass('stdButtonsAndMessages') && $(this).hasClass('module')) { + curDest = res.display_modules; + } + else if ($(this).hasClass('stdButtonsAndMessages')) { + curDest = res.display; + } + else if ($(this).hasClass('stdAnswerTypes') && $(this).hasClass('module')) { + curDest = res.sat_modules; + } + else if ($(this).hasClass('stdAnswerTypes')) { + curDest = res.sat; + } + else if ($(this).hasClass('module')) { + curDest = res.task_modules; + } + else { + curDest = res.task; + } + + if ($(this).is('script')) { + curType = 'javascript'; + } + else if ($(this).is('style') || $(this).is('link')) { + curType = 'css'; + } + + if ($(this).attr('src')) { + curDest.push({ type: curType, url: $(this).attr('src'), id: $(this).attr('id') }); + } + else if ($(this).attr('href')) { + curDest.push({ type: curType, url: $(this).attr('href'), id: $(this).attr('id') }); + } + else { + curDest.push({ type: curType, id: $(this).attr('id'), content: $(this).html() }); + } + }); + + // Images + var images = []; + var image = ''; + $('#task img').each(function() { + var src = $(this).attr('src'); + if (src) { + image = src.toString(); + if ($.inArray(image, images) === -1) { + res.task.push({ type: 'image', url: image }); + images.push(image); + } + } + }); + fillImages($('#task').html(), images, res.task); + $('script').each(function() { + if ($(this).hasClass('remove') || $(this).attr('src') || $(this).attr('href')) { + return; + } + fillImages($(this).html(), images, res.task); + }); + $('#solution img').each(function() { + image = $(this).attr('src').toString(); + if ($.inArray(image, images) === -1) { + res.solution.push({ type: 'image', url: image }); + images.push(image); + } + }); + fillImages($('#solution').html(), images, res.solution); + $('.hint').each(function() { + var hintnum = $(this).attr('hint-num'); + $('[hint-num='+hintnum+'] img').each(function() { + image = $(this).attr('src').toString(); + if ($.inArray(image, images) === -1) { + res.hints[hintnum].push({ type: 'image', url: image }); + images.push(image); + } + }); + fillImages($(this).html(), images, res.hints[hintnum]); + }); + + // Links + $('iframe').each(function () { + var curUrl = $(this).attr('src'); + if(curUrl.indexOf('://') == -1 && curUrl.charAt(0) != '/') { + res.files.push({ type: this.tagName, url: $(this).attr('src') }); + } + }); + + // Other resources + $('source, track').each(function() { + res.files.push({ type: this.tagName, url: $(this).attr('src') }); + }); + $('fioi-video-player').each(function() { + var fileAttributes = ["data-source", "data-image", "data-subtitles"]; + for(var i=0; i\ + \ + \ + \ + \ +
高阶思维能力测试Le concours Castor
\ + ' + }, + laptop: { + 'header' : '\ +
\ + \ + \ + \ + \ +
Concours AlkindiLe concours Alkindi
\ +
' + }, + none: { + 'header' : '' + } + }; + + function inIframe() { + try { + return window.self !== window.top; + } catch (e) { + return false; + } + } + + + + if(typeof window.jwt == 'undefined') { + window.jwt = { + isDummy: true, + sign: function() { return null; }, + decode: function(token) { return token; } + }; + } + + function TaskToken(data, key) { + + this.data = data + this.data.sHintsRequested = "[]"; + this.key = key + + var query = document.location.search.replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0]; + this.queryToken = query.sToken; + + this.addHintRequest = function(hint_params, callback) { + try { + hint_params = jwt.decode(hint_params).askedHint; + } catch(e) {} + var hintsReq = JSON.parse(this.data.sHintsRequested); + var exists = hintsReq.find(function(h) { + return h == hint_params; + }); + if(!exists) { + hintsReq.push(hint_params); + this.data.sHintsRequested = JSON.stringify(hintsReq); + } + return this.get(callback); + } + + this.update = function(newData, callback) { + for(var key in newData) { + this.data[key] = newData[key]; + } + } + + this.getToken = function(data, callback) { + var res = jwt.sign(data, this.key) + if(callback) { + // imitate async req + setTimeout(function() { + callback(res) + }, 0); + } + return res; + } + + this.get = function(callback) { + if(window.jwt.isDummy && this.queryToken) { + var token = this.queryToken; + if(callback) { + // imitate async req + setTimeout(function() { + callback(token) + }, 0); + } + return token; + } + return this.getToken(this.data, callback); + } + + this.getAnswerToken = function(answer, callback) { + var answerData = {}; + for(var key in this.data) { + answerData[key] = this.data[key]; + } + answerData.sAnswer = answer; + return this.getToken(answerData, callback); + } + } + + + function AnswerToken(key) { + this.key = key + this.get = function(answer, callback) { + var res = jwt.sign(answer, this.key) + if(callback) { + // imitate async req + setTimeout(function() { + callback(res) + }, 0) + } + return res; + } + } + + + +var taskMetaData; + +// important for tracker.js +var compiledTask = true; + +window.miniPlatformShowSolution = function() { + $("#showSolutionButton").hide(); + task.getAnswer(function(answer) { + task.showViews({"task": true, "solution": true}, function() { + // For tasks with no feedback / older tasks + // miniPlatformPreviewGrade(answer); + platform.trigger('showViews', [{"task": true, "solution": true}]); + }); + }); +} + +function miniPlatformPreviewGrade(answer) { + var minScore = -3; + if (taskMetaData.fullFeedback) { + minScore = 0; + } + var maxScore = 40; + var score; + var showGrade = function(score) { + if ($("#previewScorePopup").length === 0) { + $("
" + + "
" + + "


").insertBefore("#solution"); + } + $("#previewScorePopup").show(); + $("#previewScoreMessage").html("" + getLanguageString('showSolution') + " " + score + "/" + maxScore + "
" + getLanguageString('showSolution')); + }; + // acceptedAnswers is not documented, but necessary for old Bebras tasks + if (taskMetaData.acceptedAnswers && taskMetaData.acceptedAnswers[0]) { + if ($.inArray("" + answer, taskMetaData.acceptedAnswers) > -1) { + score = maxScore; + } + else { + score = minScore; + } + showGrade(score); + } else { + score = grader.gradeTask(answer, null, showGrade); + } +} + +var alreadyStayed = false; + +var miniPlatformValidate = function(task) { return function(mode, success, error) { + //$.post('updateTestToken.php', {action: 'showSolution'}, function(){}, 'json'); + if (mode == 'nextImmediate' || mode == 'log') { + return; + } + if (mode == 'stay') { + if (alreadyStayed) { + platform.trigger('validate', [mode]); + if (success) { + success(); + } + } else { + alreadyStayed = true; + } + } + if (mode == 'cancel') { + alreadyStayed = false; + } + if(platform.registered_objects && platform.registered_objects.length > 0) { + platform.trigger('validate', [mode]); + } else { + // Try to validate + task.getAnswer(function(answer) { + task.gradeAnswer(answer, task_token.getAnswerToken(answer), function(score, message) { + if(success) { success(); } + }) + }); + } + if (success) { + success(); + } +}}; + +function getUrlParameter(sParam) +{ + var sPageURL = window.location.search.substring(1); + var sURLVariables = sPageURL.split('&'); + for (var i = 0; i < sURLVariables.length; i++) + { + var sParameterName = sURLVariables[i].split('='); + if (sParameterName[0] == sParam) + { + return decodeURIComponent(sParameterName[1]); + } + } +} + +function getHashParameter(sParam) +{ + var sPageURL = window.location.hash.substring(1); + var sURLVariables = sPageURL.split('&'); + for (var i = 0; i < sURLVariables.length; i++) + { + var sParameterName = sURLVariables[i].split('='); + if (sParameterName[0] == sParam) + { + return decodeURIComponent(sParameterName[1]); + } + } +} + +var chooseView = (function () { + // Manages the buttons to choose the view + return { + doubleEnabled: false, + isDouble: false, + lastShownViews: {}, + + init: function(views) { + if (! $("#choose-view").length) + $(document.body).append('
'); + $("#choose-view").html(""); + // Display buttons to select task view or solution view + /* + for(var viewName in views) { + if (!views[viewName].requires) { + var btn = $('') + $("#choose-view").append(btn); + btn.click(this.selectFactory(viewName)); + } + } + */ + $("#grade").remove(); + var btnGradeAnswer = $('
'); + // display grader button only if dev mode by adding URL hash 'dev' + if (getHashParameter('dev')) { + $(document.body).append(btnGradeAnswer); + } + btnGradeAnswer.click(function() { + task.getAnswer(function(answer) { + answer_token.get(answer, function(answer_token) { + task.gradeAnswer(answer, answer_token, function(score, message, scoreToken) { + alert("Score : " + score + ", message : " + message); + }); + }) + }, function() { + alert("error"); + }); + }) + }, + + reinit: function(views) { + this.init(views); + var newShownViews = {}; + for(var viewName in this.lastShownViews) { + if(!this.lastShownViews[viewName]) { continue; } + if(views[viewName] && !views[viewName].requires) { + newShownViews[viewName] = true; + } + } + for(var viewName in views) { + if(views[viewName].includes) { + for(var i=0; i'); + var platformLoad = function(task) { + window.task_token.update({id: taskMetaData.id}); + window.answer_token = new AnswerToken(demo_key) + + platform.validate = miniPlatformValidate(task); + platform.updateHeight = function(height,success,error) {if (success) {success();}}; + platform.updateDisplay = function(data,success,error) { + if(data.views) { + chooseView.reinit(data.views); + } + if (success) {success();} + }; + var taskOptions = {}; + try { + var strOptions = getUrlParameter("options"); + if (strOptions !== undefined) { + taskOptions = $.parseJSON(strOptions); + } + } catch(exception) { + alert("Error: invalid options"); + } + var minScore = -3; + if (taskMetaData.fullFeedback) { + minScore = 0; + } + platform.getTaskParams = function(key, defaultValue, success, error) { + var res = {'minScore': minScore, 'maxScore': 40, 'noScore': 0, 'readOnly': false, 'randomSeed': "0", 'options': taskOptions}; + if (key) { + if (key !== 'options' && key in res) { + res = res[key]; + } else if (res.options && key in res.options) { + res = res.options[key]; + } else { + res = (typeof defaultValue !== 'undefined') ? defaultValue : null; + } + } + if (success) { + success(res); + } else { + return res; + } + }; + platform.askHint = function(hint_params, success, error) { + /* + $.post('updateTestToken.php', JSON.stringify({action: 'askHint'}), function(postRes){ + if (success) {success();} + }, 'json'); + */ + task_token.addHintRequest(hint_params, function(token) { + task.updateToken(token, function() {}) + success(token) + }) + }; + + + var loadedViews = {'task': true, 'solution': true, 'hints': true, 'editor': true, 'grader': true, 'metadata': true, 'submission': true}; + var shownViews = {'task': true}; + // TODO: modifs ARTHUR à relire + if (taskOptions.showSolutionOnLoad) { + shownViews.solution = true; + } + if (!taskOptions.hideTitle) { + $("#task h1").show(); + } + + if (taskMetaData.fullFeedback) { + loadedViews.grader = true; + } + + task.load( + loadedViews, + function() { + platform.trigger('load', [loadedViews]); + task.getViews(function(views) { + chooseView.init(views); + }); + task.showViews(shownViews, function() { + chooseView.update(shownViews); + platform.trigger('showViews', [{"task": true}]); + }); + if ($("#solution").length) { + $("#task").append("
"); + } + + // add branded header to platformless task depending on avatarType + // defaults to beaver platform branding + if(window.displayHelper) { + if (miniPlatformWrapping[displayHelper.avatarType].header) { + $('body').prepend(miniPlatformWrapping[displayHelper.avatarType].header); + } else { + $('body').prepend(miniPlatformWrapping[beaver].header); + } + } + }, + function(error) { + console.error(error) + } + ); + + + task_token.get(function(token) { + task.updateToken(token, function() {}) + }) + + + /* For the 'resize' event listener below, we use a cross-browser + * compatible version for "addEventListener" (modern) and "attachEvent" (old). + * Source: https://stackoverflow.com/questions/6927637/addeventlistener-in-internet-explorer + */ + function addEvent(evnt, elem, func) { + if (elem.addEventListener) // W3C DOM + elem.addEventListener(evnt,func,false); + else if (elem.attachEvent) { // IE DOM + elem.attachEvent("on"+evnt, func); + } + else { // No much to do + elem[evnt] = func; + } + } + + addEvent('resize', window, function() { + task.getViews(function(views) { + chooseView.reinit(views); + }); + }); + }; + var getMetaDataAndLoad = function(task) { + task.getMetaData(function(metaData) { + taskMetaData = metaData; + platformLoad(task); + }); + }; + if (window.platform.task || platform.initFailed) { + // case everything went fine with task loading, or task loading failed + // (due to missing jschannel and file:// protocol... + getMetaDataAndLoad(window.task ? window.task : window.platform.task); + } else { + // task is not loaded yet + var oldInit = platform.initWithTask; + platform.initWithTask = function(task) { + oldInit(task); + getMetaDataAndLoad(task); + }; + } + } +}); + +})(); diff --git a/_common/modules/integrationAPI.01/installationAPI.01/pemFioi/buttonsAndMessages.js b/_common/modules/integrationAPI.01/installationAPI.01/pemFioi/buttonsAndMessages.js index 6391964..b729b8b 100644 --- a/_common/modules/integrationAPI.01/installationAPI.01/pemFioi/buttonsAndMessages.js +++ b/_common/modules/integrationAPI.01/installationAPI.01/pemFioi/buttonsAndMessages.js @@ -95,7 +95,7 @@ window.displayHelper = { restart: "Recommencer", harderLevelSolved: "Attention : vous avez déjà résolu une version plus difficile. Vous ne pourrez pas gagner de points supplémentaires avec cette version.", showLevelAnyway: "Voir quand même", - scoreObtained: "Score obtenu :", + scoreObtained: "得分 :", hardVersionTakesTime: "Résoudre une {0} peut vous prendre beaucoup de temps ; songez en priorité à répondre aux questions en {1} pour gagner des points rapidement.", illKeepThatInMind: "J'y prendrai garde", harderLevelAvailable: "Notez que pour cette question, vous pouvez résoudre directement une version plus difficile que celle-ci.", @@ -127,50 +127,50 @@ window.displayHelper = { enemyWarning: "Attention : dans ce défi, l'ordinateur vous empêchera de trouver la solution par hasard." }, en: { - version: "Version", - levelVersionName_easy: "easy version", - levelVersionName_medium: "medium version", - levelVersionName_hard: "hard version", - levelVersionName_easy_stars: "2 stars version", - levelVersionName_medium_stars: "3 stars version", - levelVersionName_hard_stars: "4 stars version", - levelName_easy: "Easy", - levelName_medium: "Medium", - levelName_hard: "Hard", - warningTimeout: "

Warning, it has been more than {0} minutes since you started working on this task.

You should probably switch to a diffrent task, by clicking on the button on the top-right.

", - alright: "Alright", - moveOn: "Move on", - solvedMoveOn: "You solved this task completely, move on to another task.", - confirmRestart: "Are you sure you want to restart this version?", - yes: "Yes", - no: "No", - tryHardLevel: "We suggest you try the 4 stars version.", - tryMediumLevel: "We suggest you try the 3 stars version.", - tryNextTask: "We suggest you try the next task. If you still have time, come back later and try the next version of this task.", - yourScoreIsNow: "Your score is now:", - worseScoreStays: "This is not as good as before. Your score stays:", - scoreStays: "Your score stays the same:", + version: "版本", + levelVersionName_easy: "初级版", + levelVersionName_medium: "中级版", + levelVersionName_hard: "高级版", + levelVersionName_easy_stars: "初级版", + levelVersionName_medium_stars: "中级版", + levelVersionName_hard_stars: "高级版", + levelName_easy: "初级", + levelName_medium: "中级", + levelName_hard: "高级", + warningTimeout: "

注意,你在当前任务已经耗费超过 {0} 分钟了.

你可能应该切换到另一个不同的任务了哦。

", + alright: "好的", + moveOn: "继续", + solvedMoveOn: "你已经完全解决当前任务了,可以继续下一个任务。", + confirmRestart: "你确定要重新开始这个版本吗?", + yes: "确定", + no: "取消", + tryHardLevel: "我们建议你尝试一下四星版。", + tryMediumLevel: "我们建议你尝试一下三星版", + tryNextTask: "我们建议你直接进入下一个任务。如果最后你还有时间,可以再回来尝试此任务的下一个版本。", + yourScoreIsNow: "你的得分是:", + worseScoreStays: "这次还不如之前呢,你的得分将保持在:", + scoreStays: "你的得分保持不变:", score: "Score:", - noPointsForLevel: "You have not received any points yet on this version.", + noPointsForLevel: "在这个版本中你还没有得到任何分数哦。", outOf: " out of ", - tryToDoBetterOrChangeTask: "Try to do even better, or move on to another task.", - tryToDoBetterOrMoveToNextLevel: "Try to do even better, or move on to a more difficult version.", - bestPossibleScoreCongrats: "This is the best possible score on this task, congratulations!", - forMorePointsMoveToNextLevel: "To obtain more points, move on to a harder version of this task.", - youDidBetterBefore: "You did better before.", - scoreStays2: "Your score stays the same.", - reloadBestAnswer: "Reload your best answer.", - noAnswerSaved: "No answer saved so far for this version.", - validate: "Validate", - restart: "Restart", - harderLevelSolved: "Warning: you already solved a harder version of this task. You won't be able to obtain extra points with this version.", - showLevelAnyway: "Show it to me anyways.", - scoreObtained: "Obtained score:", + tryToDoBetterOrChangeTask: "你可以尝试做得更好,或者继续做下一项任务。", + tryToDoBetterOrMoveToNextLevel: "你可以尝试做得更好,或者挑战更难的版本。", + bestPossibleScoreCongrats: "你已经获得了这项任务的最好成绩,祝贺你哦!", + forMorePointsMoveToNextLevel: "为了获得更多的分数,你可以继续挑战难度更大的任务。", + youDidBetterBefore: "你比之前做的更好了!", + scoreStays2: "你的得分保持不变。", + reloadBestAnswer: "重新发挥你最好的理解。", + noAnswerSaved: "到目前为止,在这个版本中你还没有得到任何分数哦。", + validate: "验证一下", + restart: "重新开始", + harderLevelSolved: "注意:你已经解决了此任务的一个较难版本。在这个版本中你不会再获得额外的得分了哦。", + showLevelAnyway: "不管怎样,给我看看。", + scoreObtained: "得分:", hardVersionTakesTime: "Solving a {0} can take a lot of time. Consider working on the {1} to gain points quickly.", - illKeepThatInMind: "I'll consider it.", + illKeepThatInMind: "我会考虑的。", harderLevelAvailable: "Note that for this task, you may try to directly work on a harder version than this one.", lockedLevel: "This version is locked. Solve the previous version to display it!", - gradeThisAnswer: "Grade this answer", + gradeThisAnswer: "验证一下", // The following messages are used for tasks with no feedback saveAnswer: "Save this answer", @@ -193,7 +193,7 @@ window.displayHelper = { scoreWouldStay: "With this answer, your score would stay the same:", answerNotSavedContestOver: "The contest being over, your answer was not saved. You may {0}.", reloadSubmittedAnswer: "reload the validated answer", - difficultyWarning: "Warning: solving this version takes time.
You would solve the 2 or 3 star versions of other tasks more quickly.", + difficultyWarning: "提醒: 解决这个版本很耗费时间。
解决2星或3星版本的任务可以更快哦。", enemyWarning: "Warning: in this challenge, the computer will make sure you don't find the solution by chance." }, sv: { @@ -235,7 +235,7 @@ window.displayHelper = { restart: "Börja om", harderLevelSolved: "Varning: du har redan löst en svårare version av den här uppgiften. Du kommer inte kunna få mer poäng med den här versionen.", showLevelAnyway: "Visa den ändå.", - scoreObtained: "Uppnådd poäng:", + scoreObtained: "得分:", hardVersionTakesTime: "Att lösa en {0} kan ta lång tid. Fundera på om du ska jobba med en {1} för att tjäna poäng snabbare.", illKeepThatInMind: "Jag ska tänka på det.", harderLevelAvailable: "Notera att på den här uppgiften kan du direkt försöka med en svårare version än denna.", @@ -305,7 +305,7 @@ window.displayHelper = { restart: "Aloita alusta", harderLevelSolved: "Varoitus: olet jo ratkaissut vaikeamman version tästä tehtävästä. Tämän helpomman version ratkaiseminen ei voi korottaa pistemäärääsi.", showLevelAnyway: "Siirry joka tapauksessa.", - scoreObtained: "Saatu pistemäärä:", + scoreObtained: "得分:", hardVersionTakesTime: "{0} voi viedä runsaasti aikaa. {1} voi tuottaa pisteitä nopeammin.", illKeepThatInMind: "Ymmärrän tämän.", harderLevelAvailable: "Huomaa, että voit myös suoraan koittaa ratkaista vaikeampaa versiota tästä tehtävästä.", @@ -375,7 +375,7 @@ window.displayHelper = { restart: "Neustarten", harderLevelSolved: "Achtung: Du hast schon eine schwerere Version gelöst. Du kannst mit dieser Version keine zusätzlichen Punkte bekommen.", showLevelAnyway: "Trotzdem anzeigen", - scoreObtained: "Erhaltene Punkte:", + scoreObtained: "得分:", hardVersionTakesTime: "Eine {0} zu lösen kann dich viel Zeit kosten; Denke zunächst daran, die Fragen in {1} zu beantworten, um schnell Punkte zu bekommen.", illKeepThatInMind: "Ich hab das verstanden", harderLevelAvailable: "Beachte, dass du bei dieser Frage direkt zu einer schwereren Version gehen kannst.", @@ -445,7 +445,7 @@ window.displayHelper = { restart: "ابدأ من جديد", harderLevelSolved: "لقد قمت بحل المستوى الأصعب في هذا السؤال, لن تتمكن من الحصول على درجات أعلى في هذا السؤال", showLevelAnyway: "اظهرها لي على أي حال", - scoreObtained: "النقاط المكتسبة:", + scoreObtained: "得分", hardVersionTakesTime: "Solving a {0} can take a lot of time. Consider working on the {1} to gain points quickly.", illKeepThatInMind: "I'll consider it.", harderLevelAvailable: "تنبيه: يمكنك حل المستوى الأصعب في هذه المسألة مباشرة", @@ -515,7 +515,7 @@ window.displayHelper = { restart: "Reiniciar", harderLevelSolved: "Atención: ya has resuelto una versión más difícil. No puedes ganar puntos extra con esta versión.", showLevelAnyway: "Mostrar el nivel de igual manera", - scoreObtained: "Puntuación obtenida:", + scoreObtained: "得分:", hardVersionTakesTime: "Resolver una {0} puede tomar mucho tiempo; te aconsejamos priorizar el resolver las preguntas en {1} para ganar puntos más rápidamente.", illKeepThatInMind: "Lo tendré en mente", harderLevelAvailable: "Nota que para esta pregunta, puedes resolver directamente una versión más difícil que esta.", diff --git a/_common/modules/integrationAPI.01/official/miniPlatform.js b/_common/modules/integrationAPI.01/official/miniPlatform.js index 44753bc..80cc726 100644 --- a/_common/modules/integrationAPI.01/official/miniPlatform.js +++ b/_common/modules/integrationAPI.01/official/miniPlatform.js @@ -112,7 +112,7 @@ function getLanguageString(key) {
\ \ \ - \ + \ \
Concours castor高阶思维能力测试Le concours Castor
\
' diff --git a/_common/modules/integrationAPI.01/official/miniPlatform_M.js b/_common/modules/integrationAPI.01/official/miniPlatform_M.js index 3caf2b1..537eb94 100644 --- a/_common/modules/integrationAPI.01/official/miniPlatform_M.js +++ b/_common/modules/integrationAPI.01/official/miniPlatform_M.js @@ -105,8 +105,8 @@
\ \ \ - \ - \ + \ + \
Concours castorLe concours Castor高阶思维能力测试计算思维
\
' }, diff --git a/_common/modules/pemFioi/quickAlgo/doc.js b/_common/modules/pemFioi/quickAlgo/doc.js index e22ed56..7590d3f 100644 --- a/_common/modules/pemFioi/quickAlgo/doc.js +++ b/_common/modules/pemFioi/quickAlgo/doc.js @@ -52,7 +52,7 @@ var docLanguageStrings = { subcategory: 'Subcategory “{}”', blocklyColumns: ["Display", "Internal name", "Comment"], columns: ["Block name", "Python name", "Internal name", "Type", "Arguments", "Description", "Comment"], - nameUndefined: 'undefined!', + nameUndefined: '未定义!', action: 'Action', sensor: 'Sensor' }, diff --git a/bebras/2018/2018-FR-05-treasure/index_en.html b/bebras/2018/2018-FR-05-treasure/index_en.html index a8f6eac..a11c599 100644 --- a/bebras/2018/2018-FR-05-treasure/index_en.html +++ b/bebras/2018/2018-FR-05-treasure/index_en.html @@ -42,7 +42,7 @@ } return "You have found the treasure, but it was possible to do it with " + walls + ". Try again. Be careful, the treasure might be in a different room." }, - success: "Congratulations, you succeeded!", + success: "祝贺你,你成功了!", notFinished: "You haven't found the treasure yet!", feedbackHard: "Total thickness
of walls broken: ", feedbackEasyMedium: "Number of walls broken: " @@ -50,7 +50,7 @@ diff --git a/bebras/2018/2018-FR-05-treasure/index_en2.html b/bebras/2018/2018-FR-05-treasure/index_en2.html index 280d151..17df6e9 100644 --- a/bebras/2018/2018-FR-05-treasure/index_en2.html +++ b/bebras/2018/2018-FR-05-treasure/index_en2.html @@ -42,7 +42,7 @@ } return "You have found the treasure, but it was possible to do it with " + walls + ". Try again. Be careful, the treasure might be in a different room." }, - success: "Congratulations, you succeeded!", + success: "祝贺你,你成功了!", notFinished: "You haven't found the treasure yet!", feedbackHard: "Total thickness
of walls broken: ", feedbackEasyMedium: "Number of walls broken: " @@ -50,7 +50,7 @@ @@ -100,7 +100,7 @@

Solution

- +

In each step you choose to destroy the walls of the corridor that has the least number of walls, of those that lead to rooms that you cannot yet visit.

In the example below you should therefore start with the corridor at the bottom right.

@@ -118,7 +118,7 @@

For example, in the part below, the next wall to break is one of the thick walls 13.

- +
diff --git a/bebras/2019/FR-2019-01-poles/index_en.html b/bebras/2019/FR-2019-01-poles/index_en.html index 8ea4218..21c3140 100644 --- a/bebras/2019/FR-2019-01-poles/index_en.html +++ b/bebras/2019/FR-2019-01-poles/index_en.html @@ -36,10 +36,10 @@ @@ -59,19 +59,19 @@
-

Jumping posts

+

小松鼠跳柱子

- Beaver tries to touch as many bamboos as possible. Your goal is to stop him. + 小松鼠想要尽可能多地碰到柱子。而你的目标是阻止它碰到柱子。

- Beaver can only jump down. Beaver can never jump above bamboos higher than himself. + 小松鼠只能从高的柱子跳到低的柱子上,它没办法跳到比自己高的柱子上。

- Change the order of the bamboos, to prevent him from jumping more than twothree times. + 改变柱子的顺序,使得小松鼠最多只能跳跃 23次。

@@ -87,8 +87,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!折半查找,快速排序

diff --git a/bebras/2019/FR-2019-02-registers/index_en.html b/bebras/2019/FR-2019-02-registers/index_en.html index 872715c..0186bb1 100644 --- a/bebras/2019/FR-2019-02-registers/index_en.html +++ b/bebras/2019/FR-2019-02-registers/index_en.html @@ -37,21 +37,21 @@ @@ -76,17 +76,17 @@
-

Rising pebbles

+

填充小石子

- Your goal is to place a pebble in the top circle. + 你的目标是在最顶部的圆圈中放置一个小石子。

-

To place a pebbles in a circle, all the circles underneath need to have pebbles. You can then get these back. +

想要在一个圆圈中放置数字所对应数量的小石子, 下面所有箭头指向的圆圈里都要有小石子。 然后你可以再把这些小石子拿回储备库。

-

Click on a circle to place athe number of pebbles indicated in the circle, or to remove itthem.

+

点击圆圈放置一个圆圈中数字所对应数量的小石子组合 , 或者拿回所放置的小石子小石子.

@@ -102,8 +102,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!贪心算法

diff --git a/bebras/2019/FR-2019-03-prediction/index_en.html b/bebras/2019/FR-2019-03-prediction/index_en.html index 2d2d63c..77f4611 100644 --- a/bebras/2019/FR-2019-03-prediction/index_en.html +++ b/bebras/2019/FR-2019-03-prediction/index_en.html @@ -37,16 +37,16 @@ @@ -63,25 +63,25 @@
-

Predictions

+

预测

-

Your goal is to understand why some kangaroos receive flowers, and others don't.

-

Click on the "try" button to make flowers appear.

-

Look carefully at the content of the +

你的目标是探究为什么有些袋鼠会收到花,而有些则不会。

+

点击“试一试”按钮,让花朵出现。

+

请仔细观察一下: - cell above each kangaroo. - cells below and above each kangaroo. + 注意每只袋鼠上方的小方格哦。 + 注意每只袋鼠上方和下方的小方格哦。

-

Then, click on the "next" button, then click on the kangaroos that will receive flowers, to give them a flower pot.

+

然后,点击“下一步”按钮,再点击将收到鲜花的袋鼠,给它们一个花盆。

- +
@@ -96,8 +96,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!分治法

diff --git a/bebras/2019/FR-2019-06-inclusions/index_en.html b/bebras/2019/FR-2019-06-inclusions/index_en.html index 716e64f..98262d6 100644 --- a/bebras/2019/FR-2019-06-inclusions/index_en.html +++ b/bebras/2019/FR-2019-06-inclusions/index_en.html @@ -37,8 +37,8 @@ @@ -77,38 +77,38 @@
-

Nested rectangles

+

嵌套的矩形

- The current diagram describes how the rectangles with blue corners are nested within one another. + 上方的图形描述了下方带蓝色角的矩形之间的组合关系是如何的。

- An arrow from B to A means that rectangle B needs to be entirely inside rectangle A. + 从B到A的箭头意味着矩形B需要完全在矩形A内。

- To recreat the target, move rectangles by dragging them, and change their sizes by dragging the blue corners. + 如果你想改变嵌套关系,可以采取下列两种方式:(1)拖动矩形进行移动;(2)拖动矩形的蓝色角来改变它们的大小。

-

Current Diagram

+

你的图形

- +
-

Target Diagram

+

目标图形

- - + +
@@ -120,8 +120,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!计算机图形学-碰撞检测算法

diff --git a/bebras/2019/FR-2019-07-two-connect/index_en.html b/bebras/2019/FR-2019-07-two-connect/index_en.html index 675f0c5..cf5133f 100644 --- a/bebras/2019/FR-2019-07-two-connect/index_en.html +++ b/bebras/2019/FR-2019-07-two-connect/index_en.html @@ -33,9 +33,9 @@ @@ -64,14 +64,14 @@
-

Repeated patterns

+

模式的复制

-

Place the blue shapes on the grid.

-

The content of every shape should be the same.

-

You can turn the shapes at each step.

+

请把 个蓝色图形放在下方的网格上。

+

请保持每个形状所覆盖图案的内容是相同的。

+

你可以在每一步结束后转动形状,改变形状的方向。

@@ -89,8 +89,8 @@
-

Solution

-

C'est de l'informatique !

+

答案解析

+

这是提示信息!排列组合

diff --git a/bebras/2019/FR-2019-09-hidden-words/index_en.html b/bebras/2019/FR-2019-09-hidden-words/index_en.html index cadb2ef..99a7177 100644 --- a/bebras/2019/FR-2019-09-hidden-words/index_en.html +++ b/bebras/2019/FR-2019-09-hidden-words/index_en.html @@ -37,17 +37,17 @@ @@ -96,23 +96,23 @@
-

Passwords

+

密码

-

Drag cards from the grid into the answer area, to form a passwordthree passwords made of 5 symbols each.

-

For each password:

+

将卡片从网格拖到答案区域,形成一个密码三个密码,是由5个符号组成的密码

+

对于每个密码:

    -
  • The first card is the card from cell A1.
  • -
  • We don't tell you where the first card is from.
  • -
  • Each card indicates which cell contains the next card.
  • -
  • The last card is from cell F3C6.
  • +
  • 第一张卡片来自单元格 A1
  • +
  • 我们不会告诉你第一张卡片是哪里来的。
  • +
  • 每张卡片下方的字母和数字指示包含下一张卡片来自哪个单元格。
  • +
  • 最后一张卡来自单元格 F3 C6
-
For example, after this card,
you need to put the card located in column C, row 2. +
例如,在这张卡片之后,你需要放置的卡片是来自C列第2行的卡片。
@@ -127,8 +127,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!

diff --git a/bebras/2019/FR-2019-10-lighting/index_en.html b/bebras/2019/FR-2019-10-lighting/index_en.html index 5114151..45f8305 100644 --- a/bebras/2019/FR-2019-10-lighting/index_en.html +++ b/bebras/2019/FR-2019-10-lighting/index_en.html @@ -3,7 +3,7 @@ - FR-2019-10-lighting + FR-2019-10-光线 @@ -37,21 +37,21 @@ @@ -70,18 +70,18 @@
-

Lighting

+

光线

-

Drag colored lamps towards gray spots, and recreate Beaver's objective.

+

把彩色的灯拖拽到灰色的点上,实现目标光线。

-

Use the number displayed in the tables to help you.

- -

To help you, we already placed two lamps.

- -

To get all the points, only use  lamps.

+

表格中显示的数字或许可以帮助你进行判断。

+ +

作为提示,我们已经放置了两盏灯。

+ +

希望你可以仅仅使用  盏灯,就实现目标。

@@ -101,7 +101,7 @@

Solution

-

It's informatics!

+

It's informatics! 分治法

diff --git a/bebras/2019/FR-2019-12-roller/index_en.html b/bebras/2019/FR-2019-12-roller/index_en.html index 66bf522..c8c4ebb 100644 --- a/bebras/2019/FR-2019-12-roller/index_en.html +++ b/bebras/2019/FR-2019-12-roller/index_en.html @@ -37,21 +37,21 @@ @@ -90,21 +90,21 @@
-

Roller

+

滚筒

-

A roller rolls on the cells. It applies Rollers roll on the cells. They apply stamps while rolling.

+

一个滚筒在方格纸上滚动。 它可以印制滚筒在方格纸上滚动。 在滚动的时候它们可以印出来 邮票。

-

Modify its parameters to recreate the target.

-

Click on each roller to view its parameters, and modify them to recreate the target.

+

修改滚筒的各个参数,以便印刷出目标中的邮票序列。

+

单击每个滚轮可以查看它的参数,请修改它们,以便你可以创建出来目标中的邮票序列。

-

Roller 1 will roll first, then roller 2.

+

先滚1号滚筒,然后再滚2号滚筒。

-

Roller 1 will roll first, then roller 2, then roller 3.

- -

A roller can change what the previous one did.

+

先滚1号滚筒,然后再滚2号滚筒,最后是3号滚筒。

+ +

每个滚轮可以改变前一个滚轮所形成的形状。

@@ -130,8 +130,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!

diff --git a/bebras/2019/FR-2019-13-align-strips/index_en.html b/bebras/2019/FR-2019-13-align-strips/index_en.html index 7cef808..b407207 100644 --- a/bebras/2019/FR-2019-13-align-strips/index_en.html +++ b/bebras/2019/FR-2019-13-align-strips/index_en.html @@ -38,20 +38,20 @@ @@ -71,19 +71,19 @@
-

Water network

+

供水系统

-

Your goal is to align the gray pipes so that the water flows from the square tank to Beavereach of the 4 Beavers.

+

你的目标是对齐灰色的管道,使水从方形水箱流向 小松鼠所在的位置4只小松鼠中的每一只所在的位置

-

The pipes are attatched to wheels. To orient them, you can perform two actions: +

管道装在轮子上。要改变管道的方向,可以进行两个操作:

    -
  1. Move the black lever to make all the connected wheels turn
  2. -
  3. Click on a wheel to disconnect from others, or reconnect it.
  4. +
  5. 移动黑色的杠杆使所有相连的轮子转动。
  6. +
  7. 点击轮子可以断开该轮子与其它轮子的联动(黑色杠杆移动时该轮子不再一起转动),或者重新连接轮子。
@@ -99,8 +99,8 @@
-

Solution

-

C'est de l'informatique !

+

答案解析

+

这是提示信息!

diff --git a/bebras/2019/FR-2019-15-shape-compression/index_en.html b/bebras/2019/FR-2019-15-shape-compression/index_en.html index 6be7af7..09d4fc8 100644 --- a/bebras/2019/FR-2019-15-shape-compression/index_en.html +++ b/bebras/2019/FR-2019-15-shape-compression/index_en.html @@ -38,16 +38,16 @@ @@ -64,17 +64,17 @@
-

Compacted shapes

+

对应的形状

-

Beaver has a machine that transforms a sequence of shapes according to some rules.

-

Find rules and a sequence of shapes that give a result identical to the target.

-

Click on the buttons to add or remove shapes.

-

Click on the shapes in the gray buttons to change them. For example, click on .

-

To get all the points, your sequence should only contain 6 shapes.

+

小松鼠有一种机器,可以根据某些规则变换一系列形状。

+

寻找规则, 并且 制作一个形状序列, 使它对应的结果与目标相同。

+

点击按钮 增加或者减少形状。

+

点击灰色按钮中的形状来更改结果中的形状。 例如, 点击 .

+

为了得到所有的分数,你的序列应该只包含6个形状。

@@ -88,8 +88,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!

diff --git a/bebras/2019/FR-2019-17-base-4-encoding/index_en.html b/bebras/2019/FR-2019-17-base-4-encoding/index_en.html index 6035049..72098de 100644 --- a/bebras/2019/FR-2019-17-base-4-encoding/index_en.html +++ b/bebras/2019/FR-2019-17-base-4-encoding/index_en.html @@ -37,12 +37,12 @@ @@ -60,13 +60,13 @@
-

Base 4 encoding

+

4进制编码

-

Beaver uses sliders to represent a symbol2 symbols3 symbols.

-

Move these sliders so that the result becomes identical to the target.

+

小松鼠用滑块来代表 1个符号2 个符号3 个符号.

+

移动这些滑块,使结果与目标相同。

@@ -82,8 +82,8 @@
-

Solution

-

It's informatics!

+

答案解析

+

这是提示信息!

diff --git a/bebras/2019/contents.js b/bebras/2019/contents.js index 27d50f3..961df83 100644 --- a/bebras/2019/contents.js +++ b/bebras/2019/contents.js @@ -5,29 +5,29 @@ standaloneAddContents({ folder: "2019/", tasks: [ { code: "FR-2019-01-poles", - title: "Bambous" }, + title: "小松鼠跳柱子" }, { code: "FR-2019-02-registers", - title: "Cailloux" }, + title: "填充小石子" }, { code: "FR-2019-03-prediction", - title: "Prédictions" }, + title: "预测" }, { code: "FR-2019-06-inclusions", - title: "Rectangles imbriqués" }, + title: "嵌套的矩形" }, { code: "FR-2019-07-two-connect", - title: "Arroser les fleurs" }, + title: "浇花" }, { code: "FR-2019-08-patterns", - title: "Motifs répétés" }, + title: "模式的复制" }, { code: "FR-2019-09-hidden-words", - title: "Mots de passe" }, + title: "密码" }, { code: "FR-2019-10-lighting", - title: "Ambiance lumineuse" }, + title: "光线" }, { code: "FR-2019-12-roller", - title: "Tampons" }, + title: "滚筒" }, { code: "FR-2019-13-align-strips", - title: "Réseau hydraulique" }, + title: "供水系统" }, { code: "FR-2019-15-shape-compression", - title: "Formes compactées" }, + title: "对应的形状" }, { code: "FR-2019-17-base-4-encoding", - title: "Curseurs" } + title: "4进制编码" } ] });