1
0
Fork 0

feat(ursula): Initial release of Ursula

Ursula is a basic, highly-customizable underwear pattern
This commit is contained in:
Natalia 2021-06-26 10:29:28 +02:00 committed by Joost De Cock
parent a3b37b060b
commit cc00ec65ff
7 changed files with 727 additions and 0 deletions

View file

@ -0,0 +1,51 @@
import { version } from '../package.json'
// ?? 🤔 ?? --> https://en.freesewing.dev/packages/core/config
export default {
name: 'ursula',
version,
design: 'natalia',
code: 'natalia',
department: 'womenswear',
type: 'pattern',
difficulty: 1,
tags: [
'freesewing',
'design',
'diy',
'fashion',
'made to measure',
'parametric design',
'pattern',
'sewing',
'sewing pattern',
],
optionGroups: {
fit: ['fabricStretch','gussetWidth','gussetLength','elasticStretch'],
style: ['rise','legOpening','frontDip','backDip','taperToGusset','backExposure'],
},
measurements: ['waist','seat','waistToSeat','waistToUpperLeg'], // Potentially useful: 'hips', 'waistToHips'
dependencies: {},
inject: {},
hide: [],
parts: ['front','back','gusset','elastic'],
//Constants
options: {
backToFrontLength: 1.15, // Maybe include this in advanced options?
backToFrontWidth: 1.1, // Maybe include this in advanced options?
gussetRatio: 0.7, // Relationship between front and back gusset widths
// Percentages
gussetWidth: { pct : 7.7, min: 4, max: 12 }, // Gusset width in relation to seat
gussetLength: { pct: 12.7, min: 10, max: 16 }, // Gusset length in relation to seat
fabricStretch: { pct: 15, min: 5, max: 25 },
rise: { pct: 60, min: 30, max: 100 },
legOpening: { pct: 58, min: 5, max: 85 },
frontDip: { pct: 5.0, min: -5, max: 15 },
backDip: { pct: 2.5, min: -5, max: 15 },
taperToGusset: { pct: 70, min: 5, max: 100},
backExposure: { pct: 20, min: -30, max: 90},
elasticStretch: { pct: 8, min: 5, max: 15 }
},
}

View file

@ -0,0 +1,93 @@
{
"name": "@freesewing/ursula",
"version": "2.16.2",
"description": "A FreeSewing pattern for a basic, highly-customizable underwear pattern",
"author": "Joost De Cock <joost@joost.at> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",
"repository": "github:freesewing/freesewing",
"license": "MIT",
"bugs": {
"url": "https://github.com/freesewing/freesewing/issues"
},
"keywords": [
"freesewing",
"design",
"diy",
"fashion",
"made to measure",
"parametric design",
"pattern",
"sewing",
"sewing pattern"
],
"main": "dist/index.js",
"module": "dist/index.mjs",
"scripts": {
"clean": "rimraf dist",
"build": "rollup -c",
"test": "BABEL_ENV=production ../../node_modules/.bin/_mocha tests/*.test.js --require @babel/register",
"pubtest": "npm publish --registry http://localhost:6662",
"pubforce": "npm publish",
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
"start": "rollup -c -w",
"netlify": "echo \"Not configured yet\"",
"testci": "BABEL_ENV=production ./node_modules/.bin/_mocha tests/*.test.js --require @babel/register"
},
"peerDependencies": {
"@freesewing/core": "^2.16.2",
"@freesewing/plugin-bundle": "^2.16.2"
},
"dependencies": {},
"devDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.27.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^1.1.0",
"@freesewing/components": "^2.16.2",
"@freesewing/css-theme": "^2.16.2",
"@freesewing/i18n": "^2.16.2",
"@freesewing/mui-theme": "^2.16.2",
"@freesewing/plugin-bust": "^2.16.2",
"@freesewing/plugin-buttons": "^2.16.2",
"@freesewing/plugin-flip": "^2.16.2",
"@freesewing/utils": "^2.16.2",
"react-scripts": "^4.0.3",
"webpack": "^5.37.0",
"rollup": "^2.50.6",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^19.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"@material-ui/core": "^4.11.4",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^v4.0.0-alpha.57",
"axios": "0.21.1",
"react-intl": "^5.17.6",
"prop-types": "^15.7.2",
"mocha": "^8.1.0",
"chai": "^4.2.0",
"chai-string": "^1.5.0",
"@babel/register": "^7.10.5"
},
"files": [
"dist/*",
"README.md",
"package.json"
],
"publishConfig": {
"access": "public",
"tag": "latest"
},
"engines": {
"node": ">=12.0.0",
"npm": ">=6"
},
"rollup": {
"exports": "default"
}
}

