1
0
Fork 0

chore: Merged in cleaned up lily branch

This commit is contained in:
joostdecock 2024-05-04 16:23:03 +02:00
commit 13a390e707
30 changed files with 1931 additions and 134 deletions

View file

@ -85,6 +85,10 @@ jaeger:
'@freesewing/brian': *freesewing
'@freesewing/bent': *freesewing
'@freesewing/plugin-bust': *freesewing
lily:
peer:
'@freesewing/titan': *freesewing
'@freesewing/paco': *freesewing
new-design:
_:
'axios': &axios '1.6.8'

View file

@ -34,6 +34,8 @@ packageJson:
private: true
lab:
private: true
lily:
author: Anna Puk (https://github.com/anna-puk)
lucy:
author: SeaZeeZee (https://github.com/SeaZeeZee)
lunetius: &starf

View file

@ -554,14 +554,25 @@
"techniques": []
},
"naomiwu": {
"description": "A FreeSewing pattern for Naomi Wu's signature cargo skirt",
"code": "Joost De Cock",
"design": ["Naomi Wu", "Joost De Cock"],
"description": "A FreeSewing pattern for Naomi Wu's signature cargo skirt",
"design": [
"Naomi Wu",
"Joost De Cock"
],
"difficulty": 3,
"lab": false,
"org": false,
"tags": ["bottoms", "skirts"],
"techniques": ["button", "hem", "pocket", "lining"]
"tags": [
"bottoms",
"skirts"
],
"techniques": [
"button",
"hem",
"pocket",
"lining"
]
},
"noble": {
"code": "Wouter Van Wageningen",
@ -976,5 +987,21 @@
"hem",
"button"
]
},
"lily": {
"code": "Anna Puk, Joost De Cock",
"description": "A FreeSewing pattern for basic leggings",
"design": "Anna Puk",
"difficulty": 2,
"lab": true,
"org": true,
"tags": [
"bottoms"
],
"techniques": [
"elastic",
"curvedSeam",
"hem"
]
}
}

17
designs/lily/CHANGELOG.md Normal file
View file

@ -0,0 +1,17 @@
# Change log for: @freesewing/lily
## 3.0.0 (2023-09-30)
### Changed
- All FreeSewing packages are now ESM only.
- All FreeSewing packages now use named exports.
- Dropped support for NodeJS 14. NodeJS 18 (LTS/hydrogen) or more recent is now required.
This is the **initial release**, and the start of this change log.
> Prior to version 2, FreeSewing was not a JavaScript project.
> As such, that history is out of scope for this change log.

162
designs/lily/README.md Normal file
View file

