diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..4e9f5f8fb --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "web/slide_puzzle"] + path = web/slide_puzzle + url = git@github.com:kevmoo/slide_puzzle.git diff --git a/web/slide_puzzle b/web/slide_puzzle new file mode 160000 index 000000000..5ef5526ac --- /dev/null +++ b/web/slide_puzzle @@ -0,0 +1 @@ +Subproject commit 5ef5526acb58f9ffb6f3fb22118cbd825613dc73 diff --git a/web/slide_puzzle/README.md b/web/slide_puzzle/README.md deleted file mode 100644 index 998c2fa12..000000000 --- a/web/slide_puzzle/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Get the numbers in order by clicking tiles next to the open space. - -Created by [Kevin Moore](https://twitter.com/kevmoo). Original source at -[github.com/kevmoo/slide_puzzle](https://github.com/kevmoo/slide_puzzle). diff --git a/web/slide_puzzle/asset/fonts/plaster/OFL.txt b/web/slide_puzzle/asset/fonts/plaster/OFL.txt deleted file mode 100755 index e0d637407..000000000 --- a/web/slide_puzzle/asset/fonts/plaster/OFL.txt +++ /dev/null @@ -1,94 +0,0 @@ -Copyright (c) 2011 by Sorkin Type Co (www.sorkintype.com), -with Reserved Font Name "Plaster". - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/web/slide_puzzle/asset/fonts/plaster/Plaster-Regular.ttf b/web/slide_puzzle/asset/fonts/plaster/Plaster-Regular.ttf deleted file mode 100755 index eb49b39c6..000000000 Binary files a/web/slide_puzzle/asset/fonts/plaster/Plaster-Regular.ttf and /dev/null differ diff --git a/web/slide_puzzle/asset/seattle.jpg b/web/slide_puzzle/asset/seattle.jpg deleted file mode 100644 index 18f3880be..000000000 Binary files a/web/slide_puzzle/asset/seattle.jpg and /dev/null differ diff --git a/web/slide_puzzle/lib/main.dart b/web/slide_puzzle/lib/main.dart deleted file mode 100644 index 2a3e8ee50..000000000 --- a/web/slide_puzzle/lib/main.dart +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'src/core/puzzle_animator.dart'; -import 'src/flutter.dart'; -import 'src/puzzle_home_state.dart'; - -void main() => runApp(PuzzleApp()); - -class PuzzleApp extends StatelessWidget { - final int rows, columns; - - PuzzleApp({int columns = 4, int rows = 4}) - : columns = columns ?? 4, - rows = rows ?? 4; - - @override - Widget build(BuildContext context) => MaterialApp( - title: 'Slide Puzzle', - home: _PuzzleHome(rows, columns), - ); -} - -class _PuzzleHome extends StatefulWidget { - final int _rows, _columns; - - const _PuzzleHome(this._rows, this._columns); - - @override - PuzzleHomeState createState() => - PuzzleHomeState(PuzzleAnimator(_columns, _rows)); -} diff --git a/web/slide_puzzle/lib/src/app_state.dart b/web/slide_puzzle/lib/src/app_state.dart deleted file mode 100644 index 7f9191e61..000000000 --- a/web/slide_puzzle/lib/src/app_state.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/foundation.dart'; - -import 'core/puzzle_proxy.dart'; - -abstract class AppState { - PuzzleProxy get puzzle; - - Listenable get animationNotifier; -} diff --git a/web/slide_puzzle/lib/src/core/body.dart b/web/slide_puzzle/lib/src/core/body.dart deleted file mode 100644 index 851439cf5..000000000 --- a/web/slide_puzzle/lib/src/core/body.dart +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:math' show Point; - -const zeroPoint = Point(0, 0); - -const _epsilon = 0.0001; - -/// Represents a point object with a location and velocity. -class Body { - Point _velocity; - Point _location; - - Point get velocity => _velocity; - - Point get location => _location; - - Body({Point location = zeroPoint, Point velocity = zeroPoint}) - : assert(location.magnitude.isFinite), - _location = location, - assert(velocity.magnitude.isFinite), - _velocity = velocity; - - factory Body.raw(double x, double y, double vx, double vy) => - Body(location: Point(x, y), velocity: Point(vx, vy)); - - Body clone() => Body(location: _location, velocity: _velocity); - - /// Add the velocity specified in [delta] to `this`. - void kick(Point delta) { - assert(delta.magnitude.isFinite); - _velocity = delta; - } - - /// [drag] must be greater than or equal to zero. It defines the percent of - /// the previous velocity that is lost every second. - bool animate(double seconds, - {Point force = zeroPoint, - double drag = 0, - double maxVelocity, - Point snapTo}) { - assert(seconds.isFinite && seconds > 0, - 'milliseconds must be finite and > 0 (was $seconds)'); - - force ??= zeroPoint; - assert(force.x.isFinite && force.y.isFinite, 'force must be finite'); - - drag ??= 0; - assert(drag.isFinite && drag >= 0, 'drag must be finiate and >= 0'); - - maxVelocity ??= double.infinity; - assert(maxVelocity > 0, 'maxVelocity must be null or > 0'); - - final dragVelocity = _velocity * (1 - drag * seconds); - - if (_sameDirection(_velocity, dragVelocity)) { - assert(dragVelocity.magnitude <= _velocity.magnitude, - 'Huh? $dragVelocity $_velocity'); - _velocity = dragVelocity; - } else { - _velocity = zeroPoint; - } - - // apply force to velocity - _velocity += force * seconds; - - // apply terminal velocity - if (_velocity.magnitude > maxVelocity) { - _velocity = _unitPoint(_velocity) * maxVelocity; - } - - // update location - final locationDelta = _velocity * seconds; - if (locationDelta.magnitude > _epsilon || - (force.magnitude * seconds) > _epsilon) { - _location += locationDelta; - return true; - } else { - if (snapTo != null && (_location.distanceTo(snapTo) < _epsilon * 2)) { - _location = snapTo; - } - _velocity = zeroPoint; - return false; - } - } - - @override - String toString() => - 'Body @(${_location.x},${_location.y}) ↕(${_velocity.x},${_velocity.y})'; - - @override - bool operator ==(Object other) => - other is Body && - other._location == _location && - other._velocity == _velocity; - - // Since this is a mutable class, a constant value is returned for `hashCode` - // This ensures values don't get lost in a Hashing data structure. - // Note: this means you shouldn't use this type in most Map/Set impls. - @override - int get hashCode => 199; -} - -Point _unitPoint(Point source) { - final result = source * (1 / source.magnitude); - return Point(result.x.isNaN ? 0 : result.x, result.y.isNaN ? 0 : result.y); -} - -bool _sameDirection(Point a, Point b) { - return a.x.sign == b.x.sign && a.y.sign == b.y.sign; -} diff --git a/web/slide_puzzle/lib/src/core/point_int.dart b/web/slide_puzzle/lib/src/core/point_int.dart deleted file mode 100644 index cdaf6fec4..000000000 --- a/web/slide_puzzle/lib/src/core/point_int.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:math' as math; - -class Point extends math.Point { - Point(int x, int y) : super(x, y); - - @override - Point operator +(math.Point other) => Point(x + other.x, y + other.y); -} diff --git a/web/slide_puzzle/lib/src/core/puzzle.dart b/web/slide_puzzle/lib/src/core/puzzle.dart deleted file mode 100644 index e843aa199..000000000 --- a/web/slide_puzzle/lib/src/core/puzzle.dart +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:collection'; -import 'dart:convert'; -import 'dart:math' show Random, max; -import 'dart:typed_data'; - -import 'point_int.dart'; -import 'util.dart'; - -part 'puzzle_simple.dart'; - -part 'puzzle_smart.dart'; - -final _rnd = Random(); - -final _spacesRegexp = RegExp(' +'); - -abstract class Puzzle { - int get width; - - int get length; - - int operator [](int index); - - int indexOf(int value); - - List get _intView; - - List _copyData(); - - Puzzle _newWithValues(List values); - - Puzzle clone(); - - int get height => length ~/ width; - - Puzzle._(); - - factory Puzzle._raw(int width, List source) { - if (source.length <= 16) { - return _PuzzleSmart(width, source); - } - return _PuzzleSimple(width, source); - } - - factory Puzzle.raw(int width, List source) { - requireArgument(width >= 3, 'width', 'Must be at least 3.'); - requireArgument(source.length >= 6, 'source', 'Must be at least 6 items'); - _validate(source); - - return Puzzle._raw(width, source); - } - - factory Puzzle(int width, int height) => - Puzzle.raw(width, _randomList(width, height)); - - factory Puzzle.parse(String input) { - final rows = LineSplitter.split(input).map((line) { - final splits = line.trim().split(_spacesRegexp); - return splits.map(int.parse).toList(); - }).toList(); - - return Puzzle.raw(rows.first.length, rows.expand((row) => row).toList()); - } - - int valueAt(int x, int y) { - final i = _getIndex(x, y); - return this[i]; - } - - int get tileCount => length - 1; - - bool isCorrectPosition(int cellValue) => cellValue == this[cellValue]; - - bool get solvable => isSolvable(width, _intView); - - Puzzle reset({List source}) { - final data = (source == null) - ? _randomizeList(width, _intView) - : Uint8List.fromList(source); - - if (data.length != length) { - throw ArgumentError.value(source, 'source', 'Cannot change the size!'); - } - _validate(data); - if (!isSolvable(width, data)) { - throw ArgumentError.value(source, 'source', 'Not a solvable puzzle.'); - } - - return _newWithValues(data); - } - - int get incorrectTiles { - var count = tileCount; - for (var i = 0; i < tileCount; i++) { - if (isCorrectPosition(i)) { - count--; - } - } - return count; - } - - Point openPosition() => coordinatesOf(tileCount); - - /// A measure of how close the puzzle is to being solved. - /// - /// The sum of all of the distances squared `(x + y)^2 ` each tile has to move - /// to be in the correct position. - /// - /// `0` - you've won! - int get fitness { - var value = 0; - for (var i = 0; i < tileCount; i++) { - if (!isCorrectPosition(i)) { - final correctColumn = i % width; - final correctRow = i ~/ width; - - final index = indexOf(i); - final x = index % width; - final y = index ~/ width; - - final delta = (correctColumn - x).abs() + (correctRow - y).abs(); - - value += delta * delta; - } - } - return value * incorrectTiles; - } - - Puzzle clickRandom({bool vertical}) { - final clickable = clickableValues(vertical: vertical).toList(); - return clickValue(clickable[_rnd.nextInt(clickable.length)]); - } - - Iterable allMovable() => - (clickableValues()..shuffle(_rnd)).map(_clickValue); - - List clickableValues({bool vertical}) { - final open = openPosition(); - final doRow = vertical == null || vertical == false; - final doColumn = vertical == null || vertical; - - final values = - Uint8List((doRow ? (width - 1) : 0) + (doColumn ? (height - 1) : 0)); - - var index = 0; - - if (doRow) { - for (var x = 0; x < width; x++) { - if (x != open.x) { - values[index++] = valueAt(x, open.y); - } - } - } - if (doColumn) { - for (var y = 0; y < height; y++) { - if (y != open.y) { - values[index++] = valueAt(open.x, y); - } - } - } - - return values; - } - - bool _movable(int tileValue) { - if (tileValue == tileCount) { - return false; - } - - final target = coordinatesOf(tileValue); - final lastCoord = openPosition(); - if (lastCoord.x != target.x && lastCoord.y != target.y) { - return false; - } - return true; - } - - Puzzle clickValue(int tileValue) { - if (!_movable(tileValue)) { - return null; - } - return _clickValue(tileValue); - } - - Puzzle _clickValue(int tileValue) { - assert(_movable(tileValue)); - final target = coordinatesOf(tileValue); - - final newStore = _copyData(); - - _shift(newStore, target.x, target.y); - return _newWithValues(newStore); - } - - void _shift(List source, int targetX, int targetY) { - final lastCoord = openPosition(); - final deltaX = lastCoord.x - targetX; - final deltaY = lastCoord.y - targetY; - - if ((deltaX.abs() + deltaY.abs()) > 1) { - final shiftPointX = targetX + deltaX.sign; - final shiftPointY = targetY + deltaY.sign; - _shift(source, shiftPointX, shiftPointY); - _staticSwap(source, targetX, targetY, shiftPointX, shiftPointY); - } else { - _staticSwap(source, lastCoord.x, lastCoord.y, targetX, targetY); - } - } - - void _staticSwap(List source, int ax, int ay, int bx, int by) { - final aIndex = ax + ay * width; - final aValue = source[aIndex]; - final bIndex = bx + by * width; - - source[aIndex] = source[bIndex]; - source[bIndex] = aValue; - } - - Point coordinatesOf(int value) { - final index = indexOf(value); - final x = index % width; - final y = index ~/ width; - assert(_getIndex(x, y) == index); - return Point(x, y); - } - - int _getIndex(int x, int y) { - assert(x >= 0 && x < width); - assert(y >= 0 && y < height); - return x + y * width; - } - - @override - String toString() => _toString(); - - String _toString() { - final grid = List>.generate( - height, - (row) => List.generate( - width, (col) => valueAt(col, row).toString())); - - final longestLength = - grid.expand((r) => r).fold(0, (int l, cell) => max(l, cell.length)); - - return grid - .map((r) => r.map((v) => v.padLeft(longestLength)).join(' ')) - .join('\n'); - } -} - -Uint8List _randomList(int width, int height) => _randomizeList( - width, List.generate(width * height, (i) => i, growable: false)); - -Uint8List _randomizeList(int width, List existing) { - final copy = Uint8List.fromList(existing); - do { - copy.shuffle(_rnd); - } while (!isSolvable(width, copy) || - copy.any((v) => copy[v] == v || copy[v] == existing[v])); - return copy; -} - -void _validate(List source) { - for (var i = 0; i < source.length; i++) { - requireArgument( - source.contains(i), - 'source', - 'Must contain each number from 0 to `length - 1` ' - 'once and only once.'); - } -} diff --git a/web/slide_puzzle/lib/src/core/puzzle_animator.dart b/web/slide_puzzle/lib/src/core/puzzle_animator.dart deleted file mode 100644 index 2ecf0d82e..000000000 --- a/web/slide_puzzle/lib/src/core/puzzle_animator.dart +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'dart:math' show Point, Random; - -import 'body.dart'; -import 'puzzle.dart'; -import 'puzzle_proxy.dart'; - -class PuzzleAnimator implements PuzzleProxy { - final _rnd = Random(); - final List _locations; - final _controller = StreamController(); - bool _nextRandomVertical = true; - Puzzle _puzzle; - int _clickCount = 0; - - bool _stable; - - bool get stable => _stable; - - @override - bool get solved => _puzzle.incorrectTiles == 0; - - @override - int get width => _puzzle.width; - - @override - int get height => _puzzle.height; - - @override - int get length => _puzzle.length; - - @override - int get tileCount => _puzzle.tileCount; - - int get incorrectTiles => _puzzle.incorrectTiles; - - int get clickCount => _clickCount; - - void reset() => _resetCore(); - - Stream get onEvent => _controller.stream; - - @override - bool isCorrectPosition(int value) => _puzzle.isCorrectPosition(value); - - @override - Point location(int index) => _locations[index].location; - - int _lastBadClick; - int _badClickCount = 0; - - PuzzleAnimator(int width, int height) : this._(Puzzle(width, height)); - - PuzzleAnimator._(this._puzzle) - : _locations = List.generate(_puzzle.length, (i) { - return Body.raw( - (_puzzle.width - 1.0) / 2, (_puzzle.height - 1.0) / 2, 0, 0); - }); - - void playRandom() { - if (_puzzle.fitness == 0) { - return; - } - - _puzzle = _puzzle.clickRandom(vertical: _nextRandomVertical); - _nextRandomVertical = !_nextRandomVertical; - _clickCount++; - _controller.add(PuzzleEvent.random); - } - - @override - void clickOrShake(int tileValue) { - if (solved) { - _controller.add(PuzzleEvent.noop); - _shake(tileValue); - _lastBadClick = null; - _badClickCount = 0; - return; - } - - _controller.add(PuzzleEvent.click); - if (!_clickValue(tileValue)) { - _shake(tileValue); - - // This is logic to allow a user to skip to the end – useful for testing - // click on 5 un-movable tiles in a row, but not the same tile twice - // in a row - if (tileValue != _lastBadClick) { - _badClickCount++; - if (_badClickCount >= 5) { - // Do the reset! - final newValues = List.generate(_puzzle.length, (i) { - if (i == _puzzle.tileCount) { - return _puzzle.tileCount - 1; - } else if (i == (_puzzle.tileCount - 1)) { - return _puzzle.tileCount; - } - return i; - }); - _resetCore(source: newValues); - _clickCount = 999; - } - } else { - _badClickCount = 0; - } - _lastBadClick = tileValue; - } else { - _lastBadClick = null; - _badClickCount = 0; - } - } - - void _resetCore({List source}) { - _puzzle = _puzzle.reset(source: source); - _clickCount = 0; - _lastBadClick = null; - _badClickCount = 0; - _controller.add(PuzzleEvent.reset); - } - - bool _clickValue(int value) { - final newPuzzle = _puzzle.clickValue(value); - if (newPuzzle == null) { - return false; - } else { - _clickCount++; - _puzzle = newPuzzle; - return true; - } - } - - void _shake(int tileValue) { - Point deltaDouble; - if (solved) { - deltaDouble = Point(_rnd.nextDouble() - 0.5, _rnd.nextDouble() - 0.5); - } else { - final delta = _puzzle.openPosition() - _puzzle.coordinatesOf(tileValue); - deltaDouble = Point(delta.x.toDouble(), delta.y.toDouble()); - } - deltaDouble *= 0.5 / deltaDouble.magnitude; - - _locations[tileValue].kick(deltaDouble); - } - - void update(Duration timeDelta) { - assert(!timeDelta.isNegative); - assert(timeDelta != Duration.zero); - - var animationSeconds = timeDelta.inMilliseconds / 60.0; - if (animationSeconds == 0) { - animationSeconds = 0.1; - } - assert(animationSeconds > 0); - - _stable = true; - for (var i = 0; i < _puzzle.length; i++) { - final target = _target(i); - final body = _locations[i]; - - _stable = !body.animate(animationSeconds, - force: target - body.location, - drag: .9, - maxVelocity: 1.0, - snapTo: target) && - _stable; - } - } - - Point _target(int item) { - final target = _puzzle.coordinatesOf(item); - return Point(target.x.toDouble(), target.y.toDouble()); - } -} diff --git a/web/slide_puzzle/lib/src/core/puzzle_proxy.dart b/web/slide_puzzle/lib/src/core/puzzle_proxy.dart deleted file mode 100644 index 6bbf02a32..000000000 --- a/web/slide_puzzle/lib/src/core/puzzle_proxy.dart +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:math' show Point; - -enum PuzzleEvent { click, random, reset, noop } - -abstract class PuzzleProxy { - int get width; - - int get height; - - int get length; - - bool get solved; - - void clickOrShake(int tileValue); - - int get tileCount; - - Point location(int index); - - bool isCorrectPosition(int value); -} diff --git a/web/slide_puzzle/lib/src/core/puzzle_simple.dart b/web/slide_puzzle/lib/src/core/puzzle_simple.dart deleted file mode 100644 index fc17a579a..000000000 --- a/web/slide_puzzle/lib/src/core/puzzle_simple.dart +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of 'puzzle.dart'; - -class _PuzzleSimple extends Puzzle { - @override - final int width; - final Uint8List _source; - - _PuzzleSimple(this.width, List source) - : _source = UnmodifiableUint8ListView(Uint8List.fromList(source)), - super._(); - - @override - int indexOf(int value) => _source.indexOf(value); - - @override - List get _intView => _source; - - @override - List _copyData() => Uint8List.fromList(_source); - - @override - Puzzle _newWithValues(List values) => _PuzzleSimple(width, values); - - @override - int operator [](int index) => _source[index]; - - @override - Puzzle clone() => _PuzzleSimple(width, _source); - - @override - int get length => _source.length; - - @override - bool operator ==(other) { - if (other is Puzzle && - other.width == width && - other.length == _source.length) { - for (var i = 0; i < _source.length; i++) { - if (other[i] != _source[i]) { - return false; - } - } - return true; - } - return false; - } - - @override - int get hashCode { - var v = 0; - for (var i = 0; i < _source.length; i++) { - v = (v << 2) + _source[i]; - } - v += v << 3; - v ^= v >> 11; - v += v << 15; - return v; - } -} diff --git a/web/slide_puzzle/lib/src/core/puzzle_smart.dart b/web/slide_puzzle/lib/src/core/puzzle_smart.dart deleted file mode 100644 index 17bd72cfc..000000000 --- a/web/slide_puzzle/lib/src/core/puzzle_smart.dart +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of 'puzzle.dart'; - -mixin _SliceListMixin on ListMixin { - static const _bitsPerValue = 4; - static const _maxShift = _valuesPerCell - 1; - - static const _bitsPerCell = 32; - static const _valuesPerCell = _bitsPerCell ~/ _bitsPerValue; - static const _valueMask = (1 << _bitsPerValue) - 1; - - Uint32List get _data; - - int _cellValue(int index) => _data[index ~/ _valuesPerCell]; - - @override - int operator [](int index) { - /* - final bigValue = _data[index ~/ _valuesPerCell]; - final shiftedValue = - bigValue >> (_maxShift - (index % _valuesPerCell)) * _bitsPerValue; - final flattenedValue = shiftedValue & _valueMask; - return flattenedValue; - */ - return (_cellValue(index) >> - (_maxShift - (index % _valuesPerCell)) * _bitsPerValue) & - _valueMask; - } - - @override - int indexOf(Object value, [int start]) { - for (var i = 0; i < _data.length; i++) { - final cellValue = _data[i]; - for (var j = 0; j < _valuesPerCell; j++) { - final option = - (cellValue >> (_maxShift - j) * _bitsPerValue) & _valueMask; - - if (value == option) { - final k = i * _valuesPerCell + j; - if (k < length && (start == null || k >= start)) { - return k; - } - } - } - } - return -1; - } - - @override - set length(int value) => throw UnsupportedError('immutable, yo!'); -} - -class _SliceList with ListMixin, _SliceListMixin { - @override - final Uint32List _data; - - @override - final int length; - - _SliceList(this.length, this._data); - - @override - void operator []=(int index, int value) { - var cellValue = _cellValue(index); - - // clear out the target bits in `cellValue` - - final sharedShift = - (_SliceListMixin._maxShift - (index % _SliceListMixin._valuesPerCell)) * - _SliceListMixin._bitsPerValue; - - final wipeout = _SliceListMixin._valueMask << sharedShift; - - cellValue &= ~wipeout; - - final newShiftedValue = value << sharedShift; - - cellValue |= newShiftedValue; - - _data[index ~/ _SliceListMixin._valuesPerCell] = cellValue; - } -} - -class _PuzzleSmart extends Puzzle with ListMixin, _SliceListMixin { - static const _bitsPerValue = 4; - static const _maxShift = _valuesPerCell - 1; - - static const _bitsPerCell = 32; - static const _valuesPerCell = _bitsPerCell ~/ _bitsPerValue; - static const _valueMask = (1 << _bitsPerValue) - 1; - - @override - final Uint32List _data; - - @override - final int width; - - @override - final int length; - - int _fitnessCache; - - @override - int get fitness => _fitnessCache ??= super.fitness; - - _PuzzleSmart(this.width, List source) - : length = source.length, - _data = _create(source), - super._(); - - @override - void operator []=(int index, int value) => - throw UnsupportedError('immutable, yo!'); - - @override - List get _intView => this; - - @override - List _copyData() => _SliceList(length, Uint32List.fromList(_data)); - - @override - Puzzle _newWithValues(List values) => _PuzzleSmart(width, values); - - @override - Puzzle clone() => _PuzzleSmart(width, this); - - @override - String toString() => _toString(); - - @override - bool operator ==(other) { - if (other is _PuzzleSmart && - other.width == width && - other._data.length == _data.length) { - for (var i = 0; i < _data.length; i++) { - if (other._data[i] != _data[i]) { - return false; - } - } - return true; - } - if (other is Puzzle && other.width == width && other.length == length) { - for (var i = 0; i < length; i++) { - if (other[i] != this[i]) { - return false; - } - } - return true; - } - return false; - } - - @override - int get hashCode { - var v = 0; - for (var i = 0; i < _data.length; i++) { - v = (v << 2) + _data[i]; - } - v += v << 3; - v ^= v >> 11; - v += v << 15; - return v; - } - - static Uint32List _create(List source) { - if (source is _SliceList) { - return source._data; - } - - final data = Uint32List((source.length / _valuesPerCell).ceil()); - for (var i = 0; i < data.length; i++) { - var value = 0; - for (var j = 0; j < _valuesPerCell; j++) { - final k = i * _valuesPerCell + j; - if (k < source.length) { - // shift the value over 4 bits for item 0, 3 for item 2, etc - final sourceValue = source[k] << ((_maxShift - j) * _bitsPerValue); - value |= sourceValue; - } - } - data[i] = value; - } - return data; - } -} diff --git a/web/slide_puzzle/lib/src/core/util.dart b/web/slide_puzzle/lib/src/core/util.dart deleted file mode 100644 index 331bc6af3..000000000 --- a/web/slide_puzzle/lib/src/core/util.dart +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -void requireArgument(bool truth, String argName, [String message]) { - if (!truth) { - if (message == null || message.isEmpty) { - message = 'value was invalid'; - } - throw ArgumentError('`$argName` - $message'); - } -} - -void requireArgumentNotNull(argument, String argName) { - if (argument == null) { - throw ArgumentError.notNull(argName); - } -} - -// Logic from -// https://www.cs.bham.ac.uk/~mdr/teaching/modules04/java2/TilesSolvability.html -// Used with gratitude! -bool isSolvable(int width, List list) { - final height = list.length ~/ width; - assert(width * height == list.length); - final inversions = _countInversions(list); - - if (width.isOdd) { - return inversions.isEven; - } - - final blankRow = list.indexOf(list.length - 1) ~/ width; - - if ((height - blankRow).isEven) { - return inversions.isOdd; - } else { - return inversions.isEven; - } -} - -int _countInversions(List items) { - final tileCount = items.length - 1; - var score = 0; - for (var i = 0; i < items.length; i++) { - final value = items[i]; - if (value == tileCount) { - continue; - } - - for (var j = i + 1; j < items.length; j++) { - final v = items[j]; - if (v != tileCount && v < value) { - score++; - } - } - } - return score; -} diff --git a/web/slide_puzzle/lib/src/flutter.dart b/web/slide_puzzle/lib/src/flutter.dart deleted file mode 100644 index bd5cb4d53..000000000 --- a/web/slide_puzzle/lib/src/flutter.dart +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -export 'package:flutter/material.dart'; -export 'package:flutter/scheduler.dart' show Ticker; diff --git a/web/slide_puzzle/lib/src/puzzle_controls.dart b/web/slide_puzzle/lib/src/puzzle_controls.dart deleted file mode 100644 index 9c83013fb..000000000 --- a/web/slide_puzzle/lib/src/puzzle_controls.dart +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/foundation.dart'; - -abstract class PuzzleControls implements Listenable { - void reset(); - - int get clickCount; - - int get incorrectTiles; - - bool get autoPlay; - - void Function(bool newValue) get setAutoPlayFunction; -} diff --git a/web/slide_puzzle/lib/src/puzzle_flow_delegate.dart b/web/slide_puzzle/lib/src/puzzle_flow_delegate.dart deleted file mode 100644 index 3d076905e..000000000 --- a/web/slide_puzzle/lib/src/puzzle_flow_delegate.dart +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'core/puzzle_proxy.dart'; -import 'flutter.dart'; - -class PuzzleFlowDelegate extends FlowDelegate { - final Size _tileSize; - final PuzzleProxy _puzzleProxy; - - PuzzleFlowDelegate(this._tileSize, this._puzzleProxy, Listenable repaint) - : super(repaint: repaint); - - @override - Size getSize(BoxConstraints constraints) => Size( - _tileSize.width * _puzzleProxy.width, - _tileSize.height * _puzzleProxy.height); - - @override - BoxConstraints getConstraintsForChild(int i, BoxConstraints constraints) => - BoxConstraints.tight(_tileSize); - - @override - void paintChildren(FlowPaintingContext context) { - for (var i = 0; i < _puzzleProxy.length; i++) { - final tileLocation = _puzzleProxy.location(i); - context.paintChild( - i, - transform: Matrix4.translationValues( - tileLocation.x * _tileSize.width, - tileLocation.y * _tileSize.height, - i.toDouble(), - ), - ); - } - } - - @override - bool shouldRepaint(covariant PuzzleFlowDelegate oldDelegate) => - _tileSize != oldDelegate._tileSize || - !identical(oldDelegate._puzzleProxy, _puzzleProxy); -} diff --git a/web/slide_puzzle/lib/src/puzzle_home_state.dart b/web/slide_puzzle/lib/src/puzzle_home_state.dart deleted file mode 100644 index 497e5f36d..000000000 --- a/web/slide_puzzle/lib/src/puzzle_home_state.dart +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; - -import 'package:provider/provider.dart'; - -import 'app_state.dart'; -import 'core/puzzle_animator.dart'; -import 'core/puzzle_proxy.dart'; -import 'flutter.dart'; -import 'puzzle_controls.dart'; -import 'puzzle_flow_delegate.dart'; -import 'shared_theme.dart'; -import 'themes.dart'; -import 'value_tab_controller.dart'; - -class _PuzzleControls extends ChangeNotifier implements PuzzleControls { - final PuzzleHomeState _parent; - - _PuzzleControls(this._parent); - - @override - bool get autoPlay => _parent._autoPlay; - - void _notify() => notifyListeners(); - - @override - void Function(bool newValue) get setAutoPlayFunction { - if (_parent.puzzle.solved) { - return null; - } - return _parent._setAutoPlay; - } - - @override - int get clickCount => _parent.puzzle.clickCount; - - @override - int get incorrectTiles => _parent.puzzle.incorrectTiles; - - @override - void reset() => _parent.puzzle.reset(); -} - -class PuzzleHomeState extends State - with SingleTickerProviderStateMixin, AppState { - @override - final PuzzleAnimator puzzle; - - @override - final _AnimationNotifier animationNotifier = _AnimationNotifier(); - - Duration _tickerTimeSinceLastEvent = Duration.zero; - Ticker _ticker; - Duration _lastElapsed; - StreamSubscription _puzzleEventSubscription; - - bool _autoPlay = false; - _PuzzleControls _autoPlayListenable; - - PuzzleHomeState(this.puzzle) { - _puzzleEventSubscription = puzzle.onEvent.listen(_onPuzzleEvent); - } - - @override - void initState() { - super.initState(); - _autoPlayListenable = _PuzzleControls(this); - _ticker ??= createTicker(_onTick); - _ensureTicking(); - } - - void _setAutoPlay(bool newValue) { - if (newValue != _autoPlay) { - setState(() { - // Only allow enabling autoPlay if the puzzle is not solved - _autoPlayListenable._notify(); - _autoPlay = newValue && !puzzle.solved; - if (_autoPlay) { - _ensureTicking(); - } - }); - } - } - - @override - Widget build(BuildContext context) => MultiProvider( - providers: [ - Provider.value(value: this), - ListenableProvider.value( - listenable: _autoPlayListenable, - ) - ], - child: Material( - child: Stack( - children: [ - const SizedBox.expand( - child: FittedBox( - fit: BoxFit.cover, - child: Image( - image: AssetImage('asset/seattle.jpg'), - ), - ), - ), - const LayoutBuilder(builder: _doBuild), - ], - ), - ), - ); - - @override - void dispose() { - animationNotifier.dispose(); - _ticker?.dispose(); - _autoPlayListenable?.dispose(); - _puzzleEventSubscription.cancel(); - super.dispose(); - } - - void _onPuzzleEvent(PuzzleEvent e) { - _autoPlayListenable._notify(); - if (e != PuzzleEvent.random) { - _setAutoPlay(false); - } - _tickerTimeSinceLastEvent = Duration.zero; - _ensureTicking(); - setState(() { - // noop - }); - } - - void _ensureTicking() { - if (!_ticker.isTicking) { - _ticker.start(); - } - } - - void _onTick(Duration elapsed) { - if (elapsed == Duration.zero) { - _lastElapsed = elapsed; - } - final delta = elapsed - _lastElapsed; - _lastElapsed = elapsed; - - if (delta.inMilliseconds <= 0) { - // `_delta` may be negative or zero if `elapsed` is zero (first tick) - // or during a restart. Just ignore this case. - return; - } - - _tickerTimeSinceLastEvent += delta; - puzzle.update(delta > _maxFrameDuration ? _maxFrameDuration : delta); - - if (!puzzle.stable) { - animationNotifier.animate(); - } else { - if (!_autoPlay) { - _ticker.stop(); - _lastElapsed = null; - } - } - - if (_autoPlay && - _tickerTimeSinceLastEvent > const Duration(milliseconds: 200)) { - puzzle.playRandom(); - - if (puzzle.solved) { - _setAutoPlay(false); - } - } - } -} - -class _AnimationNotifier extends ChangeNotifier { - void animate() { - notifyListeners(); - } -} - -const _maxFrameDuration = Duration(milliseconds: 34); - -Widget _updateConstraints( - BoxConstraints constraints, Widget Function(bool small) builder) { - const _smallWidth = 580; - - final constraintWidth = - constraints.hasBoundedWidth ? constraints.maxWidth : 1000.0; - - final constraintHeight = - constraints.hasBoundedHeight ? constraints.maxHeight : 1000.0; - - return builder(constraintWidth < _smallWidth || constraintHeight < 690); -} - -Widget _doBuild(BuildContext _, BoxConstraints constraints) => - _updateConstraints(constraints, _doBuildCore); - -Widget _doBuildCore(bool small) => ValueTabController( - values: themes, - child: Consumer( - builder: (_, theme, __) => AnimatedContainer( - duration: puzzleAnimationDuration, - color: theme.puzzleThemeBackground, - child: Center( - child: theme.styledWrapper( - small, - SizedBox( - width: 580, - child: Consumer( - builder: (context, appState, _) => Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - decoration: const BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.black26, - width: 1, - ), - ), - ), - margin: const EdgeInsets.symmetric(horizontal: 20), - child: TabBar( - controller: ValueTabController.of(context), - labelPadding: const EdgeInsets.fromLTRB(0, 20, 0, 12), - labelColor: theme.puzzleAccentColor, - indicatorColor: theme.puzzleAccentColor, - indicatorWeight: 1.5, - unselectedLabelColor: Colors.black.withOpacity(0.6), - tabs: themes - .map((st) => Text( - st.name.toUpperCase(), - style: const TextStyle( - letterSpacing: 0.5, - ), - )) - .toList(), - ), - ), - Flexible( - child: Container( - padding: const EdgeInsets.all(10), - child: Flow( - delegate: PuzzleFlowDelegate( - small ? const Size(90, 90) : const Size(140, 140), - appState.puzzle, - appState.animationNotifier, - ), - children: List.generate( - appState.puzzle.length, - (i) => theme.tileButtonCore( - i, appState.puzzle, small), - ), - ), - ), - ), - Container( - decoration: const BoxDecoration( - border: Border( - top: BorderSide(color: Colors.black26, width: 1), - ), - ), - padding: const EdgeInsets.only( - left: 10, - bottom: 6, - top: 2, - right: 10, - ), - child: Consumer( - builder: (_, controls, __) => - Row(children: theme.bottomControls(controls)), - ), - ) - ], - ), - ), - ), - ), - ), - ), - ), - ); diff --git a/web/slide_puzzle/lib/src/shared_theme.dart b/web/slide_puzzle/lib/src/shared_theme.dart deleted file mode 100644 index 53fdcc120..000000000 --- a/web/slide_puzzle/lib/src/shared_theme.dart +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'core/puzzle_proxy.dart'; -import 'flutter.dart'; -import 'puzzle_controls.dart'; -import 'widgets/material_interior_alt.dart'; - -final puzzleAnimationDuration = kThemeAnimationDuration * 3; - -abstract class SharedTheme { - const SharedTheme(); - - String get name; - - Color get puzzleThemeBackground; - - RoundedRectangleBorder puzzleBorder(bool small); - - Color get puzzleBackgroundColor; - - Color get puzzleAccentColor; - - EdgeInsetsGeometry tilePadding(PuzzleProxy puzzle) => const EdgeInsets.all(6); - - Widget tileButton(int i, PuzzleProxy puzzle, bool small); - - Ink createInk( - Widget child, { - DecorationImage image, - EdgeInsetsGeometry padding, - }) => - Ink( - padding: padding, - decoration: BoxDecoration( - image: image, - ), - child: child, - ); - - Widget createButton( - PuzzleProxy puzzle, - bool small, - int tileValue, - Widget content, { - Color color, - RoundedRectangleBorder shape, - }) => - AnimatedContainer( - duration: puzzleAnimationDuration, - padding: tilePadding(puzzle), - child: RaisedButton( - elevation: 4, - clipBehavior: Clip.hardEdge, - animationDuration: puzzleAnimationDuration, - onPressed: () => puzzle.clickOrShake(tileValue), - shape: shape ?? puzzleBorder(small), - padding: const EdgeInsets.symmetric(), - child: content, - color: color, - ), - ); - - // Thought about using AnimatedContainer here, but it causes some weird - // resizing behavior - Widget styledWrapper(bool small, Widget child) => MaterialInterior( - duration: puzzleAnimationDuration, - shape: puzzleBorder(small), - color: puzzleBackgroundColor, - child: child, - ); - - TextStyle get _infoStyle => TextStyle( - color: puzzleAccentColor, - fontWeight: FontWeight.bold, - ); - - List bottomControls(PuzzleControls controls) => [ - IconButton( - onPressed: controls.reset, - icon: Icon(Icons.refresh, color: puzzleAccentColor), - ), - Checkbox( - value: controls.autoPlay, - onChanged: controls.setAutoPlayFunction, - activeColor: puzzleAccentColor, - ), - Expanded( - child: Container(), - ), - Text( - controls.clickCount.toString(), - textAlign: TextAlign.right, - style: _infoStyle, - ), - const Text(' Moves'), - SizedBox( - width: 28, - child: Text( - controls.incorrectTiles.toString(), - textAlign: TextAlign.right, - style: _infoStyle, - ), - ), - const Text(' Tiles left ') - ]; - - Widget tileButtonCore(int i, PuzzleProxy puzzle, bool small) { - if (i == puzzle.tileCount && !puzzle.solved) { - return const Center(); - } - - return tileButton(i, puzzle, small); - } -} diff --git a/web/slide_puzzle/lib/src/theme_plaster.dart b/web/slide_puzzle/lib/src/theme_plaster.dart deleted file mode 100644 index 15614aa75..000000000 --- a/web/slide_puzzle/lib/src/theme_plaster.dart +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'core/puzzle_proxy.dart'; -import 'flutter.dart'; -import 'shared_theme.dart'; - -const _yellowIsh = Color.fromARGB(255, 248, 244, 233); -const _chocolate = Color.fromARGB(255, 66, 66, 68); -const _orangeIsh = Color.fromARGB(255, 224, 107, 83); - -class ThemePlaster extends SharedTheme { - @override - String get name => 'Plaster'; - - const ThemePlaster(); - - @override - Color get puzzleThemeBackground => _chocolate; - - @override - Color get puzzleBackgroundColor => _yellowIsh; - - @override - Color get puzzleAccentColor => _orangeIsh; - - @override - RoundedRectangleBorder puzzleBorder(bool small) => RoundedRectangleBorder( - side: const BorderSide( - color: Color.fromARGB(255, 103, 103, 105), - width: 8, - ), - borderRadius: BorderRadius.all( - Radius.circular(small ? 10 : 18), - ), - ); - - @override - Widget tileButton(int i, PuzzleProxy puzzle, bool small) { - final correctColumn = i % puzzle.width; - final correctRow = i ~/ puzzle.width; - - final primary = (correctColumn + correctRow).isEven; - - if (i == puzzle.tileCount) { - assert(puzzle.solved); - return Center( - child: Icon( - Icons.thumb_up, - size: small ? 50 : 72, - color: _orangeIsh, - ), - ); - } - - final content = Text( - (i + 1).toString(), - style: TextStyle( - color: primary ? _yellowIsh : _chocolate, - fontFamily: 'Plaster', - fontSize: small ? 40 : 77, - ), - ); - - return createButton( - puzzle, - small, - i, - content, - color: primary ? _orangeIsh : _yellowIsh, - shape: RoundedRectangleBorder( - side: BorderSide(color: primary ? _chocolate : _orangeIsh, width: 5), - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/web/slide_puzzle/lib/src/theme_seattle.dart b/web/slide_puzzle/lib/src/theme_seattle.dart deleted file mode 100644 index 8204298e1..000000000 --- a/web/slide_puzzle/lib/src/theme_seattle.dart +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'core/puzzle_proxy.dart'; -import 'flutter.dart'; -import 'shared_theme.dart'; -import 'widgets/decoration_image_plus.dart'; - -class ThemeSeattle extends SharedTheme { - @override - String get name => 'Seattle'; - - const ThemeSeattle(); - - @override - Color get puzzleThemeBackground => const Color.fromARGB(153, 90, 135, 170); - - @override - Color get puzzleBackgroundColor => Colors.white70; - - @override - Color get puzzleAccentColor => const Color(0xff000579f); - - @override - RoundedRectangleBorder puzzleBorder(bool small) => - const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(1), - ), - ); - - @override - EdgeInsetsGeometry tilePadding(PuzzleProxy puzzle) => - puzzle.solved ? const EdgeInsets.all(1) : const EdgeInsets.all(4); - - @override - Widget tileButton(int i, PuzzleProxy puzzle, bool small) { - if (i == puzzle.tileCount && !puzzle.solved) { - assert(puzzle.solved); - } - - final decorationImage = DecorationImagePlus( - puzzleWidth: puzzle.width, - puzzleHeight: puzzle.height, - pieceIndex: i, - fit: BoxFit.cover, - image: const AssetImage('asset/seattle.jpg')); - - final correctPosition = puzzle.isCorrectPosition(i); - final content = createInk( - puzzle.solved - ? const Center() - : Container( - decoration: ShapeDecoration( - shape: const CircleBorder(), - color: correctPosition ? Colors.black38 : Colors.white54, - ), - alignment: Alignment.center, - child: Text( - (i + 1).toString(), - style: TextStyle( - fontWeight: FontWeight.normal, - color: correctPosition ? Colors.white : Colors.black, - fontSize: small ? 25 : 42, - ), - ), - ), - image: decorationImage, - padding: EdgeInsets.all(small ? 20 : 32), - ); - - return createButton(puzzle, small, i, content); - } -} diff --git a/web/slide_puzzle/lib/src/theme_simple.dart b/web/slide_puzzle/lib/src/theme_simple.dart deleted file mode 100644 index 7ba20257b..000000000 --- a/web/slide_puzzle/lib/src/theme_simple.dart +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'core/puzzle_proxy.dart'; -import 'flutter.dart'; -import 'shared_theme.dart'; - -const _accentBlue = Color(0xff000579e); - -class ThemeSimple extends SharedTheme { - @override - String get name => 'Simple'; - - const ThemeSimple(); - - @override - Color get puzzleThemeBackground => Colors.white; - - @override - Color get puzzleBackgroundColor => Colors.white70; - - @override - Color get puzzleAccentColor => _accentBlue; - - @override - RoundedRectangleBorder puzzleBorder(bool small) => - const RoundedRectangleBorder( - side: BorderSide(color: Colors.black26, width: 1), - borderRadius: BorderRadius.all( - Radius.circular(4), - ), - ); - - @override - Widget tileButton(int i, PuzzleProxy puzzle, bool small) { - if (i == puzzle.tileCount) { - assert(puzzle.solved); - return const Center( - child: Icon( - Icons.thumb_up, - size: 72, - color: _accentBlue, - ), - ); - } - - final correctPosition = puzzle.isCorrectPosition(i); - - final content = createInk( - Center( - child: Text( - (i + 1).toString(), - style: TextStyle( - color: Colors.white, - fontWeight: correctPosition ? FontWeight.bold : FontWeight.normal, - fontSize: small ? 30 : 49, - ), - ), - ), - ); - - return createButton( - puzzle, - small, - i, - content, - color: const Color.fromARGB(255, 13, 87, 155), - ); - } -} diff --git a/web/slide_puzzle/lib/src/themes.dart b/web/slide_puzzle/lib/src/themes.dart deleted file mode 100644 index ec9bbea85..000000000 --- a/web/slide_puzzle/lib/src/themes.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'theme_plaster.dart'; -import 'theme_seattle.dart'; -import 'theme_simple.dart'; - -const themes = [ - ThemeSimple(), - ThemeSeattle(), - ThemePlaster(), -]; diff --git a/web/slide_puzzle/lib/src/value_tab_controller.dart b/web/slide_puzzle/lib/src/value_tab_controller.dart deleted file mode 100644 index 7463e5a40..000000000 --- a/web/slide_puzzle/lib/src/value_tab_controller.dart +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class ValueTabController extends StatefulWidget { - /// Creates a default tab controller for the given [child] widget. - const ValueTabController({ - Key key, - @required this.child, - @required this.values, - }) : super(key: key); - - /// The widget below this widget in the tree. - /// - /// Typically a [Scaffold] whose [AppBar] includes a [TabBar]. - /// - /// {@macro flutter.widgets.child} - final Widget child; - - final List values; - - /// The closest instance of this class that encloses the given context. - /// - /// Typical usage: - /// - /// ```dart - /// TabController controller = DefaultTabBarController.of(context); - /// ``` - static TabController of(BuildContext context) { - final scope = context.inheritFromWidgetOfExactType(_ValueTabControllerScope) - as _ValueTabControllerScope; - return scope?.controller; - } - - @override - _ValueTabControllerState createState() => _ValueTabControllerState(); -} - -class _ValueTabControllerState extends State> - with SingleTickerProviderStateMixin { - final _notifier = ValueNotifier(null); - - TabController _controller; - - @override - void initState() { - super.initState(); - _controller = TabController( - vsync: this, - length: widget.values.length, - initialIndex: 0, - ); - - _notifier.value = widget.values.first; - - _controller.addListener(() { - _notifier.value = widget.values[_controller.index]; - }); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) => _ValueTabControllerScope( - controller: _controller, - enabled: TickerMode.of(context), - child: ValueListenableProvider.value( - valueListenable: _notifier, - child: widget.child, - ), - ); -} - -class _ValueTabControllerScope extends InheritedWidget { - const _ValueTabControllerScope( - {Key key, this.controller, this.enabled, Widget child}) - : super(key: key, child: child); - - final TabController controller; - final bool enabled; - - @override - bool updateShouldNotify(_ValueTabControllerScope old) => - enabled != old.enabled || controller != old.controller; -} diff --git a/web/slide_puzzle/lib/src/widgets/decoration_image_plus.dart b/web/slide_puzzle/lib/src/widgets/decoration_image_plus.dart deleted file mode 100644 index 868c28ea5..000000000 --- a/web/slide_puzzle/lib/src/widgets/decoration_image_plus.dart +++ /dev/null @@ -1,334 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// ignore_for_file: omit_local_variable_types, annotate_overrides - -import 'dart:developer' as developer; -import 'dart:ui' as ui show Image; - -import '../flutter.dart'; - -// A model on top of DecorationImage that supports slicing up the source image -// efficiently to draw it as tiles in the puzzle game -@immutable -class DecorationImagePlus implements DecorationImage { - final int puzzleWidth, puzzleHeight, pieceIndex; - - /// Creates an image to show in a [BoxDecoration]. - /// - /// The [image], [alignment], [repeat], and [matchTextDirection] arguments - /// must not be null. - const DecorationImagePlus({ - @required this.image, - @required this.puzzleWidth, - @required this.puzzleHeight, - @required this.pieceIndex, - this.colorFilter, - this.fit, - this.alignment = Alignment.center, - this.centerSlice, - this.repeat = ImageRepeat.noRepeat, - this.matchTextDirection = false, - }) : assert(image != null), - assert(alignment != null), - assert(repeat != null), - assert(matchTextDirection != null), - assert(puzzleHeight > 1 && - puzzleHeight > 1 && - pieceIndex >= 0 && - pieceIndex < (puzzleHeight * puzzleWidth)); - - /// The image to be painted into the decoration. - /// - /// Typically this will be an [AssetImage] (for an image shipped with the - /// application) or a [NetworkImage] (for an image obtained from the network). - final ImageProvider image; - - /// A color filter to apply to the image before painting it. - final ColorFilter colorFilter; - - /// How the image should be inscribed into the box. - /// - /// The default is [BoxFit.scaleDown] if [centerSlice] is null, and - /// [BoxFit.fill] if [centerSlice] is not null. - /// - /// See the discussion at [_paintImage] for more details. - final BoxFit fit; - - /// How to align the image within its bounds. - /// - /// The alignment aligns the given position in the image to the given position - /// in the layout bounds. For example, an [Alignment] alignment of (-1.0, - /// -1.0) aligns the image to the top-left corner of its layout bounds, while a - /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the - /// image with the bottom right corner of its layout bounds. Similarly, an - /// alignment of (0.0, 1.0) aligns the bottom middle of the image with the - /// middle of the bottom edge of its layout bounds. - /// - /// To display a subpart of an image, consider using a [CustomPainter] and - /// [Canvas.drawImageRect]. - /// - /// If the [alignment] is [TextDirection]-dependent (i.e. if it is a - /// [AlignmentDirectional]), then a [TextDirection] must be available - /// when the image is painted. - /// - /// Defaults to [Alignment.center]. - /// - /// See also: - /// - /// * [Alignment], a class with convenient constants typically used to - /// specify an [AlignmentGeometry]. - /// * [AlignmentDirectional], like [Alignment] for specifying alignments - /// relative to text direction. - final AlignmentGeometry alignment; - - /// The center slice for a nine-patch image. - /// - /// The region of the image inside the center slice will be stretched both - /// horizontally and vertically to fit the image into its destination. The - /// region of the image above and below the center slice will be stretched - /// only horizontally and the region of the image to the left and right of - /// the center slice will be stretched only vertically. - /// - /// The stretching will be applied in order to make the image fit into the box - /// specified by [fit]. When [centerSlice] is not null, [fit] defaults to - /// [BoxFit.fill], which distorts the destination image size relative to the - /// image's original aspect ratio. Values of [BoxFit] which do not distort the - /// destination image size will result in [centerSlice] having no effect - /// (since the nine regions of the image will be rendered with the same - /// scaling, as if it wasn't specified). - final Rect centerSlice; - - /// How to paint any portions of the box that would not otherwise be covered - /// by the image. - final ImageRepeat repeat; - - /// Whether to paint the image in the direction of the [TextDirection]. - /// - /// If this is true, then in [TextDirection.ltr] contexts, the image will be - /// drawn with its origin in the top left (the "normal" painting direction for - /// images); and in [TextDirection.rtl] contexts, the image will be drawn with - /// a scaling factor of -1 in the horizontal direction so that the origin is - /// in the top right. - final bool matchTextDirection; - - /// Creates a [DecorationImagePainterPlus] for this [DecorationImagePlus]. - /// - /// The `onChanged` argument must not be null. It will be called whenever the - /// image needs to be repainted, e.g. because it is loading incrementally or - /// because it is animated. - DecorationImagePainterPlus createPainter(VoidCallback onChanged) { - assert(onChanged != null); - return DecorationImagePainterPlus._(this, onChanged); - } - - @override - bool operator ==(dynamic other) { - if (identical(this, other)) return true; - return other is DecorationImagePlus && - other.runtimeType == runtimeType && - image == other.image && - colorFilter == other.colorFilter && - fit == other.fit && - alignment == other.alignment && - centerSlice == other.centerSlice && - repeat == other.repeat && - matchTextDirection == other.matchTextDirection; - } - - @override - int get hashCode => hashValues(image, colorFilter, fit, alignment, - centerSlice, repeat, matchTextDirection); - - @override - String toString() { - final List properties = []; - properties.add('$image'); - if (colorFilter != null) properties.add('$colorFilter'); - if (fit != null && - !(fit == BoxFit.fill && centerSlice != null) && - !(fit == BoxFit.scaleDown && centerSlice == null)) { - properties.add('$fit'); - } - properties.add('$alignment'); - if (centerSlice != null) properties.add('centerSlice: $centerSlice'); - if (repeat != ImageRepeat.noRepeat) properties.add('$repeat'); - if (matchTextDirection) properties.add('match text direction'); - return '$runtimeType(${properties.join(", ")})'; - } - - @override - ImageErrorListener get onError => (error, stackTrace) { - developer.log( - 'Failed to load image.\n' - '$error\n' - '$stackTrace', - name: 'slide_puzzle.decoration_image_plus'); - }; -} - -/// The painter for a [DecorationImagePlus]. -/// -/// To obtain a painter, call [DecorationImagePlus.createPainter]. -/// -/// To paint, call [paint]. The `onChanged` callback passed to -/// [DecorationImagePlus.createPainter] will be called if the image needs to paint -/// again (e.g. because it is animated or because it had not yet loaded the -/// first time the [paint] method was called). -/// -/// This object should be disposed using the [dispose] method when it is no -/// longer needed. -class DecorationImagePainterPlus implements DecorationImagePainter { - DecorationImagePainterPlus._(this._details, this._onChanged) - : assert(_details != null); - - final DecorationImagePlus _details; - final VoidCallback _onChanged; - - ImageStream _imageStream; - ImageInfo _image; - - /// Draw the image onto the given canvas. - /// - /// The image is drawn at the position and size given by the `rect` argument. - /// - /// The image is clipped to the given `clipPath`, if any. - /// - /// The `configuration` object is used to resolve the image (e.g. to pick - /// resolution-specific assets), and to implement the - /// [DecorationImagePlus.matchTextDirection] feature. - /// - /// If the image needs to be painted again, e.g. because it is animated or - /// because it had not yet been loaded the first time this method was called, - /// then the `onChanged` callback passed to [DecorationImagePlus.createPainter] - /// will be called. - void paint(Canvas canvas, Rect rect, Path clipPath, - ImageConfiguration configuration) { - assert(canvas != null); - assert(rect != null); - assert(configuration != null); - - if (_details.matchTextDirection) { - assert(() { - // We check this first so that the assert will fire immediately, not just - // when the image is ready. - if (configuration.textDirection == null) { - throw FlutterError( - 'ImageDecoration.matchTextDirection can only be used when a TextDirection is available.\n' - 'When DecorationImagePainter.paint() was called, there was no text direction provided ' - 'in the ImageConfiguration object to match.\n' - 'The DecorationImage was:\n' - ' $_details\n' - 'The ImageConfiguration was:\n' - ' $configuration'); - } - return true; - }()); - } - - final ImageStream newImageStream = _details.image.resolve(configuration); - if (newImageStream.key != _imageStream?.key) { - final listener = ImageStreamListener(_imageListener); - _imageStream?.removeListener(listener); - _imageStream = newImageStream; - _imageStream.addListener(listener); - } - if (_image == null) return; - - if (clipPath != null) { - canvas.save(); - canvas.clipPath(clipPath); - } - - _paintImage( - canvas: canvas, - puzzleWidth: _details.puzzleWidth, - puzzleHeight: _details.puzzleHeight, - pieceIndex: _details.pieceIndex, - rect: rect, - image: _image.image, - scale: _image.scale, - colorFilter: _details.colorFilter, - fit: _details.fit, - alignment: _details.alignment.resolve(configuration.textDirection), - ); - - if (clipPath != null) canvas.restore(); - } - - void _imageListener(ImageInfo value, bool synchronousCall) { - if (_image == value) return; - _image = value; - assert(_onChanged != null); - if (!synchronousCall) _onChanged(); - } - - /// Releases the resources used by this painter. - /// - /// This should be called whenever the painter is no longer needed. - /// - /// After this method has been called, the object is no longer usable. - @mustCallSuper - void dispose() { - _imageStream?.removeListener(ImageStreamListener(_imageListener)); - } - - @override - String toString() { - return '$runtimeType(stream: $_imageStream, image: $_image) for $_details'; - } -} - -void _paintImage( - {@required Canvas canvas, - @required Rect rect, - @required ui.Image image, - @required int puzzleWidth, - @required int puzzleHeight, - @required int pieceIndex, - double scale = 1.0, - ColorFilter colorFilter, - BoxFit fit, - Alignment alignment = Alignment.center}) { - assert(canvas != null); - assert(image != null); - assert(alignment != null); - - if (rect.isEmpty) return; - final outputSize = rect.size; - final inputSize = Size(image.width.toDouble(), image.height.toDouble()); - fit ??= BoxFit.scaleDown; - final FittedSizes fittedSizes = - applyBoxFit(fit, inputSize / scale, outputSize); - final Size sourceSize = fittedSizes.source * scale; - final destinationSize = fittedSizes.destination; - final Paint paint = Paint() - ..isAntiAlias = false - ..filterQuality = FilterQuality.medium; - if (colorFilter != null) paint.colorFilter = colorFilter; - final double halfWidthDelta = - (outputSize.width - destinationSize.width) / 2.0; - final double halfHeightDelta = - (outputSize.height - destinationSize.height) / 2.0; - final double dx = halfWidthDelta + (alignment.x) * halfWidthDelta; - final double dy = halfHeightDelta + alignment.y * halfHeightDelta; - final Offset destinationPosition = rect.topLeft.translate(dx, dy); - final Rect destinationRect = destinationPosition & destinationSize; - final Rect sourceRect = - alignment.inscribe(sourceSize, Offset.zero & inputSize); - - final sliceSize = - Size(sourceRect.width / puzzleWidth, sourceRect.height / puzzleHeight); - - final col = pieceIndex % puzzleWidth; - final row = pieceIndex ~/ puzzleWidth; - - final sliceRect = Rect.fromLTWH( - sourceRect.left + col * sliceSize.width, - sourceRect.top + row * sliceSize.height, - sliceSize.width, - sliceSize.height); - - canvas.drawImageRect(image, sliceRect, destinationRect, paint); -} diff --git a/web/slide_puzzle/lib/src/widgets/material_interior_alt.dart b/web/slide_puzzle/lib/src/widgets/material_interior_alt.dart deleted file mode 100644 index ee0421445..000000000 --- a/web/slide_puzzle/lib/src/widgets/material_interior_alt.dart +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2020, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import '../flutter.dart'; - -// Copied from -// https://github.com/flutter/flutter/blob/f5b02e3c05ed1ab31e890add84fb56e35de2d392/packages/flutter/lib/src/material/material.dart#L593-L715 -// So I could have animated color! -// TODO(kevmoo): file a feature request for this? -class MaterialInterior extends ImplicitlyAnimatedWidget { - const MaterialInterior({ - Key key, - @required this.child, - @required this.shape, - @required this.color, - Curve curve = Curves.linear, - @required Duration duration, - }) : assert(child != null), - assert(shape != null), - assert(color != null), - super(key: key, curve: curve, duration: duration); - - /// The widget below this widget in the tree. - /// - /// {@macro flutter.widgets.child} - final Widget child; - - /// The border of the widget. - /// - /// This border will be painted, and in addition the outer path of the border - /// determines the physical shape. - final ShapeBorder shape; - - /// The target background color. - final Color color; - - @override - _MaterialInteriorState createState() => _MaterialInteriorState(); -} - -class _MaterialInteriorState extends AnimatedWidgetBaseState { - ShapeBorderTween _border; - ColorTween _color; - - @override - void forEachTween(TweenVisitor visitor) { - _border = visitor(_border, widget.shape, - (value) => ShapeBorderTween(begin: value as ShapeBorder)) - as ShapeBorderTween; - _color = visitor( - _color, widget.color, (value) => ColorTween(begin: value as Color)) - as ColorTween; - } - - @override - Widget build(BuildContext context) { - final shape = _border.evaluate(animation); - return PhysicalShape( - child: _ShapeBorderPaint( - child: widget.child, - shape: shape, - ), - clipper: ShapeBorderClipper( - shape: shape, - textDirection: Directionality.of(context), - ), - color: _color.evaluate(animation), - ); - } -} - -class _ShapeBorderPaint extends StatelessWidget { - const _ShapeBorderPaint({ - @required this.child, - @required this.shape, - }); - - final Widget child; - final ShapeBorder shape; - - @override - Widget build(BuildContext context) { - return CustomPaint( - child: child, - foregroundPainter: _ShapeBorderPainter(shape, Directionality.of(context)), - ); - } -} - -class _ShapeBorderPainter extends CustomPainter { - _ShapeBorderPainter(this.border, this.textDirection); - - final ShapeBorder border; - final TextDirection textDirection; - - @override - void paint(Canvas canvas, Size size) { - border.paint(canvas, Offset.zero & size, textDirection: textDirection); - } - - @override - bool shouldRepaint(_ShapeBorderPainter oldDelegate) { - return oldDelegate.border != border; - } -} diff --git a/web/slide_puzzle/pubspec.lock b/web/slide_puzzle/pubspec.lock deleted file mode 100644 index be339bab7..000000000 --- a/web/slide_puzzle/pubspec.lock +++ /dev/null @@ -1,426 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "0.39.8" - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - coverage: - dependency: transitive - description: - name: coverage - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.9" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - csslib: - dependency: transitive - description: - name: csslib - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - html: - dependency: transitive - description: - name: html - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.0+3" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.12" - io: - dependency: transitive - description: - name: io - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.4" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - logging: - dependency: transitive - description: - name: logging - url: "https://pub.dartlang.org" - source: hosted - version: "0.11.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - mime: - dependency: transitive - description: - name: mime - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.6+3" - multi_server_socket: - dependency: transitive - description: - name: multi_server_socket - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - node_preamble: - dependency: transitive - description: - name: node_preamble - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.8" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.4" - pedantic: - dependency: "direct dev" - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - pool: - dependency: transitive - description: - name: pool - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" - provider: - dependency: "direct dev" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1+1" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.4" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - shelf: - dependency: transitive - description: - name: shelf - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.5" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - shelf_static: - dependency: transitive - description: - name: shelf_static - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.8" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - source_maps: - dependency: transitive - description: - name: source_maps - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.9" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test: - dependency: "direct dev" - description: - name: test - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.3" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.15" - test_core: - dependency: transitive - description: - name: test_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.4" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - vm_service: - dependency: transitive - description: - name: vm_service - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7+15" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.3" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.1" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/web/slide_puzzle/pubspec.yaml b/web/slide_puzzle/pubspec.yaml deleted file mode 100644 index e28692e1b..000000000 --- a/web/slide_puzzle/pubspec.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: slide_puzzle - -version: 1.0.0 - -environment: - sdk: ">=2.0.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - pedantic: ^1.3.0 - provider: ^2.0.0 - test: ^1.3.4 - -flutter: - uses-material-design: true - assets: - - asset/ - - fonts: - - family: Plaster - fonts: - - asset: asset/fonts/plaster/Plaster-Regular.ttf diff --git a/web/slide_puzzle/web/index.html b/web/slide_puzzle/web/index.html deleted file mode 100644 index 6bfc669e9..000000000 --- a/web/slide_puzzle/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - slide_puzzle - - - - -