diff --git a/CHANGELOG.md b/CHANGELOG.md index e5d9138a..dec14540 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,16 +8,17 @@ ### Updates -- Added the emote feature to Workadventure. (@Kharhamel, @Tabascoeye) +- Added the emote feature to WorkAdventure. (@Kharhamel, @Tabascoeye) - The emote menu can be opened by clicking on your character. - Clicking on one of its element will close the menu and play an emote above your character. - This emote can be seen by other players. - Mobile support has been improved - - WorkAdventure automatically sets the zoom level based on the viewport size to ensure a sensible size of the map is visible, whatever the viewport used - - Mouse wheel support to zoom in / out - - Pinch support on mobile to zoom in / out - - Improved virtual joystick size (adapts to the zoom level) - + - WorkAdventure automatically sets the zoom level based on the viewport size to ensure a sensible size of the map is visible, whatever the viewport used + - Mouse wheel support to zoom in / out + - Pinch support on mobile to zoom in / out + - Improved virtual joystick size (adapts to the zoom level) +- New scripting API features: + - Use `WA.loadSound(): Sound` to load / play / stop a sound ### Bug Fixes diff --git a/front/src/Api/Events/IframeEvent.ts b/front/src/Api/Events/IframeEvent.ts index 598f4544..67a30027 100644 --- a/front/src/Api/Events/IframeEvent.ts +++ b/front/src/Api/Events/IframeEvent.ts @@ -9,6 +9,8 @@ import type { OpenCoWebSiteEvent } from './OpenCoWebSiteEvent'; import type { OpenPopupEvent } from './OpenPopupEvent'; import type { OpenTabEvent } from './OpenTabEvent'; import type { UserInputChatEvent } from './UserInputChatEvent'; +import type {LoadSoundEvent} from "./LoadSoundEvent"; +import type {PlaySoundEvent} from "./PlaySoundEvent"; export interface TypedMessageEvent extends MessageEvent { @@ -29,6 +31,9 @@ export type IframeEventMap = { restorePlayerControls: null displayBubble: null removeBubble: null + loadSound: LoadSoundEvent + playSound: PlaySoundEvent + stopSound: null } export interface IframeEvent { type: T; diff --git a/front/src/Api/Events/LoadSoundEvent.ts b/front/src/Api/Events/LoadSoundEvent.ts new file mode 100644 index 00000000..19b4b8e1 --- /dev/null +++ b/front/src/Api/Events/LoadSoundEvent.ts @@ -0,0 +1,11 @@ +import * as tg from "generic-type-guard"; + +export const isLoadSoundEvent = + new tg.IsInterface().withProperties({ + url: tg.isString, + }).get(); + +/** + * A message sent from the iFrame to the game to add a message in the chat. + */ +export type LoadSoundEvent = tg.GuardedType; diff --git a/front/src/Api/Events/PlaySoundEvent.ts b/front/src/Api/Events/PlaySoundEvent.ts new file mode 100644 index 00000000..33ca1ff4 --- /dev/null +++ b/front/src/Api/Events/PlaySoundEvent.ts @@ -0,0 +1,24 @@ +import * as tg from "generic-type-guard"; + + +const isSoundConfig = + new tg.IsInterface().withProperties({ + volume: tg.isOptional(tg.isNumber), + loop: tg.isOptional(tg.isBoolean), + mute: tg.isOptional(tg.isBoolean), + rate: tg.isOptional(tg.isNumber), + detune: tg.isOptional(tg.isNumber), + seek: tg.isOptional(tg.isNumber), + delay: tg.isOptional(tg.isNumber) + }).get(); + +export const isPlaySoundEvent = + new tg.IsInterface().withProperties({ + url: tg.isString, + config : tg.isOptional(isSoundConfig), + }).get(); + +/** + * A message sent from the iFrame to the game to add a message in the chat. + */ +export type PlaySoundEvent = tg.GuardedType; diff --git a/front/src/Api/Events/StopSoundEvent.ts b/front/src/Api/Events/StopSoundEvent.ts new file mode 100644 index 00000000..6d12516d --- /dev/null +++ b/front/src/Api/Events/StopSoundEvent.ts @@ -0,0 +1,11 @@ +import * as tg from "generic-type-guard"; + +export const isStopSoundEvent = + new tg.IsInterface().withProperties({ + url: tg.isString, + }).get(); + +/** + * A message sent from the iFrame to the game to add a message in the chat. + */ +export type StopSoundEvent = tg.GuardedType; diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 5079fb28..fbc2b4f1 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -1,3 +1,4 @@ + import { Subject } from "rxjs"; import { ChatEvent, isChatEvent } from "./Events/ChatEvent"; import { HtmlUtils } from "../WebRtc/HtmlUtils"; @@ -11,8 +12,9 @@ import { GoToPageEvent, isGoToPageEvent } from "./Events/GoToPageEvent"; import { isOpenCoWebsite, OpenCoWebSiteEvent } from "./Events/OpenCoWebSiteEvent"; import { IframeEventMap, IframeEvent, IframeResponseEvent, IframeResponseEventMap, isIframeEventWrapper, TypedMessageEvent } from "./Events/IframeEvent"; import type { UserInputChatEvent } from "./Events/UserInputChatEvent"; - - +import {isPlaySoundEvent, PlaySoundEvent} from "./Events/PlaySoundEvent"; +import {isStopSoundEvent, StopSoundEvent} from "./Events/StopSoundEvent"; +import {isLoadSoundEvent, LoadSoundEvent} from "./Events/LoadSoundEvent"; /** * Listens to messages from iframes and turn those messages into easy to use observables. * Also allows to send messages to those iframes. @@ -51,6 +53,15 @@ class IframeListener { private readonly _removeBubbleStream: Subject = new Subject(); public readonly removeBubbleStream = this._removeBubbleStream.asObservable(); + private readonly _playSoundStream: Subject = new Subject(); + public readonly playSoundStream = this._playSoundStream.asObservable(); + + private readonly _stopSoundStream: Subject = new Subject(); + public readonly stopSoundStream = this._stopSoundStream.asObservable(); + + private readonly _loadSoundStream: Subject = new Subject(); + public readonly loadSoundStream = this._loadSoundStream.asObservable(); + private readonly iframes = new Set(); private readonly scripts = new Map(); @@ -85,6 +96,15 @@ class IframeListener { else if (payload.type === 'goToPage' && isGoToPageEvent(payload.data)) { scriptUtils.goToPage(payload.data.url); } + else if (payload.type === 'playSound' && isPlaySoundEvent(payload.data)) { + this._playSoundStream.next(payload.data); + } + else if (payload.type === 'stopSound' && isStopSoundEvent(payload.data)) { + this._stopSoundStream.next(payload.data); + } + else if (payload.type === 'loadSound' && isLoadSoundEvent(payload.data)) { + this._loadSoundStream.next(payload.data); + } else if (payload.type === 'openCoWebSite' && isOpenCoWebsite(payload.data)) { const scriptUrl = [...this.scripts.keys()].find(key => { return this.scripts.get(key)?.contentWindow == message.source @@ -92,9 +112,11 @@ class IframeListener { scriptUtils.openCoWebsite(payload.data.url, scriptUrl || foundSrc); } + else if (payload.type === 'closeCoWebSite') { scriptUtils.closeCoWebSite(); } + else if (payload.type === 'disablePlayerControls') { this._disablePlayerControlStream.next(); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 95ec6689..4de5ffd9 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -52,6 +52,7 @@ import {mediaManager} from "../../WebRtc/MediaManager"; import type {ItemFactoryInterface} from "../Items/ItemFactoryInterface"; import type {ActionableItem} from "../Items/ActionableItem"; import {UserInputManager} from "../UserInput/UserInputManager"; +import {soundManager} from "./SoundManager"; import type {UserMovedMessage} from "../../Messages/generated/messages_pb"; import {ProtobufClientUtils} from "../../Network/ProtobufClientUtils"; import {connectionManager} from "../../Connexion/ConnectionManager"; @@ -874,9 +875,28 @@ ${escapedMessage} this.userInputManager.disableControls(); })); + this.iframeSubscriptionList.push(iframeListener.playSoundStream.subscribe((playSoundEvent)=> + { + const url = new URL(playSoundEvent.url, this.MapUrlFile); + soundManager.playSound(this.load,this.sound,url.toString(),playSoundEvent.config); + })) + + this.iframeSubscriptionList.push(iframeListener.stopSoundStream.subscribe((stopSoundEvent)=> + { + const url = new URL(stopSoundEvent.url, this.MapUrlFile); + soundManager.stopSound(this.sound,url.toString()); + })) + + this.iframeSubscriptionList.push(iframeListener.loadSoundStream.subscribe((loadSoundEvent)=> + { + const url = new URL(loadSoundEvent.url, this.MapUrlFile); + soundManager.loadSound(this.load,this.sound,url.toString()); + })) + this.iframeSubscriptionList.push(iframeListener.enablePlayerControlStream.subscribe(()=>{ this.userInputManager.restoreControls(); })); + let scriptedBubbleSprite : Sprite; this.iframeSubscriptionList.push(iframeListener.displayBubbleStream.subscribe(()=>{ scriptedBubbleSprite = new Sprite(this,this.CurrentPlayer.x + 25,this.CurrentPlayer.y,'circleSprite-white'); diff --git a/front/src/Phaser/Game/SoundManager.ts b/front/src/Phaser/Game/SoundManager.ts new file mode 100644 index 00000000..f0210494 --- /dev/null +++ b/front/src/Phaser/Game/SoundManager.ts @@ -0,0 +1,37 @@ +import LoaderPlugin = Phaser.Loader.LoaderPlugin; +import BaseSoundManager = Phaser.Sound.BaseSoundManager; +import BaseSound = Phaser.Sound.BaseSound; +import SoundConfig = Phaser.Types.Sound.SoundConfig; + +class SoundManager { + private soundPromises : Map> = new Map>(); + public loadSound (loadPlugin: LoaderPlugin, soundManager : BaseSoundManager, soundUrl: string) : Promise { + let soundPromise = this.soundPromises.get(soundUrl); + if (soundPromise !== undefined) { + return soundPromise; + } + soundPromise = new Promise((res) => { + + const sound = soundManager.get(soundUrl); + if (sound !== null) { + return res(sound); + } + loadPlugin.audio(soundUrl, soundUrl); + loadPlugin.once('filecomplete-audio-' + soundUrl, () => res(soundManager.add(soundUrl))); + loadPlugin.start(); + }); + this.soundPromises.set(soundUrl,soundPromise); + return soundPromise; + } + + public async playSound(loadPlugin: LoaderPlugin, soundManager : BaseSoundManager, soundUrl: string, config: SoundConfig|undefined) : Promise { + const sound = await this.loadSound(loadPlugin,soundManager,soundUrl); + if (config === undefined) sound.play(); + else sound.play(config); + } + + public stopSound(soundManager : BaseSoundManager,soundUrl : string){ + soundManager.get(soundUrl).stop(); + } +} +export const soundManager = new SoundManager(); diff --git a/front/src/iframe_api.ts b/front/src/iframe_api.ts index df37e53d..17b979df 100644 --- a/front/src/iframe_api.ts +++ b/front/src/iframe_api.ts @@ -9,6 +9,10 @@ import type { ClosePopupEvent } from "./Api/Events/ClosePopupEvent"; import type { OpenTabEvent } from "./Api/Events/OpenTabEvent"; import type { GoToPageEvent } from "./Api/Events/GoToPageEvent"; import type { OpenCoWebSiteEvent } from "./Api/Events/OpenCoWebSiteEvent"; +import type {PlaySoundEvent} from "./Api/Events/PlaySoundEvent"; +import type {StopSoundEvent} from "./Api/Events/StopSoundEvent"; +import type {LoadSoundEvent} from "./Api/Events/LoadSoundEvent"; +import SoundConfig = Phaser.Types.Sound.SoundConfig; interface WorkAdventureApi { sendChatMessage(message: string, author: string): void; @@ -24,6 +28,7 @@ interface WorkAdventureApi { restorePlayerControls(): void; displayBubble(): void; removeBubble(): void; + loadSound(url : string): Sound; } declare global { @@ -57,7 +62,7 @@ interface ButtonDescriptor { callback: ButtonClickedCallback, } -class Popup { +export class Popup { constructor(private id: number) { } @@ -74,6 +79,41 @@ class Popup { } } +export class Sound { + constructor(private url: string) { + window.parent.postMessage({ + "type" : 'loadSound', + "data": { + url: this.url, + } as LoadSoundEvent + + },'*'); + } + + public play(config : SoundConfig) { + window.parent.postMessage({ + "type" : 'playSound', + "data": { + url: this.url, + config + } as PlaySoundEvent + + },'*'); + return this.url; + } + public stop() { + window.parent.postMessage({ + "type" : 'stopSound', + "data": { + url: this.url, + } as StopSoundEvent + + },'*'); + return this.url; + } + +} + window.WA = { /** * Send a message in the chat. @@ -113,7 +153,11 @@ window.WA = { }, '*'); }, - goToPage(url: string): void { + loadSound(url: string) : Sound { + return new Sound(url); + }, + + goToPage(url : string) : void{ window.parent.postMessage({ "type": 'goToPage', "data": { diff --git a/maps/Tuto/scriptTuto.js b/maps/Tuto/scriptTuto.js index 65962a94..8821134b 100644 --- a/maps/Tuto/scriptTuto.js +++ b/maps/Tuto/scriptTuto.js @@ -5,6 +5,12 @@ var targetObjectTutoBubble ='Tutobubble'; var targetObjectTutoChat ='tutoChat'; var targetObjectTutoExplanation ='tutoExplanation'; var popUpExplanation = undefined; +var enterSoundUrl = "webrtc-in.mp3"; +var exitSoundUrl = "webrtc-out.mp3"; +var soundConfig = { + volume : 0.2, + loop : false +} function launchTuto (){ WA.openPopup(targetObjectTutoBubble, textFirstPopup, [ { @@ -25,7 +31,8 @@ function launchTuto (){ label: "Got it!", className : "success",callback:(popup2 => { popup2.close(); - WA.restorePlayerControls(); + WA.restorePlayerControl(); + WA.loadSound(winSoundUrl).play(soundConfig); }) } ]) @@ -36,13 +43,14 @@ function launchTuto (){ } } ]); - WA.disablePlayerControls(); + WA.disablePlayerControl(); } WA.onEnterZone('popupZone', () => { WA.displayBubble(); + WA.loadSound(enterSoundUrl).play(soundConfig); if (!isFirstTimeTuto) { isFirstTimeTuto = true; launchTuto(); @@ -71,4 +79,5 @@ WA.onEnterZone('popupZone', () => { WA.onLeaveZone('popupZone', () => { if (popUpExplanation !== undefined) popUpExplanation.close(); WA.removeBubble(); + WA.loadSound(exitSoundUrl).play(soundConfig); }) diff --git a/maps/Tuto/webrtc-in.mp3 b/maps/Tuto/webrtc-in.mp3 new file mode 100644 index 00000000..34e22003 Binary files /dev/null and b/maps/Tuto/webrtc-in.mp3 differ diff --git a/maps/Tuto/webrtc-out.mp3 b/maps/Tuto/webrtc-out.mp3 new file mode 100644 index 00000000..dcf02928 Binary files /dev/null and b/maps/Tuto/webrtc-out.mp3 differ diff --git a/maps/Village/Village.json b/maps/Village/Village.json index e4ee93bf..30733388 100644 --- a/maps/Village/Village.json +++ b/maps/Village/Village.json @@ -33,7 +33,7 @@ "y":0 }, { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 1979, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 1979, 0, 1979, 1979, 0, 1979, 1979, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 1979, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 1979, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 1979, 1979, 0, 1979, 1979, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 1979, 1979, 0, 1979, 1979, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 1979, 1979, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 1979, 0, 1979, 0, 0, 1979, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 1979, 0, 0, 0, 0, 0, 0, 0, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "height":39, "id":7, "name":"collides", @@ -769,7 +769,20 @@ "tilecount":121, "tileheight":32, "tilewidth":32 - }, + }, + { + "columns":3, + "firstgid":4611, + "image":"su1 Student fmale 12.png", + "imageheight":128, + "imagewidth":96, + "margin":0, + "name":"su1 Student fmale 12", + "spacing":0, + "tilecount":12, + "tileheight":32, + "tilewidth":32 + }, { "columns":5, "firstgid":4611, diff --git a/maps/tests/Audience.mp3 b/maps/tests/Audience.mp3 new file mode 100644 index 00000000..81745d14 Binary files /dev/null and b/maps/tests/Audience.mp3 differ diff --git a/maps/tests/SoundScript.js b/maps/tests/SoundScript.js new file mode 100644 index 00000000..f90dfe0f --- /dev/null +++ b/maps/tests/SoundScript.js @@ -0,0 +1,44 @@ +var zonePlaySound = "PlaySound"; +var zonePlaySoundLoop = "playSoundLoop"; +var stopSound = "StopSound"; +var loopConfig ={ + volume : 0.5, + loop : true +} +var configBase = { + volume : 0.5, + loop : false +} +var enterSoundUrl = "webrtc-in.mp3"; +var exitSoundUrl = "webrtc-out.mp3"; +var winSoundUrl = "Win.ogg"; +var enterSound; +var exitSound; +var winSound; +loadAllSounds(); +winSound.play(configBase); +WA.onEnterZone(zonePlaySound, () => { +enterSound.play(configBase); +}) + +WA.onEnterZone(zonePlaySoundLoop, () => { +winSound.play(loopConfig); +}) + +WA.onLeaveZone(zonePlaySoundLoop, () => { + winSound.stop(); +}) + +WA.onEnterZone('popupZone', () => { + +}); + +WA.onLeaveZone('popupZone', () => { + +}) + + function loadAllSounds(){ + winSound = WA.loadSound(winSoundUrl); + enterSound = WA.loadSound(enterSoundUrl); + exitSound = WA.loadSound(exitSoundUrl); + } diff --git a/maps/tests/SoundTest.json b/maps/tests/SoundTest.json new file mode 100644 index 00000000..f1e38761 --- /dev/null +++ b/maps/tests/SoundTest.json @@ -0,0 +1,154 @@ +{ "compressionlevel":-1, + "height":20, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":20, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":20, + "id":4, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":20, + "id":3, + "name":"playSound", + "opacity":1, + "properties":[ + { + "name":"zone", + "type":"string", + "value":"PlaySound" + }], + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":20, + "id":6, + "name":"playSoundLoop", + "opacity":1, + "properties":[ + { + "name":"zone", + "type":"string", + "value":"playSoundLoop" + }], + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":5, + "name":"floorLayer", + "objects":[ + { + "height":19.296875, + "id":2, + "name":"", + "rotation":0, + "text": + { + "text":"Play Sound", + "wrap":true + }, + "type":"", + "visible":true, + "width":107.109375, + "x":258.4453125, + "y":197.018229166667 + }, + { + "height":19.296875, + "id":3, + "name":"", + "rotation":0, + "text": + { + "text":"Bonjour Monde", + "wrap":true + }, + "type":"", + "visible":true, + "width":107.109375, + "x":-348.221354166667, + "y":257.018229166667 + }, + { + "height":55.296875, + "id":4, + "name":"", + "rotation":0, + "text": + { + "text":"Play Sound Loop\nexit Zone Stop Sound \n", + "wrap":true + }, + "type":"", + "visible":true, + "width":176.442708333333, + "x":243.778645833333, + "y":368.3515625 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":8, + "nextobjectid":5, + "orientation":"orthogonal", + "properties":[ + { + "name":"script", + "type":"string", + "value":"SoundScript.js" + }], + "renderorder":"right-down", + "tiledversion":"1.5.0", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.5, + "width":20 +} \ No newline at end of file diff --git a/maps/tests/Win.ogg b/maps/tests/Win.ogg new file mode 100644 index 00000000..43880a77 Binary files /dev/null and b/maps/tests/Win.ogg differ diff --git a/maps/tests/index.html b/maps/tests/index.html index 9b54a5af..a17a3b5d 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -42,6 +42,14 @@ Testing scripting API with a script + + + Success Failure Pending + + + Testing scripting API loadSound() function + + Success Failure Pending diff --git a/maps/tests/webrtc-in.mp3 b/maps/tests/webrtc-in.mp3 new file mode 100644 index 00000000..34e22003 Binary files /dev/null and b/maps/tests/webrtc-in.mp3 differ diff --git a/maps/tests/webrtc-out.mp3 b/maps/tests/webrtc-out.mp3 new file mode 100644 index 00000000..dcf02928 Binary files /dev/null and b/maps/tests/webrtc-out.mp3 differ