Safecracking Game
金庫の鍵を解除するだけのゲーム。
ヒント
・青いランプは入力した数字のどれかが場所と数字があっている。
・黄色いランプは入力した数字がどこかに使われているが場所は合っていない。
・赤いランプはハズレ。
SWF素材(フォント部分) http://wonderfl.net/c/gLbF
/**
* Copyright bkzen ( http://wonderfl.net/user/bkzen )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/hFfA
*/
package
{
import flash.system.LoaderContext;
import com.bit101.components.ProgressBar;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import net.wonderfl.utils.WonderflAPI;
/**
* 金庫の鍵を解除するだけのゲーム
* @author jc at bkzen
*/
[SWF (backgroundColor = "0xFFFFFF", frameRate = "60", width = "465", height = "465")]
public class SafecrackingGame extends Sprite
{
private static const FONT_URL: String = "http://swf.wonderfl.net/swf/usercode/7/75/7578/757853e7ae03772ea09030f20674fdad479984fb.swf";
private static const ASSET_URL: String = "http://assets.wonderfl.net/images/related_images/5/51/51ab/51abaa807c1725ea72f46bd5e25d11950ae6613f";
private var progressBar: ProgressBar;
public function SafecrackingGame()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e: Event = null): void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//
api = new WonderflAPI(loaderInfo.parameters);
progressBar = new ProgressBar();
progressBar.maximum = 100;
progressBar.draw();
progressBar.x = stage.stageWidth - progressBar.width >> 1;
progressBar.y = stage.stageHeight - progressBar.height >> 1;
addChild(progressBar);
var fontLoader: Loader = new Loader();
fontLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteFont);
fontLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressFont);
fontLoader.load(new URLRequest(FONT_URL + "?t=" + new Date().getTime()));
}
private function onProgressFont(e:ProgressEvent):void
{
progressBar.value = e.bytesLoaded / e.bytesTotal * 50;
}
private function onCompleteFont(e:Event):void
{
var info: LoaderInfo = LoaderInfo(e.target);
fontCreater = info.loader.content as Object;
info.removeEventListener(Event.COMPLETE, onCompleteFont);
info.removeEventListener(ProgressEvent.PROGRESS, onProgressFont);
var assetLoader: Loader = new Loader();
assetLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteAsset);
assetLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressAsset);
assetLoader.load(new URLRequest(ASSET_URL + "?t=" + new Date().getTime()),new LoaderContext(true));
}
private function onProgressAsset(e:ProgressEvent):void
{
progressBar.value = e.bytesLoaded / e.bytesTotal * 50 + 50;
}
private function onCompleteAsset(e:Event):void
{
var info: LoaderInfo = LoaderInfo(e.target);
asset = info.loader.content as Bitmap;
info.removeEventListener(Event.COMPLETE, onCompleteAsset);
info.removeEventListener(ProgressEvent.PROGRESS, onProgressAsset);
removeChild(progressBar);
addChild(new SafecrackingGameMain());
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageDisplayState;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.system.Capabilities;
import flash.utils.escapeMultiByte;
import net.wonderfl.utils.WonderflAPI;
var fontCreater: Object;
var asset: Bitmap;
var api: WonderflAPI;
const COLOR_RED: uint = 0xCC0000;
const COLOR_YELLOW: uint = 0xFFCC33;
const COLOR_BLUE: uint = 0x0000CC;
class SafecrackingGameMain extends Sprite
{
private var startBtn: STextBtn, helpBtn: STextBtn, fullBtn: STextBtn, nextLevelBtn: STextBtn, tweetBtn: STextBtn;
private var help: Help;
private var gameLevelTxt:Object;
private var input:InputArea;
private var modalSp: Sprite;
private var tweet: String;
private var nextLevelHandler: Function;
function SafecrackingGameMain()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e: Event = null): void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//
var title: DisplayObject = fontCreater.create(0x000000, 1, 1, 1);
title.x = stage.stageWidth >> 1, title.y = (stage.stageHeight >> 1) - 50;
addChild(title);
Object(title).add("Safecracking Game");
addChild(startBtn = new STextBtn(" START", "㊨"));
addChild(helpBtn = new STextBtn(" HELP", "㊨"));
addChild(fullBtn = new STextBtn(" FULL SCREEN", "㊨"));
fullBtn.x = helpBtn.x = startBtn.x = stage.stageWidth >> 1;
startBtn.y = (stage.stageHeight >> 1) + 0;
helpBtn.y = (stage.stageHeight >> 1) + 20;
fullBtn.y = (stage.stageHeight >> 1) + 50;
startBtn.addEventListener(MouseEvent.CLICK, onClickStart);
helpBtn.addEventListener( MouseEvent.CLICK, onClickHelp);
fullBtn.addEventListener( MouseEvent.CLICK, onClickFullScreen);
}
private function onClickFullScreen(e:MouseEvent):void
{
stage.displayState = stage.displayState == StageDisplayState.FULL_SCREEN
? StageDisplayState.NORMAL
: stage.displayState = StageDisplayState.FULL_SCREEN;
}
private function onClickHelp(e: MouseEvent): void
{
while (numChildren > 0) removeChildAt(0);
addChild(help = new Help(onClickStart));
}
private function onClickStart(e:MouseEvent = null):void
{
startBtn.removeEventListener(MouseEvent.CLICK, onClickStart);
helpBtn.removeEventListener( MouseEvent.CLICK, onClickHelp);
startBtn.clear();
helpBtn.clear();
help = null;
while (numChildren > 0) removeChildAt(0);
createUI();
start("01", 4, "1111111110", clearLevel01);
}
private function onClickTweet(e:MouseEvent):void
{
navigateToURL(new URLRequest("http://twitter.com/share?" +
"text=" + escapeMultiByte(tweet) +
"&url=" + escapeMultiByte("http://wonderfl.net/c/" + api.appID)
));
}
private function onClickNextLevel(e:MouseEvent):void
{
nextLevelHandler();
nextLevelHandler = null;
}
private function createUI():void
{
var bg: Shape = new Shape();
addChild(bg);
var g: Graphics = bg.graphics;
g.beginFill(0x777777);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
g.beginFill(0xFFFFFF);
g.drawRect(1, 1, stage.stageWidth - 2, stage.stageHeight - 2);
addChild(input = new InputArea());
input.x = stage.stageWidth - input.width >> 1;
input.y = 50;
//input.init(4);
addChild(modalSp = new Sprite());
modalSp.graphics.beginFill(0xCCCCCC, 0.8);
modalSp.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
nextLevelBtn = new STextBtn(" NEXT LEVEL", "㊨"), tweetBtn = new STextBtn(" TWEET SCORE", "㊨");
nextLevelBtn.addEventListener(MouseEvent.CLICK, onClickNextLevel);
tweetBtn.addEventListener(MouseEvent.CLICK, onClickTweet);
gameLevelTxt = fontCreater.create(0x000000, 2, 10, 1);
}
private function start(level:String, char: int, usekey: String, clearHandler: Function):void
{
modalSp.visible = true;
input.init(char);
if (nextLevelBtn.parent) removeChild(nextLevelBtn);
if (tweetBtn.parent) removeChild(tweetBtn);
gameLevelTxt.clear();
gameLevelTxt.x = stage.stageWidth >> 1, gameLevelTxt.y = (stage.stageHeight >> 1) - 100;
gameLevelTxt.add("LEVEL " + level);
gameLevelTxt.add(" ", 0x000000, 1, 50);
gameLevelTxt.add("PASS WORD : " + char + " characters");
gameLevelTxt.add(" ", 0x000000, 1, 50);
gameLevelTxt.add("START", 0x000000, 2, 2);
gameLevelTxt.add(" ", 1, 50);
addChild(DisplayObject(gameLevelTxt));
var gameStartHandler: Function = function(e: Event): void
{
gameLevelTxt.removeEventListener(Event.COMPLETE, gameStartHandler);
gameLevelTxt.clear();
modalSp.visible = false;
input.start(parseInt(String(usekey), 2), clearHandler);
}
gameLevelTxt.addEventListener(Event.COMPLETE, gameStartHandler);
}
private function gameClear(level: String, clearTime: int): void
{
modalSp.visible = true;
var score: String = timeToString(clearTime);
tweet = "Playing Safecracking Game [ level " + level + " score : " + score + " ] #wonderfl";
gameLevelTxt.add("LEVEL " + level, 0, 2, 2);
gameLevelTxt.add("CLEAR!!", 0, 2, 2);
gameLevelTxt.add(" ", 0, 2, 100);
gameLevelTxt.add("CLEAR TIME", 0xCC0000, 2, 5);
gameLevelTxt.add(" ", 0, 0.1, 100);
gameLevelTxt.add(score, 0xCC0000, 2, 5);
var clearLevelCompHandler: Function = function(e: Event): void
{
gameLevelTxt.removeEventListener(Event.COMPLETE, clearLevelCompHandler);
nextLevelBtn.x = stage.stageWidth >> 1, nextLevelBtn.y = gameLevelTxt.y + gameLevelTxt.height + 10;
tweetBtn.x = stage.stageWidth >> 1, tweetBtn.y = nextLevelBtn.y + nextLevelBtn.height + 10;
if (nextLevelHandler != null) addChild(nextLevelBtn);
addChild(tweetBtn);
}
gameLevelTxt.addEventListener(Event.COMPLETE, clearLevelCompHandler);
}
private function clearLevel01(clearTime: int):void
{
gameClear("01", clearTime);
nextLevelHandler = start02;
}
private function start02():void
{
start("02", 4, "1111111111", clearLevel02);
}
private function clearLevel02(clearTime: int):void
{
gameClear("02", clearTime);
nextLevelHandler = start03;
}
private function start03():void
{
start("03", 5, "1111111110", clearLevel03);
}
private function clearLevel03(clearTime: int):void
{
gameClear("03", clearTime);
nextLevelHandler = start04;
}
private function start04():void
{
start("Final", 5, "1111111111", clearLevel04);
}
private function clearLevel04(clearTime: int): void
{
gameClear("Final", clearTime);
}
private function timeToString(clearTime: int): String
{
var str: String = "";
for (var i: int = 0; i < 9; i++)
{
if ((i - 1) % 3 == 2) str = ":" + str;
else if (i == 5) str = (clearTime % 6) + str, clearTime /= 6;
else str = (clearTime % 10) + str, clearTime /= 10;
}
return str;
}
}
class Help extends Sprite
{
private var txt: Object;
private var startBtn: STextBtn;
private var _startHandler: Function;
function Help(startHandler: Function)
{
_startHandler = startHandler;
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e: Event = null): void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
addChild((txt = fontCreater.create(0, 2, 1, 1)) as DisplayObject);
txt.x = stage.stageWidth >> 1;
txt.add("HELP", 0, 2);
txt.add(" ");
if (Capabilities.language == "ja")
{
txt.add("きんこのかぎを かいじょせよ");
txt.add("PASS WORD は いくつかのすうじ");
txt.add("おなじすうじは つかわれていない");
txt.add(" ");
txt.add(" BLUEのランプ:すうじとばしょが せいかい", COLOR_BLUE);
txt.add("YELLOWのランプ:すうじのみ せいかい ", COLOR_YELLOW);
txt.add(" REDのランプ:はずれ ", COLOR_RED);
}
else
{
txt.add("Release the key to the safe.", 0, 1.5);
txt.add("Pass word is some numbsers.", 0, 1.5);
txt.add("Same numbers as", 0, 1.5);
txt.add("the password is not used.", 0, 1.5);
txt.add(" ", 0, 1.5);
txt.add("Blue lamp : ", 0, 1.5);
txt.add("Number and place are right", COLOR_BLUE, 1.5);
txt.add("Yelow lamp : ", 0, 1.5);
txt.add("Number only right", COLOR_YELLOW, 1.5);
txt.add("Red lamp : ", 0, 1.5);
txt.add("Miss", COLOR_RED, 1.5);
}
txt.addEventListener(Event.COMPLETE, onComp);
}
private function onComp(e:Event):void
{
addChild(startBtn = new STextBtn("START", "㊨", 0, 2));
startBtn.addEventListener(MouseEvent.CLICK, onClickStart);
startBtn.x = stage.stageWidth >> 1;
startBtn.y = txt.height + 10;
}
private function onClickStart(e:MouseEvent):void
{
startBtn.clear();
startBtn.removeEventListener(MouseEvent.CLICK, onClickStart);
txt.clear();
txt = null;
while (numChildren > 0) removeChildAt(0);
_startHandler();
}
}
class InputArea extends Sprite
{
private const TW: int = 8 * 2;
private const TW2: int = TW * 8;
private const TH: int = 15 * 2;
private var stxt: Object;
private var lampBmps: Array, lampBBmps: Array, lampYBmps: Array, lampRBmps: Array;
public var keys: Array;
private var clearKey: KeyButton, okKey: KeyButton;
private var inputKey: String = "";
private var length: int;
private var usedKey: uint;
private var startTime: Number, beforeTime: Number, clearTime: Number;
private var timeTxt: BitmapData, timerBmd: BitmapData;
private var timerRect: Rectangle = new Rectangle(0, 0, TW, TH);
private var timerPoint: Point = new Point();
private var pass: String;
private var _clearHandler:Function;
function InputArea()
{
var g: Graphics = graphics;
g.beginFill(0x777777);
g.drawRect(0, 0, 200, 40);
g.beginFill(0xEEEEEE);
g.drawRect(1, 1, 198, 38);
stxt = fontCreater.create(0x555555, 3, 0, 1);
stxt.x = 100, stxt.y = -5;
addChild(DisplayObject(stxt));
lampBmps = [], lampBBmps = [], lampYBmps = [], lampRBmps = [], keys = [];
var dx: int = 200 - 34 * 3 >> 1;
var dy: int = 75;
for (var i:int = 0; i < 10; i++)
{
var key: KeyButton = new KeyButton(String((i + 1) % 10));
addChild(keys[i] = key);
key.x = (i % 3) * 34 + dx;
key.y = (i / 3 | 0) * 34 + dy;
key.addEventListener(MouseEvent.CLICK, onClick);
if (i == 9)
{
key.x = 34 + dx;
addChild(clearKey = new KeyButton("C"));
addChild(okKey = new KeyButton("¢"));
clearKey.y = okKey.y = key.y;
clearKey.x = dx, okKey.x = 34 * 2 + dx;
clearKey.addEventListener(MouseEvent.CLICK, onClick);
okKey.addEventListener(MouseEvent.CLICK, onClick);
}
}
g.beginFill(0x777777);
g.drawRect(0, dy = key.y + key.height + 20, 200, 30);
g.beginFill(0xEEEEEE);
g.drawRect(1, dy + 1, 198, 28);
timeTxt = fontCreater.getBmd("0123456789:", 0x555555, 2);
var bmp: Bitmap;
addChild(bmp = new Bitmap(timerBmd = new BitmapData(TW2, TH, true, 0)));
bmp.x = 200 - timerBmd.width >> 1, bmp.y = dy + (30 - timerBmd.height >> 1);
}
public function start(usedKey: uint, clearHandler: Function): void
{
this.usedKey = usedKey;
_clearHandler = clearHandler;
pass = inputKey = "";
var arr: Array = [];
for (var i: int = 0; i < 10; i++) { if ((keys[i].enabled = (usedKey >> (9 - i)) & 1)) arr.push((i + 1) % 10); }
for (var j: int, t: int, l: int = arr.length; l; j = Math.random() * l, t = arr[--l], arr[l] = arr[j], arr[j] = t) { }
i = Math.random() * (arr.length - 4);
pass = arr.splice(i, length).join("");
beforeTime = startTime = new Date().getTime();
addEventListener(Event.ENTER_FRAME, loop);
}
private function loop(e:Event):void
{
var d: Number = new Date().getTime();
var len: int = d - beforeTime;
beforeTime = d;
if (len < 0) startTime -= len;
showTime((beforeTime - startTime) / 10);
}
private function showTime(c: int): void
{
timerBmd.lock();
timerBmd.fillRect(timerBmd.rect, 0);
for (var i: int = 0; i < 8; i++)
{
timerPoint.x = TW2 - (i + 1) * TW;
if (i % 3 == 2) timerRect.x = 10 * TW;
else if (i == 4) timerRect.x = (c % 6) * TW, c /= 6;
else timerRect.x = (c % 10) * TW, c /= 10;
timerBmd.copyPixels(timeTxt, timerRect, timerPoint);
}
timerBmd.unlock();
}
private function onClick(e:MouseEvent):void
{
var key: KeyButton = KeyButton(e.target);
switch (key.txt)
{
case "C":
inputKey = "";
for (var i: int = 0; i < 10; i++)
{
keys[i].enabled = (usedKey >> (9 - i)) & 1;
}
stxt.clear();
break;
case "¢":
if (inputKey.length == length)
{
if (pass == inputKey)
{
clearTime = new Date().getTime();
showTime((clearTime - startTime) / 10);
for (i = 0; i < length; i++)
{
lampYBmps[i].visible = lampRBmps[i].visible = false;
lampBBmps[i].visible = true;
}
_clearHandler(clearTime - startTime);
removeEventListener(Event.ENTER_FRAME, loop);
}
else
{
var t: int, b: int, r: int, y: int;
for (i = 0; i < length; i++)
{
if ((t = pass.indexOf(inputKey.charAt(i))) >= 0)
{
lampBBmps[b + y].visible = lampYBmps[b + y].visible = false;
if (t == i) b ++;
else y ++;
}
else
{
lampBBmps[length - (r + 1)].visible = lampYBmps[length - (r + 1)].visible = false;
lampRBmps[length - (r + 1)].visible = true;
r++;
}
}
t = b + y;
for (i = 0; i < t; i++)
{
if (i < b) lampBBmps[i].visible = true;
else lampYBmps[i].visible = true;
}
}
}
break;
default:
if (inputKey.length == length) return;
key.enabled = false;
stxt.clear();
inputKey += key.txt
stxt.add(inputKey);
break;
}
}
public function init(length: int = 5): void
{
this.length = length;
stxt.clear();
while (lampBmps.length > 0)
{
Bitmap(removeChild(lampBmps.pop())).bitmapData.dispose();
Bitmap(removeChild(lampBBmps.pop())).bitmapData.dispose();
Bitmap(removeChild(lampYBmps.pop())).bitmapData.dispose();
Bitmap(removeChild(lampRBmps.pop())).bitmapData.dispose();
}
var r: Rectangle = new Rectangle(0, 0, 16, 16);
var p: Point = new Point();
var str: String = "";
for (var i:int = 0; i < length; i++)
{
var bmd: BitmapData = new BitmapData(16, 16, true, 0);
bmd.copyPixels(asset.bitmapData, r, p);
var base: BitmapData = bmd;
var bmp: Bitmap;
addChild(bmp = lampBmps[i] = new Bitmap(bmd));
bmd = base.clone();
bmd.threshold(bmd, bmd.rect, p, "==", 0xFF666666, 0xFFCC0000, 0xFFFFFFFF, true);
bmd.threshold(bmd, bmd.rect, p, "==", 0xFFCCCCCC, 0xFFFFCCCC, 0xFFFFFFFF, true);
addChild(bmp = lampRBmps[i] = new Bitmap(bmd));
bmd = base.clone();
bmd.threshold(bmd, bmd.rect, p, "==", 0xFF666666, 0xFF0000CC, 0xFFFFFFFF, true);
bmd.threshold(bmd, bmd.rect, p, "==", 0xFFCCCCCC, 0xFFCCCCFF, 0xFFFFFFFF, true);
addChild(bmp = lampBBmps[i] = new Bitmap(bmd));
bmd = base.clone();
bmd.threshold(bmd, bmd.rect, p, "==", 0xFF666666, 0xFFFFCC00, 0xFFFFFFFF, true);
bmd.threshold(bmd, bmd.rect, p, "==", 0xFFCCCCCC, 0xFFFFFFCC, 0xFFFFFFFF, true);
addChild(bmp = lampYBmps[i] = new Bitmap(bmd));
lampBmps[i].x = lampBBmps[i].x = lampYBmps[i].x = lampRBmps[i].x = (200 - 16 * length + 32 * i - 2) >> 1;
lampBmps[i].y = lampBBmps[i].y = lampYBmps[i].y = lampRBmps[i].y = 45;
lampBBmps[i].visible = lampYBmps[i].visible = lampRBmps[i].visible = false;
str += "*";
}
stxt.add(str);
}
}
class KeyButton extends Sprite
{
private var _txt: String, stxt: Object, skin: Shape;
private var _enabled: Boolean = true;
function KeyButton(txt: String)
{
_txt = txt;
stxt = fontCreater.create(0x777777, 2, 0);
stxt.x = 9;
addChild(DisplayObject(stxt));
graphics.clear();
graphics.beginFill(0x777777);
graphics.drawRoundRect(0, 0, 32, 32, 3, 3);
graphics.beginFill(0xFFFFFF);
graphics.drawRoundRect(2, 2, 28, 28, 3, 3);
stxt.add(txt);
addChild(skin = new Shape());
mouseChildren = false;
buttonMode = true;
addEventListener(MouseEvent.MOUSE_OVER, onOver);
addEventListener(MouseEvent.MOUSE_OUT, onOut);
}
private function onOut(e:MouseEvent):void
{
if (!_enabled) return;
var g: Graphics = skin.graphics;
g.clear();
}
private function onOver(e:MouseEvent):void
{
if (!_enabled) return;
var g: Graphics = skin.graphics;
g.clear();
g.beginFill(0x0080FF, 0.5);
g.drawRoundRect(2, 2, 28, 28, 3, 3);
}
public function get txt(): String { return _txt; }
public function get enabled():Boolean { return _enabled; }
public function set enabled(value:Boolean):void
{
if (_enabled == value) return;
var g: Graphics = skin.graphics;
g.clear();
if (!(mouseEnabled = buttonMode = _enabled = value))
{
g.beginFill(0x999999, 0.5);
g.drawRoundRect(2, 2, 28, 28, 3, 3);
}
}
}
class STextBtn extends Sprite
{
public var stxt: Object;
private var txt: String, marker: String;
function STextBtn(txt: String, marker: String, color: uint = 0, scale: Number = 1, delay: uint = 1, align: uint = 1)
{
stxt = fontCreater.create(color, scale, delay, align);
this.marker = marker, this.txt = txt;
addChild(DisplayObject(stxt));
stxt.addEventListener(Event.COMPLETE, onComp);
stxt.add(txt);
buttonMode = true;
addEventListener(MouseEvent.MOUSE_OVER, onOver);
addEventListener(MouseEvent.MOUSE_OUT, onOut);
mouseChildren = false;
}
private function onComp(e:Event):void
{
var r: Rectangle = stxt.getBounds(this);
graphics.clear();
graphics.beginFill(0xFFFFFF, 0.001);
graphics.drawRect(r.x, r.y, r.width, r.height);
}
private function onOut(e:MouseEvent):void
{
stxt.clear();
stxt.add(txt);
}
private function onOver(e:MouseEvent):void
{
stxt.clear();
stxt.add(marker + txt.replace(/ /, ""));
}
public function clear():void
{
removeEventListener(MouseEvent.MOUSE_OVER, onOver);
removeEventListener(MouseEvent.MOUSE_OUT, onOut);
stxt.clear();
stxt = null;
while (numChildren > 0) removeChildAt(0);
}
}