240
packages/ursula/src/back.js Normal file
View file

@ -0,0 +1,240 @@
export default function (part) {
let {
options,
Point,
Path,
points,
paths,
measurements,
// Snippet,
// snippets,
store,
utils,
complete,
sa,
paperless,
macro,
} = part.shorthand()
// Design pattern here
// Create points
points.backWaistMid = new Point(measurements.seat / 4, 0)
points.backWaistBandLeft = new Point(store.get('sideSeamWaist').x / options.backToFrontWidth, store.get('sideSeamWaist').y)
points.backLegOpeningLeft = new Point(store.get('sideSeamHip').x / options.backToFrontWidth, store.get('sideSeamHip').y)
points.backGussetLeft = new Point(
(measurements.seat / 4) - (measurements.waist * options.gussetWidth) * store.get('xScale') / options.gussetRatio * options.backToFrontWidth,
measurements.waistToUpperLeg * options.backToFrontLength
)
points.backGussetMid = new Point(measurements.seat / 4, measurements.waistToUpperLeg * options.backToFrontLength)
points.backGussetRight = points.backGussetLeft.flipX(points.backWaistMid)
points.backLegOpeningRight = points.backLegOpeningLeft.flipX(points.backWaistMid)
points.backWaistBandRight = points.backWaistBandLeft.flipX(points.backWaistMid)
points.backWaistBandMid = points.backWaistBandLeft.shiftFractionTowards(points.backWaistBandRight, 0.5)
.shift(270,measurements.waistToUpperLeg * options.backDip)
/* Middle point for label */
points.backMidMid = points.backLegOpeningLeft.shiftFractionTowards(points.backLegOpeningRight, 0.5)
// Create control points
/* Control point for waistband dip */
points.backWaistBandLeftCp1 = new Point(points.backWaistBandRight.x / 3, points.backWaistBandMid.y)
/* Flip points to right side */
points.backWaistBandRightCp1 = points.backWaistBandLeftCp1.flipX(points.backWaistMid)
// Shape back coverage
/* Only have to do this on one side */
points.backLegOpeningCorner = utils.beamsIntersect(
points.backLegOpeningLeft,
points.backLegOpeningLeft.shift(180, points.backGussetLeft.dy(points.backLegOpeningLeft)),
points.backGussetLeft,
points.backGussetLeft.shift(270, points.backGussetLeft.dy(points.backLegOpeningLeft))
)
if (options.backExposure >= 0) {
/* If back exposure is high, like a thong style */
/* This controls the hip bit */
points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shiftFractionTowards(
points.backLegOpeningCorner,
options.backExposure
)
/* This controls the center bit */
points.backGussetLeftCp1 = points.backGussetLeft.shiftFractionTowards(
points.backWaistBandMid,
options.backExposure
)
points.backGussetLeft = points.backGussetLeft.shiftFractionTowards(points.backGussetMid, options.backExposure) // This narrows the back of the gusset
points.backGussetRight = points.backGussetLeft.flipX(points.backWaistMid)
} else {
/* If back exposure is low and flares out to cover more */
/* This controls the hip bit */
points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shift(
-45,
points.backWaistBandMid.x / 8
)
/* This controls the taper to gusset */
points.backGussetLeftCp1 = points.backGussetLeft.shift(
115,
points.backWaistBandMid.x / 8
)
/* This adds a new point in the middle of the back coverage */
points.backFlare = points.backGussetLeft.shiftFractionTowards(
points.backLegOpeningLeft,
0.5
)
points.backFlareLeft = points.backFlare.shift(
215,
-points.backWaistBandMid.x / 2 * options.backExposure
)
points.backFlareRight = points.backFlareLeft.flipX(points.backWaistBandMid)
/* This controls the flare */
points.backFlareLeftCp1 = points.backFlareLeft.shift(
115,
points.backWaistBandMid.x / 5//-150*options.backExposure
)
points.backFlareLeftCp2 = points.backFlareLeft.shift(
295,
points.backWaistBandMid.x / 5//-150*options.backExposure
)
points.backFlareRightCp1 = points.backFlareLeftCp1.flipX(points.backWaistMid)
points.backFlareRightCp2 = points.backFlareLeftCp2.flipX(points.backWaistMid)
}
/* Flip points to the right */
points.backLegOpeningRightCp1 = points.backLegOpeningLeftCp1.flipX(points.backWaistMid)
points.backGussetRightCp1 = points.backGussetLeftCp1.flipX(points.backWaistMid)
// Draw paths
if (options.backExposure >= 0) {
paths.seam = new Path()
.move(points.backWaistBandMid)
.curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip
.line(points.backLegOpeningLeft)
.curve(points.backLegOpeningLeftCp1, points.backGussetLeftCp1, points.backGussetLeft)
.line(points.backGussetMid)
.line(points.backGussetRight)
.curve(points.backGussetRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight)
.line(points.backWaistBandRight)
.curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip
.close()
.attr('class', 'fabric')
} else {
paths.seam = new Path()
.move(points.backWaistBandMid)
.curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip
.line(points.backLegOpeningLeft)
.curve(points.backLegOpeningLeftCp1, points.backFlareLeftCp1, points.backFlareLeft)
.curve(points.backFlareLeftCp2, points.backGussetLeftCp1, points.backGussetLeft)
.line(points.backGussetMid)
.line(points.backGussetRight)
.curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight)
.curve(points.backFlareRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight)
.line(points.backWaistBandRight)
.curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip
.close()
.attr('class', 'fabric')
}
// Store points for use in other parts
/* Store gusset points for use in gusset */
store.set('backGussetLeft', points.backGussetLeft)
store.set('backGussetRight', points.backGussetRight)
/* Store lengths for use in elastic */
if (options.backExposure >= 0 ) {
store.set(
'backLegOpeningLength',
new Path()
.move(points.backGussetRight)
.curve(points.backGussetRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight)
.length()
)
} else {
store.set(
'backLegOpeningLength',
new Path()
.move(points.backGussetRight)
.curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight)
.curve(points.backFlareRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight),
)
}
store.set(
'backWaistBandLength',
new Path()
.move(points.backWaistBandRight)
.curve(points.backWaistBandRightCp1, points.backWaistBandLeftCp1, points.backWaistBandLeft)
.length()
)
// Complete?
if (complete) {
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
macro('title', {
at: points.backMidMid,
nr: 2,
title: 'back',
})
points.scaleboxAnchor = points.scalebox = points.backMidMid.shift(90, -50)
macro('miniscale', { at: points.scalebox })
// Paperless?
if (paperless) {
macro('hd', {
from: points.backWaistBandRight,
to: points.backWaistBandLeft,
y: points.backWaistBandRight.y + sa - 15,
})
macro('hd', {
from: points.backLegOpeningRight,
to: points.backLegOpeningLeft,
y: points.backLegOpeningRight.y + sa - 15,
})
macro('hd', {
from: points.backGussetLeft,
to: points.backGussetRight,
y: points.backGussetLeft.y + sa + 15,
})
macro('vd', {
from: points.backWaistBandMid,
to: points.backGussetMid,
x: points.backWaistBandMid.x + sa + 15,
})
if (options.backExposure >= 0 ) {
macro('pd', {
path: new Path()
.move(points.backGussetRight)
.curve(points.backGussetRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight),
d: 15
})
} else {
macro('pd', {
path: new Path()
.move(points.backGussetRight)
.curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight)
.curve(points.backFlareRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight),
d: 15
})
}
}
return part
}

