This commit is contained in:
Mike Welsh 2019-04-25 20:27:44 -07:00
parent 8d4ce5af8a
commit 975d31ac58
11 changed files with 380 additions and 162 deletions

View File

@ -16,6 +16,7 @@ console_error_panic_hook = { version = "0.1.1", optional = true }
console_log = { version = "0.1", optional = true }
js-sys = "0.3.19"
log = "0.4"
url = "1.7.2"
svg = "0.5.12"
swf = { path = "../swf-rs", version = "*" }
wasm-bindgen = "0.2"

View File

@ -3,10 +3,12 @@ use web_sys::HtmlImageElement;
pub enum Character {
Graphic {
image: HtmlImageElement,
x_min: f32,
y_min: f32,
},
MovieClip {
num_frames: u16,
tag_stream: swf::read::Reader<std::io::Cursor<Vec<u8>>>,
tag_stream_start: u64,
},
Sound,
}

View File

@ -1,24 +1,36 @@
use crate::Library;
use crate::RenderContext;
use crate::{graphic::Graphic, MovieClip};
use crate::Matrix;
use crate::{graphic::Graphic, MovieClip, Stage};
use crate::{RenderContext, UpdateContext};
use bacon_rajan_cc::{Trace, Tracer};
pub trait DisplayObject {
//fn children_gc_mut(&self) -> std::slice::Iter<&mut DisplayObjectNode>;
fn run_frame(&mut self, library: &Library);
fn run_frame(&mut self, context: &mut UpdateContext);
fn update_frame_number(&mut self) {}
fn render(&self, context: &mut RenderContext);
fn set_matrix(&mut self, matrix: Matrix);
}
pub enum DisplayObjectNode {
Graphic(Graphic),
MovieClip(MovieClip),
Stage(Stage),
}
impl DisplayObject for DisplayObjectNode {
fn run_frame(&mut self, library: &Library) {
fn run_frame(&mut self, context: &mut UpdateContext) {
match self {
DisplayObjectNode::Graphic(graphic) => graphic.run_frame(library),
DisplayObjectNode::MovieClip(movie_clip) => movie_clip.run_frame(library),
DisplayObjectNode::Graphic(graphic) => graphic.run_frame(context),
DisplayObjectNode::MovieClip(movie_clip) => movie_clip.run_frame(context),
DisplayObjectNode::Stage(stage) => stage.run_frame(context),
}
}
fn update_frame_number(&mut self) {
match self {
DisplayObjectNode::Graphic(graphic) => graphic.update_frame_number(),
DisplayObjectNode::MovieClip(movie_clip) => movie_clip.update_frame_number(),
DisplayObjectNode::Stage(stage) => stage.update_frame_number(),
}
}
@ -26,6 +38,15 @@ impl DisplayObject for DisplayObjectNode {
match self {
DisplayObjectNode::Graphic(graphic) => graphic.render(context),
DisplayObjectNode::MovieClip(movie_clip) => movie_clip.render(context),
DisplayObjectNode::Stage(stage) => stage.render(context),
}
}
fn set_matrix(&mut self, matrix: Matrix) {
match self {
DisplayObjectNode::Graphic(graphic) => graphic.set_matrix(matrix),
DisplayObjectNode::MovieClip(movie_clip) => movie_clip.set_matrix(matrix),
DisplayObjectNode::Stage(stage) => stage.set_matrix(matrix),
}
}
}
@ -35,6 +56,7 @@ impl Trace for DisplayObjectNode {
match self {
DisplayObjectNode::Graphic(graphic) => graphic.trace(tracer),
DisplayObjectNode::MovieClip(movie_clip) => movie_clip.trace(tracer),
DisplayObjectNode::Stage(stage) => stage.trace(tracer),
}
}
}

View File