@ -0,0 +1,162 @@
<p align='center'><a
href="https://www.npmjs.com/package/@freesewing/lily"
title="@freesewing/lily on NPM"
><img src="https://img.shields.io/npm/v/@freesewing/lily.svg"
alt="@freesewing/lily on NPM"/>
</a><a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img src="https://img.shields.io/npm/l/@freesewing/lily.svg?label=License"
alt="License: MIT"/>
</a><a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="Code quality on DeepScan"/>
</a><a
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen+label%3Apkg%3Alily"
title="Open issues tagged pkg:lily"
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:lily.svg?label=Issues"
alt="Open issues tagged pkg:lily"/>
</a><a
href="#contributors-"
title="All Contributors"
><img src="https://img.shields.io/badge/all_contributors-126-pink.svg"
alt="All Contributors"/>
</a></p><p align='center'><a
href="https://twitter.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-blue.svg?logo=twitter&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a><a
href="https://chat.freesewing.org"
title="Chat with us on Discord"
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"/>
</a><a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"/>
</a><a
href="https://instagram.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-E4405F.svg?logo=instagram&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a></p>
# @freesewing/lily
A FreeSewing pattern for basic leggings
# FreeSewing
> [!TIP]
>#### Support FreeSewing: Become a patron, or make a one-time donation 🥰
>
> FreeSewing is an open source project maintained by Joost De Cock and financially supported by the FreeSewing patrons.
>
> If you feel FreeSewing is worthwhile, and you can spend a few coins without
hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
## What am I looking at? 🤔
This repository is the FreeSewing *monorepo* holding all FreeSewing's websites, documentation, designs, plugins, and other NPM packages.
This folder holds: @freesewing/lily
If you're not entirely sure what to do or how to start, type this command:
```
npm run tips
```
> [!NOTE]
> If you don't want to set up a dev environment, you can run it in your browser:
>
> [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/freesewing/freesewing)
>
> We recommend that you fork our repository and then
> put `gitpod.io/#<entire-url-of-your-fork` into a browser
> to start up a browser-based dev environment of your own.
## About FreeSewing 💀
Where the world of makers and developers collide, that's where you'll find FreeSewing.
If you're a maker, checkout [freesewing.org](https://freesewing.org/) where you can generate
sewing patterns adapted to your measurements.
If you're a developer, the FreeSewing documentation lives at [freesewing.dev](https://freesewing.dev/).
The FreeSewing [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox
for parametric design of sewing patterns. But FreeSewing also provides a range
of [plugins](https://freesewing.dev/reference/plugins/) that further extend the
functionality of the platform.
If you have NodeJS installed, you can try it right now by running:
```bash
npx @freesewing/new-design
```
Getting started guides are available for:
- [Linux](https://freesewing.dev/tutorials/getting-started-linux/)
- [MacOS](https://freesewing.dev/tutorials/getting-started-mac/)
- [Windows](https://freesewing.dev/tutorials/getting-started-windows/)
The [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) will
show you how to create your first parametric design.
## Getting started ⚡
To get started with FreeSewing, you can spin up our development environment with:
```bash
npx @freesewing/new-design
```
To work with FreeSewing's monorepo, you'll need [NodeJS v18](https://nodejs.org), [lerna](https://lerna.js.org/) and [yarn](https://yarnpkg.com/) on your system.
Once you have those, clone (or fork) this repo and run `yarn kickstart`:
```bash
git clone git@github.com:freesewing/freesewing.git
cd freesewing
yarn kickstart
```
## Links 👩‍💻
**Official channels**
- 💻 Makers website: [FreeSewing.org](https://freesewing.org)
- 💻 Developers website: [FreeSewing.dev](https://freesewing.dev)
- ✅ [Support](https://github.com/freesewing/freesewing/issues/new/choose),
[Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing)
**Social media**
- 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
**Places the FreeSewing community hangs out**
- 💬 [Discord](https://discord.freesewing.org/)
- 💬 [Facebook](https://www.facebook.com/groups/627769821272714/)
- 💬 [Reddit](https://www.reddit.com/r/freesewing/)
## License: MIT 🤓
© [Joost De Cock](https://github.com/joostdecock).
See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details.
## Where to get help 🤯
For [Support](https://github.com/freesewing/freesewing/issues/new/choose),
please use the [Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing).

35
designs/lily/build.mjs Normal file
View file

@ -0,0 +1,35 @@
/* This script will build the package with esbuild */
import esbuild from 'esbuild'
import pkg from './package.json' assert { type: 'json' }
// Create banner based on package info
const banner = `/**
* ${pkg.name} | v${pkg.version}
* ${pkg.description}
* (c) ${new Date().getFullYear()} ${pkg.author}
* @license ${pkg.license}
*/`
// Shared esbuild options
const options = {
banner: { js: banner },
bundle: true,
entryPoints: ['src/index.mjs'],
format: 'esm',
outfile: 'dist/index.mjs',
external: ['@freesewing'],
metafile: process.env.VERBOSE ? true : false,
minify: process.env.NO_MINIFY ? false : true,
sourcemap: true,
}
// Let esbuild generate the build
const build = async () => {
const result = await esbuild.build(options).catch(() => process.exit(1))
if (process.env.VERBOSE) {
const info = await esbuild.analyzeMetafile(result.metafile)
console.log(info)
}
}
build()

4
designs/lily/data.mjs Normal file
View file

@ -0,0 +1,4 @@
// This file is auto-generated | All changes you make will be overwritten.
export const name = '@freesewing/lily'
export const version = '3.2.0'
export const data = { name, version }

View file

@ -0,0 +1,7 @@
{
"t": "Lily",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

24
designs/lily/i18n/en.json Normal file
View file

@ -0,0 +1,24 @@
{
"t": "Lily",
"d": "A FreeSewing pattern for basic leggings",
"p": {
"back": "Back",
"front": "Front",
"waistband": "Waistband"
},
"s": {
"adjustEase.t": "Adjust ease settings to match fabric stretch",
"adjustEase.d": "Knee, seat and waist ease should be set to fabric stretch * -1/10; click the button to adjust all three.",
"adjustEase": "adjust ease"
},
"o": {
"lengthReduction": {
"t": "Length reduction",
"d": "Controls how much the leggings are shortened with respect to ankle length"
},
"fabricStretch": {
"t": "Fabric stretch",
"d": "How much the fabric can stretch horizontally; this is used to calculate ease"
}
}
}

View file

@ -0,0 +1,7 @@
{
"t": "Lily",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

View file

@ -0,0 +1,7 @@
{
"t": "Lily",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

View file

@ -0,0 +1,8 @@
import en from './en.json' assert { type: 'json' }
import de from './de.json' assert { type: 'json' }
import es from './es.json' assert { type: 'json' }
import fr from './fr.json' assert { type: 'json' }
import nl from './nl.json' assert { type: 'json' }
import uk from './uk.json' assert { type: 'json' }
export const i18n = { en, de, es, fr, nl, uk }

View file

@ -0,0 +1,7 @@
{
"t": "Lily",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

View file

@ -0,0 +1,7 @@
{
"t": "Lily",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

74
designs/lily/package.json Normal file
View file

@ -0,0 +1,74 @@
{
"name": "@freesewing/lily",
"version": "3.2.0",
"description": "A FreeSewing pattern for basic leggings",
"author": "Anna Puk (https://github.com/anna-puk)",
"homepage": "https://freesewing.org/",
"repository": "github:freesewing/freesewing",
"license": "MIT",
"bugs": {
"url": "https://github.com/freesewing/freesewing/issues"
},
"funding": {
"type": "individual",
"url": "https://freesewing.org/patrons/join"
},
"keywords": [
"freesewing",
"design",
"diy",
"fashion",
"made to measure",
"parametric design",
"pattern",
"sewing",
"sewing pattern"
],
"type": "module",
"module": "dist/index.mjs",
"exports": {
".": {
"internal": "./src/index.mjs",
"default": "./dist/index.mjs"
}
},
"scripts": {
"build": "node build.mjs",
"build:all": "yarn build",
"clean": "rimraf dist",
"mbuild": "NO_MINIFY=1 node build.mjs",
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
"test": "npx mocha tests/*.test.mjs",
"vbuild": "VERBOSE=1 node build.mjs",
"lab": "cd ../../sites/lab && yarn start",
"tips": "node ../../scripts/help.mjs",
"lint": "npx eslint 'src/**' 'tests/*.mjs'",
"prettier": "npx prettier --write 'src/*.mjs' 'tests/*.mjs'",
"testci": "NODE_OPTIONS=\"--conditions=internal\" npx mocha tests/*.test.mjs --reporter ../../tests/reporters/terse.js",
"wbuild": "node build.mjs",
"wbuild:all": "yarn wbuild"
},
"peerDependencies": {
"@freesewing/core": "3.2.0",
"@freesewing/titan": "3.2.0",
"@freesewing/paco": "3.2.0"
},
"dependencies": {},
"devDependencies": {
"mocha": "10.3.0",
"chai": "5.1.0",
"@freesewing/models": "3.2.0",
"@freesewing/plugin-timing": "3.2.0"
},
"files": [
"dist/*",
"README.md"
],
"publishConfig": {
"access": "public",
"tag": "latest"
},
"engines": {
"node": ">= 18.17.0 <22"
}
}

590
designs/lily/src/back.mjs Normal file
View file

@ -0,0 +1,590 @@
import { back as titanBack } from '@freesewing/titan'
function draftLilyBack({
points,
Point,
paths,
Path,
measurements,
options,
complete,
paperless,
store,
macro,
utils,
snippets,
Snippet,
sa,
absoluteOptions,
part,
log,
units,
}) {
//TODO: implement stretch setting to replace ease
// work-around: flag it
const stretchAsEase = -options.fabricStretch / 10
const easeTol = 0.005
if (
Math.abs(options.waistEase - stretchAsEase) > easeTol ||
Math.abs(options.seatEase - stretchAsEase) > easeTol ||
Math.abs(options.kneeEase - stretchAsEase) > easeTol
) {
store.flag.note({
msg: `lily:adjustEase`,
replace: {
stretch: units(options.fabricStretch),
ease: stretchAsEase,
},
suggest: {
text: 'adjustEase',
icon: 'options',
update: {
settings: [
'options',
{
...options,
waistEase: stretchAsEase,
seatEase: stretchAsEase,
kneeEase: stretchAsEase,
},
],
},
},
})
}
/*
* Helper method to draw the inseam path
*/
const drawInseam = () =>
new Path()
.move(points.fork)
.curve(points.forkCp2, points.kneeInCp1, points.kneeIn)
.curve(points.kneeInCp2, points.floorInCp2, points.floorIn)
/*
* Helper method to draw the outseam path
*/
const drawOutseam = () => {
const waistOut = points.styleWaistOutLily || points.waistOut
if (points.waistOut.x > points.seatOut.x)
return new Path()
.move(points.floorOut)
.curve(points.floorOutCp2, points.kneeOutCp1, points.kneeOut)
.curve(points.kneeOutCp2, points.seatOut, waistOut)
else
return new Path()
.move(points.floorOut)
.curve(points.floorOutCp2, points.kneeOutCp1, points.kneeOut)
.curve(points.kneeOutCp2, points.seatOutCp1, points.seatOut)
.curve_(points.seatOutCp2, waistOut)
}
/*
* Helper method to draw the outline path
*/
const drawPath = () => {
const waistIn = points.styleWaistInLily || points.waistIn
return drawInseam()
.line(points.floorOut)
.join(drawOutseam())
.line(waistIn)
.line(points.crossSeamCurveStart)
.curve(points.crossSeamCurveCp1, points.crossSeamCurveCp2, points.fork)
.close()
}
/*
* Helper method to calculate the length of the cross seam
*/
const crossSeamDelta = () =>
new Path()
.move(points.waistIn)
.line(points.crossSeamCurveStart)
.curve(points.crossSeamCurveCp1, points.crossSeamCurveCp2, points.fork)
.length() - measurements.crossSeamBack
/*
* Helper method to (re)draw the cross seam
*/
const drawCrossSeam = () => {
points.crossSeamCurveStart = points.waistIn.shiftFractionTowards(
points.cbSeat,
options.crossSeamCurveStart
)
points.crossSeamCurveMax = utils.beamsIntersect(
points.waistIn,
points.cbSeat,
points.fork,
points.fork.shift(0, 1) // beams have infinite length anyway
)
points.crossSeamCurveCp1 = points.crossSeamCurveStart.shiftFractionTowards(
points.crossSeamCurveMax,
options.crossSeamCurveBend
)
points.crossSeamCurveCp2 = points.fork
.shiftFractionTowards(points.crossSeamCurveMax, options.crossSeamCurveBend)
.rotate(options.crossSeamCurveAngle, points.fork)
}
// NOTE: majority of points re-used from titan
// shape at the ankle (unlike titan)
const halfAnkle =
measurements.ankle * (1 + options.fabricStretch) > measurements.heel
? (1 - options.fabricStretch / 10) * (measurements.ankle / 4)
: measurements.heel / 4 / (1 + options.fabricStretch)
// NOTE: for shortened leggings, this may not have been necessary...
points.floorOut = points.floor.shift(0, halfAnkle)
points.floorIn = points.floorOut.flipX(points.floor)
store.set('halfAnkle', halfAnkle)
points.floorInCp2 = points.floorIn.shift(90, points.knee.dy(points.floor) / 3)
points.kneeInCp2 = points.kneeIn.shift(90, -points.knee.dy(points.floor) / 3)
points.floorOutCp2 = points.floorOut.shift(90, points.knee.dy(points.floor) / 3)
points.kneeOutCp1 = points.kneeOut.shift(90, -points.knee.dy(points.floor) / 3)
// other control points have already been calculated in titan:
// Control points to shape the legs towards the seat
// Balance the waist
// Cross seam
drawCrossSeam()
//Uncomment the line below to see the seam prior to fitting the cross seam
// paths.seam1 = drawPath().attr('class', 'dashed lining')
// Should we fit the cross seam?
if (options.fitCrossSeam && options.fitCrossSeamBack) {
let delta = crossSeamDelta()
let run = 0
do {
run++
// Remedy A: Slash and spread
for (const i of ['waistIn', 'waistOut'])
points[i] = points[i].rotate(delta / 15, points.seatOut)
// Remedy B: Nudge the fork inwards/outwards
points.fork = points.fork.shift(0, delta / 5)
points.forkCp2 = points.crossSeamCurveCp2.rotate(-90, points.fork)
drawCrossSeam()
delta = crossSeamDelta()
// Uncomment the line beloe this to see all iterations
// paths[`try${run}`] = drawPath().attr('class', 'dotted')
} while (Math.abs(delta) > 1 && run < 15)
}
// Store inseam & outseam length
store.set('inseamBack', drawInseam().length())
store.set('outseamBack', drawOutseam().length())
// Only now style the waist lower if requested
// Note: redo this for lily even though it was already done for titan;
// calculation for titan happened using its own seam lengths
store.set('waistbandWidth', absoluteOptions.waistbandWidth) // used in lilyWaistband
if (options.waistHeight < 1 || absoluteOptions.waistbandWidth > 0) {
points.styleWaistOutLily = drawOutseam()
.reverse()
.shiftAlong(
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth
)
points.styleWaistInLily = utils.beamsIntersect(
points.styleWaistOutLily,
points.styleWaistOutLily.shift(points.waistOut.angle(points.waistIn), 10),
points.waistIn,
points.crossSeamCurveStart
)
} else {
points.styleWaistInLily = points.waistIn.clone()
points.styleWaistOutLily = points.waistOut.clone()
}
// Adapt the vertical placement of the seat control point to the lowered waist
points.seatOutCp2.y = points.seatOut.y - points.styleWaistOutLily.dy(points.seatOut) / 2
let test = points.styleWaistInLily.dist(points.styleWaistOutLily)
console.log('back waist length', test)
store.set('backWaist', points.styleWaistInLily.dist(points.styleWaistOutLily))
// Paths
paths.seam = drawPath().attr('class', 'fabric')
// adjust the length (at the bottom)
let extendBeyondKnee = 1
if (options.lengthReduction > 0) {
let requestedLength = (1 - options.lengthReduction) * measurements.waistToFloor
// leggings must reach to fork at least, so define a minimum
const waistToFork = points.waistX.dy(points.fork)
if (waistToFork >= 0.999 * requestedLength) {
log.warn('length reduction capped; cutting off at fork')
// add one percent to waistToFork to ensure that path length is nonzero
requestedLength = waistToFork * 1.01
}
// work-around to avoid splitting exactly at the knee
// (due to a bug, splitting a path at a node is not possible)
if (
0.999 < requestedLength / measurements.waistToKnee &&
requestedLength / measurements.waistToKnee < 1.001
) {
requestedLength = 1.001 * measurements.waistToKnee
}
points.bottom = points.waistX.shift(270, requestedLength)
let upperPoint, upperCp
if (requestedLength < measurements.waistToKnee) {
extendBeyondKnee = 0
// 'cut' between fork and knee
if (points.waistOut.x > points.seatOut.x) {
upperPoint = points.styleWaistOutLily
upperCp = points.seatOut
} else {
upperPoint = points.seatOut
upperCp = points.seatOutCp1
}
points.bottomOut = utils.beamIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeOut,
points.kneeOutCp2,
upperCp,
upperPoint
)
points.bottomIn = utils.beamIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeIn,
points.kneeInCp1,
points.forkCp2,
points.fork
)
} else {
// 'cut' between knee and 'floor'
points.bottomOut = utils.beamIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeOut,
points.kneeOutCp1,
points.floorOutCp2,
points.floorOut
)
points.bottomIn = utils.beamIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeIn,
points.kneeInCp2,
points.floorInCp2,
points.floorIn
)
}
// define the three parts of the path, then combine
paths.bottom = new Path().move(points.bottomIn).line(points.bottomOut)
const halves = paths.seam.split(points.bottomIn)
paths.upperInseam = halves[0]
const halves2 = halves[1].split(points.bottomOut)
paths.upperOutseam = halves2[1]
paths.seam = paths.upperInseam.join(paths.bottom).join(paths.upperOutseam)
// store requestedLength for use in front part
store.set('requestedLength', requestedLength)
} else {
// define the same three parts of the path as when length reduction is enabled, then combine
// first define the points (also used for paperless)
points.bottom = points.floor
points.bottomIn = points.floorIn
points.bottomOut = points.floorOut
paths.bottom = new Path().move(points.bottomIn).line(points.bottomOut)
// note: upperOutseam contains waist and cross seam as well
paths.upperInseam = drawInseam()
paths.upperOutseam = drawOutseam().join(
new Path()
.move(points.styleWaistOutLily)
.line(points.styleWaistInLily)
.line(points.crossSeamCurveStart)
.curve(points.crossSeamCurveCp1, points.crossSeamCurveCp2, points.fork)
)
paths.bottom.hide()
paths.upperInseam.hide()
paths.upperOutseam.hide()
}
points.grainlineTop.y = points.styleWaistOutLily.y
points.grainlineBottom.y = points.bottom.y
macro('grainline', {
from: points.grainlineTop,
to: points.grainlineBottom,
})
points.logoAnchor = new Point(points.crossSeamCurveStart.x / 2, points.fork.y)
snippets.logo = new Snippet('logo', points.logoAnchor)
points.scalebox = points.logoAnchor.shiftFractionTowards(
points.styleWaistOutLily.shiftFractionTowards(points.styleWaistInLily, 0.5),
0.5
)
macro('scalebox', { at: points.scalebox })
points.titleAnchor = points.logoAnchor.shift(-90, 60)
macro('title', {
nr: 1,
title: 'back',
at: points.titleAnchor,
})
//notches
if (options.fitGuides) {
points.waistMid = points.waistOut.shiftFractionTowards(points.waistIn, 0.5)
// shift + rotate (below) is equivalent to shifting measurements.waistToSeat perpendicular to the waistIn-waistMid line
points.seatMid = points.waistMid
.shiftTowards(points.waistIn, measurements.waistToSeat)
.rotate(90, points.waistMid)
points.seatInTarget = points.seatOut.shiftOutwards(points.seatMid, measurements.seat / 4)
points.seatOutTarget = points.seatMid.shiftTowards(points.seatOut, measurements.seat / 4)
// shift + rotate (below) is equivalent to shifting measurements.waistToHips perpendicular to the waistIn-waistOut line
points.hipsInTarget = points.waistIn
.shiftTowards(points.waistOut, measurements.waistToHips)
.rotate(-90, points.waistIn)
points.hipsOutTarget = points.waistOut
.shiftTowards(points.waistIn, measurements.waistToHips)
.rotate(90, points.waistOut)
points.hipsIn = utils.beamsIntersect(
points.hipsOutTarget,
points.hipsInTarget,
points.waistIn,
points.crossSeamCurveStart
)
points.crossSeamCurveStartMid = utils.beamsIntersect(
points.crossSeamCurveStart,
points.crossSeamCurveStart.shift(points.waistIn.angle(points.waistOut), 1),
points.waistMid,
points.seatMid
)
if (points.seatMid.y > points.crossSeamCurveStartMid.y) {
points.seatIn = utils.lineIntersectsCurve(
points.seatMid,
points.seatInTarget,
points.crossSeamCurveStart,
points.crossSeamCurveCp1,
points.crossSeamCurveCp2,
points.fork
)
} else {
points.seatIn = utils.beamsIntersect(
points.seatMid,
points.seatInTarget,
points.waistIn,
points.crossSeamCurveStart
)
}
if (points.waistOut.x > points.seatOut.x) {
points.hipsOut = utils.lineIntersectsCurve(
points.hipsIn,
points.hipsIn.rotate(180, points.hipsOutTarget),
points.kneeOut,
points.kneeOutCp2,
points.seatOut,
points.waistOut
)
points.seatOutNotch = utils.lineIntersectsCurve(
points.seatMid,
points.seatOutTarget,
points.kneeOut,
points.kneeOutCp2,
points.seatOut,
points.waistOut
)
} else {
points.hipsOut = utils.lineIntersectsCurve(
points.hipsIn,
points.hipsIn.rotate(180, points.hipsOutTarget),
points.seatOut,
points.seatOutCp2,
points.waistOut,
points.waistOut
)
points.seatOutNotch = points.seatOut
}
points.kneeOutNotch = points.kneeOut
points.kneeInNotch = points.kneeIn
macro('sprinkle', {
snippet: 'notch',
on: ['seatOutNotch'],
})
if (extendBeyondKnee) {
macro('sprinkle', {
snippet: 'notch',
on: ['kneeInNotch', 'kneeOutNotch'],
})
}
macro('sprinkle', {
snippet: 'bnotch',
on: ['crossSeamCurveStart', 'seatIn'],
})
if (complete) {
paths.seatline = new Path()
.move(points.seatIn)
.line(points.seatOutNotch)
.addClass('fabric help')
.addText('Seat Line', 'center')
if (
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth <
measurements.waistToHips
) {
snippets.hipsIn = new Snippet('bnotch', points.hipsIn)
snippets.hipsOut = new Snippet('notch', points.hipsOut)
paths.hipline = new Path()
.move(points.hipsIn)
.line(points.hipsOut)
.addClass('fabric help')
.addText('Hip Line', 'center')
}
}
}
if (sa) {
paths.saBase = paths.upperOutseam.join(paths.upperInseam).hide()
paths.hemBase = paths.bottom.hide()
paths.sa = paths.hemBase
.offset(sa * 3)
.join(paths.saBase.offset(sa))
.close()
.addClass('fabric sa')
}
if (paperless) {
// Help construct cross seam
paths.hint = new Path()
.move(points.crossSeamCurveStart)
.line(points.crossSeamCurveMax)
.line(points.fork)
.addClass('note lashed')
macro('hd', {
id: 'wHem',
from: points.bottomIn,
to: points.bottomOut,
y: points.bottomIn.y - 30,
})
macro('hd', {
id: 'wHemLeft',
from: points.bottomIn,
to: points.bottom,
y: points.bottomIn.y - 15,
})
macro('hd', {
id: 'wHemRight',
from: points.bottom,
to: points.bottomOut,
y: points.bottomIn.y - 15,
})
macro('vd', {
id: 'hHemToSideWaist',
from: points.bottomOut,
to: points.styleWaistOutLily,
x:
(points.seatOut.x > points.styleWaistOutLily.x
? points.seatOut.x
: points.styleWaistOutLily.x) +
sa +
15,
})
macro('vd', {
id: 'hHemToFork',
from: points.bottomIn,
to: points.fork,
x: points.fork.x - sa - 15,
})
macro('vd', {
id: 'hForkToCbWaist',
from: points.fork,
to: points.styleWaistInLily,
x: points.fork.x - sa - 15,
})
macro('vd', {
id: 'hFull',
from: points.bottomIn,
to: points.styleWaistInLily,
x: points.fork.x - sa - 30,
})
macro('vd', {
id: 'hStartCrotchCurveToCbWaist',
from: points.crossSeamCurveStart,
to: points.styleWaistInLily,
x: points.crossSeamCurveStart.x - sa - 15,
})
macro('hd', {
id: 'wCbWaistToPleat',
from: points.styleWaistInLily,
to: points.grainlineTop,
y: points.styleWaistInLily.y - sa - 15,
})
macro('hd', {
id: 'wStartCrotchCurveToPleat',
from: points.crossSeamCurveStart,
to: points.grainlineTop,
y: points.styleWaistInLily.y - sa - 30,
})
macro('hd', {
id: 'wForkProjectionToPleat',
from: points.crossSeamCurveMax,
to: points.grainlineTop,
y: points.styleWaistInLily.y - sa - 45,
})
macro('hd', {
id: 'wForkToPleat',
from: points.fork,
to: points.grainlineTop,
y: points.styleWaistInLily.y - sa - 60,
})
macro('hd', {
id: 'wPleatToSideWaist',
from: points.grainlineTop,
to: points.styleWaistOutLily,
y: points.styleWaistInLily.y - sa - 15,
})
if (points.seatOut.x > points.styleWaistOutLily.x) {
macro('hd', {
id: 'wPleatToSideWaistAlt',
from: points.grainlineTop,
to: points.seatOut,
y: points.styleWaistInLily.y - sa - 30,
})
}
}
return part
}
export const back = {
name: 'lily.back',
from: titanBack,
//after: titanFront,
measurements: [
'ankle',
'heel', // secondary measurement, used instead of ankle
],
options: {
fitGuides: { bool: false, menu: 'advanced' },
fitKnee: { bool: true, hide: true },
legBalance: 0.5, // between back and front parts
waistBalance: 0.5,
crotchDrop: { pct: 0, min: 0, max: 15, menu: 'advanced' }, // 'downgrade' to advanced menu
waistHeight: { ...titanBack.options.waistHeight, pct: 50 }, // halfway between waist and hips
fabricStretch: { pct: 40, min: 0, max: 50, menu: 'fit' },
waistEase: { pct: -4, min: -20, max: 0, menu: 'fit' }, // -fabricStretch/10,
seatEase: { pct: -4, min: -20, max: 0, menu: 'fit' }, // -fabricStretch/10,
kneeEase: { pct: -4, min: -20, max: 0, menu: 'fit' }, // -fabricStretch/10,
//test: {pct: back.options.fabricStretch/2, min: 0, max: 50, menu: 'fit'},
lengthBonus: 0,
lengthReduction: {
pct: 0,
min: 0,
max: 100,
toAbs: (pct, { measurements }) => measurements.waistToFloor * pct,
menu: 'style',
},
waistbandWidth: { ...titanBack.options.waistbandWidth, menu: 'style' },
},
hide: 'HIDE_TREE',
draft: draftLilyBack,
}

602
designs/lily/src/front.mjs Normal file
View file

@ -0,0 +1,602 @@
import { front as titanFront } from '@freesewing/titan'
import { back } from './back.mjs'
function draftLilyFront({
points,
Point,
paths,
Path,
measurements,
options,
complete,
paperless,
store,
macro,
utils,
snippets,
Snippet,
sa,
absoluteOptions,
log,
part,
}) {
/*
* Helper method to draw the inseam path
*/
const drawInseam = () =>
new Path()
.move(points.floorIn)
.curve(points.floorInCp2, points.kneeInCp1, points.kneeIn)
.curve(points.kneeInCp2, points.forkCp1, points.fork)
/*
* Helper method to draw the outseam path
*/
const drawOutseam = () => {
const waistOut = points.styleWaistOutLily || points.waistOut
return points.waistOut.x < points.seatOut.x
? new Path()
.move(waistOut)
.curve(points.seatOut, points.kneeOutCp1, points.kneeOut)
.curve(points.kneeOutCp2, points.floorOutCp2, points.floorOut)
: new Path()
.move(waistOut)
._curve(points.seatOutCp1, points.seatOut)
.curve(points.seatOutCp2, points.kneeOutCp1, points.kneeOut)
.curve(points.kneeOutCp2, points.floorOutCp2, points.floorOut)
}
/*
* Helper method to draw the outline path
*/
const drawPath = () => {
const waistIn = points.styleWaistInLily || points.waistIn
const waistOut = points.styleWaistOutLily || points.waistOut
return drawOutseam()
.line(points.floorIn)
.join(drawInseam())
.curve(points.crotchSeamCurveCp1, points.crotchSeamCurveCp2, points.crotchSeamCurveStart)
.line(waistIn)
.line(waistOut)
.close()
}
/*
* Helper method to calculate the length of the crotch seam
*/
const crotchSeamDelta = () =>
new Path()
.move(points.waistIn)
.line(points.crotchSeamCurveStart)
.curve(points.crotchSeamCurveCp2, points.crotchSeamCurveCp1, points.fork)
.length() - measurements.crossSeamFront
/*
* Helper method to (re)draw the crotch seam
*/
const drawCrotchSeam = () => {
points.crotchSeamCurveStart = points.waistIn.shiftFractionTowards(
points.cfSeat,
options.crotchSeamCurveStart
)
points.crotchSeamCurveMax = utils.beamsIntersect(
points.waistIn,
points.cfSeat,
points.fork,
points.fork.shift(0, 666)
)
points.crotchSeamCurveCp1 = points.fork
.shiftFractionTowards(points.crotchSeamCurveMax, options.crotchSeamCurveBend)
.rotate(options.crotchSeamCurveAngle * -1, points.fork)
points.crotchSeamCurveCp2 = points.crotchSeamCurveStart.shiftFractionTowards(
points.crotchSeamCurveMax,
options.crotchSeamCurveBend
)
points.forkCp1 = points.crotchSeamCurveCp1.rotate(90, points.fork)
}
/*
* Helper method to calculate the inseam delta
*/
const inseamDelta = () => drawInseam().length() - store.get('inseamBack')
/*
* Helper method to calculate the outseam delta
*/
const outseamDelta = () => drawOutseam().length() - store.get('outseamBack')
/*
* Helper method to lengthen/shorten both inseam and outseam
*/
const adaptInseamAndOutseam = () => {
const shift = [
'kneeInCp1',
'kneeInCp2',
'kneeOutCp1',
'kneeOutCp2',
'kneeIn',
'kneeOut',
'knee',
'floorInCp2',
'floorIn',
'floorOutCp2',
'floorOut',
'floor',
'grainlineBottom',
]
let delta = seamDelta()
let run = 0
do {
run++
for (const i of shift) points[i] = points[i].shift(90, delta)
delta = seamDelta()
} while (Math.abs(delta) > 1 && run < 10)
}
/*
* Helper method to determine the delta common when both inseam and outseam
* are either too long or too short
*/
const seamDelta = () => {
const inseam = inseamDelta()
const outseam = outseamDelta()
return Math.abs(inseam) > Math.abs(outseam) ? outseam : inseam
}
/*
* Helper method that can fit either inseam or outseam
*/
const adaptSeam = (side) => {
const out = side === 'out' ? true : false
const rotate = [
'cfSeat',
'crotchSeamCurveCp1',
'crotchSeamCurveCp2',
'crotchSeamCurveStart',
'waistIn',
'cfWaist',
'waistOut',
]
rotate.push(out ? 'seatOut' : 'fork')
const deltaMethod = out ? outseamDelta : inseamDelta
let run = 0
let delta = deltaMethod()
do {
for (const i of rotate)
points[i] = points[i].rotate(
(delta / 10) * (out ? 1 : -1),
points[out ? 'fork' : 'seatOut']
)
run++
delta = deltaMethod()
} while (Math.abs(delta) > 1 && run < 20)
}
const adaptOutseam = () => adaptSeam('out')
const adaptInseam = () => adaptSeam('in')
// NOTE: majority of points re-used from titan
// shape at the ankle (unlike titan)
points.floorOut = points.floor.shift(180, store.get('halfAnkle'))
points.floorIn = points.floorOut.flipX(points.floor)
// Control points between knee and ankle
points.floorInCp2 = points.floorIn.shift(90, points.knee.dy(points.floor) / 3)
points.kneeInCp1 = points.kneeIn.shift(90, -points.knee.dy(points.floor) / 3)
points.floorOutCp2 = points.floorOut.shift(90, points.knee.dy(points.floor) / 3)
points.kneeOutCp2 = points.kneeOut.shift(90, -points.knee.dy(points.floor) / 3)
// other control points have already been calculated in titan
// Control points to shape the legs towards the seat
// Balance the waist
// Draw initial crotch seam
drawCrotchSeam()
// Uncomment this to see the outline prior to fitting the crotch seam
//paths.seam1 = drawPath().attr('class', 'dashed lining')
if (options.fitCrossSeam && options.fitCrossSeamFront) {
let delta = crotchSeamDelta()
let run = 0
do {
run++
// Remedy A: Slash and spread
for (const i of ['waistIn', 'waistOut', 'cfWaist'])
points[i] = points[i].rotate(delta / -15, points.seatOut)
// Remedy B: Nudge the fork inwards/outwards
points.fork = points.fork.shift(180, delta / 5)
drawCrotchSeam()
delta = crotchSeamDelta()
// Uncomment the line below this to see all iterations
//paths[`try${run}`] = drawPath().attr('class', 'dotted')
} while (Math.abs(delta) > 1 && run < 15)
}
// Uncomment this to see the outline prior to fitting the inseam & outseam
//paths.seam2 = drawPath().attr('class', 'dotted interfacing')
/*
* With the cross seams matched back and front,
* all that's left is to match the inseam and outseam
*/
// When both are too short/long, adapt the leg length
if ((inseamDelta() < 0 && outseamDelta() < 0) || (inseamDelta() > 0 && outseamDelta() > 0))
adaptInseamAndOutseam()
// Now one is ok, the other will be adapted
adaptOutseam()
adaptInseam()
// Changing one will ever so slightly impact the other, so let's run both again to be sure
adaptOutseam()
adaptInseam()
// Only now style the waist lower if requested
// Note: redo this for lily even though it was already done for titan;
// calculation for titan happened using its own seam lengths
if (options.waistHeight < 1 || absoluteOptions.waistbandWidth > 0) {
points.styleWaistOutLily = drawOutseam().shiftAlong(
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth
)
points.styleWaistInLily = utils.beamsIntersect(
points.styleWaistOutLily,
points.styleWaistOutLily.shift(points.waistOut.angle(points.waistIn), 10),
points.waistIn,
points.crotchSeamCurveStart
)
} else {
points.styleWaistInLily = points.waistIn.clone()
points.styleWaistOutLily = points.waistOut.clone()
}
store.set('frontWaist', points.styleWaistInLily.dist(points.styleWaistOutLily))
// Now that the top of the garment has been lowered, adjust the
// crotchSeamCurveStart so it doesn't start above the top of the garment.
if (points.crotchSeamCurveStart.y < points.styleWaistInLily.y) {
points.crotchSeamCurveStart = points.styleWaistInLily.clone()
}
// Seamline
paths.seam = drawPath().attr('class', 'fabric')
// adjust the length (at the bottom)
let extendBeyondKnee = 1
if (options.lengthReduction > 0) {
let requestedLength = store.get('requestedLength')
// leggings must reach to fork at least, so define a minimum
let waistToFork = points.waistX.dy(points.fork)
let waistToKnee = points.waistX.dy(points.knee) // adapting the seams may have shifted the knee up or down
if (waistToFork > requestedLength) {
//log.warning('length reduction capped; cutting off at fork') // log only for back part
// add one percent to waistToFork to ensure that path length is nonzero
requestedLength = waistToFork * 1.01
}
// work-around to avoid splitting exactly at the knee
// (due to a bug, splitting a path at a node is not possible)
if (0.999 < requestedLength / waistToKnee && requestedLength / waistToKnee < 1.001) {
requestedLength = 1.001 * waistToKnee
}
points.bottom = points.waistX.shift(270, requestedLength)
let upperPoint, upperCp
if (requestedLength < waistToKnee) {
extendBeyondKnee = 0
// 'cut' between fork and knee
if (points.waistOut.x < points.seatOut.x) {
upperPoint = points.styleWaistOutLily
upperCp = points.seatOut
} else {
upperPoint = points.seatOut
upperCp = points.seatOutCp2
}
points.bottomOut = utils.lineIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeOut,
points.kneeOutCp1,
upperCp,
upperPoint
)
points.bottomIn = utils.lineIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeIn,
points.kneeInCp2,
points.forkCp1,
points.fork
)
} else {
// 'cut' between knee and 'floor'
points.bottomOut = utils.lineIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeOut,
points.kneeOutCp2,
points.floorOutCp2,
points.floorOut
)
points.bottomIn = utils.lineIntersectsCurve(
points.bottom.shift(0, 999),
points.bottom.shift(180, 999),
points.kneeIn,
points.kneeInCp1,
points.floorInCp2,
points.floorIn
)
}
// define the three parts of the path, then combine
paths.bottom = new Path().move(points.bottomOut).line(points.bottomIn)
const halves = paths.seam.split(points.bottomOut)
paths.upperOutseam = halves[0]
const halves2 = halves[1].split(points.bottomIn)
paths.upperInseam = halves2[1]
paths.seam = paths.upperOutseam.join(paths.bottom).join(paths.upperInseam)
} else {
// define the same three parts of the path as when length reduction is enabled, then combine
// first define the points (also used for paperless)
points.bottom = points.floor
points.bottomIn = points.floorIn
points.bottomOut = points.floorOut
paths.bottom = new Path().move(points.bottomOut).line(points.bottomIn)
// note: upperInseam contains waist and cross seam as well
paths.upperInseam = drawInseam()
.curve(points.crotchSeamCurveCp1, points.crotchSeamCurveCp2, points.crotchSeamCurveStart)
.line(points.styleWaistInLily)
.line(points.styleWaistOutLily)
paths.upperOutseam = drawOutseam()
paths.bottom.hide()
paths.upperInseam.hide()
paths.upperOutseam.hide()
}
if (complete) {
points.grainlineTop.y = points.styleWaistInLily.y
points.grainlineBottom.y = points.bottom.y
macro('grainline', {
from: points.grainlineTop,
to: points.grainlineBottom,
})
points.logoAnchor = new Point(points.crotchSeamCurveStart.x / 2, points.fork.y)
snippets.logo = new Snippet('logo', points.logoAnchor)
points.titleAnchor = points.logoAnchor.shift(-90, 60)
macro('title', {
nr: 2,
title: 'front',
at: points.titleAnchor,
})
//notches
if (options.fitGuides) {
points.waistMid = points.waistOut.shiftFractionTowards(points.waistIn, 0.5)
points.seatMid = points.waistMid
.shiftTowards(points.waistOut, measurements.waistToSeat)
.rotate(90, points.waistMid)
points.seatInTarget = points.seatOut.shiftOutwards(points.seatMid, measurements.seat / 4)
points.seatOutTarget = points.seatMid.shiftTowards(points.seatOut, measurements.seat / 4)
points.hipsInTarget = points.waistIn
.shiftTowards(points.waistOut, measurements.waistToHips)
.rotate(90, points.waistIn)
points.hipsOutTarget = points.waistOut
.shiftTowards(points.waistIn, measurements.waistToHips)
.rotate(-90, points.waistOut)
points.hipsIn = utils.beamsIntersect(
points.hipsOutTarget,
points.hipsInTarget,
points.waistIn,
points.crotchSeamCurveStart
)
// intersection between the vertical line from waistMid to seatMid and a line parallel to waistIn-waistOut that goes through crotchSeamCurveStart
points.crotchSeamCurveStartMid = utils.beamsIntersect(
points.crotchSeamCurveStart,
points.crotchSeamCurveStart.shift(points.waistIn.angle(points.waistOut), 1),
points.waistMid,
points.seatMid
)
// check whether intersection occurs above or below crotch seam curve start
points.seatInTemp = utils.beamsIntersect(
points.seatMid,
points.seatInTarget,
points.crotchSeamCurveStart,
points.waistIn
) // NOTE: guaranteed to return a Point since the lines cannot be parallel
if (points.seatInTemp.y <= points.crotchSeamCurveStartMid.y) {
// intersection is above the crotch seam curve start, so on the line segment
points.seatIn = points.seatInTemp.clone()
} else if (points.seatInTemp.y > points.fork.y) {
// seat appears to be below crotch
log.warn('seat estimated to be below crotch; this is probably not accurate')
points.seatIn = points.fork.clone()
} else {
points.seatIn = utils.beamIntersectsCurve(
points.seatMid,
points.seatInTarget,
points.crotchSeamCurveStart,
points.crotchSeamCurveCp2,
points.crotchSeamCurveCp1,
points.fork
)
}
if (points.waistOut.x < points.seatOut.x) {
//log.info('waist to the left of seat')
points.hipsOut = utils.lineIntersectsCurve(
points.hipsIn,
points.hipsIn.rotate(180, points.hipsOutTarget),
points.waistOut,
points.seatOut,
points.kneeOutCp1,
points.kneeOut
)
points.seatOutNotch = utils.lineIntersectsCurve(
points.seatMid,
points.seatOutTarget,
points.waistOut,
points.seatOut,
points.kneeOutCp1,
points.kneeOut
)
} else {
//log.info('waist to the right of seat')
points.hipsOut = utils.lineIntersectsCurve(
points.hipsIn,
points.hipsIn.rotate(180, points.hipsOutTarget),
points.waistOut,
points.waistOut,
points.seatOutCp1,
points.seatOut
)
points.seatOutNotch = points.seatOut
}
points.kneeOutNotch = points.kneeOut
points.kneeInNotch = points.kneeIn
macro('sprinkle', {
snippet: 'notch',
on: ['crotchSeamCurveStart', 'seatIn', 'seatOutNotch'],
})
if (extendBeyondKnee) {
macro('sprinkle', {
snippet: 'notch',
on: ['kneeInNotch', 'kneeOutNotch'],
})
}
paths.seatline = new Path()
.move(points.seatOutNotch)
.line(points.seatIn)
.addClass('fabric help')
.addText('Seat Line', 'center')
if (
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth <
measurements.waistToHips
) {
macro('sprinkle', {
snippet: 'notch',
on: ['hipsIn', 'hipsOut'],
})
paths.hipline = new Path()
.move(points.hipsOut)
.line(points.hipsIn)
.addClass('fabric help')
.addText('Hip Line', 'center')
}
}
if (sa) {
paths.saBase = paths.upperInseam.join(paths.upperOutseam).hide()
paths.hemBase = paths.bottom.hide()
paths.sa = paths.hemBase
.offset(sa * 3)
.join(paths.saBase.offset(sa))
.close()
.addClass('fabric sa')
}
// Delete Titan's old hint path (which could start above the top
// of the garment)
// delete paths.hint
if (paperless) {
// Help construct crotch seam
paths.hint = new Path()
.move(points.crotchSeamCurveStart)
.line(points.crotchSeamCurveMax)
.line(points.fork)
.addClass('note lashed')
macro('hd', {
id: 'wHemLeftToPleat',
from: points.bottomOut,
to: points.bottom,
y: points.bottomIn.y - 15,
})
macro('hd', {
id: 'wHemRightToPleat',
from: points.bottom,
to: points.bottomIn,
y: points.bottomIn.y - 15,
})
macro('hd', {
id: 'wHem',
from: points.bottomOut,
to: points.bottomIn,
y: points.bottomIn.y - 30,
})
macro('vd', {
id: 'hHemToFork',
from: points.bottomOut,
to: points.fork,
x: points.fork.x + sa + 15,
})
macro('vd', {
id: 'hForkToCfWaist',
from: points.fork,
to: points.styleWaistInLily,
x: points.fork.x + sa + 15,
})
macro('vd', {
id: 'hHemToSideWaist',
from: points.bottomIn,
to: points.styleWaistOutLily,
x:
(points.seatOut.x < points.styleWaistOutLily.x
? points.seatOut.x
: points.styleWaistOutLily.x) -
sa -
15,
})
macro('vd', {
id: 'hStartCrotchCurveToCfWaist',
from: points.crotchSeamCurveStart,
to: points.styleWaistInLily,
x: points.crotchSeamCurveStart.x + sa + 15,
})
macro('hd', {
id: 'wSideWaistToPleat',
from: points.seatOut,
to: points.grainlineTop,
y: points.styleWaistInLily.y - sa - 15,
})
if (points.styleWaistOutLily.x < points.seatOut.x) {
macro('hd', {
id: 'wSideWaistToPleatAlt',
from: points.styleWaistOutLily,
to: points.grainlineTop,
y: points.styleWaistInLily.y - sa - 30,
})
}
macro('hd', {
id: 'wPleatToCfWaist',
from: points.grainlineTop,
to: points.styleWaistInLily,
y: points.styleWaistInLily.y - sa - 15,
})
macro('hd', {
id: 'wPleatToStartCrotchCurve',
from: points.grainlineTop,
to: points.crotchSeamCurveStart,
y: points.styleWaistInLily.y - sa - 30,
})
macro('hd', {
id: 'wPleatToCrotchProjection',
from: points.grainlineTop,
to: points.crotchSeamCurveMax,
y: points.styleWaistInLily.y - sa - 45,
})
macro('hd', {
id: 'wPleatToFork',
from: points.grainlineTop,
to: points.fork,
y: points.styleWaistInLily.y - sa - 60,
})
}
}
return part
}
export const front = {
name: 'lily.front',
from: titanFront,
after: back,
hide: 'HIDE_TREE',
draft: draftLilyFront,
}

View file

@ -0,0 +1,16 @@
import { Design } from '@freesewing/core'
import { i18n } from '../i18n/index.mjs'
import { data } from '../data.mjs'
// Parts
import { front } from './front.mjs'
import { back } from './back.mjs'
import { waistband } from './waistband.mjs'
// Create new design
const Lily = new Design({
data,
parts: [front, back, waistband],
})
// Named exports
export { front, back, waistband, i18n, Lily }

View file

@ -0,0 +1,18 @@
import { back } from './back.mjs'
import { front } from './front.mjs'
import { waistband as pacoWaistband } from '@freesewing/paco'
export const waistband = {
name: 'lily.waistband',
after: [back, front],
hide: 'HIDE_TREE',
draft: (sh) => {
const { snippets, part } = sh
//draft
pacoWaistband.draft(sh)
//delete eyelets
for (let s in snippets) delete snippets[s]
return part
},
}

View file

@ -0,0 +1,20 @@
// This file is auto-generated | Any changes you make will be overwritten.
import { Lily, i18n } from '../src/index.mjs'
// Shared tests
import { testPatternConfig } from '../../../tests/designs/config.mjs'
import { testPatternI18n } from '../../../tests/designs/i18n.mjs'
import { testPatternDrafting } from '../../../tests/designs/drafting.mjs'
import { testPatternSampling } from '../../../tests/designs/sampling.mjs'
// Test config
testPatternConfig(Lily)
// Test translation
testPatternI18n(Lily, i18n)
// Test drafting - Change the second parameter to `true` to log errors
testPatternDrafting(Lily, false)
// Test sampling - Change the second parameter to `true` to log errors
testPatternSampling(Lily, false)

View file

@ -10,7 +10,6 @@ export const downloads = {
'sde/site.config.mjs',
'sde/tailwind.config.mjs',
'sde/hooks/use-design.mjs',
'sde/pkgs/.gitkeep',
'sde/mock/designs.mjs',
'sde/mock/docs-helpers.mjs',
'sde/mock/highlight.mjs',
@ -21,6 +20,7 @@ export const downloads = {
'sde/mock/read-more.mjs',
'sde/mock/tabbed-example.mjs',
'sde/mock/youtube.mjs',
'sde/pkgs/.gitkeep',
'sde/prebuild/.gitkeep',
'sde/prebuild/sitenav.de.mjs',
'sde/prebuild/sitenav.en.mjs',
@ -36,23 +36,11 @@ export const downloads = {
'sde/components/search.mjs',
'sde/components/header/design-picker.mjs',
'sde/components/header/index.mjs',
'sde/components/navigation/modal-menu.mjs',
'sde/components/layouts/bare.mjs',
'sde/components/layouts/default.mjs',
'sde/components/layouts/workbench.mjs',
'sde/components/navigation/modal-menu.mjs',
'sde/components/wrappers/page.mjs',
'sde/design/from-bent/src/back.mjs',
'sde/design/from-bent/src/front.mjs',
'sde/design/from-bent/src/index.mjs',
'sde/design/from-bent/src/top-sleeve.mjs',
'sde/design/from-bent/src/under-sleeve.mjs',
'sde/design/from-bent/i18n/de.json',
'sde/design/from-bent/i18n/en.json',
'sde/design/from-bent/i18n/es.json',
'sde/design/from-bent/i18n/fr.json',
'sde/design/from-bent/i18n/index.mjs',
'sde/design/from-bent/i18n/nl.json',
'sde/design/from-bent/i18n/uk.json',
'sde/design/from-bella/en.json',
'sde/design/from-bella/i18n/de.json',
'sde/design/from-bella/i18n/en.json',
@ -64,6 +52,18 @@ export const downloads = {
'sde/design/from-bella/src/back.mjs',
'sde/design/from-bella/src/front.mjs',
'sde/design/from-bella/src/index.mjs',
'sde/design/from-bent/i18n/de.json',
'sde/design/from-bent/i18n/en.json',
'sde/design/from-bent/i18n/es.json',
'sde/design/from-bent/i18n/fr.json',
'sde/design/from-bent/i18n/index.mjs',
'sde/design/from-bent/i18n/nl.json',
'sde/design/from-bent/i18n/uk.json',
'sde/design/from-bent/src/back.mjs',
'sde/design/from-bent/src/front.mjs',
'sde/design/from-bent/src/index.mjs',
'sde/design/from-bent/src/top-sleeve.mjs',
'sde/design/from-bent/src/under-sleeve.mjs',
'sde/design/from-breanna/i18n/de.json',
'sde/design/from-breanna/i18n/en.json',
'sde/design/from-breanna/i18n/es.json',
@ -75,6 +75,10 @@ export const downloads = {
'sde/design/from-breanna/src/front.mjs',
'sde/design/from-breanna/src/index.mjs',
'sde/design/from-breanna/src/sleeve.mjs',
'sde/design/from-brian/src/back.mjs',
'sde/design/from-brian/src/front.mjs',
'sde/design/from-brian/src/index.mjs',
'sde/design/from-brian/src/sleeve.mjs',
'sde/design/from-brian/i18n/de.json',
'sde/design/from-brian/i18n/en.json',
'sde/design/from-brian/i18n/es.json',
@ -82,10 +86,6 @@ export const downloads = {
'sde/design/from-brian/i18n/index.mjs',
'sde/design/from-brian/i18n/nl.json',
'sde/design/from-brian/i18n/uk.json',
'sde/design/from-brian/src/back.mjs',
'sde/design/from-brian/src/front.mjs',
'sde/design/from-brian/src/index.mjs',
'sde/design/from-brian/src/sleeve.mjs',
'sde/design/from-scratch/i18n/de.json',
'sde/design/from-scratch/i18n/en.json',
'sde/design/from-scratch/i18n/es.json',
@ -189,6 +189,60 @@ export const downloads = {
'sde/public/locales/de/tutorial.json',
'sde/public/locales/de/ui-settings.json',
'sde/public/locales/de/workbench.json',
'sde/public/locales/es/account.json',
'sde/public/locales/es/auth.json',
'sde/public/locales/es/bella.json',
'sde/public/locales/es/bent.json',
'sde/public/locales/es/breanna.json',
'sde/public/locales/es/brian.json',
'sde/public/locales/es/common.json',
'sde/public/locales/es/core-settings.json',
'sde/public/locales/es/curate.json',
'sde/public/locales/es/cut.json',
'sde/public/locales/es/design-options.json',
'sde/public/locales/es/designs.json',
'sde/public/locales/es/docs.json',
'sde/public/locales/es/errors.json',
'sde/public/locales/es/flag.json',
'sde/public/locales/es/footer.json',
'sde/public/locales/es/frombella.json',
'sde/public/locales/es/frombent.json',
'sde/public/locales/es/frombreanna.json',
'sde/public/locales/es/frombrian.json',
'sde/public/locales/es/fromscratch.json',
'sde/public/locales/es/fromtitan.json',
'sde/public/locales/es/gdpr.json',
'sde/public/locales/es/header.json',
'sde/public/locales/es/hodl.json',
'sde/public/locales/es/homepage.json',
'sde/public/locales/es/lab.json',
'sde/public/locales/es/locales.json',
'sde/public/locales/es/logs.json',
'sde/public/locales/es/measurements.json',
'sde/public/locales/es/modal.json',
'sde/public/locales/es/newsletter.json',
'sde/public/locales/es/patrons.json',
'sde/public/locales/es/plugin-annotations.json',
'sde/public/locales/es/plugins.json',
'sde/public/locales/es/popout.json',
'sde/public/locales/es/print.json',
'sde/public/locales/es/roles.json',
'sde/public/locales/es/sde.json',
'sde/public/locales/es/sections.json',
'sde/public/locales/es/sets.json',
'sde/public/locales/es/sponsors.json',
'sde/public/locales/es/status.json',
'sde/public/locales/es/submissions.json',
'sde/public/locales/es/support.json',
'sde/public/locales/es/susi.json',
'sde/public/locales/es/tags.json',
'sde/public/locales/es/techniques.json',
'sde/public/locales/es/themes.json',
'sde/public/locales/es/timeago.json',
'sde/public/locales/es/titan.json',
'sde/public/locales/es/tutorial.json',
'sde/public/locales/es/ui-settings.json',
'sde/public/locales/es/workbench.json',
'sde/public/locales/en/account.json',
'sde/public/locales/en/auth.json',
'sde/public/locales/en/bella.json',
@ -297,114 +351,6 @@ export const downloads = {
'sde/public/locales/fr/tutorial.json',
'sde/public/locales/fr/ui-settings.json',
'sde/public/locales/fr/workbench.json',
'sde/public/locales/nl/account.json',
'sde/public/locales/nl/auth.json',
'sde/public/locales/nl/bella.json',
'sde/public/locales/nl/bent.json',
'sde/public/locales/nl/breanna.json',
'sde/public/locales/nl/brian.json',
'sde/public/locales/nl/common.json',
'sde/public/locales/nl/core-settings.json',
'sde/public/locales/nl/curate.json',
'sde/public/locales/nl/cut.json',
'sde/public/locales/nl/design-options.json',
'sde/public/locales/nl/designs.json',
'sde/public/locales/nl/docs.json',
'sde/public/locales/nl/errors.json',
'sde/public/locales/nl/flag.json',
'sde/public/locales/nl/footer.json',
'sde/public/locales/nl/frombella.json',
'sde/public/locales/nl/frombent.json',
'sde/public/locales/nl/frombreanna.json',
'sde/public/locales/nl/frombrian.json',
'sde/public/locales/nl/fromscratch.json',
'sde/public/locales/nl/fromtitan.json',
'sde/public/locales/nl/gdpr.json',
'sde/public/locales/nl/header.json',
'sde/public/locales/nl/hodl.json',
'sde/public/locales/nl/homepage.json',
'sde/public/locales/nl/lab.json',
'sde/public/locales/nl/locales.json',
'sde/public/locales/nl/logs.json',
'sde/public/locales/nl/measurements.json',
'sde/public/locales/nl/modal.json',
'sde/public/locales/nl/newsletter.json',
'sde/public/locales/nl/patrons.json',
'sde/public/locales/nl/plugin-annotations.json',
'sde/public/locales/nl/plugins.json',
'sde/public/locales/nl/popout.json',
'sde/public/locales/nl/print.json',
'sde/public/locales/nl/roles.json',
'sde/public/locales/nl/sde.json',
'sde/public/locales/nl/sections.json',
'sde/public/locales/nl/sets.json',
'sde/public/locales/nl/sponsors.json',
'sde/public/locales/nl/status.json',
'sde/public/locales/nl/submissions.json',
'sde/public/locales/nl/support.json',
'sde/public/locales/nl/susi.json',
'sde/public/locales/nl/tags.json',
'sde/public/locales/nl/techniques.json',
'sde/public/locales/nl/themes.json',
'sde/public/locales/nl/timeago.json',
'sde/public/locales/nl/titan.json',
'sde/public/locales/nl/tutorial.json',
'sde/public/locales/nl/ui-settings.json',
'sde/public/locales/nl/workbench.json',
'sde/public/locales/es/account.json',
'sde/public/locales/es/auth.json',
'sde/public/locales/es/bella.json',
'sde/public/locales/es/bent.json',
'sde/public/locales/es/breanna.json',
'sde/public/locales/es/brian.json',
'sde/public/locales/es/common.json',
'sde/public/locales/es/core-settings.json',
'sde/public/locales/es/curate.json',
'sde/public/locales/es/cut.json',
'sde/public/locales/es/design-options.json',
'sde/public/locales/es/designs.json',
'sde/public/locales/es/docs.json',
'sde/public/locales/es/errors.json',
'sde/public/locales/es/flag.json',
'sde/public/locales/es/footer.json',
'sde/public/locales/es/frombella.json',
'sde/public/locales/es/frombent.json',
'sde/public/locales/es/frombreanna.json',
'sde/public/locales/es/frombrian.json',
'sde/public/locales/es/fromscratch.json',
'sde/public/locales/es/fromtitan.json',
'sde/public/locales/es/gdpr.json',
'sde/public/locales/es/header.json',
'sde/public/locales/es/hodl.json',
'sde/public/locales/es/homepage.json',
'sde/public/locales/es/lab.json',
'sde/public/locales/es/locales.json',
'sde/public/locales/es/logs.json',
'sde/public/locales/es/measurements.json',
'sde/public/locales/es/modal.json',
'sde/public/locales/es/newsletter.json',
'sde/public/locales/es/patrons.json',
'sde/public/locales/es/plugin-annotations.json',
'sde/public/locales/es/plugins.json',
'sde/public/locales/es/popout.json',
'sde/public/locales/es/print.json',
'sde/public/locales/es/roles.json',
'sde/public/locales/es/sde.json',
'sde/public/locales/es/sections.json',
'sde/public/locales/es/sets.json',
'sde/public/locales/es/sponsors.json',
'sde/public/locales/es/status.json',
'sde/public/locales/es/submissions.json',
'sde/public/locales/es/support.json',
'sde/public/locales/es/susi.json',
'sde/public/locales/es/tags.json',
'sde/public/locales/es/techniques.json',
'sde/public/locales/es/themes.json',
'sde/public/locales/es/timeago.json',
'sde/public/locales/es/titan.json',
'sde/public/locales/es/tutorial.json',
'sde/public/locales/es/ui-settings.json',
'sde/public/locales/es/workbench.json',
'sde/public/locales/uk/account.json',
'sde/public/locales/uk/auth.json',
'sde/public/locales/uk/bella.json',
@ -459,6 +405,60 @@ export const downloads = {
'sde/public/locales/uk/tutorial.json',
'sde/public/locales/uk/ui-settings.json',
'sde/public/locales/uk/workbench.json',
'sde/public/locales/nl/account.json',
'sde/public/locales/nl/auth.json',
'sde/public/locales/nl/bella.json',
'sde/public/locales/nl/bent.json',
'sde/public/locales/nl/breanna.json',
'sde/public/locales/nl/brian.json',
'sde/public/locales/nl/common.json',
'sde/public/locales/nl/core-settings.json',
'sde/public/locales/nl/curate.json',
'sde/public/locales/nl/cut.json',
'sde/public/locales/nl/design-options.json',
'sde/public/locales/nl/designs.json',
'sde/public/locales/nl/docs.json',
'sde/public/locales/nl/errors.json',
'sde/public/locales/nl/flag.json',
'sde/public/locales/nl/footer.json',
'sde/public/locales/nl/frombella.json',
'sde/public/locales/nl/frombent.json',
'sde/public/locales/nl/frombreanna.json',
'sde/public/locales/nl/frombrian.json',
'sde/public/locales/nl/fromscratch.json',
'sde/public/locales/nl/fromtitan.json',
'sde/public/locales/nl/gdpr.json',
'sde/public/locales/nl/header.json',
'sde/public/locales/nl/hodl.json',
'sde/public/locales/nl/homepage.json',
'sde/public/locales/nl/lab.json',
'sde/public/locales/nl/locales.json',
'sde/public/locales/nl/logs.json',
'sde/public/locales/nl/measurements.json',
'sde/public/locales/nl/modal.json',
'sde/public/locales/nl/newsletter.json',
'sde/public/locales/nl/patrons.json',
'sde/public/locales/nl/plugin-annotations.json',
'sde/public/locales/nl/plugins.json',
'sde/public/locales/nl/popout.json',
'sde/public/locales/nl/print.json',
'sde/public/locales/nl/roles.json',
'sde/public/locales/nl/sde.json',
'sde/public/locales/nl/sections.json',
'sde/public/locales/nl/sets.json',
'sde/public/locales/nl/sponsors.json',
'sde/public/locales/nl/status.json',
'sde/public/locales/nl/submissions.json',
'sde/public/locales/nl/support.json',
'sde/public/locales/nl/susi.json',
'sde/public/locales/nl/tags.json',
'sde/public/locales/nl/techniques.json',
'sde/public/locales/nl/themes.json',
'sde/public/locales/nl/timeago.json',
'sde/public/locales/nl/titan.json',
'sde/public/locales/nl/tutorial.json',
'sde/public/locales/nl/ui-settings.json',
'sde/public/locales/nl/workbench.json',
'shared/utils.mjs',
'shared/components/mdx/dynamic.mjs',
'shared/components/mdx/design-measurements.mjs',

View file

@ -58,6 +58,7 @@ import { Wahid as wahid } from '@freesewing/wahid'
import { Walburga as walburga } from '@freesewing/walburga'
import { Waralee as waralee } from '@freesewing/waralee'
import { Yuri as yuri } from '@freesewing/yuri'
import { Lily as lily } from '@freesewing/lily'
const designs = {
aaron,
@ -116,6 +117,7 @@ const designs = {
walburga,
waralee,
yuri,
lily,
}
export const useDesign = (design) => (designs[design] ? designs[design] : false)

View file

@ -55,6 +55,7 @@ import { Wahid as wahid } from '@freesewing/wahid'
import { Walburga as walburga } from '@freesewing/walburga'
import { Waralee as waralee } from '@freesewing/waralee'
import { Yuri as yuri } from '@freesewing/yuri'
import { Lily as lily } from '@freesewing/lily'
const designs = {
aaron,
@ -110,6 +111,7 @@ const designs = {
walburga,
waralee,
yuri,
lily,
}
export const useDesign = (design) => (designs[design] ? designs[design] : false)

View file

@ -0,0 +1,86 @@
/*
* This page is auto-generated. Do not edit it by hand.
*/
import { Lily } from 'designs/lily/src/index.mjs'
// Dependencies
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { nsMerge, getSearchParam } from 'shared/utils.mjs'
// Hooks
import { useState, useEffect, useContext } from 'react'
import { useTranslation } from 'next-i18next'
import { useBackend } from 'shared/hooks/use-backend.mjs'
// Context
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
// Components
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
import { Workbench, ns as wbNs } from 'shared/components/workbench/new.mjs'
import { WorkbenchLayout } from 'site/components/layouts/workbench.mjs'
import { Loading } from 'shared/components/spinner.mjs'
// Translation namespaces used on this page
const ns = nsMerge('lily', wbNs, pageNs)
const EditDesignComponent = ({ id, design, Design, settings }) => (
<Workbench preload={{ settings }} saveAs={{ pattern: id }} {...{ design, Design }} />
)
const EditLilyPage = ({ page }) => {
const { setLoadingStatus } = useContext(LoadingStatusContext)
const backend = useBackend()
const { t } = useTranslation(ns)
const [pattern, setPattern] = useState(false)
useEffect(() => {
const getPattern = async () => {
setLoadingStatus([true, t('backendLoadingStarted')])
let result
try {
result = await backend.getPattern(id)
if (result.success) {
setPattern(result.data.pattern)
setLoadingStatus([true, 'backendLoadingCompleted', true, true])
} else setLoadingStatus([true, 'backendError', true, false])
} catch (err) {
console.log(err)
setLoadingStatus([true, 'backendError', true, false])
}
}
const id = getSearchParam('id')
if (id) getPattern()
}, [backend, setLoadingStatus, t])
return (
// prettier-ignore
<PageWrapper {...page} title="Lily" layout={pattern ? WorkbenchLayout : false} header={null}>
{pattern ? (
<EditDesignComponent
id={pattern.id}
settings={pattern.settings}
design="lily"
Design={Lily}
/>
) : (
<div>
<h1>{t('account:oneMomentPLease')}</h1>
<Loading />
</div>
)}
</PageWrapper>
)
}
export default EditLilyPage
export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, ns)),
page: {
locale,
path: ['account', 'patterns', 'lily'],
title: 'Lily',
},
},
}
}

View file

@ -0,0 +1,41 @@
/*
* This page is auto-generated. Do not edit it by hand.
*/
import { Lily } from 'designs/lily/src/index.mjs'
// Dependencies
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { nsMerge } from 'shared/utils.mjs'
// Components
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
import { Workbench, ns as wbNs } from 'shared/components/workbench/new.mjs'
import { WorkbenchLayout } from 'site/components/layouts/workbench.mjs'
// Translation namespaces used on this page
const ns = nsMerge('lily', wbNs, pageNs)
const NewLilyPage = ({ page, docs }) => (
<PageWrapper {...page} title="Lily" layout={WorkbenchLayout} header={null}>
<Workbench
{...{
design: 'lily',
Design: Lily,
docs,
}}
/>
</PageWrapper>
)
export default NewLilyPage
export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, ns)),
page: {
locale,
path: ['new', 'lily'],
title: 'Lily',
},
},
}
}

View file

@ -61,6 +61,7 @@ import { i18n as wahid } from '@freesewing/wahid'
import { i18n as walburga } from '@freesewing/walburga'
import { i18n as waralee } from '@freesewing/waralee'
import { i18n as yuri } from '@freesewing/yuri'
import { i18n as lily } from '@freesewing/lily'
export const designs = {
aaron,
@ -122,4 +123,5 @@ export const designs = {
walburga,
waralee,
yuri,
lily,
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,3 @@
// __SDEFILE__ - This file is a dependency for the stand-alone environment
// This file is auto-generated by the prebuild script | Any changes will be overwritten
export const designs = ["aaron","albert","bee","bella","benjamin","bent","bob","breanna","brian","bruce","carlita","carlton","cathrin","charlie","cornelius","diana","examples","florence","florent","gozer","hi","holmes","hortensia","huey","hugo","jaeger","legend","lucy","lumina","lumira","lunetius","magde","naomiwu","noble","octoplushy","onyx","otis","paco","penelope","plugintest","rendertest","sandy","shelly","shin","simon","simone","skully","sven","tamiko","teagan","tiberius","titan","trayvon","tristan","uma","wahid","walburga","waralee","yuri"]
export const designs = ["aaron","albert","bee","bella","benjamin","bent","bob","breanna","brian","bruce","carlita","carlton","cathrin","charlie","cornelius","diana","examples","florence","florent","gozer","hi","holmes","hortensia","huey","hugo","jaeger","legend","lucy","lumina","lumira","lunetius","magde","naomiwu","noble","octoplushy","onyx","otis","paco","penelope","plugintest","rendertest","sandy","shelly","shin","simon","simone","skully","sven","tamiko","teagan","tiberius","titan","trayvon","tristan","uma","wahid","walburga","waralee","yuri","lily"]

View file

@ -10024,6 +10024,32 @@ mocha-steps@1.3.0:
resolved "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz"
integrity sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==
mocha@10.3.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9"
integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==
dependencies:
ansi-colors "4.1.1"
browser-stdout "1.3.1"
chokidar "3.5.3"
debug "4.3.4"
diff "5.0.0"
escape-string-regexp "4.0.0"
find-up "5.0.0"
glob "8.1.0"
he "1.2.0"
js-yaml "4.1.0"
log-symbols "4.1.0"
minimatch "5.0.1"
ms "2.1.3"
serialize-javascript "6.0.0"
strip-json-comments "3.1.1"
supports-color "8.1.1"
workerpool "6.2.1"
yargs "16.2.0"
yargs-parser "20.2.4"
yargs-unparser "2.0.0"
mocha@10.4.0, mocha@^10.0.0:
version "10.4.0"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261"