View file

@ -0,0 +1,56 @@
export default function (part) {
let {
options,
Point,
Path,
points,
paths,
measurements,
// Snippet,
// snippets,
store,
utils,
units,
complete,
sa,
paperless,
macro,
} = part.shorthand()
// Stretch utility method
store.set('elasticScale', utils.stretchToScale(options.elasticStretch))
// Design pattern here
let legOpeningLength = store.get('frontLegOpeningLength') + store.get('backLegOpeningLength') + store.get('gussetSideLength')
let waistBandLength = store.get('frontWaistBandLength') + store.get('backWaistBandLength')
points.elasticInfo = new Point(0,0)
.attr('data-text', 'cutTwoPiecesOfElasticToFinishTheLegOpenings')
.attr('data-text', ':')
.attr('data-text', units(legOpeningLength * store.get('elasticScale') + 2 * sa))
.attr('data-text', '\n')
.attr('data-text', 'cutOnePieceOfElasticToFinishTheWaistBand')
.attr('data-text', ':')
.attr('data-text', units(waistBandLength * store.get('elasticScale') + 2 * sa))
// Complete?
if (complete) {
// if (sa) {
// paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
// }
}
// Paperless?
if (paperless) {
macro('hd', {
from: points.elasticInfo,
to: points.elasticInfo,
y: points.elasticInfo.y + sa + 15,
})
}
return part
}