@ -1,26 +1,31 @@
use crate::display_object::DisplayObject;
use crate::library::Library;
use crate::Matrix;
use crate::RenderContext;
use crate::{RenderContext, UpdateContext};
use bacon_rajan_cc::{Trace, Tracer};
use log::{info, trace, warn};
use web_sys::HtmlImageElement;
pub struct Graphic {
matrix: Matrix,
x_min: f32,
y_min: f32,
image: HtmlImageElement,
}
impl Graphic {
pub fn new(image: HtmlImageElement) -> Graphic {
pub fn new(image: HtmlImageElement, x_min: f32, y_min: f32) -> Graphic {
Graphic {
image,
x_min,
y_min,
matrix: std::default::Default::default(),
}
}
}
impl DisplayObject for Graphic {
fn run_frame(&mut self, _library: &Library) {
fn run_frame(&mut self, _context: &mut UpdateContext) {
// Noop
}
@ -29,7 +34,7 @@ impl DisplayObject for Graphic {
let world_matrix = context.matrix_stack.matrix();
context
.context_2d
.transform(
.set_transform(
world_matrix.a.into(),
world_matrix.b.into(),
world_matrix.c.into(),
@ -40,10 +45,14 @@ impl DisplayObject for Graphic {
.unwrap();
context
.context_2d
.draw_image_with_html_image_element(&self.image, 0.0, 0.0)
.unwrap();
.draw_image_with_html_image_element(&self.image, self.x_min.into(), self.y_min.into())
.expect("Couldn't render image");
context.matrix_stack.pop();
}
fn set_matrix(&mut self, matrix: Matrix) {
self.matrix = matrix;
}
}
impl Trace for Graphic {

View File

@ -5,12 +5,13 @@ mod library;
mod matrix;
mod movie_clip;
mod shape_utils;
mod stage;
use self::character::Character;
use self::display_object::DisplayObject;
use self::library::Library;
use self::matrix::{Matrix, MatrixStack};
use self::movie_clip::MovieClip;
use self::stage::Stage;
use bacon_rajan_cc::Cc;
use js_sys::{ArrayBuffer, Uint8Array};
use log::{info, trace, warn};
@ -18,7 +19,6 @@ use std::cell::RefCell;
use std::collections::HashMap;
use std::io::Cursor;
use std::rc::Rc;
use swf::Color;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement, HtmlImageElement};
@ -28,17 +28,16 @@ type CharacterId = swf::CharacterId;
#[wasm_bindgen]
pub struct Player {
tag_stream: swf::read::Reader<Cursor<Vec<u8>>>,
canvas: HtmlCanvasElement,
render_context: RenderContext,
library: Library,
root: Cc<RefCell<MovieClip>>,
stage: Cc<RefCell<Stage>>,
frame_rate: f64,
frame_accumulator: f64,
cur_timestamp: f64,
background_color: Color,
}
#[wasm_bindgen]
@ -66,15 +65,15 @@ impl Player {
Player {
tag_stream,
canvas,
render_context: RenderContext {
context_2d: context,
matrix_stack: MatrixStack::new(),
},
library: Library::new(),
root: MovieClip::new(),
stage: Stage::new(swf.num_frames),
frame_rate: swf.frame_rate.into(),
frame_accumulator: 0.0,
@ -83,12 +82,6 @@ impl Player {
.performance()
.expect("Expected performance")
.now(),
background_color: Color {
r: 255,
g: 255,
b: 255,
a: 255,
},
}
}
@ -112,48 +105,28 @@ impl Player {
impl Player {
fn run_frame(&mut self) {
use swf::Tag;
let mut update_context = UpdateContext {
tag_stream: &mut self.tag_stream,
position_stack: vec![],
library: &mut self.library,
};
while let Ok(Some(tag)) = self.tag_stream.read_tag() {
trace!("{:?}", tag);
match tag {
Tag::FileAttributes(file_attributes) => {}
Tag::SetBackgroundColor(color) => self.background_color = color,
Tag::ShowFrame => break,
Tag::DefineSceneAndFrameLabelData {
scenes,
frame_labels,
} => (), // TODO(Herschel)
Tag::DefineShape(shape) => {
if !self.library.contains_character(shape.id) {
let svg = shape_utils::swf_shape_to_svg(&shape);
info!("{}", svg);
let mut image = HtmlImageElement::new().unwrap();
image.set_src(&format!("data:image/svg+xml;utf8;{}", svg));
self.library
.register_character(shape.id, Character::Graphic { image });
}
}
//tag => self.root.borrow_mut().run_tag(tag)
_ => (),
}
}
let mut stage = self.stage.borrow_mut();
stage.run_frame(&mut update_context);
stage.update_frame_number();
}
fn render(&mut self) {
let background_color = format!(
let stage = self.stage.borrow_mut();
let background_color = stage.background_color();
let css_color = format!(
"rgb({}, {}, {})",
self.background_color.r, self.background_color.g, self.background_color.b
background_color.r, background_color.g, background_color.b
);
info!("{:?}", background_color);
self.render_context.context_2d.reset_transform().unwrap();
self.render_context
.context_2d
.set_fill_style(&background_color.into());
.set_fill_style(&format!("{}", css_color).into());
let width: f64 = self.canvas.width().into();
let height: f64 = self.canvas.height().into();
@ -162,10 +135,16 @@ impl Player {
.context_2d
.fill_rect(0.0, 0.0, width, height);
self.root.borrow_mut().render(&mut self.render_context);
stage.render(&mut self.render_context);
}
}
pub struct UpdateContext<'a> {
tag_stream: &'a mut swf::read::Reader<Cursor<Vec<u8>>>,
position_stack: Vec<u64>,
library: &'a mut Library,
}
pub struct RenderContext {
context_2d: CanvasRenderingContext2d,
matrix_stack: MatrixStack,

View File

@ -30,14 +30,20 @@ impl Library {
id: CharacterId,
) -> Result<DisplayObjectNode, Box<std::error::Error>> {
match self.characters.get(&id) {
Some(Character::Graphic { image }) => {
Ok(DisplayObjectNode::Graphic(Graphic::new(image.clone())))
}
Some(Character::Graphic {
image,
x_min,
y_min,
}) => Ok(DisplayObjectNode::Graphic(Graphic::new(
image.clone(),
*x_min,
*y_min,
))),
Some(Character::MovieClip {
tag_stream,
tag_stream_start,
num_frames,
}) => Ok(DisplayObjectNode::MovieClip(MovieClip::new_with_data(
tag_stream.clone(),
*tag_stream_start,
*num_frames,
))),
Some(_) => Err("Not a DisplayObject".into()),

View File

@ -12,8 +12,8 @@ impl From<swf::Matrix> for Matrix {
fn from(matrix: swf::Matrix) -> Matrix {
Matrix {
a: matrix.scale_x,
b: matrix.rotate_skew_1,
c: matrix.rotate_skew_0,
b: matrix.rotate_skew_0,
c: matrix.rotate_skew_1,
d: matrix.scale_y,
tx: matrix.translate_x,
ty: matrix.translate_y,
@ -69,7 +69,7 @@ impl MatrixStack {
}
pub fn push(&mut self, matrix: &Matrix) {
let new_matrix = *matrix * *self.matrix();
let new_matrix = *self.matrix() * *matrix;
self.0.push(new_matrix);
}

View File

@ -1,7 +1,7 @@
use crate::display_object::{DisplayObject, DisplayObjectNode};
use crate::matrix::Matrix;
use crate::Library;
use crate::RenderContext;
use crate::{RenderContext, UpdateContext};
use bacon_rajan_cc::{Cc, Trace, Tracer};
use log::{info, trace, warn};
use std::cell::RefCell;
@ -12,10 +12,12 @@ type Depth = i16;
type FrameNumber = u16;
pub struct MovieClip {
tag_stream: Option<swf::read::Reader<Cursor<Vec<u8>>>>,
tag_stream_start: Option<u64>,
tag_stream_pos: u64,
is_playing: bool,
matrix: Matrix,
current_frame: FrameNumber,
next_frame: FrameNumber,
total_frames: FrameNumber,
children: HashMap<Depth, Cc<RefCell<DisplayObjectNode>>>,
}
@ -23,106 +25,164 @@ pub struct MovieClip {
impl MovieClip {
pub fn new() -> Cc<RefCell<MovieClip>> {
let clip = MovieClip {
tag_stream: None,
tag_stream_start: None,
tag_stream_pos: 0,
is_playing: true,
matrix: Matrix::default(),
current_frame: 1,
current_frame: 0,
next_frame: 1,
total_frames: 1,
children: HashMap::new(),
};
Cc::new(RefCell::new(clip))
}
pub fn new_with_data(
tag_stream: swf::read::Reader<Cursor<Vec<u8>>>,
num_frames: u16,
) -> MovieClip {
pub fn new_with_data(tag_stream_start: u64, num_frames: u16) -> MovieClip {
info!("start: {} ", tag_stream_start);
MovieClip {
tag_stream: Some(tag_stream),
tag_stream_start: Some(tag_stream_start),
tag_stream_pos: tag_stream_start,
is_playing: true,
matrix: Matrix::default(),
current_frame: 1,
current_frame: 0,
next_frame: 1,
total_frames: num_frames,
children: HashMap::new(),
}
}
fn run_place_object(&mut self, place_object: &swf::PlaceObject, library: &Library) {
pub fn run_place_object(
children: &mut HashMap<Depth, Cc<RefCell<DisplayObjectNode>>>,
place_object: &swf::PlaceObject,
context: &mut UpdateContext,
) {
use swf::PlaceObjectAction;
match place_object.action {
let mut character = match place_object.action {
PlaceObjectAction::Place(id) => {
// TODO(Herschel): Behavior when character doesn't exist/isn't a DisplayObject?
let mut character = library.instantiate_display_object(id).unwrap();
let character =
if let Ok(mut character) = context.library.instantiate_display_object(id) {
Cc::new(RefCell::new(character))
} else {
return;
};
// TODO(Herschel): Behavior when depth is occupied? (I think it replaces)
self.children
.insert(place_object.depth, Cc::new(RefCell::new(character)));
children.insert(place_object.depth, character.clone());
character
}
PlaceObjectAction::Modify => {
if let Some(child) = children.get(&place_object.depth) {
child.clone()
} else {
return;
}
}
PlaceObjectAction::Modify => (),
PlaceObjectAction::Replace(id) => {
let mut character = library.instantiate_display_object(id).unwrap();
let character =
if let Ok(mut character) = context.library.instantiate_display_object(id) {
Cc::new(RefCell::new(character))
} else {
return;
};
// TODO(Herschel): Behavior when depth is occupied? (I think it replaces)
self.children
.insert(place_object.depth, Cc::new(RefCell::new(character)));
children.insert(place_object.depth, character.clone());
character
}
};
let mut character = character.borrow_mut();
if let Some(matrix) = &place_object.matrix {
let m = matrix.clone();
character.set_matrix(Matrix::from(m));
}
}
}
impl DisplayObject for MovieClip {
fn run_frame(&mut self, library: &Library) {
use swf::Tag;
if self.tag_stream.is_some() {
while let Ok(Some(tag)) = self.tag_stream.as_mut().unwrap().read_tag() {
trace!("{:?}", tag);
fn run_frame(&mut self, context: &mut UpdateContext) {
use swf::{read::SwfRead, Tag};
if self.tag_stream_start.is_some() {
context
.position_stack
.push(context.tag_stream.get_ref().position());
context
.tag_stream
.get_inner()
.set_position(self.tag_stream_pos);
while let Ok(Some(tag)) = context.tag_stream.read_tag() {
//trace!("mc: {:?}", tag);
match tag {
Tag::ShowFrame => break,
Tag::PlaceObject(place_object) => {
self.run_place_object(&*place_object, library)
}
_ => unimplemented!("Umimplemented tag: {:?}", tag),
MovieClip::run_place_object(&mut self.children, &*place_object, context)
}
Tag::RemoveObject {
depth,
character_id,
} => {
// TODO(Herschel): How does the character ID work for RemoveObject?
self.children.remove(&depth);
info!("REMOVE {} {}", depth, self.children.len());
}
Tag::JpegTables(_) => (),
Tag::SoundStreamHead(_) => (),
Tag::SoundStreamHead2(_) => (),
Tag::SoundStreamBlock(_) => (),
Tag::DoAction(_) => (),
_ => info!("Umimplemented tag: {:?}", tag),
}
}
self.tag_stream_pos = context.tag_stream.get_ref().position();
context
.tag_stream
.get_inner()
.set_position(context.position_stack.pop().unwrap());
// Advance frame number.
self.current_frame += 1;
if self.current_frame < self.total_frames {
self.current_frame += 1;
if self.next_frame < self.total_frames {
self.next_frame += 1;
} else {
self.current_frame = 1;
//tag_stream.to_inner().set_position(0);
self.next_frame = 1;
if let Some(start) = self.tag_stream_start {
self.tag_stream_pos = start;
}
}
}
// TODO(Herschel): Verify order of execution for parent/children.
// Parent first? Children first? Sorted by depth?
for child in self.children.values() {
child.borrow_mut().run_frame(library);
child.borrow_mut().run_frame(context);
}
}
fn update_frame_number(&mut self) {
self.current_frame = self.next_frame;
for child in self.children.values() {
child.borrow_mut().update_frame_number();
}
}
fn render(&self, context: &mut RenderContext) {
context.matrix_stack.push(&self.matrix);
let world_matrix = context.matrix_stack.matrix();
context
.context_2d
.transform(
world_matrix.a.into(),
world_matrix.b.into(),
world_matrix.c.into(),
world_matrix.d.into(),
world_matrix.tx.into(),
world_matrix.ty.into(),
)
.unwrap();
for child in self.children.values() {
child.borrow_mut().render(context);
let mut sorted_children: Vec<_> = self.children.iter().collect();
sorted_children.sort_by_key(|(depth, _)| *depth);
for child in sorted_children {
child.1.borrow_mut().render(context);
}
context.matrix_stack.pop();
}
fn set_matrix(&mut self, matrix: Matrix) {
self.matrix = matrix;
}
}
impl Trace for MovieClip {

View File

@ -1,23 +1,27 @@
use crate::Matrix;
use std::collections::{HashMap, VecDeque};
use svg::node::element::{path::Data, Definitions, LinearGradient, Path as SvgPath, Stop};
use svg::node::element::{
path::Data, Definitions, Image, LinearGradient, Path as SvgPath, Pattern, RadialGradient, Stop,
};
use svg::Document;
use swf::{Color, FillStyle, LineStyle, Shape};
pub fn swf_shape_to_svg(shape: &Shape) -> String {
//let mut svg = String::new();
let mut document = Document::new()
.set("width", shape.shape_bounds.x_max - shape.shape_bounds.x_min)
.set(
"height",
let (width, height) = (
shape.shape_bounds.x_max - shape.shape_bounds.x_min,
shape.shape_bounds.y_max - shape.shape_bounds.y_min,
)
);
let mut document = Document::new()
.set("width", width)
.set("height", height)
.set(
"viewBox",
(
shape.shape_bounds.x_min,
shape.shape_bounds.y_min,
shape.shape_bounds.x_max - shape.shape_bounds.x_min,
shape.shape_bounds.y_max - shape.shape_bounds.y_min,
width,
height,
),
);
@ -33,19 +37,34 @@ pub fn swf_shape_to_svg(shape: &Shape) -> String {
match path.fill_style {
FillStyle::Color(Color { r, g, b, a }) => format!("rgba({},{},{},{})", r, g, b, a),
FillStyle::LinearGradient(gradient) => {
let x1 = 0.0;
let y1 = 0.0;
let x2 = 1.0;
let y2 = 1.0;
let matrix = Matrix::from(gradient.matrix);
let shift = Matrix {
a: 1638.4 / width,
d: 1638.4 / height,
tx: -819.2,
ty: -819.2,
..Default::default()
};
let gradient_matrix = matrix * shift;
let mut svg_gradient = LinearGradient::new()
.set("id", format!("f{}", num_defs))
.set("x1", x1)
.set("y1", y1)
.set("x2", x2)
.set("y2", y2);
.set("gradientUnits", "userSpaceOnUse")
.set(
"gradientTransform",
format!(
"matrix({} {} {} {} {} {})",
gradient_matrix.a,
gradient_matrix.b,
gradient_matrix.c,
gradient_matrix.d,
gradient_matrix.tx,
gradient_matrix.ty
),
);
for record in &gradient.records {
let stop = Stop::new()
.set("offset", format!("{}%", f32::from(record.ratio) / 255.0))
.set("offset", format!("{}%", f32::from(record.ratio) / 2.55))
.set(
"stop-color",
format!(
@ -61,7 +80,116 @@ pub fn swf_shape_to_svg(shape: &Shape) -> String {
num_defs += 1;
fill_id
}
_ => unimplemented!(),
FillStyle::RadialGradient(gradient) => {
let matrix = Matrix::from(gradient.matrix);
let shift = Matrix {
a: 1638.4 / width,
d: 1638.4 / height,
tx: -819.2,
ty: -819.2,
..Default::default()
};
let gradient_matrix = matrix * shift;
let mut svg_gradient = RadialGradient::new()
.set("id", format!("f{}", num_defs))
.set("gradientUnits", "userSpaceOnUse")
.set(
"gradientTransform",
format!(
"matrix({} {} {} {} {} {})",
gradient_matrix.a,
gradient_matrix.b,
gradient_matrix.c,
gradient_matrix.d,
gradient_matrix.tx,
gradient_matrix.ty
),
);
for record in &gradient.records {
let stop = Stop::new()
.set("offset", format!("{}%", f32::from(record.ratio) / 2.55))
.set(
"stop-color",
format!(
"rgba({},{},{},{})",
record.color.r, record.color.g, record.color.b, record.color.a
),
);
svg_gradient = svg_gradient.add(stop);
}
defs = defs.add(svg_gradient);
let fill_id = format!("url(#f{})", num_defs);
num_defs += 1;
fill_id
}
FillStyle::FocalGradient {
gradient,
focal_point,
} => {
let matrix = Matrix::from(gradient.matrix);
let shift = Matrix {
a: 1638.4 / width,
d: 1638.4 / height,
tx: -819.2,
ty: -819.2,
..Default::default()
};
let gradient_matrix = matrix * shift;
let mut svg_gradient = RadialGradient::new()
.set("id", format!("f{}", num_defs))
.set("fx", -focal_point)
.set("gradientUnits", "userSpaceOnUse")
.set(
"gradientTransform",
format!(
"matrix({} {} {} {} {} {})",
gradient_matrix.a,
gradient_matrix.b,
gradient_matrix.c,
gradient_matrix.d,
gradient_matrix.tx,
gradient_matrix.ty
),
);
for record in &gradient.records {
let stop = Stop::new()
.set("offset", format!("{}%", f32::from(record.ratio) / 2.55))
.set(
"stop-color",
format!(
"rgba({},{},{},{})",
record.color.r, record.color.g, record.color.b, record.color.a
),
);
svg_gradient = svg_gradient.add(stop);
}
defs = defs.add(svg_gradient);
let fill_id = format!("url(#f{})", num_defs);
num_defs += 1;
fill_id
}
FillStyle::Bitmap {
id,
matrix,
is_smoothed,
is_repeating,
} => {
let svg_image = Image::new(); // TODO: .set("xlink:href", "");
let svg_pattern = Pattern::new()
.set("id", format!("f{}", num_defs))
.add(svg_image);
defs = defs.add(svg_pattern);
let fill_id = format!("url(#f{})", num_defs);
num_defs += 1;
fill_id
}
},
);

61
www/package-lock.json generated
View File

@ -574,7 +574,7 @@
},
"browserify-aes": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
@ -611,7 +611,7 @@
},
"browserify-rsa": {
"version": "4.0.1",
"resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
"requires": {
@ -645,7 +645,7 @@
},
"buffer": {
"version": "4.9.1",
"resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
@ -1075,7 +1075,7 @@
},
"create-hash": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
@ -1088,7 +1088,7 @@
},
"create-hmac": {
"version": "1.1.7",
"resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
@ -1347,7 +1347,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
"resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
@ -1521,7 +1521,7 @@
},
"events": {
"version": "3.0.0",
"resolved": "http://registry.npmjs.org/events/-/events-3.0.0.tgz",
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
"integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==",
"dev": true
},
@ -1964,14 +1964,14 @@
"dev": true
},
"fsevents": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
"integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==",
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.8.tgz",
"integrity": "sha512-tPvHgPGB7m40CZ68xqFGkKuzN+RnpGmSV+hgeKxhRpbxdqKXUFJGC3yonBOLzQBcJyGpdZFDfCsdOC2KFsXzeA==",
"dev": true,
"optional": true,
"requires": {
"nan": "^2.9.2",
"node-pre-gyp": "^0.10.0"
"nan": "^2.12.1",
"node-pre-gyp": "^0.12.0"
},
"dependencies": {
"abbrev": {
@ -2043,12 +2043,12 @@
"optional": true
},
"debug": {
"version": "2.6.9",
"version": "4.1.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ms": "2.0.0"
"ms": "^2.1.1"
}
},
"deep-extend": {
@ -2213,24 +2213,31 @@
}
},
"ms": {
"version": "2.0.0",
"version": "2.1.1",
"bundled": true,
"dev": true,
"optional": true
},
"nan": {
"version": "2.13.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
"integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==",
"dev": true,
"optional": true
},
"needle": {
"version": "2.2.4",
"version": "2.3.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"debug": "^2.1.2",
"debug": "^4.1.0",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
}
},
"node-pre-gyp": {
"version": "0.10.3",
"version": "0.12.0",
"bundled": true,
"dev": true,
"optional": true,
@ -2258,13 +2265,13 @@
}
},
"npm-bundled": {
"version": "1.0.5",
"version": "1.0.6",
"bundled": true,
"dev": true,
"optional": true
},
"npm-packlist": {
"version": "1.2.0",
"version": "1.4.1",
"bundled": true,
"dev": true,
"optional": true,
@ -2400,7 +2407,7 @@
"optional": true
},
"semver": {
"version": "5.6.0",
"version": "5.7.0",
"bundled": true,
"dev": true,
"optional": true
@ -3783,7 +3790,7 @@
},
"parse-asn1": {
"version": "5.1.4",
"resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
"integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
"dev": true,
"requires": {
@ -4380,7 +4387,7 @@
},
"sha.js": {
"version": "2.4.11",
"resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
@ -5353,12 +5360,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -5378,7 +5387,8 @@
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
@ -5526,6 +5536,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}

View File

@ -27,10 +27,10 @@
},
"homepage": "https://github.com/rustwasm/create-wasm-app#readme",
"devDependencies": {
"copy-webpack-plugin": "^5.0.0",
"hello-wasm-pack": "^0.1.0",
"webpack": "^4.29.3",
"webpack": "^4.30.0",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5",
"copy-webpack-plugin": "^5.0.0"
"webpack-dev-server": "^3.1.5"
}
}