/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "../../node_modules/source-map-js/lib/array-set.js":
/*!*********************************************************!*\
!*** ../../node_modules/source-map-js/lib/array-set.js ***!
\*********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(/*! ./util */ "../../node_modules/source-map-js/lib/util.js");
var has = Object.prototype.hasOwnProperty;
var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
* member is O(1), testing for membership is O(1), and finding the index of an
* element is O(1). Removing elements from the set is not supported. Only
* strings are supported for membership.
*/
function ArraySet() {
this._array = [];
this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
* Static method for creating ArraySet instances from an existing array.
*/
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
var set = new ArraySet();
for (var i = 0, len = aArray.length; i < len; i++) {
set.add(aArray[i], aAllowDuplicates);
}
return set;
};
/**
* Return how many unique items are in this ArraySet. If duplicates have been
* added, than those do not count towards the size.
*
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
* Add the given string to this set.
*
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
if (hasNativeMap) {
this._set.set(aStr, idx);
} else {
this._set[sStr] = idx;
}
}
};
/**
* Is the given string a member of this set?
*
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
if (hasNativeMap) {
return this._set.has(aStr);
} else {
var sStr = util.toSetString(aStr);
return has.call(this._set, sStr);
}
};
/**
* What is the index of the given string in the array?
*
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
if (hasNativeMap) {
var idx = this._set.get(aStr);
if (idx >= 0) {
return idx;
}
} else {
var sStr = util.toSetString(aStr);
if (has.call(this._set, sStr)) {
return this._set[sStr];
}
}
throw new Error('"' + aStr + '" is not in the set.');
};
/**
* What is the element at the given index?
*
* @param Number aIdx
*/
ArraySet.prototype.at = function ArraySet_at(aIdx) {
if (aIdx >= 0 && aIdx < this._array.length) {
return this._array[aIdx];
}
throw new Error('No element indexed by ' + aIdx);
};
/**
* Returns the array representation of this set (which has the proper indices
* indicated by indexOf). Note that this is a copy of the internal array used
* for storing the members so that no one can mess with internal state.
*/
ArraySet.prototype.toArray = function ArraySet_toArray() {
return this._array.slice();
};
exports.ArraySet = ArraySet;
/***/ }),
/***/ "../../node_modules/source-map-js/lib/base64-vlq.js":
/*!**********************************************************!*\
!*** ../../node_modules/source-map-js/lib/base64-vlq.js ***!
\**********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*
* Based on the Base 64 VLQ implementation in Closure Compiler:
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var base64 = __webpack_require__(/*! ./base64 */ "../../node_modules/source-map-js/lib/base64.js");
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
var VLQ_BASE_SHIFT = 5;
// binary: 100000
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
// binary: 011111
var VLQ_BASE_MASK = VLQ_BASE - 1;
// binary: 100000
var VLQ_CONTINUATION_BIT = VLQ_BASE;
/**
* Converts from a two-complement value to a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
*/
function toVLQSigned(aValue) {
return aValue < 0
? ((-aValue) << 1) + 1
: (aValue << 1) + 0;
}
/**
* Converts to a two-complement value from a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
*/
function fromVLQSigned(aValue) {
var isNegative = (aValue & 1) === 1;
var shifted = aValue >> 1;
return isNegative
? -shifted
: shifted;
}
/**
* Returns the base 64 VLQ encoded value.
*/
exports.encode = function base64VLQ_encode(aValue) {
var encoded = "";
var digit;
var vlq = toVLQSigned(aValue);
do {
digit = vlq & VLQ_BASE_MASK;
vlq >>>= VLQ_BASE_SHIFT;
if (vlq > 0) {
// There are still more digits in this value, so we must make sure the
// continuation bit is marked.
digit |= VLQ_CONTINUATION_BIT;
}
encoded += base64.encode(digit);
} while (vlq > 0);
return encoded;
};
/**
* Decodes the next base 64 VLQ value from the given string and returns the
* value and the rest of the string via the out parameter.
*/
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
var strLen = aStr.length;
var result = 0;
var shift = 0;
var continuation, digit;
do {
if (aIndex >= strLen) {
throw new Error("Expected more digits in base 64 VLQ value.");
}
digit = base64.decode(aStr.charCodeAt(aIndex++));
if (digit === -1) {
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
}
continuation = !!(digit & VLQ_CONTINUATION_BIT);
digit &= VLQ_BASE_MASK;
result = result + (digit << shift);
shift += VLQ_BASE_SHIFT;
} while (continuation);
aOutParam.value = fromVLQSigned(result);
aOutParam.rest = aIndex;
};
/***/ }),
/***/ "../../node_modules/source-map-js/lib/base64.js":
/*!******************************************************!*\
!*** ../../node_modules/source-map-js/lib/base64.js ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports) => {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
/**
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
exports.encode = function (number) {
if (0 <= number && number < intToCharMap.length) {
return intToCharMap[number];
}
throw new TypeError("Must be between 0 and 63: " + number);
};
/**
* Decode a single base 64 character code digit to an integer. Returns -1 on
* failure.
*/
exports.decode = function (charCode) {
var bigA = 65; // 'A'
var bigZ = 90; // 'Z'
var littleA = 97; // 'a'
var littleZ = 122; // 'z'
var zero = 48; // '0'
var nine = 57; // '9'
var plus = 43; // '+'
var slash = 47; // '/'
var littleOffset = 26;
var numberOffset = 52;
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
if (bigA <= charCode && charCode <= bigZ) {
return (charCode - bigA);
}
// 26 - 51: abcdefghijklmnopqrstuvwxyz
if (littleA <= charCode && charCode <= littleZ) {
return (charCode - littleA + littleOffset);
}
// 52 - 61: 0123456789
if (zero <= charCode && charCode <= nine) {
return (charCode - zero + numberOffset);
}
// 62: +
if (charCode == plus) {
return 62;
}
// 63: /
if (charCode == slash) {
return 63;
}
// Invalid base64 digit.
return -1;
};
/***/ }),
/***/ "../../node_modules/source-map-js/lib/mapping-list.js":
/*!************************************************************!*\
!*** ../../node_modules/source-map-js/lib/mapping-list.js ***!
\************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2014 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(/*! ./util */ "../../node_modules/source-map-js/lib/util.js");
/**
* Determine whether mappingB is after mappingA with respect to generated
* position.
*/
function generatedPositionAfter(mappingA, mappingB) {
// Optimized for most common case
var lineA = mappingA.generatedLine;
var lineB = mappingB.generatedLine;
var columnA = mappingA.generatedColumn;
var columnB = mappingB.generatedColumn;
return lineB > lineA || lineB == lineA && columnB >= columnA ||
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
}
/**
* A data structure to provide a sorted view of accumulated mappings in a
* performance conscious manner. It trades a neglibable overhead in general
* case for a large speedup in case of mappings being added in order.
*/
function MappingList() {
this._array = [];
this._sorted = true;
// Serves as infimum
this._last = {generatedLine: -1, generatedColumn: 0};
}
/**
* Iterate through internal items. This method takes the same arguments that
* `Array.prototype.forEach` takes.
*
* NOTE: The order of the mappings is NOT guaranteed.
*/
MappingList.prototype.unsortedForEach =
function MappingList_forEach(aCallback, aThisArg) {
this._array.forEach(aCallback, aThisArg);
};
/**
* Add the given source mapping.
*
* @param Object aMapping
*/
MappingList.prototype.add = function MappingList_add(aMapping) {
if (generatedPositionAfter(this._last, aMapping)) {
this._last = aMapping;
this._array.push(aMapping);
} else {
this._sorted = false;
this._array.push(aMapping);
}
};
/**
* Returns the flat, sorted array of mappings. The mappings are sorted by
* generated position.
*
* WARNING: This method returns internal data without copying, for
* performance. The return value must NOT be mutated, and should be treated as
* an immutable borrow. If you want to take ownership, you must make your own
* copy.
*/
MappingList.prototype.toArray = function MappingList_toArray() {
if (!this._sorted) {
this._array.sort(util.compareByGeneratedPositionsInflated);
this._sorted = true;
}
return this._array;
};
exports.MappingList = MappingList;
/***/ }),
/***/ "../../node_modules/source-map-js/lib/source-map-generator.js":
/*!********************************************************************!*\
!*** ../../node_modules/source-map-js/lib/source-map-generator.js ***!
\********************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var base64VLQ = __webpack_require__(/*! ./base64-vlq */ "../../node_modules/source-map-js/lib/base64-vlq.js");
var util = __webpack_require__(/*! ./util */ "../../node_modules/source-map-js/lib/util.js");
var ArraySet = (__webpack_require__(/*! ./array-set */ "../../node_modules/source-map-js/lib/array-set.js").ArraySet);
var MappingList = (__webpack_require__(/*! ./mapping-list */ "../../node_modules/source-map-js/lib/mapping-list.js").MappingList);
/**
* An instance of the SourceMapGenerator represents a source map which is
* being built incrementally. You may pass an object with the following
* properties:
*
* - file: The filename of the generated source.
* - sourceRoot: A root for all relative URLs in this source map.
*/
function SourceMapGenerator(aArgs) {
if (!aArgs) {
aArgs = {};
}
this._file = util.getArg(aArgs, 'file', null);
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
this._sources = new ArraySet();
this._names = new ArraySet();
this._mappings = new MappingList();
this._sourcesContents = null;
}
SourceMapGenerator.prototype._version = 3;
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
*
* @param aSourceMapConsumer The SourceMap.
*/
SourceMapGenerator.fromSourceMap =
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
var sourceRoot = aSourceMapConsumer.sourceRoot;
var generator = new SourceMapGenerator({
file: aSourceMapConsumer.file,
sourceRoot: sourceRoot
});
aSourceMapConsumer.eachMapping(function (mapping) {
var newMapping = {
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn
}
};
if (mapping.source != null) {
newMapping.source = mapping.source;
if (sourceRoot != null) {
newMapping.source = util.relative(sourceRoot, newMapping.source);
}
newMapping.original = {
line: mapping.originalLine,
column: mapping.originalColumn
};
if (mapping.name != null) {
newMapping.name = mapping.name;
}
}
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var sourceRelative = sourceFile;
if (sourceRoot !== null) {
sourceRelative = util.relative(sourceRoot, sourceFile);
}
if (!generator._sources.has(sourceRelative)) {
generator._sources.add(sourceRelative);
}
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
}
});
return generator;
};
/**
* Add a single mapping from original source line and column to the generated
* source's line and column for this source map being created. The mapping
* object should have the following properties:
*
* - generated: An object with the generated line and column positions.
* - original: An object with the original line and column positions.
* - source: The original source file (relative to the sourceRoot).
* - name: An optional original token name for this mapping.
*/
SourceMapGenerator.prototype.addMapping =
function SourceMapGenerator_addMapping(aArgs) {
var generated = util.getArg(aArgs, 'generated');
var original = util.getArg(aArgs, 'original', null);
var source = util.getArg(aArgs, 'source', null);
var name = util.getArg(aArgs, 'name', null);
if (!this._skipValidation) {
this._validateMapping(generated, original, source, name);
}
if (source != null) {
source = String(source);
if (!this._sources.has(source)) {
this._sources.add(source);
}
}
if (name != null) {
name = String(name);
if (!this._names.has(name)) {
this._names.add(name);
}
}
this._mappings.add({
generatedLine: generated.line,
generatedColumn: generated.column,
originalLine: original != null && original.line,
originalColumn: original != null && original.column,
source: source,
name: name
});
};
/**
* Set the source content for a source file.
*/
SourceMapGenerator.prototype.setSourceContent =
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
var source = aSourceFile;
if (this._sourceRoot != null) {
source = util.relative(this._sourceRoot, source);
}
if (aSourceContent != null) {
// Add the source content to the _sourcesContents map.
// Create a new _sourcesContents map if the property is null.
if (!this._sourcesContents) {
this._sourcesContents = Object.create(null);
}
this._sourcesContents[util.toSetString(source)] = aSourceContent;
} else if (this._sourcesContents) {
// Remove the source file from the _sourcesContents map.
// If the _sourcesContents map is empty, set the property to null.
delete this._sourcesContents[util.toSetString(source)];
if (Object.keys(this._sourcesContents).length === 0) {
this._sourcesContents = null;
}
}
};
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map. Note: The resolution for the
* resulting mappings is the minimium of this map and the supplied map.
*
* @param aSourceMapConsumer The source map to be applied.
* @param aSourceFile Optional. The filename of the source file.
* If omitted, SourceMapConsumer's file property will be used.
* @param aSourceMapPath Optional. The dirname of the path to the source map
* to be applied. If relative, it is relative to the SourceMapConsumer.
* This parameter is needed when the two source maps aren't in the same
* directory, and the source map to be applied contains relative source
* paths. If so, those relative source paths need to be rewritten
* relative to the SourceMapGenerator.
*/
SourceMapGenerator.prototype.applySourceMap =
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
var sourceFile = aSourceFile;
// If aSourceFile is omitted, we will use the file property of the SourceMap
if (aSourceFile == null) {
if (aSourceMapConsumer.file == null) {
throw new Error(
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
'or the source map\'s "file" property. Both were omitted.'
);
}
sourceFile = aSourceMapConsumer.file;
}
var sourceRoot = this._sourceRoot;
// Make "sourceFile" relative if an absolute Url is passed.
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
// Applying the SourceMap can add and remove items from the sources and
// the names array.
var newSources = new ArraySet();
var newNames = new ArraySet();
// Find mappings for the "sourceFile"
this._mappings.unsortedForEach(function (mapping) {
if (mapping.source === sourceFile && mapping.originalLine != null) {
// Check if it can be mapped by the source map, then update the mapping.
var original = aSourceMapConsumer.originalPositionFor({
line: mapping.originalLine,
column: mapping.originalColumn
});
if (original.source != null) {
// Copy mapping
mapping.source = original.source;
if (aSourceMapPath != null) {
mapping.source = util.join(aSourceMapPath, mapping.source)
}
if (sourceRoot != null) {
mapping.source = util.relative(sourceRoot, mapping.source);
}
mapping.originalLine = original.line;
mapping.originalColumn = original.column;
if (original.name != null) {
mapping.name = original.name;
}
}
}
var source = mapping.source;
if (source != null && !newSources.has(source)) {
newSources.add(source);
}
var name = mapping.name;
if (name != null && !newNames.has(name)) {
newNames.add(name);
}
}, this);
this._sources = newSources;
this._names = newNames;
// Copy sourcesContents of applied map.
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
if (aSourceMapPath != null) {
sourceFile = util.join(aSourceMapPath, sourceFile);
}
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
this.setSourceContent(sourceFile, content);
}
}, this);
};
/**
* A mapping can have one of the three levels of data:
*
* 1. Just the generated position.
* 2. The Generated position, original position, and original source.
* 3. Generated and original position, original source, as well as a name
* token.
*
* To maintain consistency, we validate that any new mapping being added falls
* in to one of these categories.
*/
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
// When aOriginal is truthy but has empty values for .line and .column,
// it is most likely a programmer error. In this case we throw a very
// specific error message to try to guide them the right way.
// For example: https://github.com/Polymer/polymer-bundler/pull/519
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
throw new Error(
'original.line and original.column are not numbers -- you probably meant to omit ' +
'the original mapping entirely and only map the generated position. If so, pass ' +
'null for the original mapping instead of an object with empty or null values.'
);
}
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
// Case 1.
return;
}
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
&& aGenerated.line > 0 && aGenerated.column >= 0
&& aOriginal.line > 0 && aOriginal.column >= 0
&& aSource) {
// Cases 2 and 3.
return;
}
else {
throw new Error('Invalid mapping: ' + JSON.stringify({
generated: aGenerated,
source: aSource,
original: aOriginal,
name: aName
}));
}
};
/**
* Serialize the accumulated mappings in to the stream of base 64 VLQs
* specified by the source map format.
*/
SourceMapGenerator.prototype._serializeMappings =
function SourceMapGenerator_serializeMappings() {
var previousGeneratedColumn = 0;
var previousGeneratedLine = 1;
var previousOriginalColumn = 0;
var previousOriginalLine = 0;
var previousName = 0;
var previousSource = 0;
var result = '';
var next;
var mapping;
var nameIdx;
var sourceIdx;
var mappings = this._mappings.toArray();
for (var i = 0, len = mappings.length; i < len; i++) {
mapping = mappings[i];
next = ''
if (mapping.generatedLine !== previousGeneratedLine) {
previousGeneratedColumn = 0;
while (mapping.generatedLine !== previousGeneratedLine) {
next += ';';
previousGeneratedLine++;
}
}
else {
if (i > 0) {
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
continue;
}
next += ',';
}
}
next += base64VLQ.encode(mapping.generatedColumn
- previousGeneratedColumn);
previousGeneratedColumn = mapping.generatedColumn;
if (mapping.source != null) {
sourceIdx = this._sources.indexOf(mapping.source);
next += base64VLQ.encode(sourceIdx - previousSource);
previousSource = sourceIdx;
// lines are stored 0-based in SourceMap spec version 3
next += base64VLQ.encode(mapping.originalLine - 1
- previousOriginalLine);
previousOriginalLine = mapping.originalLine - 1;
next += base64VLQ.encode(mapping.originalColumn
- previousOriginalColumn);
previousOriginalColumn = mapping.originalColumn;
if (mapping.name != null) {
nameIdx = this._names.indexOf(mapping.name);
next += base64VLQ.encode(nameIdx - previousName);
previousName = nameIdx;
}
}
result += next;
}
return result;
};
SourceMapGenerator.prototype._generateSourcesContent =
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
return aSources.map(function (source) {
if (!this._sourcesContents) {
return null;
}
if (aSourceRoot != null) {
source = util.relative(aSourceRoot, source);
}
var key = util.toSetString(source);
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
? this._sourcesContents[key]
: null;
}, this);
};
/**
* Externalize the source map.
*/
SourceMapGenerator.prototype.toJSON =
function SourceMapGenerator_toJSON() {
var map = {
version: this._version,
sources: this._sources.toArray(),
names: this._names.toArray(),
mappings: this._serializeMappings()
};
if (this._file != null) {
map.file = this._file;
}
if (this._sourceRoot != null) {
map.sourceRoot = this._sourceRoot;
}
if (this._sourcesContents) {
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
}
return map;
};
/**
* Render the source map being generated to a string.
*/
SourceMapGenerator.prototype.toString =
function SourceMapGenerator_toString() {
return JSON.stringify(this.toJSON());
};
exports.SourceMapGenerator = SourceMapGenerator;
/***/ }),
/***/ "../../node_modules/source-map-js/lib/util.js":
/*!****************************************************!*\
!*** ../../node_modules/source-map-js/lib/util.js ***!
\****************************************************/
/***/ ((__unused_webpack_module, exports) => {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
/**
* This is a helper function for getting values from parameter/options
* objects.
*
* @param args The object we are extracting values from
* @param name The name of the property we are getting.
* @param defaultValue An optional value to return if the property is missing
* from the object. If this is not specified and the property is missing, an
* error will be thrown.
*/
function getArg(aArgs, aName, aDefaultValue) {
if (aName in aArgs) {
return aArgs[aName];
} else if (arguments.length === 3) {
return aDefaultValue;
} else {
throw new Error('"' + aName + '" is a required argument.');
}
}
exports.getArg = getArg;
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
var match = aUrl.match(urlRegexp);
if (!match) {
return null;
}
return {
scheme: match[1],
auth: match[2],
host: match[3],
port: match[4],
path: match[5]
};
}
exports.urlParse = urlParse;
function urlGenerate(aParsedUrl) {
var url = '';
if (aParsedUrl.scheme) {
url += aParsedUrl.scheme + ':';
}
url += '//';
if (aParsedUrl.auth) {
url += aParsedUrl.auth + '@';
}
if (aParsedUrl.host) {
url += aParsedUrl.host;
}
if (aParsedUrl.port) {
url += ":" + aParsedUrl.port
}
if (aParsedUrl.path) {
url += aParsedUrl.path;
}
return url;
}
exports.urlGenerate = urlGenerate;
var MAX_CACHED_INPUTS = 32;
/**
* Takes some function `f(input) -> result` and returns a memoized version of
* `f`.
*
* We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The
* memoization is a dumb-simple, linear least-recently-used cache.
*/
function lruMemoize(f) {
var cache = [];
return function(input) {
for (var i = 0; i < cache.length; i++) {
if (cache[i].input === input) {
var temp = cache[0];
cache[0] = cache[i];
cache[i] = temp;
return cache[0].result;
}
}
var result = f(input);
cache.unshift({
input,
result,
});
if (cache.length > MAX_CACHED_INPUTS) {
cache.pop();
}
return result;
};
}
/**
* Normalizes a path, or the path portion of a URL:
*
* - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '
/..' parts.
*
* Based on code in the Node.js 'path' core module.
*
* @param aPath The path or url to normalize.
*/
var normalize = lruMemoize(function normalize(aPath) {
var path = aPath;
var url = urlParse(aPath);
if (url) {
if (!url.path) {
return aPath;
}
path = url.path;
}
var isAbsolute = exports.isAbsolute(path);
// Split the path into parts between `/` characters. This is much faster than
// using `.split(/\/+/g)`.
var parts = [];
var start = 0;
var i = 0;
while (true) {
start = i;
i = path.indexOf("/", start);
if (i === -1) {
parts.push(path.slice(start));
break;
} else {
parts.push(path.slice(start, i));
while (i < path.length && path[i] === "/") {
i++;
}
}
}
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
part = parts[i];
if (part === '.') {
parts.splice(i, 1);
} else if (part === '..') {
up++;
} else if (up > 0) {
if (part === '') {
// The first part is blank if the path is absolute. Trying to go
// above the root is a no-op. Therefore we can remove all '..' parts
// directly after the root.
parts.splice(i + 1, up);
up = 0;
} else {
parts.splice(i, 2);
up--;
}
}
}
path = parts.join('/');
if (path === '') {
path = isAbsolute ? '/' : '.';
}
if (url) {
url.path = path;
return urlGenerate(url);
}
return path;
});
exports.normalize = normalize;
/**
* Joins two paths/URLs.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be joined with the root.
*
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
* first.
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
* is updated with the result and aRoot is returned. Otherwise the result
* is returned.
* - If aPath is absolute, the result is aPath.
* - Otherwise the two paths are joined with a slash.
* - Joining for example 'http://' and 'www.example.com' is also supported.
*/
function join(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
if (aPath === "") {
aPath = ".";
}
var aPathUrl = urlParse(aPath);
var aRootUrl = urlParse(aRoot);
if (aRootUrl) {
aRoot = aRootUrl.path || '/';
}
// `join(foo, '//www.example.org')`
if (aPathUrl && !aPathUrl.scheme) {
if (aRootUrl) {
aPathUrl.scheme = aRootUrl.scheme;
}
return urlGenerate(aPathUrl);
}
if (aPathUrl || aPath.match(dataUrlRegexp)) {
return aPath;
}
// `join('http://', 'www.example.com')`
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
aRootUrl.host = aPath;
return urlGenerate(aRootUrl);
}
var joined = aPath.charAt(0) === '/'
? aPath
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
if (aRootUrl) {
aRootUrl.path = joined;
return urlGenerate(aRootUrl);
}
return joined;
}
exports.join = join;
exports.isAbsolute = function (aPath) {
return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
* Make a path relative to a URL or another path.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be made relative to aRoot.
*/
function relative(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
aRoot = aRoot.replace(/\/$/, '');
// It is possible for the path to be above the root. In this case, simply
// checking whether the root is a prefix of the path won't work. Instead, we
// need to remove components from the root one by one, until either we find
// a prefix that fits, or we run out of components to remove.
var level = 0;
while (aPath.indexOf(aRoot + '/') !== 0) {
var index = aRoot.lastIndexOf("/");
if (index < 0) {
return aPath;
}
// If the only part of the root that is left is the scheme (i.e. http://,
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
// have exhausted all components, so the path is not relative to the root.
aRoot = aRoot.slice(0, index);
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
return aPath;
}
++level;
}
// Make sure we add a "../" for each component we removed from the root.
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
}
exports.relative = relative;
var supportsNullProto = (function () {
var obj = Object.create(null);
return !('__proto__' in obj);
}());
function identity (s) {
return s;
}
/**
* Because behavior goes wacky when you set `__proto__` on objects, we
* have to prefix all the strings in our set with an arbitrary character.
*
* See https://github.com/mozilla/source-map/pull/31 and
* https://github.com/mozilla/source-map/issues/30
*
* @param String aStr
*/
function toSetString(aStr) {
if (isProtoString(aStr)) {
return '$' + aStr;
}
return aStr;
}
exports.toSetString = supportsNullProto ? identity : toSetString;
function fromSetString(aStr) {
if (isProtoString(aStr)) {
return aStr.slice(1);
}
return aStr;
}
exports.fromSetString = supportsNullProto ? identity : fromSetString;
function isProtoString(s) {
if (!s) {
return false;
}
var length = s.length;
if (length < 9 /* "__proto__".length */) {
return false;
}
if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
s.charCodeAt(length - 2) !== 95 /* '_' */ ||
s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
s.charCodeAt(length - 4) !== 116 /* 't' */ ||
s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
s.charCodeAt(length - 8) !== 95 /* '_' */ ||
s.charCodeAt(length - 9) !== 95 /* '_' */) {
return false;
}
for (var i = length - 10; i >= 0; i--) {
if (s.charCodeAt(i) !== 36 /* '$' */) {
return false;
}
}
return true;
}
/**
* Comparator between two mappings where the original positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same original source/line/column, but different generated
* line and column the same. Useful when searching for a mapping with a
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0 || onlyCompareOriginal) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
function compareByOriginalPositionsNoSource(mappingA, mappingB, onlyCompareOriginal) {
var cmp
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0 || onlyCompareOriginal) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositionsNoSource = compareByOriginalPositionsNoSource;
/**
* Comparator between two mappings with deflated source and name indices where
* the generated positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same generated line and column, but different
* source/name/original line and column the same. Useful when searching for a
* mapping with a stubbed out mapping.
*/
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
var cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0 || onlyCompareGenerated) {
return cmp;
}
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
function compareByGeneratedPositionsDeflatedNoLine(mappingA, mappingB, onlyCompareGenerated) {
var cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0 || onlyCompareGenerated) {
return cmp;
}
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflatedNoLine = compareByGeneratedPositionsDeflatedNoLine;
function strcmp(aStr1, aStr2) {
if (aStr1 === aStr2) {
return 0;
}
if (aStr1 === null) {
return 1; // aStr2 !== null
}
if (aStr2 === null) {
return -1; // aStr1 !== null
}
if (aStr1 > aStr2) {
return 1;
}
return -1;
}
/**
* Comparator between two mappings with inflated source and name strings where
* the generated positions are compared.
*/
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
var cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0) {
return cmp;
}
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
/**
* Strip any JSON XSSI avoidance prefix from the string (as documented
* in the source maps specification), and then parse the string as
* JSON.
*/
function parseSourceMapInput(str) {
return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
}
exports.parseSourceMapInput = parseSourceMapInput;
/**
* Compute the URL of a source given the the source root, the source's
* URL, and the source map's URL.
*/
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
sourceURL = sourceURL || '';
if (sourceRoot) {
// This follows what Chrome does.
if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
sourceRoot += '/';
}
// The spec says:
// Line 4: An optional source root, useful for relocating source
// files on a server or removing repeated values in the
// “sources” entry. This value is prepended to the individual
// entries in the “source” field.
sourceURL = sourceRoot + sourceURL;
}
// Historically, SourceMapConsumer did not take the sourceMapURL as
// a parameter. This mode is still somewhat supported, which is why
// this code block is conditional. However, it's preferable to pass
// the source map URL to SourceMapConsumer, so that this function
// can implement the source URL resolution algorithm as outlined in
// the spec. This block is basically the equivalent of:
// new URL(sourceURL, sourceMapURL).toString()
// ... except it avoids using URL, which wasn't available in the
// older releases of node still supported by this library.
//
// The spec says:
// If the sources are not absolute URLs after prepending of the
// “sourceRoot”, the sources are resolved relative to the
// SourceMap (like resolving script src in a html document).
if (sourceMapURL) {
var parsed = urlParse(sourceMapURL);
if (!parsed) {
throw new Error("sourceMapURL could not be parsed");
}
if (parsed.path) {
// Strip the last path component, but keep the "/".
var index = parsed.path.lastIndexOf('/');
if (index >= 0) {
parsed.path = parsed.path.substring(0, index + 1);
}
}
sourceURL = join(urlGenerate(parsed), sourceURL);
}
return normalize(sourceURL);
}
exports.computeSourceURL = computeSourceURL;
/***/ }),
/***/ "../action/userContributionToGrid.ts":
/*!*******************************************!*\
!*** ../action/userContributionToGrid.ts ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "userContributionToGrid": () => (/* binding */ userContributionToGrid)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
const userContributionToGrid = (cells, colorScheme) => {
const width = Math.max(0, ...cells.map((c) => c.x)) + 1;
const height = Math.max(0, ...cells.map((c) => c.y)) + 1;
const grid = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.createEmptyGrid)(width, height);
for (const c of cells) {
const k = colorScheme.indexOf(c.color);
if (k > 0)
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColor)(grid, c.x, c.y, k);
else
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColorEmpty)(grid, c.x, c.y);
}
return grid;
};
/***/ }),
/***/ "./springUtils.ts":
/*!************************!*\
!*** ./springUtils.ts ***!
\************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "clamp": () => (/* binding */ clamp),
/* harmony export */ "isStable": () => (/* binding */ isStable),
/* harmony export */ "isStableAndBound": () => (/* binding */ isStableAndBound),
/* harmony export */ "stepSpring": () => (/* binding */ stepSpring)
/* harmony export */ });
const epsilon = 0.01;
const clamp = (a, b) => (x) => Math.max(a, Math.min(b, x));
/**
* step the spring, mutate the state to reflect the state at t+dt
*
*/
const stepSpringOne = (s, { tension, friction, maxVelocity = Infinity, }, target, dt = 1 / 60) => {
const a = -tension * (s.x - target) - friction * s.v;
s.v += a * dt;
s.v = clamp(-maxVelocity / dt, maxVelocity / dt)(s.v);
s.x += s.v * dt;
};
/**
* return true if the spring is to be considered in a stable state
* ( close enough to the target and with a small enough velocity )
*/
const isStable = (s, target, dt = 1 / 60) => Math.abs(s.x - target) < epsilon && Math.abs(s.v * dt) < epsilon;
const isStableAndBound = (s, target, dt) => {
const stable = isStable(s, target, dt);
if (stable) {
s.x = target;
s.v = 0;
}
return stable;
};
const stepSpring = (s, params, target, dt = 1 / 60) => {
const interval = 1 / 60;
while (dt > 0) {
stepSpringOne(s, params, target, Math.min(interval, dt));
// eslint-disable-next-line no-param-reassign
dt -= interval;
}
};
/***/ }),
/***/ "../draw/drawGrid.ts":
/*!***************************!*\
!*** ../draw/drawGrid.ts ***!
\***************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "drawGrid": () => (/* binding */ drawGrid)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _pathRoundedRect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pathRoundedRect */ "../draw/pathRoundedRect.ts");
const drawGrid = (ctx, grid, o) => {
for (let x = grid.width; x--;)
for (let y = grid.height; y--;) {
if (!o.cells || o.cells.some((c) => c.x === x && c.y === y)) {
const c = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y);
// @ts-ignore
const color = !c ? o.colorEmpty : o.colorDots[c];
ctx.save();
ctx.translate(x * o.sizeCell + (o.sizeCell - o.sizeDot) / 2, y * o.sizeCell + (o.sizeCell - o.sizeDot) / 2);
ctx.fillStyle = color;
ctx.strokeStyle = o.colorBorder;
ctx.lineWidth = 1;
ctx.beginPath();
(0,_pathRoundedRect__WEBPACK_IMPORTED_MODULE_1__.pathRoundedRect)(ctx, o.sizeDot, o.sizeDot, o.sizeBorderRadius);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
}
}
};
/***/ }),
/***/ "../draw/drawSnake.ts":
/*!****************************!*\
!*** ../draw/drawSnake.ts ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "drawSnake": () => (/* binding */ drawSnake),
/* harmony export */ "drawSnakeLerp": () => (/* binding */ drawSnakeLerp)
/* harmony export */ });
/* harmony import */ var _pathRoundedRect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pathRoundedRect */ "../draw/pathRoundedRect.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
const drawSnake = (ctx, snake, o) => {
const cells = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.snakeToCells)(snake);
for (let i = 0; i < cells.length; i++) {
const u = (i + 1) * 0.6;
ctx.save();
ctx.fillStyle = o.colorSnake;
ctx.translate(cells[i].x * o.sizeCell + u, cells[i].y * o.sizeCell + u);
ctx.beginPath();
(0,_pathRoundedRect__WEBPACK_IMPORTED_MODULE_0__.pathRoundedRect)(ctx, o.sizeCell - u * 2, o.sizeCell - u * 2, (o.sizeCell - u * 2) * 0.25);
ctx.fill();
ctx.restore();
}
};
const lerp = (k, a, b) => (1 - k) * a + k * b;
const clamp = (x, a, b) => Math.max(a, Math.min(b, x));
const drawSnakeLerp = (ctx, snake0, snake1, k, o) => {
const m = 0.8;
const n = snake0.length / 2;
for (let i = 0; i < n; i++) {
const u = (i + 1) * 0.6 * (o.sizeCell / 16);
const a = (1 - m) * (i / Math.max(n - 1, 1));
const ki = clamp((k - a) / m, 0, 1);
const x = lerp(ki, snake0[i * 2 + 0], snake1[i * 2 + 0]) - 2;
const y = lerp(ki, snake0[i * 2 + 1], snake1[i * 2 + 1]) - 2;
ctx.save();
ctx.fillStyle = o.colorSnake;
ctx.translate(x * o.sizeCell + u, y * o.sizeCell + u);
ctx.beginPath();
(0,_pathRoundedRect__WEBPACK_IMPORTED_MODULE_0__.pathRoundedRect)(ctx, o.sizeCell - u * 2, o.sizeCell - u * 2, (o.sizeCell - u * 2) * 0.25);
ctx.fill();
ctx.restore();
}
};
/***/ }),
/***/ "../draw/drawWorld.ts":
/*!****************************!*\
!*** ../draw/drawWorld.ts ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "drawLerpWorld": () => (/* binding */ drawLerpWorld),
/* harmony export */ "drawStack": () => (/* binding */ drawStack),
/* harmony export */ "drawWorld": () => (/* binding */ drawWorld),
/* harmony export */ "getCanvasWorldSize": () => (/* binding */ getCanvasWorldSize)
/* harmony export */ });
/* harmony import */ var _drawGrid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./drawGrid */ "../draw/drawGrid.ts");
/* harmony import */ var _drawSnake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./drawSnake */ "../draw/drawSnake.ts");
const drawStack = (ctx, stack, max, width, o) => {
ctx.save();
const m = width / max;
for (let i = 0; i < stack.length; i++) {
// @ts-ignore
ctx.fillStyle = o.colorDots[stack[i]];
ctx.fillRect(i * m, 0, m + width * 0.005, 10);
}
ctx.restore();
};
const drawWorld = (ctx, grid, snake, stack, o) => {
ctx.save();
ctx.translate(1 * o.sizeCell, 2 * o.sizeCell);
(0,_drawGrid__WEBPACK_IMPORTED_MODULE_0__.drawGrid)(ctx, grid, o);
(0,_drawSnake__WEBPACK_IMPORTED_MODULE_1__.drawSnake)(ctx, snake, o);
ctx.restore();
ctx.save();
ctx.translate(o.sizeCell, (grid.height + 4) * o.sizeCell);
const max = grid.data.reduce((sum, x) => sum + +!!x, stack.length);
drawStack(ctx, stack, max, grid.width * o.sizeCell, o);
ctx.restore();
// ctx.save();
// ctx.translate(o.sizeCell + 100, (grid.height + 4) * o.sizeCell + 100);
// ctx.scale(0.6, 0.6);
// drawCircleStack(ctx, stack, o);
// ctx.restore();
};
const drawLerpWorld = (ctx, grid, snake0, snake1, stack, k, o) => {
ctx.save();
ctx.translate(1 * o.sizeCell, 2 * o.sizeCell);
(0,_drawGrid__WEBPACK_IMPORTED_MODULE_0__.drawGrid)(ctx, grid, o);
(0,_drawSnake__WEBPACK_IMPORTED_MODULE_1__.drawSnakeLerp)(ctx, snake0, snake1, k, o);
ctx.translate(0, (grid.height + 2) * o.sizeCell);
const max = grid.data.reduce((sum, x) => sum + +!!x, stack.length);
drawStack(ctx, stack, max, grid.width * o.sizeCell, o);
ctx.restore();
};
const getCanvasWorldSize = (grid, o) => {
const width = o.sizeCell * (grid.width + 2);
const height = o.sizeCell * (grid.height + 4) + 30;
return { width, height };
};
/***/ }),
/***/ "../draw/pathRoundedRect.ts":
/*!**********************************!*\
!*** ../draw/pathRoundedRect.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "pathRoundedRect": () => (/* binding */ pathRoundedRect)
/* harmony export */ });
const pathRoundedRect = (ctx, width, height, borderRadius) => {
ctx.moveTo(borderRadius, 0);
ctx.arcTo(width, 0, width, height, borderRadius);
ctx.arcTo(width, height, 0, height, borderRadius);
ctx.arcTo(0, height, 0, 0, borderRadius);
ctx.arcTo(0, 0, width, 0, borderRadius);
};
/***/ }),
/***/ "../solver/clearCleanColoredLayer.ts":
/*!*******************************************!*\
!*** ../solver/clearCleanColoredLayer.ts ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "clearCleanColoredLayer": () => (/* binding */ clearCleanColoredLayer),
/* harmony export */ "getTunnellablePoints": () => (/* binding */ getTunnellablePoints)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/* harmony import */ var _snk_types_point__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @snk/types/point */ "../types/point.ts");
/* harmony import */ var _getBestTunnel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getBestTunnel */ "../solver/getBestTunnel.ts");
/* harmony import */ var _outside__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./outside */ "../solver/outside.ts");
const clearCleanColoredLayer = (grid, outside, snake0, color) => {
const snakeN = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getSnakeLength)(snake0);
const points = getTunnellablePoints(grid, outside, snakeN, color);
const chain = [snake0];
while (points.length) {
const path = getPathToNextPoint(grid, chain[0], color, points);
path.pop();
for (const snake of path)
setEmptySafe(grid, (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadX)(snake), (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadY)(snake));
chain.unshift(...path);
}
(0,_outside__WEBPACK_IMPORTED_MODULE_4__.fillOutside)(outside, grid);
chain.pop();
return chain;
};
const unwrap = (m) => !m ? [] : [m.snake, ...unwrap(m.parent)];
const getPathToNextPoint = (grid, snake0, color, points) => {
const closeList = [];
const openList = [{ snake: snake0 }];
while (openList.length) {
const o = openList.shift();
const x = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadX)(o.snake);
const y = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadY)(o.snake);
const i = points.findIndex((p) => p.x === x && p.y === y);
if (i >= 0) {
points.splice(i, 1);
return unwrap(o);
}
for (const { x: dx, y: dy } of _snk_types_point__WEBPACK_IMPORTED_MODULE_2__.around4) {
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInsideLarge)(grid, 2, x + dx, y + dy) &&
!(0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.snakeWillSelfCollide)(o.snake, dx, dy) &&
getColorSafe(grid, x + dx, y + dy) <= color) {
const snake = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.nextSnake)(o.snake, dx, dy);
if (!closeList.some((s0) => (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.snakeEquals)(s0, snake))) {
closeList.push(snake);
openList.push({ snake, parent: o });
}
}
}
}
};
/**
* get all cells that are tunnellable
*/
const getTunnellablePoints = (grid, outside, snakeN, color) => {
const points = [];
for (let x = grid.width; x--;)
for (let y = grid.height; y--;) {
const c = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y);
if (!(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)(c) &&
c <= color &&
!points.some((p) => p.x === x && p.y === y)) {
const tunnel = (0,_getBestTunnel__WEBPACK_IMPORTED_MODULE_3__.getBestTunnel)(grid, outside, x, y, color, snakeN);
if (tunnel)
for (const p of tunnel)
if (!isEmptySafe(grid, p.x, p.y))
points.push(p);
}
}
return points;
};
const getColorSafe = (grid, x, y) => (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y) ? (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y) : 0;
const setEmptySafe = (grid, x, y) => {
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y))
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColorEmpty)(grid, x, y);
};
const isEmptySafe = (grid, x, y) => !(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y) && (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y));
/***/ }),
/***/ "../solver/clearResidualColoredLayer.ts":
/*!**********************************************!*\
!*** ../solver/clearResidualColoredLayer.ts ***!
\**********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "clearResidualColoredLayer": () => (/* binding */ clearResidualColoredLayer),
/* harmony export */ "getPriority": () => (/* binding */ getPriority),
/* harmony export */ "getTunnellablePoints": () => (/* binding */ getTunnellablePoints)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/* harmony import */ var _getBestTunnel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getBestTunnel */ "../solver/getBestTunnel.ts");
/* harmony import */ var _outside__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./outside */ "../solver/outside.ts");
/* harmony import */ var _tunnel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./tunnel */ "../solver/tunnel.ts");
/* harmony import */ var _getPathTo__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./getPathTo */ "../solver/getPathTo.ts");
const clearResidualColoredLayer = (grid, outside, snake0, color) => {
const snakeN = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getSnakeLength)(snake0);
const tunnels = getTunnellablePoints(grid, outside, snakeN, color);
// sort
tunnels.sort((a, b) => b.priority - a.priority);
const chain = [snake0];
while (tunnels.length) {
// get the best next tunnel
let t = getNextTunnel(tunnels, chain[0]);
// goes to the start of the tunnel
chain.unshift(...(0,_getPathTo__WEBPACK_IMPORTED_MODULE_5__.getPathTo)(grid, chain[0], t[0].x, t[0].y));
// goes to the end of the tunnel
chain.unshift(...(0,_tunnel__WEBPACK_IMPORTED_MODULE_4__.getTunnelPath)(chain[0], t));
// update grid
for (const { x, y } of t)
setEmptySafe(grid, x, y);
// update outside
(0,_outside__WEBPACK_IMPORTED_MODULE_3__.fillOutside)(outside, grid);
// update tunnels
for (let i = tunnels.length; i--;)
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, tunnels[i].x, tunnels[i].y)))
tunnels.splice(i, 1);
else {
const t = tunnels[i];
const tunnel = (0,_getBestTunnel__WEBPACK_IMPORTED_MODULE_2__.getBestTunnel)(grid, outside, t.x, t.y, color, snakeN);
if (!tunnel)
tunnels.splice(i, 1);
else {
t.tunnel = tunnel;
t.priority = getPriority(grid, color, tunnel);
}
}
// re-sort
tunnels.sort((a, b) => b.priority - a.priority);
}
chain.pop();
return chain;
};
const getNextTunnel = (ts, snake) => {
let minDistance = Infinity;
let closestTunnel = null;
const x = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadX)(snake);
const y = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadY)(snake);
const priority = ts[0].priority;
for (let i = 0; ts[i] && ts[i].priority === priority; i++) {
const t = ts[i].tunnel;
const d = distanceSq(t[0].x, t[0].y, x, y);
if (d < minDistance) {
minDistance = d;
closestTunnel = t;
}
}
return closestTunnel;
};
/**
* get all the tunnels for all the cells accessible
*/
const getTunnellablePoints = (grid, outside, snakeN, color) => {
const points = [];
for (let x = grid.width; x--;)
for (let y = grid.height; y--;) {
const c = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y);
if (!(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)(c) && c < color) {
const tunnel = (0,_getBestTunnel__WEBPACK_IMPORTED_MODULE_2__.getBestTunnel)(grid, outside, x, y, color, snakeN);
if (tunnel) {
const priority = getPriority(grid, color, tunnel);
points.push({ x, y, priority, tunnel });
}
}
}
return points;
};
/**
* get the score of the tunnel
* prioritize tunnel with maximum color smaller than and with minimum
* with some tweaks
*/
const getPriority = (grid, color, tunnel) => {
let nColor = 0;
let nLess = 0;
for (let i = 0; i < tunnel.length; i++) {
const { x, y } = tunnel[i];
const c = getColorSafe(grid, x, y);
if (!(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)(c) && i === tunnel.findIndex((p) => p.x === x && p.y === y)) {
if (c === color)
nColor += 1;
else
nLess += color - c;
}
}
if (nColor === 0)
return 99999;
return nLess / nColor;
};
const distanceSq = (ax, ay, bx, by) => (ax - bx) ** 2 + (ay - by) ** 2;
const getColorSafe = (grid, x, y) => (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y) ? (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y) : 0;
const setEmptySafe = (grid, x, y) => {
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y))
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColorEmpty)(grid, x, y);
};
/***/ }),
/***/ "../solver/getBestRoute.ts":
/*!*********************************!*\
!*** ../solver/getBestRoute.ts ***!
\*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "getBestRoute": () => (/* binding */ getBestRoute)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _outside__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./outside */ "../solver/outside.ts");
/* harmony import */ var _clearResidualColoredLayer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clearResidualColoredLayer */ "../solver/clearResidualColoredLayer.ts");
/* harmony import */ var _clearCleanColoredLayer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./clearCleanColoredLayer */ "../solver/clearCleanColoredLayer.ts");
const getBestRoute = (grid0, snake0) => {
const grid = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.copyGrid)(grid0);
const outside = (0,_outside__WEBPACK_IMPORTED_MODULE_1__.createOutside)(grid);
const chain = [snake0];
for (const color of extractColors(grid)) {
if (color > 1)
chain.unshift(...(0,_clearResidualColoredLayer__WEBPACK_IMPORTED_MODULE_2__.clearResidualColoredLayer)(grid, outside, chain[0], color));
chain.unshift(...(0,_clearCleanColoredLayer__WEBPACK_IMPORTED_MODULE_3__.clearCleanColoredLayer)(grid, outside, chain[0], color));
}
return chain.reverse();
};
const extractColors = (grid) => {
// @ts-ignore
let maxColor = Math.max(...grid.data);
return Array.from({ length: maxColor }, (_, i) => (i + 1));
};
/***/ }),
/***/ "../solver/getBestTunnel.ts":
/*!**********************************!*\
!*** ../solver/getBestTunnel.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "getBestTunnel": () => (/* binding */ getBestTunnel)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_point__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/point */ "../types/point.ts");
/* harmony import */ var _utils_sortPush__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/sortPush */ "../solver/utils/sortPush.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/* harmony import */ var _outside__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./outside */ "../solver/outside.ts");
/* harmony import */ var _tunnel__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./tunnel */ "../solver/tunnel.ts");
const getColorSafe = (grid, x, y) => (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y) ? (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y) : 0;
const setEmptySafe = (grid, x, y) => {
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y))
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColorEmpty)(grid, x, y);
};
const unwrap = (m) => !m
? []
: [...unwrap(m.parent), { x: (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.getHeadX)(m.snake), y: (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.getHeadY)(m.snake) }];
/**
* returns the path to reach the outside which contains the least color cell
*/
const getSnakeEscapePath = (grid, outside, snake0, color) => {
const openList = [{ snake: snake0, w: 0 }];
const closeList = [];
while (openList[0]) {
const o = openList.shift();
const x = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.getHeadX)(o.snake);
const y = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.getHeadY)(o.snake);
if ((0,_outside__WEBPACK_IMPORTED_MODULE_4__.isOutside)(outside, x, y))
return unwrap(o);
for (const a of _snk_types_point__WEBPACK_IMPORTED_MODULE_1__.around4) {
const c = getColorSafe(grid, x + a.x, y + a.y);
if (c <= color && !(0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.snakeWillSelfCollide)(o.snake, a.x, a.y)) {
const snake = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.nextSnake)(o.snake, a.x, a.y);
if (!closeList.some((s0) => (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.snakeEquals)(s0, snake))) {
const w = o.w + 1 + +(c === color) * 1000;
(0,_utils_sortPush__WEBPACK_IMPORTED_MODULE_2__.sortPush)(openList, { snake, w, parent: o }, (a, b) => a.w - b.w);
closeList.push(snake);
}
}
}
}
return null;
};
/**
* compute the best tunnel to get to the cell and back to the outside ( best = less usage of )
*
* notice that it's one of the best tunnels, more with the same score could exist
*/
const getBestTunnel = (grid, outside, x, y, color, snakeN) => {
const c = { x, y };
const snake0 = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.createSnakeFromCells)(Array.from({ length: snakeN }, () => c));
const one = getSnakeEscapePath(grid, outside, snake0, color);
if (!one)
return null;
// get the position of the snake if it was going to leave the x,y cell
const snakeICells = one.slice(0, snakeN);
while (snakeICells.length < snakeN)
snakeICells.push(snakeICells[snakeICells.length - 1]);
const snakeI = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_3__.createSnakeFromCells)(snakeICells);
// remove from the grid the colors that one eat
const gridI = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.copyGrid)(grid);
for (const { x, y } of one)
setEmptySafe(gridI, x, y);
const two = getSnakeEscapePath(gridI, outside, snakeI, color);
if (!two)
return null;
one.shift();
one.reverse();
one.push(...two);
(0,_tunnel__WEBPACK_IMPORTED_MODULE_5__.trimTunnelStart)(grid, one);
(0,_tunnel__WEBPACK_IMPORTED_MODULE_5__.trimTunnelEnd)(grid, one);
return one;
};
/***/ }),
/***/ "../solver/getPathTo.ts":
/*!******************************!*\
!*** ../solver/getPathTo.ts ***!
\******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "getPathTo": () => (/* binding */ getPathTo)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_point__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/point */ "../types/point.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/* harmony import */ var _utils_sortPush__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/sortPush */ "../solver/utils/sortPush.ts");
/**
* starting from snake0, get to the cell x,y
* return the snake chain (reversed)
*/
const getPathTo = (grid, snake0, x, y) => {
const openList = [{ snake: snake0, w: 0 }];
const closeList = [];
while (openList.length) {
const c = openList.shift();
const cx = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_2__.getHeadX)(c.snake);
const cy = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_2__.getHeadY)(c.snake);
for (let i = 0; i < _snk_types_point__WEBPACK_IMPORTED_MODULE_1__.around4.length; i++) {
const { x: dx, y: dy } = _snk_types_point__WEBPACK_IMPORTED_MODULE_1__.around4[i];
const nx = cx + dx;
const ny = cy + dy;
if (nx === x && ny === y) {
// unwrap
const path = [(0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_2__.nextSnake)(c.snake, dx, dy)];
let e = c;
while (e.parent) {
path.push(e.snake);
e = e.parent;
}
return path;
}
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInsideLarge)(grid, 2, nx, ny) &&
!(0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_2__.snakeWillSelfCollide)(c.snake, dx, dy) &&
(!(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, nx, ny) || (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, nx, ny)))) {
const nsnake = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_2__.nextSnake)(c.snake, dx, dy);
if (!closeList.some((s) => (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_2__.snakeEquals)(nsnake, s))) {
const w = c.w + 1;
const h = Math.abs(nx - x) + Math.abs(ny - y);
const f = w + h;
const o = { snake: nsnake, parent: c, w, h, f };
(0,_utils_sortPush__WEBPACK_IMPORTED_MODULE_3__.sortPush)(openList, o, (a, b) => a.f - b.f);
closeList.push(nsnake);
}
}
}
}
};
/***/ }),
/***/ "../solver/getPathToPose.ts":
/*!**********************************!*\
!*** ../solver/getPathToPose.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "getPathToPose": () => (/* binding */ getPathToPose)
/* harmony export */ });
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _tunnel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./tunnel */ "../solver/tunnel.ts");
/* harmony import */ var _snk_types_point__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @snk/types/point */ "../types/point.ts");
/* harmony import */ var _utils_sortPush__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils/sortPush */ "../solver/utils/sortPush.ts");
const isEmptySafe = (grid, x, y) => !(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_1__.isInside)(grid, x, y) || (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_1__.isEmpty)((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_1__.getColor)(grid, x, y));
const getPathToPose = (snake0, target, grid) => {
if ((0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.snakeEquals)(snake0, target))
return [];
const targetCells = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.snakeToCells)(target).reverse();
const snakeN = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getSnakeLength)(snake0);
const box = {
min: {
x: Math.min((0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadX)(snake0), (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadX)(target)) - snakeN - 1,
y: Math.min((0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadY)(snake0), (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadY)(target)) - snakeN - 1,
},
max: {
x: Math.max((0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadX)(snake0), (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadX)(target)) + snakeN + 1,
y: Math.max((0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadY)(snake0), (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadY)(target)) + snakeN + 1,
},
};
const [t0, ...forbidden] = targetCells;
forbidden.slice(0, 3);
const openList = [{ snake: snake0, w: 0 }];
const closeList = [];
while (openList.length) {
const o = openList.shift();
const x = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadX)(o.snake);
const y = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getHeadY)(o.snake);
if (x === t0.x && y === t0.y) {
const path = [];
let e = o;
while (e) {
path.push(e.snake);
e = e.parent;
}
path.unshift(...(0,_tunnel__WEBPACK_IMPORTED_MODULE_2__.getTunnelPath)(path[0], targetCells));
path.pop();
path.reverse();
return path;
}
for (let i = 0; i < _snk_types_point__WEBPACK_IMPORTED_MODULE_3__.around4.length; i++) {
const { x: dx, y: dy } = _snk_types_point__WEBPACK_IMPORTED_MODULE_3__.around4[i];
const nx = x + dx;
const ny = y + dy;
if (!(0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.snakeWillSelfCollide)(o.snake, dx, dy) &&
(!grid || isEmptySafe(grid, nx, ny)) &&
(grid
? (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_1__.isInsideLarge)(grid, 2, nx, ny)
: box.min.x <= nx &&
nx <= box.max.x &&
box.min.y <= ny &&
ny <= box.max.y) &&
!forbidden.some((p) => p.x === nx && p.y === ny)) {
const snake = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.nextSnake)(o.snake, dx, dy);
if (!closeList.some((s) => (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.snakeEquals)(snake, s))) {
const w = o.w + 1;
const h = Math.abs(nx - x) + Math.abs(ny - y);
const f = w + h;
(0,_utils_sortPush__WEBPACK_IMPORTED_MODULE_4__.sortPush)(openList, { f, w, snake, parent: o }, (a, b) => a.f - b.f);
closeList.push(snake);
}
}
}
}
};
/***/ }),
/***/ "../solver/outside.ts":
/*!****************************!*\
!*** ../solver/outside.ts ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "createOutside": () => (/* binding */ createOutside),
/* harmony export */ "fillOutside": () => (/* binding */ fillOutside),
/* harmony export */ "isOutside": () => (/* binding */ isOutside)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_point__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/point */ "../types/point.ts");
const createOutside = (grid, color = 0) => {
const outside = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.createEmptyGrid)(grid.width, grid.height);
for (let x = outside.width; x--;)
for (let y = outside.height; y--;)
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColor)(outside, x, y, 1);
fillOutside(outside, grid, color);
return outside;
};
const fillOutside = (outside, grid, color = 0) => {
let changed = true;
while (changed) {
changed = false;
for (let x = outside.width; x--;)
for (let y = outside.height; y--;)
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y) <= color &&
!isOutside(outside, x, y) &&
_snk_types_point__WEBPACK_IMPORTED_MODULE_1__.around4.some((a) => isOutside(outside, x + a.x, y + a.y))) {
changed = true;
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColorEmpty)(outside, x, y);
}
}
return outside;
};
const isOutside = (outside, x, y) => !(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(outside, x, y) || (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(outside, x, y));
/***/ }),
/***/ "../solver/step.ts":
/*!*************************!*\
!*** ../solver/step.ts ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "step": () => (/* binding */ step)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
const step = (grid, stack, snake) => {
const x = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadX)(snake);
const y = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadY)(snake);
const color = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y);
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y) && !(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)(color)) {
stack.push(color);
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColorEmpty)(grid, x, y);
}
};
/***/ }),
/***/ "../solver/tunnel.ts":
/*!***************************!*\
!*** ../solver/tunnel.ts ***!
\***************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "getTunnelPath": () => (/* binding */ getTunnelPath),
/* harmony export */ "trimTunnelEnd": () => (/* binding */ trimTunnelEnd),
/* harmony export */ "trimTunnelStart": () => (/* binding */ trimTunnelStart),
/* harmony export */ "updateTunnel": () => (/* binding */ updateTunnel)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/**
* get the sequence of snake to cross the tunnel
*/
const getTunnelPath = (snake0, tunnel) => {
const chain = [];
let snake = snake0;
for (let i = 1; i < tunnel.length; i++) {
const dx = tunnel[i].x - (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadX)(snake);
const dy = tunnel[i].y - (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadY)(snake);
snake = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.nextSnake)(snake, dx, dy);
chain.unshift(snake);
}
return chain;
};
/**
* assuming the grid change and the colors got deleted, update the tunnel
*/
const updateTunnel = (grid, tunnel, toDelete) => {
while (tunnel.length) {
const { x, y } = tunnel[0];
if (isEmptySafe(grid, x, y) ||
toDelete.some((p) => p.x === x && p.y === y)) {
tunnel.shift();
}
else
break;
}
while (tunnel.length) {
const { x, y } = tunnel[tunnel.length - 1];
if (isEmptySafe(grid, x, y) ||
toDelete.some((p) => p.x === x && p.y === y)) {
tunnel.pop();
}
else
break;
}
};
const isEmptySafe = (grid, x, y) => !(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y) || (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y));
/**
* remove empty cell from start
*/
const trimTunnelStart = (grid, tunnel) => {
while (tunnel.length) {
const { x, y } = tunnel[0];
if (isEmptySafe(grid, x, y))
tunnel.shift();
else
break;
}
};
/**
* remove empty cell from end
*/
const trimTunnelEnd = (grid, tunnel) => {
while (tunnel.length) {
const i = tunnel.length - 1;
const { x, y } = tunnel[i];
if (isEmptySafe(grid, x, y) ||
tunnel.findIndex((p) => p.x === x && p.y === y) < i)
tunnel.pop();
else
break;
}
};
/***/ }),
/***/ "../solver/utils/sortPush.ts":
/*!***********************************!*\
!*** ../solver/utils/sortPush.ts ***!
\***********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "sortPush": () => (/* binding */ sortPush)
/* harmony export */ });
const sortPush = (arr, x, sortFn) => {
let a = 0;
let b = arr.length;
if (arr.length === 0 || sortFn(x, arr[a]) <= 0) {
arr.unshift(x);
return;
}
while (b - a > 1) {
const e = Math.ceil((a + b) / 2);
const s = sortFn(x, arr[e]);
if (s === 0)
a = b = e;
else if (s > 0)
a = e;
else
b = e;
}
const e = Math.ceil((a + b) / 2);
arr.splice(e, 0, x);
};
/***/ }),
/***/ "../svg-creator/grid.ts":
/*!******************************!*\
!*** ../svg-creator/grid.ts ***!
\******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "createGrid": () => (/* binding */ createGrid)
/* harmony export */ });
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils */ "../svg-creator/utils.ts");
const percent = (x) => (x * 100).toFixed(2);
const createGrid = (cells, { sizeBorderRadius, sizeDot, sizeCell }, duration) => {
const svgElements = [];
const styles = [
`.c{
shape-rendering: geometricPrecision;
rx: ${sizeBorderRadius};
ry: ${sizeBorderRadius};
fill: var(--ce);
stroke-width: 1px;
stroke: var(--cb);
animation: none ${duration}ms linear infinite;
}`,
];
let i = 0;
for (const { x, y, color, t } of cells) {
const id = t && "c" + (i++).toString(36);
const s = sizeCell;
const d = sizeDot;
const m = (s - d) / 2;
if (t !== null) {
const animationName = id;
styles.push(`@keyframes ${animationName} {` +
`${percent(t - 0.0001)}%{fill:var(--c${color})}` +
`${percent(t + 0.0001)}%,100%{fill:var(--ce)}` +
"}", `.c.${id}{fill: var(--c${color}); animation-name: ${animationName}}`);
}
svgElements.push((0,_utils__WEBPACK_IMPORTED_MODULE_0__.h)("rect", {
class: ["c", id].filter(Boolean).join(" "),
x: x * s + m,
y: y * s + m,
width: d,
height: d,
}));
}
return { svgElements, styles };
};
/***/ }),
/***/ "../svg-creator/index.ts":
/*!*******************************!*\
!*** ../svg-creator/index.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "createSvg": () => (/* binding */ createSvg)
/* harmony export */ });
/* harmony import */ var _snk_types_grid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/grid */ "../types/grid.ts");
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/* harmony import */ var _snake__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./snake */ "../svg-creator/snake.ts");
/* harmony import */ var _grid__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./grid */ "../svg-creator/grid.ts");
/* harmony import */ var _stack__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./stack */ "../svg-creator/stack.ts");
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils */ "../svg-creator/utils.ts");
/* harmony import */ var csso__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! csso */ "../../node_modules/csso/lib/index.js");
const getCellsFromGrid = ({ width, height }) => Array.from({ length: width }, (_, x) => Array.from({ length: height }, (_, y) => ({ x, y }))).flat();
const createLivingCells = (grid0, chain, drawOptions) => {
var _a;
const cells = ((_a = drawOptions.cells) !== null && _a !== void 0 ? _a : getCellsFromGrid(grid0)).map(({ x, y }) => ({
x,
y,
t: null,
color: (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid0, x, y),
}));
const grid = (0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.copyGrid)(grid0);
for (let i = 0; i < chain.length; i++) {
const snake = chain[i];
const x = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadX)(snake);
const y = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_1__.getHeadY)(snake);
if ((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isInside)(grid, x, y) && !(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.isEmpty)((0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.getColor)(grid, x, y))) {
(0,_snk_types_grid__WEBPACK_IMPORTED_MODULE_0__.setColorEmpty)(grid, x, y);
const cell = cells.find((c) => c.x === x && c.y === y);
cell.t = i / chain.length;
}
}
return cells;
};
const createSvg = (grid, chain, drawOptions, gifOptions) => {
const width = (grid.width + 2) * drawOptions.sizeCell;
const height = (grid.height + 5) * drawOptions.sizeCell;
const duration = gifOptions.frameDuration * chain.length;
const cells = createLivingCells(grid, chain, drawOptions);
const elements = [
(0,_grid__WEBPACK_IMPORTED_MODULE_3__.createGrid)(cells, drawOptions, duration),
(0,_stack__WEBPACK_IMPORTED_MODULE_4__.createStack)(cells, drawOptions, grid.width * drawOptions.sizeCell, (grid.height + 2) * drawOptions.sizeCell, duration),
(0,_snake__WEBPACK_IMPORTED_MODULE_2__.createSnake)(chain, drawOptions, duration),
];
const viewBox = [
-drawOptions.sizeCell,
-drawOptions.sizeCell * 2,
width,
height,
].join(" ");
const style = generateColorVar(drawOptions) +
elements
.map((e) => e.styles)
.flat()
.join("\n");
const svg = [
(0,_utils__WEBPACK_IMPORTED_MODULE_5__.h)("svg", {
viewBox,
width,
height,
xmlns: "http://www.w3.org/2000/svg",
}).replace("/>", ">"),
"",
...elements.map((e) => e.svgElements).flat(),
"",
].join("");
return optimizeSvg(svg);
};
const optimizeCss = (css) => csso__WEBPACK_IMPORTED_MODULE_6__.minify(css).css;
const optimizeSvg = (svg) => svg;
const generateColorVar = (drawOptions) => `
:root {
--cb: ${drawOptions.colorBorder};
--cs: ${drawOptions.colorSnake};
--ce: ${drawOptions.colorEmpty};
${Object.entries(drawOptions.colorDots)
.map(([i, color]) => `--c${i}:${color};`)
.join("")}
}
` +
(drawOptions.dark
? `
@media (prefers-color-scheme: dark) {
:root {
--cb: ${drawOptions.dark.colorBorder || drawOptions.colorBorder};
--cs: ${drawOptions.dark.colorSnake || drawOptions.colorSnake};
--ce: ${drawOptions.dark.colorEmpty};
${Object.entries(drawOptions.dark.colorDots)
.map(([i, color]) => `--c${i}:${color};`)
.join("")}
}
}
`
: "");
/***/ }),
/***/ "../svg-creator/snake.ts":
/*!*******************************!*\
!*** ../svg-creator/snake.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "createSnake": () => (/* binding */ createSnake)
/* harmony export */ });
/* harmony import */ var _snk_types_snake__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @snk/types/snake */ "../types/snake.ts");
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "../svg-creator/utils.ts");
const percent = (x) => (x * 100).toFixed(2);
const lerp = (k, a, b) => (1 - k) * a + k * b;
const createSnake = (chain, { sizeCell, sizeDot }, duration) => {
const snakeN = chain[0] ? (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.getSnakeLength)(chain[0]) : 0;
const snakeParts = Array.from({ length: snakeN }, () => []);
for (const snake of chain) {
const cells = (0,_snk_types_snake__WEBPACK_IMPORTED_MODULE_0__.snakeToCells)(snake);
for (let i = cells.length; i--;)
snakeParts[i].push(cells[i]);
}
const svgElements = snakeParts.map((_, i, { length }) => {
// compute snake part size
const dMin = sizeDot * 0.8;
const dMax = sizeCell * 0.9;
const iMax = Math.min(4, length);
const u = (1 - Math.min(i, iMax) / iMax) ** 2;
const s = lerp(u, dMin, dMax);
const m = (sizeCell - s) / 2;
const r = Math.min(4.5, (4 * s) / sizeDot);
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.h)("rect", {
class: `s s${i}`,
x: m.toFixed(1),
y: m.toFixed(1),
width: s.toFixed(1),
height: s.toFixed(1),
rx: r.toFixed(1),
ry: r.toFixed(1),
});
});
const transform = ({ x, y }) => `transform:translate(${x * sizeCell}px,${y * sizeCell}px)`;
const styles = [
`.s{
shape-rendering:geometricPrecision;
fill:var(--cs);
animation: none linear ${duration}ms infinite
}`,
...snakeParts.map((positions, i) => {
const id = `s${i}`;
const animationName = id;
return [
`@keyframes ${animationName} {` +
removeInterpolatedPositions(positions.map((tr, i, { length }) => ({ ...tr, t: i / length })))
.map((p) => `${percent(p.t)}%{${transform(p)}}`)
.join("") +
"}",
`.s.${id}{${transform(positions[0])};animation-name: ${animationName}}`,
];
}),
].flat();
return { svgElements, styles };
};
const removeInterpolatedPositions = (arr) => arr.filter((u, i, arr) => {
if (i - 1 < 0 || i + 1 >= arr.length)
return true;
const a = arr[i - 1];
const b = arr[i + 1];
const ex = (a.x + b.x) / 2;
const ey = (a.y + b.y) / 2;
// return true;
return !(Math.abs(ex - u.x) < 0.01 && Math.abs(ey - u.y) < 0.01);
});
/***/ }),
/***/ "../svg-creator/stack.ts":
/*!*******************************!*\
!*** ../svg-creator/stack.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "createStack": () => (/* binding */ createStack)
/* harmony export */ });
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils */ "../svg-creator/utils.ts");
const percent = (x) => (x * 100).toFixed(2);
const createStack = (cells, { sizeDot }, width, y, duration) => {
const svgElements = [];
const styles = [
`.u{
transform-origin: 0 0;
transform: scale(0,1);
animation: none linear ${duration}ms infinite;
}`,
];
const stack = cells
.slice()
.filter((a) => a.t !== null)
.sort((a, b) => a.t - b.t);
const blocks = [];
stack.forEach(({ color, t }) => {
const latest = blocks[blocks.length - 1];
if ((latest === null || latest === void 0 ? void 0 : latest.color) === color)
latest.ts.push(t);
else
blocks.push({ color, ts: [t] });
});
const m = width / stack.length;
let i = 0;
let nx = 0;
for (const { color, ts } of blocks) {
const id = "u" + (i++).toString(36);
const animationName = id;
const x = (nx * m).toFixed(1);
nx += ts.length;
svgElements.push((0,_utils__WEBPACK_IMPORTED_MODULE_0__.h)("rect", {
class: `u ${id}`,
height: sizeDot,
width: (ts.length * m + 0.6).toFixed(1),
x,
y,
}));
styles.push(`@keyframes ${animationName} {` +
[
...ts.map((t, i, { length }) => [
{ scale: i / length, t: t - 0.0001 },
{ scale: (i + 1) / length, t: t + 0.0001 },
]),
[{ scale: 1, t: 1 }],
]
.flat()
.map(({ scale, t }) => `${percent(t)}%{transform:scale(${scale.toFixed(2)},1)}`)
.join("\n") +
"}", `.u.${id}{fill:var(--c${color});animation-name:${animationName};transform-origin:${x}px 0}`);
}
return { svgElements, styles };
};
/***/ }),
/***/ "../svg-creator/utils.ts":
/*!*******************************!*\
!*** ../svg-creator/utils.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "h": () => (/* binding */ h),
/* harmony export */ "toAttribute": () => (/* binding */ toAttribute)
/* harmony export */ });
const h = (element, attributes) => `<${element} ${toAttribute(attributes)}/>`;
const toAttribute = (o) => Object.entries(o)
.filter(([, value]) => value !== null)
.map(([name, value]) => `${name}="${value}"`)
.join(" ");
/***/ }),
/***/ "../types/__fixtures__/snake.ts":
/*!**************************************!*\
!*** ../types/__fixtures__/snake.ts ***!
\**************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "snake1": () => (/* binding */ snake1),
/* harmony export */ "snake3": () => (/* binding */ snake3),
/* harmony export */ "snake4": () => (/* binding */ snake4),
/* harmony export */ "snake5": () => (/* binding */ snake5),
/* harmony export */ "snake9": () => (/* binding */ snake9)
/* harmony export */ });
/* harmony import */ var _snake__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../snake */ "../types/snake.ts");
const create = (length) => (0,_snake__WEBPACK_IMPORTED_MODULE_0__.createSnakeFromCells)(Array.from({ length }, (_, i) => ({ x: i, y: -1 })));
const snake1 = create(1);
const snake3 = create(3);
const snake4 = create(4);
const snake5 = create(5);
const snake9 = create(9);
/***/ }),
/***/ "../types/grid.ts":
/*!************************!*\
!*** ../types/grid.ts ***!
\************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "copyGrid": () => (/* binding */ copyGrid),
/* harmony export */ "createEmptyGrid": () => (/* binding */ createEmptyGrid),
/* harmony export */ "getColor": () => (/* binding */ getColor),
/* harmony export */ "gridEquals": () => (/* binding */ gridEquals),
/* harmony export */ "isEmpty": () => (/* binding */ isEmpty),
/* harmony export */ "isGridEmpty": () => (/* binding */ isGridEmpty),
/* harmony export */ "isInside": () => (/* binding */ isInside),
/* harmony export */ "isInsideLarge": () => (/* binding */ isInsideLarge),
/* harmony export */ "setColor": () => (/* binding */ setColor),
/* harmony export */ "setColorEmpty": () => (/* binding */ setColorEmpty)
/* harmony export */ });
const isInside = (grid, x, y) => x >= 0 && y >= 0 && x < grid.width && y < grid.height;
const isInsideLarge = (grid, m, x, y) => x >= -m && y >= -m && x < grid.width + m && y < grid.height + m;
const copyGrid = ({ width, height, data }) => ({
width,
height,
data: Uint8Array.from(data),
});
const getIndex = (grid, x, y) => x * grid.height + y;
const getColor = (grid, x, y) => grid.data[getIndex(grid, x, y)];
const isEmpty = (color) => color === 0;
const setColor = (grid, x, y, color) => {
grid.data[getIndex(grid, x, y)] = color || 0;
};
const setColorEmpty = (grid, x, y) => {
setColor(grid, x, y, 0);
};
/**
* return true if the grid is empty
*/
const isGridEmpty = (grid) => grid.data.every((x) => x === 0);
const gridEquals = (a, b) => a.data.every((_, i) => a.data[i] === b.data[i]);
const createEmptyGrid = (width, height) => ({
width,
height,
data: new Uint8Array(width * height),
});
/***/ }),
/***/ "../types/point.ts":
/*!*************************!*\
!*** ../types/point.ts ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "around4": () => (/* binding */ around4),
/* harmony export */ "pointEquals": () => (/* binding */ pointEquals)
/* harmony export */ });
const around4 = [
{ x: 1, y: 0 },
{ x: 0, y: -1 },
{ x: -1, y: 0 },
{ x: 0, y: 1 },
];
const pointEquals = (a, b) => a.x === b.x && a.y === b.y;
/***/ }),
/***/ "../types/snake.ts":
/*!*************************!*\
!*** ../types/snake.ts ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "copySnake": () => (/* binding */ copySnake),
/* harmony export */ "createSnakeFromCells": () => (/* binding */ createSnakeFromCells),
/* harmony export */ "getHeadX": () => (/* binding */ getHeadX),
/* harmony export */ "getHeadY": () => (/* binding */ getHeadY),
/* harmony export */ "getSnakeLength": () => (/* binding */ getSnakeLength),
/* harmony export */ "nextSnake": () => (/* binding */ nextSnake),
/* harmony export */ "snakeEquals": () => (/* binding */ snakeEquals),
/* harmony export */ "snakeToCells": () => (/* binding */ snakeToCells),
/* harmony export */ "snakeWillSelfCollide": () => (/* binding */ snakeWillSelfCollide)
/* harmony export */ });
const getHeadX = (snake) => snake[0] - 2;
const getHeadY = (snake) => snake[1] - 2;
const getSnakeLength = (snake) => snake.length / 2;
const copySnake = (snake) => snake.slice();
const snakeEquals = (a, b) => {
for (let i = 0; i < a.length; i++)
if (a[i] !== b[i])
return false;
return true;
};
/**
* return a copy of the next snake, considering that dx, dy is the direction
*/
const nextSnake = (snake, dx, dy) => {
const copy = new Uint8Array(snake.length);
for (let i = 2; i < snake.length; i++)
copy[i] = snake[i - 2];
copy[0] = snake[0] + dx;
copy[1] = snake[1] + dy;
return copy;
};
/**
* return true if the next snake will collide with itself
*/
const snakeWillSelfCollide = (snake, dx, dy) => {
const nx = snake[0] + dx;
const ny = snake[1] + dy;
for (let i = 2; i < snake.length - 2; i += 2)
if (snake[i + 0] === nx && snake[i + 1] === ny)
return true;
return false;
};
const snakeToCells = (snake) => Array.from({ length: snake.length / 2 }, (_, i) => ({
x: snake[i * 2 + 0] - 2,
y: snake[i * 2 + 1] - 2,
}));
const createSnakeFromCells = (points) => {
const snake = new Uint8Array(points.length * 2);
for (let i = points.length; i--;) {
snake[i * 2 + 0] = points[i].x + 2;
snake[i * 2 + 1] = points[i].y + 2;
}
return snake;
};
/***/ }),
/***/ "../../node_modules/css-tree/dist/data.js":
/*!************************************************!*\
!*** ../../node_modules/css-tree/dist/data.js ***!
\************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
"generic": true,
"types": {
"absolute-size": "xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large",
"alpha-value": "|",
"angle-percentage": "|",
"angular-color-hint": "",
"angular-color-stop": "&&?",
"angular-color-stop-list": "[ [, ]?]# , ",
"animateable-feature": "scroll-position|contents|",
"attachment": "scroll|fixed|local",
"attr()": "attr( ? [, ]? )",
"attr-matcher": "['~'|'|'|'^'|'$'|'*']? '='",
"attr-modifier": "i|s",
"attribute-selector": "'[' ']'|'[' [|] ? ']'",
"auto-repeat": "repeat( [auto-fill|auto-fit] , [? ]+ ? )",
"auto-track-list": "[? [|]]* ? [? [|]]* ?",
"baseline-position": "[first|last]? baseline",
"basic-shape": "||||",
"bg-image": "none|",
"bg-layer": "|| [/ ]?||||||||",
"bg-position": "[[left|center|right|top|bottom|]|[left|center|right|] [top|center|bottom|]|[center|[left|right] ?]&&[center|[top|bottom] ?]]",
"bg-size": "[|auto]{1,2}|cover|contain",
"blur()": "blur( )",
"blend-mode": "normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",
"box": "border-box|padding-box|content-box",
"brightness()": "brightness( )",
"calc()": "calc( )",
"calc-sum": " [['+'|'-'] ]*",
"calc-product": " ['*' |'/' ]*",
"calc-value": "|||( )",
"cf-final-image": "|",
"cf-mixing-image": "?&&",
"circle()": "circle( []? [at ]? )",
"clamp()": "clamp( #{3} )",
"class-selector": "'.' ",
"clip-source": "",
"color": "||||||currentcolor|",
"color-stop": "|",
"color-stop-angle": "{1,2}",
"color-stop-length": "{1,2}",
"color-stop-list": "[ [, ]?]# , ",
"combinator": "'>'|'+'|'~'|['||']",
"common-lig-values": "[common-ligatures|no-common-ligatures]",
"compat-auto": "searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button",
"composite-style": "clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor",
"compositing-operator": "add|subtract|intersect|exclude",
"compound-selector": "[? * [ *]*]!",
"compound-selector-list": "#",
"complex-selector": " [? ]*",
"complex-selector-list": "#",
"conic-gradient()": "conic-gradient( [from ]? [at ]? , )",
"contextual-alt-values": "[contextual|no-contextual]",
"content-distribution": "space-between|space-around|space-evenly|stretch",
"content-list": "[|contents|||||]+",
"content-position": "center|start|end|flex-start|flex-end",
"content-replacement": "",
"contrast()": "contrast( [] )",
"counter()": "counter( , ? )",
"counter-style": "|symbols( )",
"counter-style-name": "",
"counters()": "counters( , , ? )",
"cross-fade()": "cross-fade( , ? )",
"cubic-bezier-timing-function": "ease|ease-in|ease-out|ease-in-out|cubic-bezier( , , , )",
"deprecated-system-color": "ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText",
"discretionary-lig-values": "[discretionary-ligatures|no-discretionary-ligatures]",
"display-box": "contents|none",
"display-inside": "flow|flow-root|table|flex|grid|ruby",
"display-internal": "table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container",
"display-legacy": "inline-block|inline-list-item|inline-table|inline-flex|inline-grid",
"display-listitem": "?&&[flow|flow-root]?&&list-item",
"display-outside": "block|inline|run-in",
"drop-shadow()": "drop-shadow( {2,3} ? )",
"east-asian-variant-values": "[jis78|jis83|jis90|jis04|simplified|traditional]",
"east-asian-width-values": "[full-width|proportional-width]",
"element()": "element( , [first|start|last|first-except]? )|element( )",
"ellipse()": "ellipse( [{2}]? [at ]? )",
"ending-shape": "circle|ellipse",
"env()": "env( , ? )",
"explicit-track-list": "[? ]+ ?",
"family-name": "|+",
"feature-tag-value": " [|on|off]?",
"feature-type": "@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation",
"feature-value-block": " '{' '}'",
"feature-value-block-list": "+",
"feature-value-declaration": " : + ;",
"feature-value-declaration-list": "",
"feature-value-name": "",
"fill-rule": "nonzero|evenodd",
"filter-function": "|||||||||",
"filter-function-list": "[|]+",
"final-bg-layer": "<'background-color'>|||| [/ ]?||||||||",
"fit-content()": "fit-content( [|] )",
"fixed-breadth": "",
"fixed-repeat": "repeat( [] , [? ]+ ? )",
"fixed-size": "|minmax( , )|minmax( , )",
"font-stretch-absolute": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|",
"font-variant-css21": "[normal|small-caps]",
"font-weight-absolute": "normal|bold|",
"frequency-percentage": "|",
"general-enclosed": "[ )]|( )",
"generic-family": "serif|sans-serif|cursive|fantasy|monospace|-apple-system",
"generic-name": "serif|sans-serif|cursive|fantasy|monospace",
"geometry-box": "|fill-box|stroke-box|view-box",
"gradient": "|||||<-legacy-gradient>",
"grayscale()": "grayscale( )",
"grid-line": "auto||[&&?]|[span&&[||]]",
"historical-lig-values": "[historical-ligatures|no-historical-ligatures]",
"hsl()": "hsl( [/ ]? )|hsl( , , , ? )",
"hsla()": "hsla( [/ ]? )|hsla( , , , ? )",
"hue": "|",
"hue-rotate()": "hue-rotate( )",
"image": "||||||",
"image()": "image( ? [? , ?]! )",
"image-set()": "image-set( # )",
"image-set-option": "[|] [||type( )]",
"image-src": "|",
"image-tags": "ltr|rtl",
"inflexible-breadth": "||min-content|max-content|auto",
"inset()": "inset( {1,4} [round <'border-radius'>]? )",
"invert()": "invert( )",
"keyframes-name": "|",
"keyframe-block": "# { }",
"keyframe-block-list": "+",
"keyframe-selector": "from|to|",
"leader()": "leader( )",
"leader-type": "dotted|solid|space|",
"length-percentage": "|",
"line-names": "'[' * ']'",
"line-name-list": "[|]+",
"line-style": "none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset",
"line-width": "|thin|medium|thick",
"linear-color-hint": "",
"linear-color-stop": "