View file

@ -0,0 +1,174 @@
export default function (part) {
let {
options,
Point,
Path,
points,
paths,
measurements,
// Snippet,
// snippets,
store,
utils,
complete,
sa,
paperless,
macro,
} = part.shorthand()
// Stretch utility method
store.set('xScale', utils.stretchToScale(options.fabricStretch))
// Design pattern here
// Create points
points.frontWaistMid = new Point(measurements.seat / 4, 0)
points.frontWaistLeft = new Point(measurements.seat / 4 - measurements.waist / 4 * store.get('xScale'), 0)
points.frontHipLeft = new Point(measurements.seat / 4 - measurements.seat / 4 * store.get('xScale'), measurements.waistToSeat) // Consider renaming from "hip" to "seat"
points.frontGussetLeft = new Point((measurements.seat / 4) - (measurements.waist * options.gussetWidth) * store.get('xScale') / 1.2, measurements.waistToUpperLeg)
points.frontGussetMid = new Point(measurements.seat / 4, measurements.waistToUpperLeg)
/* Flip points to right side */
points.frontGussetRight = points.frontGussetLeft.flipX(points.frontWaistMid)
points.frontHipRight = points.frontHipLeft.flipX(points.frontWaistMid)
points.frontWaistRight = points.frontWaistLeft.flipX(points.frontWaistMid)
/* Waist band is based on waist at top, hip at bottom */
points.frontWaistBandLeft = points.frontHipLeft.shiftFractionTowards(points.frontWaistLeft, options.rise)
points.frontWaistBandRight = points.frontWaistBandLeft.flipX(points.frontWaistMid)
points.frontWaistBandMid = points.frontWaistBandLeft.shiftFractionTowards(points.frontWaistBandRight, 0.5)
.shift(270,measurements.waistToUpperLeg * options.frontDip) /* Waist band dip */
/* Leg opening is based on waist band and hip */
// points.frontLegOpeningLeft = points.frontHipLeft.shiftFractionTowards(points.frontWaistBandLeft, options.legOpening) // Waist band side point
// points.frontLegOpeningRight = points.frontLegOpeningLeft.flipX(points.frontWaistMid) // Waist band side point
///////////// Replace the point it's shifting towards with a beamsIntersect() of the
///////////// side (frontWaistLeft and frontHipLeft) and the lowest point of the waistband (backWaistBandMid
///////////// and backWaistBandLeftCp1 should work)
///////////// or maybe beamIntersectsY() of backWaistBandMid.y ??
points.frontLegOpeningLeft = points.frontHipLeft.shiftFractionTowards(points.frontWaistBandLeft, options.legOpening) // Waist band low point
points.frontLegOpeningRight = points.frontLegOpeningLeft.flipX(points.frontWaistMid) // Waist band low point
/* Middle point for label */
points.frontMidMid = points.frontLegOpeningLeft.shiftFractionTowards(points.frontLegOpeningRight, 0.5)
// Create control points
/* Control points for leg opening curves */
points.frontLegOpeningLeftCp1 = points.frontLegOpeningLeft
.shift(180, points.frontGussetLeft.dy(points.frontLegOpeningLeft)/3);
points.frontGussetLeftCp1 = points.frontGussetLeft
// .shift(270, points.frontGussetLeft.dy(points.frontHipLeft) * 4 * options.taperToGusset); // Consider changing this so it's relative
.shift(270, points.frontGussetLeft.dy(points.frontWaistBandMid) * options.taperToGusset);
/* Control point for waistband dip */
points.frontWaistBandLeftCp1 = new Point(points.frontWaistBandRight.x / 3, points.frontWaistBandMid.y)
/* Flip control points to right side */
points.frontGussetRightCp1 = points.frontGussetLeftCp1.flipX(points.frontWaistMid)
points.frontLegOpeningRightCp1 = points.frontLegOpeningLeftCp1.flipX(points.frontWaistMid)
points.frontWaistBandRightCp1 = points.frontWaistBandLeftCp1.flipX(points.frontWaistMid)
// Draw paths
paths.seam = new Path()
.move(points.frontWaistBandMid)
.curve(points.frontWaistBandLeftCp1, points.frontWaistBandLeft, points.frontWaistBandLeft) // Waist band dip
.line(points.frontLegOpeningLeft)
.curve(points.frontLegOpeningLeftCp1, points.frontGussetLeftCp1, points.frontGussetLeft)
.line(points.frontGussetMid)
.line(points.frontGussetRight)
.curve(points.frontGussetRightCp1, points.frontLegOpeningRightCp1, points.frontLegOpeningRight)
.line(points.frontWaistBandRight)
.curve(points.frontWaistBandRight, points.frontWaistBandRightCp1, points.frontWaistBandMid) // Waist band dip
.close()
.attr('class', 'fabric')
// Store points for use in other parts
/* Store side seam points for use in back */
store.set('sideSeamWaist', points.frontWaistBandLeft)
store.set('sideSeamHip', points.frontLegOpeningLeft)
/* Store gusset points for use in gusset */
store.set('frontGussetLeft', points.frontGussetLeft)
store.set('frontGussetRight', points.frontGussetRight)
store.set('frontGussetMid', points.frontGussetMid)
/* Store lengths for use in elastic */
store.set(
'frontLegOpeningLength',
new Path()
.move(points.frontGussetRight)
.curve(points.frontGussetRightCp1, points.frontLegOpeningRightCp1, points.frontLegOpeningRight)
.length()
)
store.set(
'frontWaistBandLength',
new Path()
.move(points.frontWaistBandRight)
.curve(points.frontWaistBandRightCp1, points.frontWaistBandLeftCp1, points.frontWaistBandLeft)
.length()
)
// Complete?
if (complete) {
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
macro('title', {
at: points.frontMidMid,
nr: 1,
title: 'front',
})
// Paperless?
if (paperless) {
macro('hd', {
from: points.frontWaistBandRight,
to: points.frontWaistBandLeft,
y: points.frontWaistBandRight.y + sa - 15,
})
macro('hd', {
from: points.frontLegOpeningRight,
to: points.frontLegOpeningLeft,
y: points.frontLegOpeningRight.y + sa - 15,
})
macro('hd', {
from: points.frontGussetLeft,
to: points.frontGussetRight,
y: points.frontGussetLeft.y + sa + 15,
})
macro('vd', {
from: points.frontWaistBandMid,
to: points.frontGussetMid,
x: points.frontWaistBandMid.x + sa + 15,
})
macro('ld', {
from: points.frontWaistBandLeft,
to: points.frontLegOpeningLeft,
d: points.frontWaistBandLeft.y + sa - 15
})
macro('pd', {
path: new Path()
.move(points.frontGussetRight)
.curve(points.frontGussetRightCp1, points.frontLegOpeningRightCp1, points.frontLegOpeningRight),
d: 15
})
/* macro('vd', {
from: points.frontWaistBandLeft,
to: points.frontWaistBandMid,
x: points.frontWaistBandMid.x + sa + 15,
}) */
}
return part
}

View file

@ -0,0 +1,95 @@
export default function (part) {
let {
options,
Point,
Path,
points,
paths,
measurements,
// Snippet,
// snippets,
store,
utils,
complete,
sa,
paperless,
macro,
} = part.shorthand()
// Design pattern here
// Create points
points.frontGussetLeft = new Point(store.get('frontGussetLeft').x, 0)
points.backGussetLeft = new Point(store.get('backGussetLeft').x, measurements.seat * options.gussetLength)
points.frontGussetRight = new Point(store.get('frontGussetRight').x, 0)
points.backGussetRight = new Point(store.get('backGussetRight').x, measurements.seat * options.gussetLength)
// Create control points
points.gussetCp1 = points.frontGussetLeft.shiftFractionTowards(points.backGussetLeft, 0.5)
.shift(180,points.frontGussetRight.x / -15)
// Flip points to right side
points.gussetCp2 = points.gussetCp1.flipX(store.get('frontGussetMid'))
// Create point for title
points.frontMidMid = points.gussetCp1.shiftFractionTowards(points.gussetCp2, 0.5)
/* Store lengths for use in elastic */
store.set(
'gussetSideLength',
new Path()
.move(points.backGussetRight)
.curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight)
.length()
)
// Draw paths
paths.seam = new Path()
.move(points.frontGussetLeft)
.curve(points.gussetCp1, points.backGussetLeft, points.backGussetLeft)
.line(points.backGussetRight)
.curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight)
.line(points.frontGussetLeft) // Without this, doesn't generate seam allowance
.close()
.attr('class', 'fabric')
// Complete?
if (complete) {
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
macro('title', {
at: points.frontMidMid,
nr: 3,
title: 'gusset',
})
// Paperless?
if (paperless) {
macro('hd', {
from: points.frontGussetLeft,
to: points.frontGussetRight,
y: points.frontGussetLeft.y + sa + 15,
})
macro('hd', {
from: points.backGussetLeft,
to: points.backGussetRight,
y: points.backGussetLeft.y + sa + 15,
})
macro('vd', {
from: points.frontGussetRight,
to: points.backGussetRight,
x: points.frontGussetRight.x + sa + 15,
})
}
return part
}

View file

@ -0,0 +1,18 @@
import freesewing from '@freesewing/core'
import plugins from '@freesewing/plugin-bundle'
import config from '../config'
import draftFront from './front'
import draftBack from './back'
import draftGusset from './gusset'
import draftElastic from './elastic'
// Create new design
const Pattern = new freesewing.Design(config, plugins)
// Attach the draft methods to the prototype
Pattern.prototype.draftFront = draftFront
Pattern.prototype.draftBack = draftBack
Pattern.prototype.draftGusset = draftGusset
Pattern.prototype.draftElastic = draftElastic
export default Pattern