From 485c2b985454548e270f637921a168291f2407ca Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 6 Aug 2023 01:23:01 +0100
Subject: [PATCH 01/34] Add files via upload
---
extensions/Lily/Video.js | 209 +++++++++++++++++++++++++++++++++++++++
1 file changed, 209 insertions(+)
create mode 100644 extensions/Lily/Video.js
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
new file mode 100644
index 0000000000..3bff3c97b2
--- /dev/null
+++ b/extensions/Lily/Video.js
@@ -0,0 +1,209 @@
+(function (Scratch) {
+ 'use strict';
+
+ const vm = Scratch.vm;
+ const runtime = vm.runtime;
+ const canvas = vm.renderer.canvas;
+ const Cast = Scratch.Cast;
+
+ class Video {
+ constructor() {
+ this.video = document.createElement('video');
+
+ this.video.style.position = 'absolute';
+ this.video.style.visibility = 'hidden';
+ this.video.style.transformOrigin = 'center center';
+ canvas.parentElement.prepend(this.video);
+
+ const adjustSize = (width, height) => {
+ this.video.style.width = `${(width / runtime.stageWidth) * 100}%`;
+ this.video.style.height = `${(height / runtime.stageHeight) * 100}%`;
+ }
+
+ runtime.on('STAGE_SIZE_CHANGED', () => adjustSize(runtime.stageWidth, runtime.stageHeight));
+ adjustSize(runtime.stageWidth, runtime.stageHeight);
+ }
+ getInfo() {
+ return {
+ id: 'lmsVideo',
+ color1: '#557882',
+ name: 'Video',
+ blocks: [
+ {
+ opcode: 'setVideoURL',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'set video URL to [URL]',
+ arguments: {
+ URL: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: ''
+ }
+ }
+ },
+ {
+ opcode: 'getVideoURL',
+ blockType: Scratch.BlockType.REPORTER,
+ text: 'current video URL'
+ },
+ '---',
+ {
+ opcode: 'startVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'start video at [DURATION] seconds',
+ arguments: {
+ DURATION: {
+ type: Scratch.ArgumentType.NUMBER,
+ defaultValue: 0
+ }
+ }
+ },
+ {
+ opcode: 'getCurrentTime',
+ blockType: Scratch.BlockType.REPORTER,
+ text: 'current time'
+ },
+ '---',
+ {
+ opcode: 'pauseVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'pause video'
+ },
+ {
+ opcode: 'resumeVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'resume video'
+ },
+ {
+ opcode: 'showVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'show video'
+ },
+ {
+ opcode: 'hideVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'hide video'
+ },
+ {
+ opcode: 'getState',
+ blockType: Scratch.BlockType.BOOLEAN,
+ text: 'video is [STATE]?',
+ arguments: {
+ STATE: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'state'
+ }
+ }
+ },
+ '---',
+ {
+ opcode: 'setOptionOnVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'set [OPTION] on video to [TOGGLE]',
+ arguments: {
+ OPTION: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'options'
+ },
+ TOGGLE: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'toggle'
+ }
+ }
+ },
+ {
+ opcode: 'getOptionIsEnabled',
+ blockType: Scratch.BlockType.BOOLEAN,
+ text: '[OPTION] is enabled?',
+ arguments: {
+ OPTION: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'options'
+ }
+ }
+ }
+ ],
+ menus: {
+ options: {
+ acceptReporters: true,
+ items: ['controls', 'loop']
+ },
+ state: {
+ acceptReporters: true,
+ items: ['playing', 'paused', 'visible', 'hidden']
+ },
+ toggle: {
+ acceptReporters: true,
+ items: ['enabled', 'disabled']
+ }
+ }
+ };
+ }
+
+ setVideoURL(args) {
+ this.video.src = Cast.toString(args.URL);
+ }
+
+ getVideoURL() {
+ return Cast.toString(this.video.src);
+ }
+
+ startVideo(args) {
+ const time = Cast.toNumber(args.DURATION);
+ this.video.currentTime = time;
+ this.video.play();
+ this.video.style.visibility = 'visible';
+ }
+
+ getCurrentTime() {
+ return Math.round(Cast.toNumber(this.video.currentTime) * 1000) / 1000;
+ }
+
+ getState(args) {
+ switch(args.STATE) {
+ case('paused'): return this.video.paused;
+ case('playing'): return !this.video.paused;
+ case('visible'): return this.video.style.visibility === 'visible';
+ case('hidden'): return this.video.style.visibility === 'hidden';
+ }
+ }
+
+ pauseVideo() {
+ this.video.pause();
+ }
+
+ resumeVideo() {
+ if (this.video.paused) this.video.play();
+ }
+
+ getIsPaused() {
+ return this.video.paused;
+ }
+
+ showVideo() {
+ this.video.style.visibility = 'visible';
+ }
+
+ hideVideo() {
+ this.video.style.visibility = 'hidden';
+ }
+
+ setOptionOnVideo(args) {
+ const option = Cast.toString(args.OPTION);
+ const toggle = Cast.toString(args.TOGGLE);
+
+ switch(option) {
+ case('controls'): this.video.controls = !!(toggle == 'enabled');
+ case('loop'): this.video.loop = !!(toggle == 'enabled');
+ }
+ }
+
+ getOptionIsEnabled(args) {
+ const option = Cast.toString(args.OPTION);
+ switch(option) {
+ case('controls'): return this.video.controls;
+ case('loop'): return this.video.loop;
+ }
+ }
+ }
+ Scratch.extensions.register(new Video());
+})(Scratch);
\ No newline at end of file
From 88987693cc30b80c61a5da0726c81c084d12b2be Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 6 Aug 2023 01:23:28 +0100
Subject: [PATCH 02/34] Add files via upload
---
images/Lily/Video.svg | 1 +
1 file changed, 1 insertion(+)
create mode 100644 images/Lily/Video.svg
diff --git a/images/Lily/Video.svg b/images/Lily/Video.svg
new file mode 100644
index 0000000000..fcc3cbfab7
--- /dev/null
+++ b/images/Lily/Video.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
From a006c8c199238f535de0e02517762e912551a3c5 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 6 Aug 2023 01:25:10 +0100
Subject: [PATCH 03/34] Update index.ejs
---
website/index.ejs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/website/index.ejs b/website/index.ejs
index da2953cdf6..d15e470b3b 100644
--- a/website/index.ejs
+++ b/website/index.ejs
@@ -470,6 +470,12 @@
Play sounds from URLs.
+
<%- banner('Xeltalliv/clippingblending') %>
Clipping & Blending
From d94d67c5c7135107fabb0b4d7bd2de7d86ff9f42 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 6 Aug 2023 01:25:40 +0100
Subject: [PATCH 04/34] Update README.md
---
images/README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/images/README.md b/images/README.md
index 7495122b82..b98c23dc6c 100644
--- a/images/README.md
+++ b/images/README.md
@@ -247,3 +247,6 @@ All images in this folder are licensed under the [GNU General Public License ver
## veggiecan/LongmanDictionary.svg
- Created by [veggiecan](https://github.com/veggiecan0419)
- The ship is based on [this](https://www.ldoceonline.com/external/images/logo_home_smartphone.svg?version=1.2.61) logo from the [ldoceonline](https://www.ldoceonline.com/) website
+
+## Lily/Video.svg
+ - Created by [@LilyMakesThings](https://github.com/LilyMakesThings) in https://github.com/TurboWarp/extensions/pull/656
From a5c131e7fc58c51589042beca0b4b5c89fc61ebb Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 6 Aug 2023 01:31:37 +0100
Subject: [PATCH 05/34] shut up, eslint
---
extensions/Lily/Video.js | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index 3bff3c97b2..b1adb82605 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -18,7 +18,7 @@
const adjustSize = (width, height) => {
this.video.style.width = `${(width / runtime.stageWidth) * 100}%`;
this.video.style.height = `${(height / runtime.stageHeight) * 100}%`;
- }
+ };
runtime.on('STAGE_SIZE_CHANGED', () => adjustSize(runtime.stageWidth, runtime.stageHeight));
adjustSize(runtime.stageWidth, runtime.stageHeight);
@@ -88,7 +88,7 @@
blockType: Scratch.BlockType.BOOLEAN,
text: 'video is [STATE]?',
arguments: {
- STATE: {
+ STATE: {
type: Scratch.ArgumentType.STRING,
menu: 'state'
}
@@ -159,11 +159,11 @@
}
getState(args) {
- switch(args.STATE) {
- case('paused'): return this.video.paused;
- case('playing'): return !this.video.paused;
- case('visible'): return this.video.style.visibility === 'visible';
- case('hidden'): return this.video.style.visibility === 'hidden';
+ switch (args.STATE) {
+ case ('paused'): return this.video.paused;
+ case ('playing'): return !this.video.paused;
+ case ('visible'): return this.video.style.visibility === 'visible';
+ case ('hidden'): return this.video.style.visibility === 'hidden';
}
}
@@ -191,19 +191,19 @@
const option = Cast.toString(args.OPTION);
const toggle = Cast.toString(args.TOGGLE);
- switch(option) {
- case('controls'): this.video.controls = !!(toggle == 'enabled');
- case('loop'): this.video.loop = !!(toggle == 'enabled');
+ switch (option) {
+ case ('controls'): return this.video.controls = !!(toggle == 'enabled');
+ case ('loop'): return this.video.loop = !!(toggle == 'enabled');
}
}
getOptionIsEnabled(args) {
const option = Cast.toString(args.OPTION);
- switch(option) {
- case('controls'): return this.video.controls;
- case('loop'): return this.video.loop;
+ switch (option) {
+ case ('controls'): return this.video.controls;
+ case ('loop'): return this.video.loop;
}
}
}
Scratch.extensions.register(new Video());
-})(Scratch);
\ No newline at end of file
+})(Scratch);
From 2c8c2c3f52b3f1d7517e66889b7ae9140b8649b4 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 06:09:36 +0100
Subject: [PATCH 06/34] Update Video.js
---
extensions/Lily/Video.js | 87 ++++++++++------------------------------
1 file changed, 21 insertions(+), 66 deletions(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index b1adb82605..3f177cb98f 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -3,25 +3,26 @@
const vm = Scratch.vm;
const runtime = vm.runtime;
- const canvas = vm.renderer.canvas;
+ const canvas = runtime.renderer.canvas;
const Cast = Scratch.Cast;
class Video {
constructor() {
this.video = document.createElement('video');
-
- this.video.style.position = 'absolute';
- this.video.style.visibility = 'hidden';
- this.video.style.transformOrigin = 'center center';
- canvas.parentElement.prepend(this.video);
-
- const adjustSize = (width, height) => {
- this.video.style.width = `${(width / runtime.stageWidth) * 100}%`;
- this.video.style.height = `${(height / runtime.stageHeight) * 100}%`;
- };
-
- runtime.on('STAGE_SIZE_CHANGED', () => adjustSize(runtime.stageWidth, runtime.stageHeight));
- adjustSize(runtime.stageWidth, runtime.stageHeight);
+ this.video.width = 480;
+ this.video.height = 360;
+ this.video.crossOrigin = 'anonymous';
+
+ runtime.on('BEFORE_EXECUTE', () => {
+ /* Scratch Addons volume slider moment */
+ this.video.volume = runtime.audioEngine.inputNode.gain.value;
+
+ const target = runtime.targets[0];
+ const drawableID = target.drawableID;
+ const skinId = runtime.renderer._allDrawables[drawableID].skin._id;
+
+ vm.renderer.updateBitmapSkin(skinId, this.video, 2);
+ });
}
getInfo() {
return {
@@ -73,16 +74,6 @@
blockType: Scratch.BlockType.COMMAND,
text: 'resume video'
},
- {
- opcode: 'showVideo',
- blockType: Scratch.BlockType.COMMAND,
- text: 'show video'
- },
- {
- opcode: 'hideVideo',
- blockType: Scratch.BlockType.COMMAND,
- text: 'hide video'
- },
{
opcode: 'getState',
blockType: Scratch.BlockType.BOOLEAN,
@@ -96,30 +87,9 @@
},
'---',
{
- opcode: 'setOptionOnVideo',
+ opcode: 'testBlock',
blockType: Scratch.BlockType.COMMAND,
- text: 'set [OPTION] on video to [TOGGLE]',
- arguments: {
- OPTION: {
- type: Scratch.ArgumentType.STRING,
- menu: 'options'
- },
- TOGGLE: {
- type: Scratch.ArgumentType.STRING,
- menu: 'toggle'
- }
- }
- },
- {
- opcode: 'getOptionIsEnabled',
- blockType: Scratch.BlockType.BOOLEAN,
- text: '[OPTION] is enabled?',
- arguments: {
- OPTION: {
- type: Scratch.ArgumentType.STRING,
- menu: 'options'
- }
- }
+ text: 'test'
}
],
menus: {
@@ -141,6 +111,7 @@
setVideoURL(args) {
this.video.src = Cast.toString(args.URL);
+ this.video.currentTime = 0;
}
getVideoURL() {
@@ -151,7 +122,6 @@
const time = Cast.toNumber(args.DURATION);
this.video.currentTime = time;
this.video.play();
- this.video.style.visibility = 'visible';
}
getCurrentTime() {
@@ -179,24 +149,6 @@
return this.video.paused;
}
- showVideo() {
- this.video.style.visibility = 'visible';
- }
-
- hideVideo() {
- this.video.style.visibility = 'hidden';
- }
-
- setOptionOnVideo(args) {
- const option = Cast.toString(args.OPTION);
- const toggle = Cast.toString(args.TOGGLE);
-
- switch (option) {
- case ('controls'): return this.video.controls = !!(toggle == 'enabled');
- case ('loop'): return this.video.loop = !!(toggle == 'enabled');
- }
- }
-
getOptionIsEnabled(args) {
const option = Cast.toString(args.OPTION);
switch (option) {
@@ -204,6 +156,9 @@
case ('loop'): return this.video.loop;
}
}
+
+ testBlock(args, util) {
+ }
}
Scratch.extensions.register(new Video());
})(Scratch);
From 32853282e4e606a3dc45139f197fe8fe6ebd1da3 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 19:25:57 +0100
Subject: [PATCH 07/34] Update Video.js
---
extensions/Lily/Video.js | 274 +++++++++++++++++++++++++++++----------
1 file changed, 209 insertions(+), 65 deletions(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index 3f177cb98f..b21f0ff5f1 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -3,25 +3,28 @@
const vm = Scratch.vm;
const runtime = vm.runtime;
- const canvas = runtime.renderer.canvas;
const Cast = Scratch.Cast;
class Video {
constructor() {
- this.video = document.createElement('video');
- this.video.width = 480;
- this.video.height = 360;
- this.video.crossOrigin = 'anonymous';
+ this.videos = [];
+ this.targets = [];
runtime.on('BEFORE_EXECUTE', () => {
- /* Scratch Addons volume slider moment */
- this.video.volume = runtime.audioEngine.inputNode.gain.value;
-
- const target = runtime.targets[0];
- const drawableID = target.drawableID;
- const skinId = runtime.renderer._allDrawables[drawableID].skin._id;
-
- vm.renderer.updateBitmapSkin(skinId, this.video, 2);
+ for (const name of Object.keys(this.videos)) {
+ const video = this.videos[name];
+ video.volume = runtime.audioEngine.inputNode.gain.value;
+ }
+
+ for (const id of Object.keys(this.targets)) {
+ const target = this.targets[id].target;
+ const drawableID = target.drawableID;
+
+ const skinId = runtime.renderer._allDrawables[drawableID].skin._id;
+ const video = this.videos[this.targets[id].videoName];
+
+ vm.renderer.updateBitmapSkin(skinId, video, 1);
+ }
});
}
getInfo() {
@@ -31,27 +34,83 @@
name: 'Video',
blocks: [
{
- opcode: 'setVideoURL',
+ opcode: 'loadVideoURL',
blockType: Scratch.BlockType.COMMAND,
- text: 'set video URL to [URL]',
+ text: 'load video from URL [URL] as [NAME]',
arguments: {
URL: {
type: Scratch.ArgumentType.STRING,
defaultValue: ''
+ },
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ }
+ }
+ },
+ {
+ opcode: 'deleteVideoURL',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'delete video [NAME]',
+ arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
}
}
},
+ '---',
{
- opcode: 'getVideoURL',
+ opcode: 'showVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'show video [NAME] on [TARGET]',
+ arguments: {
+ TARGET: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'targets'
+ },
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ },
+ }
+ },
+ {
+ opcode: 'stopShowingVideo',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'stop showing video on [TARGET]',
+ arguments: {
+ TARGET: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'targets'
+ },
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ },
+ }
+ },
+ {
+ opcode: 'getCurrentVideo',
blockType: Scratch.BlockType.REPORTER,
- text: 'current video URL'
+ text: 'current video on [TARGET]',
+ arguments: {
+ TARGET: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'targets'
+ }
+ }
},
'---',
{
opcode: 'startVideo',
blockType: Scratch.BlockType.COMMAND,
- text: 'start video at [DURATION] seconds',
+ text: 'start video [NAME] at [DURATION] seconds',
arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ },
DURATION: {
type: Scratch.ArgumentType.NUMBER,
defaultValue: 0
@@ -61,104 +120,189 @@
{
opcode: 'getCurrentTime',
blockType: Scratch.BlockType.REPORTER,
- text: 'current time'
+ text: 'current time of video [NAME]',
+ arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ }
+ }
},
'---',
{
opcode: 'pauseVideo',
blockType: Scratch.BlockType.COMMAND,
- text: 'pause video'
+ text: 'pause video [NAME]',
+ arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ }
+ }
},
{
opcode: 'resumeVideo',
blockType: Scratch.BlockType.COMMAND,
- text: 'resume video'
+ text: 'resume video [NAME]',
+ arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ }
+ }
},
{
opcode: 'getState',
blockType: Scratch.BlockType.BOOLEAN,
- text: 'video is [STATE]?',
+ text: 'video [NAME] is [STATE]?',
arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ },
STATE: {
type: Scratch.ArgumentType.STRING,
menu: 'state'
}
}
- },
- '---',
- {
- opcode: 'testBlock',
- blockType: Scratch.BlockType.COMMAND,
- text: 'test'
}
],
menus: {
- options: {
+ targets: {
acceptReporters: true,
- items: ['controls', 'loop']
+ items: '_getTargets'
},
state: {
acceptReporters: true,
- items: ['playing', 'paused', 'visible', 'hidden']
- },
- toggle: {
- acceptReporters: true,
- items: ['enabled', 'disabled']
+ items: ['playing', 'paused']
}
}
};
}
- setVideoURL(args) {
- this.video.src = Cast.toString(args.URL);
- this.video.currentTime = 0;
+ loadVideoURL(args) {
+ const videoName = Cast.toString(args.NAME);
+ const url = Cast.toString(args.URL);
+
+ this.videos[videoName] = document.createElement('video');
+ this.videos[videoName].width = 480;
+ this.videos[videoName].height = 360;
+ this.videos[videoName].crossOrigin = 'anonymous';
+
+ // To-do : Some urls can't be loaded by the renderer, how can we detect that?
+
+ this.videos[videoName].src = url;
+ this.videos[videoName].currentTime = 0;
}
- getVideoURL() {
- return Cast.toString(this.video.src);
+ deleteVideoURL(args) {
+ const name = Cast.toString(args.NAME);
+ Reflect.deleteProperty(this.videos, name);
+
+ // To-do : reset the targets with the video
+ }
+
+ showVideo(args, util) {
+ const targetName = Cast.toString(args.TARGET);
+ const videoName = Cast.toString(args.NAME);
+ const target = this._getTargetFromMenu(targetName, util);
+ if (!target) return;
+
+ const targetId = target.id;
+ this.targets[targetId] = {
+ target: target,
+ videoName: videoName
+ };
+ }
+
+ stopShowingVideo(args, util) {
+ const targetName = Cast.toString(args.TARGET);
+ const target = this._getTargetFromMenu(targetName, util);
+ if (!target) return;
+
+ const targetId = target.id;
+ Reflect.deleteProperty(this.targets, targetId);
+
+ // Why does this not work, what
+ target.updateAllDrawableProperties();
+ }
+
+ getCurrentVideo(args, util) {
+ const targetName = Cast.toString(args.TARGET);
+ const target = this._getTargetFromMenu(targetName, util);
+ if (!target) return;
+
+ const targetId = target.id;
+ return (this.targets[targetId]) ? this.targets[targetId].videoName : '';
}
startVideo(args) {
- const time = Cast.toNumber(args.DURATION);
- this.video.currentTime = time;
- this.video.play();
+ const videoName = Cast.toString(args.NAME);
+ const video = this.videos[videoName];
+ if (!video) return;
+
+ video.play();
}
- getCurrentTime() {
- return Math.round(Cast.toNumber(this.video.currentTime) * 1000) / 1000;
+ getCurrentTime(args) {
+ const videoName = Cast.toString(args.NAME);
+ const video = this.videos[videoName];
+ if (!video) return 0;
+
+ return video.currentTime;
+
}
- getState(args) {
- switch (args.STATE) {
- case ('paused'): return this.video.paused;
- case ('playing'): return !this.video.paused;
- case ('visible'): return this.video.style.visibility === 'visible';
- case ('hidden'): return this.video.style.visibility === 'hidden';
- }
+ pauseVideo(args) {
+ const videoName = Cast.toString(args.NAME);
+ const video = this.videos[videoName];
+ if (!video) return;
+
+ video.pause();
}
- pauseVideo() {
- this.video.pause();
+ resumeVideo(args) {
+ const videoName = Cast.toString(args.NAME);
+ const video = this.videos[videoName];
+ if (!video) return;
+
+ video.play();
}
- resumeVideo() {
- if (this.video.paused) this.video.play();
+ getState(args) {
+ const videoName = Cast.toString(args.NAME);
+ const video = this.videos[videoName];
+ if (!video) return (args.STATE == 'paused');
+
+ return (args.STATE == 'playing') ? !video.paused : video.paused;
}
- getIsPaused() {
- return this.video.paused;
+ _getTargetFromMenu (targetName, util) {
+ let target = Scratch.vm.runtime.getSpriteTargetByName(targetName);
+ if (targetName === '_myself_') target = util.target;
+ if (targetName === '_stage_') target = runtime.getTargetForStage();
+ return target;
}
- getOptionIsEnabled(args) {
- const option = Cast.toString(args.OPTION);
- switch (option) {
- case ('controls'): return this.video.controls;
- case ('loop'): return this.video.loop;
+ _getTargets() {
+ const spriteNames = [
+ {text: 'myself', value: '_myself_'},
+ {text: 'Stage', value: '_stage_'}
+ ];
+ const targets = Scratch.vm.runtime.targets;
+ for (let index = 1; index < targets.length; index++) {
+ const target = targets[index];
+ if (target.isOriginal) {
+ const targetName = target.getName();
+ spriteNames.push({
+ text: targetName,
+ value: targetName
+ });
+ }
}
+ return spriteNames;
}
- testBlock(args, util) {
- }
}
Scratch.extensions.register(new Video());
})(Scratch);
From 41287debc0a7ccec9640bcfca55e92921bca4cdb Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 20:19:20 +0100
Subject: [PATCH 08/34] Update Video.js
- Fixed bug with targets not getting reset
---
extensions/Lily/Video.js | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index b21f0ff5f1..068f39fd58 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -10,6 +10,26 @@
this.videos = [];
this.targets = [];
+ runtime.on('PROJECT_RUN_STOP', () => {
+ for (const name of Object.keys(this.videos)) {
+ const video = this.videos[name];
+ video.pause();
+ video.currentTime = 0;
+ }
+
+ this.targets = [];
+ });
+
+ runtime.on('PROJECT_START', () => {
+ for (const name of Object.keys(this.videos)) {
+ const video = this.videos[name];
+ video.pause();
+ video.currentTime = 0;
+ }
+
+ this.targets = [];
+ });
+
runtime.on('BEFORE_EXECUTE', () => {
for (const name of Object.keys(this.videos)) {
const video = this.videos[name];
@@ -20,7 +40,11 @@
const target = this.targets[id].target;
const drawableID = target.drawableID;
- const skinId = runtime.renderer._allDrawables[drawableID].skin._id;
+ const drawable = runtime.renderer._allDrawables[drawableID];
+ // This was only a problem when targets weren't reset, I don't
+ // expect it to happen much now but just in case..
+ if (!drawable) return;
+ const skinId = drawable.skin._id;
const video = this.videos[this.targets[id].videoName];
vm.renderer.updateBitmapSkin(skinId, video, 1);
@@ -196,8 +220,8 @@
}
deleteVideoURL(args) {
- const name = Cast.toString(args.NAME);
- Reflect.deleteProperty(this.videos, name);
+ const videoName = Cast.toString(args.NAME);
+ Reflect.deleteProperty(this.videos, videoName);
// To-do : reset the targets with the video
}
@@ -238,10 +262,12 @@
startVideo(args) {
const videoName = Cast.toString(args.NAME);
+ const duration = Cast.toNumber(args.DURATION);
const video = this.videos[videoName];
if (!video) return;
video.play();
+ video.currentTime = duration;
}
getCurrentTime(args) {
@@ -250,7 +276,6 @@
if (!video) return 0;
return video.currentTime;
-
}
pauseVideo(args) {
From 0b80d4bf7f79dd7383f91b74bd514e3099d95557 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 21:04:17 +0100
Subject: [PATCH 09/34] Update Video.js
---
extensions/Lily/Video.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index 068f39fd58..611c995ab9 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -10,7 +10,7 @@
this.videos = [];
this.targets = [];
- runtime.on('PROJECT_RUN_STOP', () => {
+ runtime.on('PROJECT_STOP_ALL', () => {
for (const name of Object.keys(this.videos)) {
const video = this.videos[name];
video.pause();
@@ -266,6 +266,8 @@
const video = this.videos[videoName];
if (!video) return;
+ console.log(video);
+
video.play();
video.currentTime = duration;
}
From 046b1e27d11b3da1d8fcce2920de930b61cf1647 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 22:14:22 +0100
Subject: [PATCH 10/34] Update Video.js
- Added volume
- More fixes
---
extensions/Lily/Video.js | 103 ++++++++++++++++++++++++++++++---------
1 file changed, 81 insertions(+), 22 deletions(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index 611c995ab9..4af26b577e 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -22,7 +22,7 @@
runtime.on('PROJECT_START', () => {
for (const name of Object.keys(this.videos)) {
- const video = this.videos[name];
+ const video = this.videos[name].video;
video.pause();
video.currentTime = 0;
}
@@ -32,8 +32,10 @@
runtime.on('BEFORE_EXECUTE', () => {
for (const name of Object.keys(this.videos)) {
- const video = this.videos[name];
- video.volume = runtime.audioEngine.inputNode.gain.value;
+ const video = this.videos[name].video;
+ const videoVolume = this.videos[name].volume;
+ const projectVolume = runtime.audioEngine.inputNode.gain.value;
+ video.volume = videoVolume * projectVolume;
}
for (const id of Object.keys(this.targets)) {
@@ -45,7 +47,7 @@
// expect it to happen much now but just in case..
if (!drawable) return;
const skinId = drawable.skin._id;
- const video = this.videos[this.targets[id].videoName];
+ const video = this.videos[this.targets[id].videoName].video;
vm.renderer.updateBitmapSkin(skinId, video, 1);
}
@@ -83,6 +85,11 @@
}
}
},
+ {
+ opcode: 'getLoadedVideos',
+ blockType: Scratch.BlockType.REPORTER,
+ text: 'loaded videos'
+ },
'---',
{
opcode: 'showVideo',
@@ -154,7 +161,7 @@
},
'---',
{
- opcode: 'pauseVideo',
+ opcode: 'pause',
blockType: Scratch.BlockType.COMMAND,
text: 'pause video [NAME]',
arguments: {
@@ -165,7 +172,7 @@
}
},
{
- opcode: 'resumeVideo',
+ opcode: 'resume',
blockType: Scratch.BlockType.COMMAND,
text: 'resume video [NAME]',
arguments: {
@@ -189,6 +196,33 @@
menu: 'state'
}
}
+ },
+ '---',
+ {
+ opcode: 'setVolume',
+ blockType: Scratch.BlockType.COMMAND,
+ text: 'set volume of video [NAME] to [VALUE]',
+ arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ },
+ VALUE: {
+ type: Scratch.ArgumentType.NUMBER,
+ defaultValue: 100
+ }
+ }
+ },
+ {
+ opcode: 'getVolume',
+ blockType: Scratch.BlockType.REPORTER,
+ text: 'volume of video [NAME]',
+ arguments: {
+ NAME: {
+ type: Scratch.ArgumentType.STRING,
+ defaultValue: 'my video'
+ }
+ }
}
],
menus: {
@@ -204,19 +238,25 @@
};
}
- loadVideoURL(args) {
+ async loadVideoURL(args) {
const videoName = Cast.toString(args.NAME);
const url = Cast.toString(args.URL);
+ if (!await Scratch.canFetch(url)) return;
+
+ this.videos[videoName] = {
+ video: document.createElement('video'),
+ volume: 1
+ }
- this.videos[videoName] = document.createElement('video');
- this.videos[videoName].width = 480;
- this.videos[videoName].height = 360;
- this.videos[videoName].crossOrigin = 'anonymous';
+ const video = this.videos[videoName].video;
+ video.width = 480;
+ video.height = 360;
+ video.crossOrigin = 'anonymous';
// To-do : Some urls can't be loaded by the renderer, how can we detect that?
- this.videos[videoName].src = url;
- this.videos[videoName].currentTime = 0;
+ video.src = url;
+ video.currentTime = 0;
}
deleteVideoURL(args) {
@@ -226,6 +266,10 @@
// To-do : reset the targets with the video
}
+ getLoadedVideos() {
+ return JSON.stringify(Object.keys(this.videos));
+ }
+
showVideo(args, util) {
const targetName = Cast.toString(args.TARGET);
const videoName = Cast.toString(args.NAME);
@@ -263,34 +307,32 @@
startVideo(args) {
const videoName = Cast.toString(args.NAME);
const duration = Cast.toNumber(args.DURATION);
- const video = this.videos[videoName];
+ const video = this.videos[videoName].video;
if (!video) return;
- console.log(video);
-
video.play();
video.currentTime = duration;
}
getCurrentTime(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName];
+ const video = this.videos[videoName].video;
if (!video) return 0;
return video.currentTime;
}
- pauseVideo(args) {
+ pause(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName];
+ const video = this.videos[videoName].video;
if (!video) return;
video.pause();
}
- resumeVideo(args) {
+ resume(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName];
+ const video = this.videos[videoName].video;
if (!video) return;
video.play();
@@ -298,12 +340,29 @@
getState(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName];
+ const video = this.videos[videoName].video;
if (!video) return (args.STATE == 'paused');
return (args.STATE == 'playing') ? !video.paused : video.paused;
}
+ setVolume(args) {
+ const videoName = Cast.toString(args.NAME);
+ const value = Cast.toNumber(args.VALUE);
+ const videoObject = this.videos[videoName];
+ if (!videoObject) return;
+
+ videoObject.volume = value / 100;
+ }
+
+ getVolume(args) {
+ const videoName = Cast.toString(args.NAME);
+ const videoObject = this.videos[videoName];
+ if (!videoObject) return 0;
+
+ return videoObject.volume * 100;
+ }
+
_getTargetFromMenu (targetName, util) {
let target = Scratch.vm.runtime.getSpriteTargetByName(targetName);
if (targetName === '_myself_') target = util.target;
From b648b32704898afe968b54f4f2197b56aba3ce5d Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 22:14:33 +0100
Subject: [PATCH 11/34] Delete Video.svg
---
images/Lily/Video.svg | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 images/Lily/Video.svg
diff --git a/images/Lily/Video.svg b/images/Lily/Video.svg
deleted file mode 100644
index fcc3cbfab7..0000000000
--- a/images/Lily/Video.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
From 169c5c42dad550b8fefcee989a07bdfcec93c174 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 22:15:09 +0100
Subject: [PATCH 12/34] Add files via upload
---
images/Lily/Video.svg | 1 +
1 file changed, 1 insertion(+)
create mode 100644 images/Lily/Video.svg
diff --git a/images/Lily/Video.svg b/images/Lily/Video.svg
new file mode 100644
index 0000000000..bd9a2f932b
--- /dev/null
+++ b/images/Lily/Video.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
From f5806e79d84021cf1ab423456cee781c3abe8c07 Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Sun, 13 Aug 2023 22:16:07 +0100
Subject: [PATCH 13/34] Update Video.js
---
extensions/Lily/Video.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index 4af26b577e..85d08fa728 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -246,7 +246,7 @@
this.videos[videoName] = {
video: document.createElement('video'),
volume: 1
- }
+ };
const video = this.videos[videoName].video;
video.width = 480;
From 81cc02ec34b7f7442f4a49331d307f8ae900219c Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Mon, 14 Aug 2023 06:13:51 +0100
Subject: [PATCH 14/34] Update Video.js
---
extensions/Lily/Video.js | 115 ++++++++++++++++++++++++++-------------
1 file changed, 78 insertions(+), 37 deletions(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index 85d08fa728..fd6d832e89 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -12,11 +12,16 @@
runtime.on('PROJECT_STOP_ALL', () => {
for (const name of Object.keys(this.videos)) {
- const video = this.videos[name];
+ const video = this.videos[name].video;
video.pause();
video.currentTime = 0;
}
+ for (const id of Object.keys(this.targets)) {
+ const target = this.targets[id].target;
+ target.updateAllDrawableProperties();
+ }
+
this.targets = [];
});
@@ -27,15 +32,26 @@
video.currentTime = 0;
}
+ for (const id of Object.keys(this.targets)) {
+ const target = this.targets[id].target;
+ target.updateAllDrawableProperties();
+ }
+
this.targets = [];
});
runtime.on('BEFORE_EXECUTE', () => {
for (const name of Object.keys(this.videos)) {
- const video = this.videos[name].video;
- const videoVolume = this.videos[name].volume;
+ const videoObject = this.videos[name];
+
+ const video = videoObject.video;
+ const videoVolume = videoObject.volume;
+ const skin = videoObject.skin;
+
const projectVolume = runtime.audioEngine.inputNode.gain.value;
video.volume = videoVolume * projectVolume;
+
+ vm.renderer.updateBitmapSkin(skin, video, 1);
}
for (const id of Object.keys(this.targets)) {
@@ -46,10 +62,8 @@
// This was only a problem when targets weren't reset, I don't
// expect it to happen much now but just in case..
if (!drawable) return;
- const skinId = drawable.skin._id;
- const video = this.videos[this.targets[id].videoName].video;
-
- vm.renderer.updateBitmapSkin(skinId, video, 1);
+ const skin = this.videos[this.targets[id].videoName].skin;
+ drawable.skin = vm.renderer._allSkins[skin];
}
});
}
@@ -149,10 +163,14 @@
}
},
{
- opcode: 'getCurrentTime',
+ opcode: 'getAttribute',
blockType: Scratch.BlockType.REPORTER,
- text: 'current time of video [NAME]',
+ text: '[ATTRIBUTE] of video [NAME]',
arguments: {
+ ATTRIBUTE: {
+ type: Scratch.ArgumentType.STRING,
+ menu: 'attribute'
+ },
NAME: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'my video'
@@ -233,6 +251,10 @@
state: {
acceptReporters: true,
items: ['playing', 'paused']
+ },
+ attribute: {
+ acceptReporters: false,
+ items: ['current time', 'duration', 'width', 'height']
}
}
};
@@ -245,25 +267,36 @@
this.videos[videoName] = {
video: document.createElement('video'),
- volume: 1
- };
+ volume: 1,
+ skin: 0
+ }
- const video = this.videos[videoName].video;
- video.width = 480;
- video.height = 360;
- video.crossOrigin = 'anonymous';
+ const videoObject = this.videos[videoName];
+ const video = videoObject.video;
- // To-do : Some urls can't be loaded by the renderer, how can we detect that?
+ video.width = 1;
+ video.height = 1;
+ video.crossOrigin = 'anonymous';
video.src = url;
video.currentTime = 0;
+
+ videoObject.skin = vm.renderer.createBitmapSkin(video);
}
deleteVideoURL(args) {
const videoName = Cast.toString(args.NAME);
- Reflect.deleteProperty(this.videos, videoName);
+ if (!this.videos[videoName]) return;
+
+ for (const id of Object.keys(this.targets)) {
+ if (this.targets[id].videoName === videoName) {
+ this.targets[id].target.updateAllDrawableProperties();
+ Reflect.deleteProperty(this.targets, id);
+ }
+ }
- // To-do : reset the targets with the video
+ this.videos[videoName].video.pause();
+ Reflect.deleteProperty(this.videos, videoName);
}
getLoadedVideos() {
@@ -274,7 +307,7 @@
const targetName = Cast.toString(args.TARGET);
const videoName = Cast.toString(args.NAME);
const target = this._getTargetFromMenu(targetName, util);
- if (!target) return;
+ if (!target || !this.videos[videoName]) return;
const targetId = target.id;
this.targets[targetId] = {
@@ -291,7 +324,6 @@
const targetId = target.id;
Reflect.deleteProperty(this.targets, targetId);
- // Why does this not work, what
target.updateAllDrawableProperties();
}
@@ -307,43 +339,52 @@
startVideo(args) {
const videoName = Cast.toString(args.NAME);
const duration = Cast.toNumber(args.DURATION);
- const video = this.videos[videoName].video;
- if (!video) return;
+ const videoObject = this.videos[videoName];
+ if (!videoObject) return;
- video.play();
- video.currentTime = duration;
+ videoObject.video.play();
+ videoObject.video.currentTime = duration;
}
- getCurrentTime(args) {
+ getAttribute(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName].video;
- if (!video) return 0;
+ const videoObject = this.videos[videoName];
+ if (!videoObject) return 0;
+
+ const skinId = videoObject.skin;
+ const skin = vm.renderer._allSkins[skinId];
- return video.currentTime;
+ switch(args.ATTRIBUTE) {
+ case('current time'): return videoObject.video.currentTime;
+ case('duration'): return videoObject.video.duration;
+ case('width'): return skin._textureSize[0];
+ case('height'): return skin._textureSize[1];
+ default: return 0;
+ }
}
pause(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName].video;
- if (!video) return;
+ const videoObject = this.videos[videoName];
+ if (!videoObject) return;
- video.pause();
+ videoObject.video.pause();
}
resume(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName].video;
- if (!video) return;
+ const videoObject = this.videos[videoName];
+ if (!videoObject) return;
- video.play();
+ videoObject.video.play();
}
getState(args) {
const videoName = Cast.toString(args.NAME);
- const video = this.videos[videoName].video;
- if (!video) return (args.STATE == 'paused');
+ const videoObject = this.videos[videoName];
+ if (!videoObject) return (args.STATE === 'paused');
- return (args.STATE == 'playing') ? !video.paused : video.paused;
+ return (args.STATE == 'playing') ? !videoObject.video.paused : videoObject.video.paused;
}
setVolume(args) {
From 178af5e34bb199b6b693b25ac04dc74af6729fbf Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Mon, 14 Aug 2023 06:16:06 +0100
Subject: [PATCH 15/34] Update Video.js
---
extensions/Lily/Video.js | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/extensions/Lily/Video.js b/extensions/Lily/Video.js
index fd6d832e89..2e23cfa1d5 100644
--- a/extensions/Lily/Video.js
+++ b/extensions/Lily/Video.js
@@ -269,7 +269,7 @@
video: document.createElement('video'),
volume: 1,
skin: 0
- }
+ };
const videoObject = this.videos[videoName];
const video = videoObject.video;
@@ -287,7 +287,7 @@
deleteVideoURL(args) {
const videoName = Cast.toString(args.NAME);
if (!this.videos[videoName]) return;
-
+
for (const id of Object.keys(this.targets)) {
if (this.targets[id].videoName === videoName) {
this.targets[id].target.updateAllDrawableProperties();
@@ -354,11 +354,11 @@
const skinId = videoObject.skin;
const skin = vm.renderer._allSkins[skinId];
- switch(args.ATTRIBUTE) {
- case('current time'): return videoObject.video.currentTime;
- case('duration'): return videoObject.video.duration;
- case('width'): return skin._textureSize[0];
- case('height'): return skin._textureSize[1];
+ switch (args.ATTRIBUTE) {
+ case ('current time'): return videoObject.video.currentTime;
+ case ('duration'): return videoObject.video.duration;
+ case ('width'): return skin._textureSize[0];
+ case ('height'): return skin._textureSize[1];
default: return 0;
}
}
From 92b22d6c5e35cbd93ddfe15b2af1e43362f5ca4c Mon Sep 17 00:00:00 2001
From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com>
Date: Mon, 14 Aug 2023 06:47:00 +0100
Subject: [PATCH 16/34] Add files via upload
---
website/dango.mp4 | Bin 0 -> 107326 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 website/dango.mp4
diff --git a/website/dango.mp4 b/website/dango.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..f5dbfd4738f45e2e1b3a4d9cbe0e91efb3991760
GIT binary patch
literal 107326
zcmeFZbwE~2*EhT`8tLv5knWW35DDo
zdEWbZKcDYE=Q!6|^P8D9v)5j;X3bm|2LJ$aGZ#+>OJ{pq0DuB+D45v|-Hh369XQzl
z0B6|N-rfxW02^C33losuO3<4CfP4r*fSZ5+PXDC{Xbo2C
zx>)}h6U2U{e@R2m|AqWy{x;4(jSH~=rvqj%QJI>!ID?ef)W+H62l8X4H*#VAHD~xX
zTN6t|u#Vi;_@nSTKm;A6{x>`lH&5S)i#d#?M;96ZcytgPfVmPQ`z+?;<^{`kbdz6L2j*h(B?
z0^nSK1W3(6S~e%@(D76kwgds;4gf%dMgx9$kTU8pLI606ud8qFc3z&H-AKSPwzqMz
zGq&*nr*rckn9v;zogF}WQ@F|4MlMc&DIfCD6}ZU&fbZ<`_+I6t4~@8kcc
zaelY{$GG4ccQ(E;L@?bL=8e6>{)_%BgBTiHwg*6O0s)l{6AID>FpGg1oC_oY#K32O
zDg$|GFbjfwBuMXpR1(amAb&IVcaX0JDI!Qa!9Jh|hD?AN3(OSYocuuw`VWW%$lnDi
zDcBD5ldwb}1+gD=7LNg6Hx~er1N$mUfaV$xKs5LOh%N>IF^B~qCfNYQauR^p&H)eyu)PNp
z0P!{gApR-_sUHE}@g
zgXzBn6wdapc0bU6eW-wClYa*kNJIY$DA1k%3MhWI{T~DqNKgJ1OnCn-n6L(;Kf`|s
z`nL+80Q4ISoa#;DFm*Qhu^~eT1O(g#{S*vHu|;rh>L91!t3HK+1raEWcsP*UtexBY
z{a+2hwFcbU@AbhpFhBnNcoQ(JU>WQOLO;qk0q5;93~2MW%l}vpPXD+1|9$*h^8QET
z|GodMG7RWTZ>;3k{Br;6^Za;zgj@Ch^!&H`|5N>~@%~@>xf%a<{muBdRd{yv`@d9b(M&;O-7Km@e^#any*BTycw
z&tDnb2X6HFqYRGo3kUu7FC5&bf8hwXaB!deh2I1vKjnaX-Y@)SFZ_w4-onAX`xkz*
zE8d
ziL>3p*>B+-w{WgoIJgJ@nkUaKoc9(E#$>Z-@w)~g)*h70-{SK$P!u@+j|`6ehX-}=
zM-TtI_VBl}$6au(+}i*EhE4!rIR~S*9suAu1}}C70YDh^;S$&YAjJS46G1=r=oJ8{
zz61bGu#a{b02uTEfC=b(EkIvp3)VSa0)Xot0C<7fp9ug0TL2&elot)258^BUAbA}C
z(!sT#1^U*UNB}4V&k!#_8RbL(P-zbUwd7#%2+D2;*Go6(3wpu+gC_tm(hmSr;5f73
z9yFf|03W6RUlxzWyf-3+7B^Q98;{p&|
z5dcDP2Y?WN10Z+%00{Mc079<_Kv+8g2v<1(;SB&F0^oT?j0Zd-Mgfoqya423Isj4T
z2Oz3(07T0SfarsL48aRc3qJs2%?v>7-hoHTAOPZp0v;br07!ru00}h!AmN_i*~1(>
zd%OqF9^m;SUKD^NA%SNPAMosP<4*~l%^gf`oV=60jSWbC_@p2AX~fP(<_;k8v*xA|
z=oNl=7$a8`7ekQOwl)1hK^CC6eYFUl9-Isv9Bw53N=%l2-Ct6_aIptf43L-@{^)!o
z7y$41%)mQ7_8)hAU>U*8$f&IXiK#KzM%>=P)5g@yg`Az0m4k_$m7N0w
zEnHk2_*hun-QAgQE<^2Y4DFchoy=Ko>XSz?d_cT$c+t+42=cZ$iWLw
zK@M^gQzILDV{1V+K2|tN^tmW@Fjf#+CDJ5U7J(8=(ojhU07t*JApEh7U5Pms4X
z5o8B>LlZ-Xo5wIRFtRjsz8S>Q$@IsAxtm&=Teuj3b@mRXb_VA54q)wHpaa;|+SC)2
zEy&Kr`Y+Z1JW+y0a%W>xJ5ys<7eP+en`t^3-ssfH)Y$^;?qqE6>v3=Dos0#Ioy^E>
z!5dxEo5unRg6tg3tmKY24|Mcf^QVoaVhnF)agcT3G&Xbcw2govG=#RlzwN!e
zogrW6&9zTV0&uo{!9&=+2P8@^K1?HFQVWvN3p?a|7x3BHb_mt|;G42gb0$F}+qFnu
z%$9Kw!_HCecl}FTIO|#ow(yVR%asrWHJ-m$}!msS?H}`r`8a
zfws_`abxjP0J1si8Fx#$P}GU7>+5T{6A0Pj+&N{%)p5y}X=8(WSi9Q2!71qn6T@d;
zSy#v)4>CHH*f>%=6dmFJVQAMJPU6ysJ-*kXtE
z@XgiDr6tBXMd9)3Js5YDd0&ieKK=>yOSZD0P@@o9PM>3=J(9ZoeWADty(HfZ`D&XK
z5o~{h;6*YWdnu`rEv-vj~3)BzWH179ZL`w9B|;(bsI}pN=k%s
ziWF_)(2>UHh*7U}?HovGtxov+oElHFwm(QE_GD##E7rp-^pRI)WI1^mDi2MIe;@;E
z|5eN`a%tUD#d((u9ll}L^YD&qVi+b1x7LuMDM_nNBPx8CXNZ^{dLe_R2<8OscZ6ON
zS0*4uYGNHGUNp|lC@_CVx~FgCH5`RT2m4)sW?hfuVQK&$3~&Cc&j{Y_9kJ+V=o4r=
zj{Lc+G9LvS{WNi>y$xeo))hU^YE9Kj2$BxDKzJrDxWoBrf)qm{t
z-T34V)z)Ox3RG>`X6WOG{Z_L+0HRb4^myrVgoiM0HE@-$!kv&RyIe&OX;9nB3I2n}*{e3gV$-nxdT7Y5ZP3B13mx`V{Im_LXZEVKY
zN^6CK-qQ9xyPHMWb~Wwk=msOYv6WUGkq59{mcG$0<19`{3knw|OHv!KcY=JK*z#Y{
ztZmO>F#8465qhoLVfBYXK3zgz9?q5B$AOxCm`}P&rjFPzx=&H$1rGG*~|6>HW<_Dw}Ug`GjYKZkc5Y)DgcMYsqP>&N$qTB++HpC|E=c7#q>
zx35&`c1JU8iv$h!hz`Os`__PVzRjQX?~?PVL?EIttg%X9?Uld_mdv5*S!#iMMd(a&
zgh~cQm&kEn%Kw6HhH+w7&muWmQGVbK0*)oV*Pvo`++6ZgqM(_sd);q0!p@yxx(F;!
zX|)FmG$T?~%3lS_33s3d=zNxMLUwy&(74y$rEtyGSN^~PwX63DiberCZG8@7p=iND
zA30(#_MKKexlm?Ylwn`~j!D=c*S_bi<#!auSuQel!d+IALLaSf!I#TpOW?nAJNlG5
zyh2GWvrBFBJWPAGD;PlBn^TK0ms(lS-s@OFf+G)a@OzP@G@DqLxHB)cdG1<&S013X
z_}Ja;_$BJzB81W&j?^^Hg;di14g){=d-hg@#s?kuoXepC5GMlSbd3yk$p-|mXWG@E
z?^Xg(;29DsL-ZMyjkxetHaZN)aW(GCP2eOcnCd0pnRJ)bF)AfcV<4gih`+_4EVZ|f
zGTt?8ooJkVgUMLainb7=4V^peFTSDibf*Tris4;vPfod5mXvd2m}{ROM{ESba}xJ1
z!bR>%Sh={#CF2kBgzxmNpjcQwjmY+#kzIZ=p1iWbS+GXQXemt(p8B$6PeAq&&b6}i
zrLtQhEE-Z1VV##Gvc}P#1Iw_Xv@O<~BWv}#mXvtUYv#Ty5gXqv6JoDY$825M`>uEAc+Po06`{icfxb
z7~&OK_d$zyr5cMi4>#YhB?^yLM+j!5P5d#QOPKLG&V(pQR44g+nRET;#+B-#j@{O3
z-7{t>Qx2x2cs5Ss5y$d)ZdEfi8tp`J928~#>)EVboU9&b7~0+Vmt2KkT=gEW7$slT
z(=03Ir!0ThwtaD&m?tx2o0tJroEbGEQ|3xBB}0SC
zU4}XNbe--Y4vIAmLJcv7-NxaVhS|Bh-t)_snr3ZJj=gNeC;~eJJgSrZ<%`UWgI^@(
zA>XNaoNT4=)z*u)DaPu1jtQd6YtYkYI@g#z(olmu)CUZw
z>T#ERnl|~4wg<#4R5d$cEuJHP_7~dI2hvDBu9Qi0A=@$T!XDa_PGa#1pE>5^w>A@7
zD7VpoJ3B;CG+WFg)E`(8cWj!pIpH3ScxPnq{pfO&8gGt{5U?hDL2Fg#Cr7RD&g2F0
zCI)=}mv)vZh>xIu!wV0ks1WC$xGLYD3p&ox44S${dQ1HFd?6eOTX(lG#nvFX{
zHnUTyb^9s_aPHw^f*!PuB2P(jw>HMvmkOF(_efW5U;`&DQCgeh#q;xuavu{{d}P>S
za>sk~CIQae1shUmL!5kTuBd=w;$vSV!6z0mi>EqI8Iq)A?_E|ieG~38flEf8(&Cp`
zwL{SEX`UDHHt3i2MXY^&*Kp8r*DxZy0|&i+&A;mt_{|T%2FW&b5%UL1?q;nD`v!I2
zpESx+T16Nzgk3b@W?6;2oy6l^{~r`**beq@NnlTkFQI{r{X=!T45K^qHw_iKs>TLj?2d8)wcl>lfkT
zFXmmws?ikc;zVSSWJ<@*C&B^!aMwoqBvyt~k1XZmY8E+_xP%wNa0&E;CQV
z^f!=X@6&!43!TYtf49}gFS`xhyj)VZL$`WQJHFUgGw+DPV7X$YSvOcSntdib9tJ+Jd(*
z1)nFCK20e-#KM5n*;$ep>clyitd6JkjWiUiIq91Sw4byCP<2WNj=FbZ4r$aW7ZCEK
zV-hG$RN-9fjxDQPRQ4V%%C7sU!aGjVaPhsU#fm(5h>PHS)`XnVXt5>8cK%74V$35~
zaY?rXE}EWlWtP0+9t26tdT_i|9nz0M$!#b8ko>ctw0S1ozU{2!e67zwgs&BOub@YD
z_k_?ld^o|-RJPPL!z?$G4s5Y25=*6O6!p2$-I+!~lh_8dx8FWt`5`GYg-bZ^urLs|
zEy(4_wG|)oE{~$fu*Bc1Ev!#=f^YpoL|0rO`suwQENi5JRS9i0N2XfQd@9W+tYJ6-
zD$eR|7opFI#rh=2uQ=evO@^jek;skTHm8;>(N7ht8z)KbNj5Og7(IS8UT(fl5AE?n
z4c+gZ_UN5Ad}gqH&z>ASYBNn7){P5}z+e(1eB`2>Z%F+`pOGbeQ(Q)htsX*U_KCve
z^&zS`N&vEZm+~4}l@tY?Ha;9HTHnJ7`(DSv3z<7&?ojT}VvoVP)
zSJ9u6uJxuK_k9ZW*qH1YDCMvSAf#!RO|423c$_Uy$}!VKow2hFe*JiEsfTYnd4+y+aBD
zU+3pdIQT*jv~e2IlYCCp4-8IJZBJ?{^6EcIfRgKk_Wk3Re)^)@^!NQzfatRb
z*^hUWO<5^&K(~YlqaQ#oXk|hD;<%*AoTS^-hWKO}&-5)nG%bM;6cg0Kw-!%!-Lo`}
zx6-PagQV_$;ra-=$meI%n1TvE!Ql^VxEJJfq!g~Sw;faQl*y#!aOc_-4q2sW5mYNQC);op%o
zs1H(Zm9xw9T0kuqliwx$AcNgW({SYe;dO#oKML*a8%$T?T*6r*;kt#@{MQ2EI&b37
z1qF!Z3Ih^Y!ukq(8t!f(Z>mPo^wb`oix2nS^}>^43^+GH)j+1S^s<3OZ6_BByd8Qw
zz|%q)anc%r?Jj>u{jU9UF_Q3|R$ER3X;DsWtno>hj>n86Dk@)IAn)kN^g+)tv^~Vj
z?>D29%*iK$LQz^`BgsB{z~!}{;HvI7)3-HNspT0Vl{uHNqG9Xe)QS6oN){P%AdtHt
z^ts530bq%6B7}9AD>Jm*k@rx`gdX3x@Cu$$m3G&-eo~xL)DMBgJer
z6YceqD^07PbYEk?EgqIGM2~a15dN;1=Y)*N>Cb8tq?pPp=p|!+6e|H+z4Nf|*Z4eq{W4xRI^HpT9Sc
z4HBQ+m%m(fo_fQ0Zwxg`)>D;L^F02{ot=0?IdaBmZIyP0!1xe_Y@u=Ea8(sf%!=`8
zPe{!PHf+K^t|7z80XE0=w|kA|m*VxIo%JOPY~dBk*CbE!c4$YQ;VS11T@8O#%ts##
z9GZZKp`C{9e1K6|&?yv+Jdqq87scFkKAQyFZILrntjwMOajb_mZ!nli7KF=tdS8_-
z#ns3|Mxl#u6Tj*U>0TmmRND)Z}gY+uH>sMl`!vlJg-y10r%r|Hv(Ip75_J-E#iu`8FzfE&!-szm)geMK7ZlI3tdf4qbLHu>
zAH8s|jYB1-Uhdv*m9q=x;IY0b1!?=axckg2^Uj>ua&%Hj-e+g$4s)D0Ercyk-&;1((&^X4zu(7oRM>6YjcFj43otWs
zf45?~_9izOAib7;5IgKw@sZ@~2yqBOA6j?6^_JTVlReSSwwRZEQ<5Mq61zc7LyEmC
z%;n48J1==zpUL#Zw^?!68=B8xB1eWBeDf1<5Whoznex<8akMEVV7(xB*1jm^q@)b#
z-9-_F+L(E_zZTK*6XAD6vqu>Ke@v(HlO(nGe~kRLasT9h)5!lQ^`|0l)8F;S;7t($
zBzxfIhGMs^ctv))>H(<;N{Vuf&TLCly`PD;jdI6WEoVq`mQu{tc2jInY!^<@MuNt^
zn$&V6{2ay6ykuFZc=m(2Q4}hgH>};KGl|J4MWZi9aV9S0&+feG9V3T*P8I*{*#v37
zQb2M`a~1wtI??#O>3SudFcSEK7;ixn41PT6dUfZiIM+w+rGoe5=q;w4_3L0wWWIeg
zh$fcKoFPffc2w7lnaTSyE>7)bcbMlNC+1X>y3{Yl|5O7J_8vvLe<*3rinZP9iRMxi
z5@Di`d#^(!`Ev4cc*MdtL4N-xmPqs_^q`U5)q6ShWDhvPEz^Zvzd9FS9XOVjOdRJQ6sg;-YM|M8dk6<~?9
zM2C1d)B6JlHe8*x#^3a)m%pnre9I;cw>`E3y+W|pd8%?h_m1X}YGe-zyQQ&`Lo}Z(
zYp9CTM#uO2xQ2<$o)>4~ww;Y9nWrY*f+9uD?vHY;tNa
z$u{PEQ6JNMH(l3@%2pp1?KVa@gE&oo(x-I1;5YVcJj1OiqACbNRV(9)v=pb#EW18@
zG>C`)`8m34QtT-%UoU1yR7ToDli++plmt^I?7V#pAs=)dJ>jL`>X24FeIfSy&7Q<>
zFzDq(qn%0+wZldWvZtew99~_;7XraP)}-TtL_7Hc&-Ka(5VwQUWM2{MQ&7?t(9F(!
z+A%*deoR!oe0MuCLXFYfEKG1^&0*iOxjMyfGJ9X6=+6BV_I8ySXwCEba54>IyO6{J
z^{0)W!>R+lbu8^PcsC2Y-7BMCA3O@HpJn=>%NXSRg~+qFEFCh!_e#?FDmM#0ujs
z{P)F_-TfM_(1_%xnRxxXfNrv$i-ti2X~(+DLr>VU)}r>tsIccI!F#dKpyVPeP_P(I
ztJe1fog-FDJ4T+7Y{u-RGUAHwV}x0|*Li9vU^+3kG*qf&cbTxkPP`>l31^Gea3TCa
zV*P$i6>*O$*Awo#hlQy@Z|;t|ucmTOxu=9JDp&G;cu%~p91{Pqgt(!ekXo;{qen9i
z5elbZtWkcd5Xxcn+Y$1Calb>IRw86oDn_^H-LNGg@y1Vw?D9{A;1leJjL`->CW_JZ
zcs+?SaJ5v2RoO7hDOkfo<;xC;s8ty4lYMIOP%SkitZ;%>3huN1@fbh7#BKVU9^;Qv
zZ!7aB|G%*FQ$eyn|JeEAR2ZV$(@#B$E@wxanNn@50Xsi>-jy1ax2MvM;+neqS{}h^
z
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%0DLQyG5(Jo5Xpz^_D2GG`>MqF@A^kT
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