diff --git a/.eslintignore b/.eslintignore index 9117bc46585..749ad3c82aa 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,6 +6,7 @@ *.svg *.sh *.md +*.mdx *.prisma *.css *.mustache diff --git a/.gitignore b/.gitignore index 03e6daf28b3..1855157f30f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ sites/*/package-lock.json # Nx cache .nx/cache +# Docusaurus cache +.docusaurus + # Sites prebuild artifacts sites/*/public/locales/*/*.json !sites/sde/public/locales/*/*.json diff --git a/designs/aaron/i18n/index.mjs b/designs/aaron/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/aaron/i18n/index.mjs +++ b/designs/aaron/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/aaron/src/front.mjs b/designs/aaron/src/front.mjs index c605c7c75bc..35e5b3f9a7c 100644 --- a/designs/aaron/src/front.mjs +++ b/designs/aaron/src/front.mjs @@ -16,7 +16,7 @@ export const front = { frontArmholeDeeper: 0, armholeDepthFactor: 0.6, shoulderSlopeReduction: 0, - chestEase: { pct: 8, min: 0, max: 20, ...pctBasedOn('chest'), menu: 'style' }, + chestEase: { pct: 8, min: 0, max: 20, ...pctBasedOn('chest'), menu: 'fit' }, draftForHighBust: { bool: false, menu: 'fit' }, hipsEase: { pct: 8, min: 0, max: 20, menu: 'fit' }, stretchFactor: { pct: 5, min: 0, max: 15, menu: 'fit' }, diff --git a/designs/albert/i18n/index.mjs b/designs/albert/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/albert/i18n/index.mjs +++ b/designs/albert/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/bee/i18n/index.mjs b/designs/bee/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/bee/i18n/index.mjs +++ b/designs/bee/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/bee/src/cup.mjs b/designs/bee/src/cup.mjs index a28d77b55a5..73c9d2a6818 100644 --- a/designs/bee/src/cup.mjs +++ b/designs/bee/src/cup.mjs @@ -28,8 +28,11 @@ export const cup = { bustDartCurve: 1, bustDartLength: 1, waistDartLength: 1, + waistDartCurve: 1, backHemSlope: 2.5, backNeckCutout: 0.06, + bustDartAngle: 0, + bustDartMinimumFabric: 0, //catergory changed from Bella armholeDepth: { pct: 44, min: 38, max: 46, menu: 'advanced' }, frontArmholePitchDepth: { pct: 29, max: 31, min: 27, menu: 'advanced' }, diff --git a/designs/bella/i18n/en.json b/designs/bella/i18n/en.json index b024f21d917..7a47d698dbc 100644 --- a/designs/bella/i18n/en.json +++ b/designs/bella/i18n/en.json @@ -50,6 +50,18 @@ "t": "Bust dart curve", "d": "Controls the curvature of the bust dart" }, + "bustDartAngle": { + "t": "Bust dart angle", + "d": "The angle of the bust dart" + }, + "bustDartMinimumFabric": { + "t": "Bust dart minimum fabric", + "d": "The minimum amount of side seam above and below the bust dart" + }, + "waistDartCurve": { + "t": "Waist dart curve", + "d": "Controls the curvature of the waist dart" + }, "armholeDepth": { "t": "Armhole depth", "d": "Controls the depth of the armhole" diff --git a/designs/bella/i18n/index.mjs b/designs/bella/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/bella/i18n/index.mjs +++ b/designs/bella/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/bella/src/back.mjs b/designs/bella/src/back.mjs index bd92208d266..05577b33564 100644 --- a/designs/bella/src/back.mjs +++ b/designs/bella/src/back.mjs @@ -31,9 +31,12 @@ export const back = { waistEase: { pct: 5, min: 1, max: 20, menu: 'fit' }, // Darts backDartHeight: { pct: 46, min: 38, max: 54, menu: 'darts' }, - bustDartCurve: { pct: 100, min: 0, max: 100, menu: 'darts' }, + bustDartCurve: { pct: 100, min: -100, max: 100, menu: 'darts' }, bustDartLength: { pct: 90, min: 75, max: 100, menu: 'darts' }, + bustDartAngle: { count: 0, min: -45, max: 45, menu: 'darts' }, + bustDartMinimumFabric: { pct: 5, min: 1, max: 50, menu: 'darts' }, waistDartLength: { pct: 90, min: 75, max: 95, menu: 'darts' }, + waistDartCurve: { pct: 100, min: -100, max: 100, menu: 'darts' }, // Armhole armholeDepth: { pct: 44, min: 38, max: 46, menu: 'armhole' }, backArmholeCurvature: { pct: 63, min: 50, max: 85, menu: 'armhole' }, diff --git a/designs/bella/src/front-side-dart.mjs b/designs/bella/src/front-side-dart.mjs index 430a9634eea..b6a5f63fe90 100644 --- a/designs/bella/src/front-side-dart.mjs +++ b/designs/bella/src/front-side-dart.mjs @@ -15,6 +15,7 @@ export const frontSideDart = { macro, utils, measurements, + log, part, }) => { // Get to work @@ -114,12 +115,32 @@ export const frontSideDart = { ) // Bust dart + const sideSeamLength = store.get('sideSeamLength') + const minimumFabric = sideSeamLength * options.bustDartMinimumFabric points.bustDartTop = utils.beamsIntersect( points.armhole, points.sideHem, points.bust, - points.bust.shift(0, 100) + points.bust.shift(Number(options.bustDartAngle), 100) ) + // Ensure minimum fabric above the bust dart + if (points.bustDartTop.y < points.armhole.y + minimumFabric) { + points.bustDartTop = points.armhole.shiftTowards(points.sideHem, minimumFabric) + log.info( + part.name + ': Restricted bust dart angle to ensure minimum fabric above the bust dart.' + ) + } + // Ensure minimum fabric below the bust dart + if (points.armhole.dist(points.bustDartTop) > sideSeamLength - minimumFabric) { + points.bustDartTop = points.armhole.shiftTowards( + points.sideHem, + sideSeamLength - minimumFabric + ) + log.info( + part.name + ': Restricted bust dart angle to ensure minimum fabric below the bust dart.' + ) + } + points.bustDartBottom = points.bustDartTop.rotate(angle * -1, points.bust) points.bustDartMiddle = points.bustDartTop.shiftFractionTowards(points.bustDartBottom, 0.5) points.bustDartTip = points.bustDartMiddle.shiftFractionTowards( @@ -140,8 +161,8 @@ export const frontSideDart = { .rotate(-5 * options.bustDartCurve, points.bust) // Side seam length - let aboveDart = points.armhole.dist(points.bustDartTop) - let belowDart = store.get('sideSeamLength') - aboveDart + const aboveDart = points.armhole.dist(points.bustDartTop) + const belowDart = sideSeamLength - aboveDart points.sideHemInitial = points.bustDartBottom .shift(-90, belowDart) .shift(180, store.get('sideReduction')) @@ -152,6 +173,16 @@ export const frontSideDart = { let reduce = points.cfHem.dist(points.sideHemInitial) - hemLen // Waist dart + let includeWaistDart = true + if (reduce <= 0) { + includeWaistDart = false + log.info( + '`' + + part.name + + '`: Front waist dart omitted (because the calculated dart' + + ' width was 0.0 mm/inches or less).' + ) + } points.waistDartHem = new Point(points.bust.x, points.cfHem.y) points.waistDartLeft = points.waistDartHem.shift(180, reduce / 2) points.waistDartRight = points.waistDartHem.shift(0, reduce / 2) @@ -167,12 +198,28 @@ export const frontSideDart = { 90, points.waistDartHem.dist(points.bust) / 2 ) - - paths.seam = new Path() - .move(points.cfHem) + // Apply option-controlled curvature to waist dart + points.waistDartLeftMid = new Path() + .move(points.bust) .line(points.waistDartLeft) - .curve_(points.waistDartLeftCp, points.waistDartTip) - ._curve(points.waistDartRightCp, points.waistDartRight) + .shiftFractionAlong(0.5) + points.waistDartRightMid = new Path() + .move(points.bust) + .line(points.waistDartRight) + .shiftFractionAlong(0.5) + const waistDartCpWidth = + points.waistDartLeftMid.dist(points.waistDartLeftCp) * options.waistDartCurve + points.waistDartLeftCp.x = points.waistDartLeftMid.x - waistDartCpWidth + points.waistDartRightCp.x = points.waistDartRightMid.x + waistDartCpWidth + + paths.seam = new Path().move(points.cfHem) + if (includeWaistDart) + paths.seam + .line(points.waistDartLeft) + .curve_(points.waistDartLeftCp, points.waistDartTip) + ._curve(points.waistDartRightCp, points.waistDartRight) + .line(points.waistDartRight) + paths.seam .line(points.sideHem) .line(points.bustDartBottom) ._curve(points.bustDartCpBottom, points.bustDartTip) @@ -186,10 +233,9 @@ export const frontSideDart = { .close() .attr('class', 'fabric') - paths.saBase = new Path() - .move(points.cfHem) - .line(points.waistDartLeft) - .line(points.waistDartRight) + paths.saBase = new Path().move(points.cfHem) + if (includeWaistDart) paths.saBase.line(points.waistDartLeft).line(points.waistDartRight) + paths.saBase .line(points.sideHem) .line(points.bustDartBottom) .line(points.bustDartEdge) @@ -248,29 +294,33 @@ export const frontSideDart = { }) // Dimensions - macro('vd', { - id: 'hCfHemToWaistDartTop', - from: points.cfHem, - to: points.waistDartTip, - x: 0 - 15, - }) + let dimensionOffset = 0 + if (includeWaistDart) { + dimensionOffset = 15 + macro('vd', { + id: 'hCfHemToWaistDartTop', + from: points.cfHem, + to: points.waistDartTip, + x: 0 - 15, + }) + } macro('vd', { id: 'hCfHemToBustPoint', from: points.cfHem, to: points.bust, - x: 0 - 30, + x: 0 - 15 - dimensionOffset, }) macro('vd', { id: 'hCfHemToNeckCutout', from: points.cfHem, to: points.cfNeck, - x: 0 - 45, + x: 0 - 30 - dimensionOffset, }) macro('vd', { id: 'hTotal', from: points.cfHem, to: points.hps, - x: 0 - 60, + x: 0 - 45 - dimensionOffset, }) macro('hd', { id: 'wCfToWaistDartTip', @@ -284,35 +334,39 @@ export const frontSideDart = { to: points.bustDartTip, y: points.bust.y - 30, }) - macro('hd', { - id: 'wCfToWaistDartLeft', - from: points.cfHem, - to: points.waistDartLeft, - y: points.cfHem.y + sa + 15, - }) - macro('hd', { - id: 'wCfToWaistDartRight', - from: points.cfHem, - to: points.waistDartRight, - y: points.cfHem.y + sa + 30, - }) + dimensionOffset = 0 + if (includeWaistDart) { + dimensionOffset = 30 + macro('hd', { + id: 'wCfToWaistDartLeft', + from: points.cfHem, + to: points.waistDartLeft, + y: points.cfHem.y + sa + 15, + }) + macro('hd', { + id: 'wCfToWaistDartRight', + from: points.cfHem, + to: points.waistDartRight, + y: points.cfHem.y + sa + 30, + }) + } macro('hd', { id: 'wHemTotal', from: points.cfHem, to: points.sideHem, - y: points.cfHem.y + sa + 45, + y: points.cfHem.y + sa + 15 + dimensionOffset, }) macro('hd', { id: 'wCfHemToBustDartBottom', from: points.cfHem, to: points.bustDartBottom, - y: points.cfHem.y + sa + 60, + y: points.cfHem.y + sa + 30 + dimensionOffset, }) macro('hd', { id: 'wCfHemToBustDartTop', from: points.cfHem, to: points.bustDartTop, - y: points.cfHem.y + sa + 75, + y: points.cfHem.y + sa + 45 + dimensionOffset, }) macro('vd', { id: 'hHemRightToBustDartBottom', diff --git a/designs/benjamin/i18n/index.mjs b/designs/benjamin/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/benjamin/i18n/index.mjs +++ b/designs/benjamin/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/bent/i18n/index.mjs b/designs/bent/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/bent/i18n/index.mjs +++ b/designs/bent/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/bent/src/sleeve.mjs b/designs/bent/src/sleeve.mjs index c54e6c03d89..4f26e9090b6 100644 --- a/designs/bent/src/sleeve.mjs +++ b/designs/bent/src/sleeve.mjs @@ -5,7 +5,8 @@ function draftBentSleeve({ Path, paths, points, store, options, part }) { let { Point, Path, points, store, options, measurements, utils } = part.shorthand() // Sleeve frame points.top = new Point(0, 0) - points.boxTopRight = points.top.shift(0, (store.get('sleevecapTarget') / 5.8) * tweak) + const easedQuarterBiceps = (measurements.biceps / 4) * (1 + options.bicepsEase) + points.boxTopRight = points.top.shift(0, easedQuarterBiceps * tweak) points.boxTopLeft = points.boxTopRight.flipX() points.boxBottom = points.top.shift( -90, diff --git a/designs/bibi/i18n/index.mjs b/designs/bibi/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/bibi/i18n/index.mjs +++ b/designs/bibi/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/bob/i18n/index.mjs b/designs/bob/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/bob/i18n/index.mjs +++ b/designs/bob/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/breanna/i18n/index.mjs b/designs/breanna/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/breanna/i18n/index.mjs +++ b/designs/breanna/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/brian/i18n/index.mjs b/designs/brian/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/brian/i18n/index.mjs +++ b/designs/brian/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/bruce/i18n/index.mjs b/designs/bruce/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/bruce/i18n/index.mjs +++ b/designs/bruce/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/carlita/i18n/index.mjs b/designs/carlita/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/carlita/i18n/index.mjs +++ b/designs/carlita/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/carlton/i18n/index.mjs b/designs/carlton/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/carlton/i18n/index.mjs +++ b/designs/carlton/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/cathrin/i18n/index.mjs b/designs/cathrin/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/cathrin/i18n/index.mjs +++ b/designs/cathrin/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/charlie/i18n/index.mjs b/designs/charlie/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/charlie/i18n/index.mjs +++ b/designs/charlie/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/cornelius/i18n/index.mjs b/designs/cornelius/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/cornelius/i18n/index.mjs +++ b/designs/cornelius/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/cornelius/src/front.mjs b/designs/cornelius/src/front.mjs index 4ed21894b05..73315d906dc 100644 --- a/designs/cornelius/src/front.mjs +++ b/designs/cornelius/src/front.mjs @@ -50,18 +50,21 @@ export const front = { waistAngle -= 180 } + const flyConst = 14 + store.set('flyConst',flyConst) + points.flyTop = points.pW.shift( points.pW.angle(points.pZ) - 180 + waistAngle, - halfInch * flyWidth + flyConst * flyWidth ) points.flyBottom = points.flyTop.shift( points.pW.angle(points.pZ), - points.pW.dist(points.pZ) - halfInch * flyWidth + points.pW.dist(points.pZ) - flyConst * flyWidth ) points.pZcpFB = points.pZ.shift( points.pW.angle(points.pZ) - waistAngle, - halfInch * flyWidth * cc + flyConst * flyWidth * cc ) points.pFBcpZ = points.flyBottom.shift(points.pW.angle(points.pZ), halfInch * flyWidth * cc) diff --git a/designs/cornelius/src/zipperguard.mjs b/designs/cornelius/src/zipperguard.mjs index f5e4ed31699..48c951d6009 100644 --- a/designs/cornelius/src/zipperguard.mjs +++ b/designs/cornelius/src/zipperguard.mjs @@ -6,8 +6,8 @@ export const zipperguard = { draft: ({ Point, Path, points, paths, Snippet, snippets, sa, store, macro, part }) => { const cc = 0.551915024494 // circle constant - const halfInch = store.get('halfInch') - const flyWidth = store.get('flyWidth') * halfInch + const flyConst = store.get('flyConst') + const flyWidth = store.get('flyWidth') * flyConst const flyLength = store.get('flyLength') points.pA = new Point(0, 0) diff --git a/designs/diana/i18n/index.mjs b/designs/diana/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/diana/i18n/index.mjs +++ b/designs/diana/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/examples/i18n/index.mjs b/designs/examples/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/examples/i18n/index.mjs +++ b/designs/examples/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/florence/i18n/index.mjs b/designs/florence/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/florence/i18n/index.mjs +++ b/designs/florence/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/florent/i18n/index.mjs b/designs/florent/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/florent/i18n/index.mjs +++ b/designs/florent/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/gozer/i18n/index.mjs b/designs/gozer/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/gozer/i18n/index.mjs +++ b/designs/gozer/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/gozer/src/ghost.mjs b/designs/gozer/src/ghost.mjs index 91b79e98149..1523548fdb7 100644 --- a/designs/gozer/src/ghost.mjs +++ b/designs/gozer/src/ghost.mjs @@ -2,15 +2,17 @@ export const ghost = { name: 'gozer.ghost', measurements: ['hpsToWaistBack', 'waistToFloor', 'head'], draft: ({ measurements, Point, points, Snippet, snippets, sa, macro, part }) => { - const eyeSize = measurements.head * 0.0416 + const eyeSize = measurements.head * (1 / 24) + const eyeLine = measurements.head / 2.25 + const eyeOffset = measurements.head * (1 / 12.7) const size = measurements.hpsToWaistBack + measurements.waistToFloor + measurements.head / Math.PI points.middle = new Point(0, 0).addCircle(size, 'fabric') - points.eyeLine = points.middle.shift(270, measurements.head / Math.PI / 2) - points.eyeLeft = points.eyeLine.shift(180, measurements.head * 0.13) - points.eyeRight = points.eyeLine.shift(0, measurements.head * 0.13) + points.eyeLine = points.middle.shift(270, eyeLine) + points.eyeLeft = points.eyeLine.shift(180, eyeOffset) + points.eyeRight = points.eyeLine.shift(0, eyeOffset) points.left = new Point(-1 * size, 0) points.right = new Point(size, 0) diff --git a/designs/hi/i18n/index.mjs b/designs/hi/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/hi/i18n/index.mjs +++ b/designs/hi/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/holmes/i18n/index.mjs b/designs/holmes/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/holmes/i18n/index.mjs +++ b/designs/holmes/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/hortensia/i18n/index.mjs b/designs/hortensia/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/hortensia/i18n/index.mjs +++ b/designs/hortensia/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/huey/i18n/en.json b/designs/huey/i18n/en.json index 546a862b6e8..61489985369 100644 --- a/designs/huey/i18n/en.json +++ b/designs/huey/i18n/en.json @@ -33,6 +33,10 @@ "t": "Pocket height", "d": "Controls the height of the pocket" }, + "pocketOpening": { + "t": "Pocket opening", + "d": "Controls the opening size of the pocket" + }, "hoodHeight": { "t": "Hood height", "d": "Controls the height of the hood" diff --git a/designs/huey/i18n/index.mjs b/designs/huey/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/huey/i18n/index.mjs +++ b/designs/huey/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/huey/src/front.mjs b/designs/huey/src/front.mjs index f9ac229b574..e744755a139 100644 --- a/designs/huey/src/front.mjs +++ b/designs/huey/src/front.mjs @@ -37,7 +37,7 @@ function draftHueyFront({ points.pocketTopRight = points.pocketCfTop.shift(0, points.hem.x * options.pocketWidth) points.pocketTip = new Point( points.pocketTopRight.x * 1.2, - points.pocketTopRight.y + (points.hem.y - points.pocketTopRight.y) * 0.9 + points.pocketTopRight.y + (points.hem.y - points.pocketTopRight.y) * options.pocketOpening ) points.pocketHem = new Point( points.pocketTopRight.x + points.pocketTopRight.dx(points.pocketTip) / 2, @@ -134,6 +134,7 @@ export const front = { pocket: { bool: true, menu: 'style' }, pocketHeight: { pct: 30, min: 25, max: 35, menu: 'style' }, pocketWidth: { pct: 60, min: 50, max: 70, menu: 'style' }, + pocketOpening: { pct: 90, min: 60, max: 90, menu: 'style' }, }, draft: draftHueyFront, } diff --git a/designs/hugo/i18n/en.json b/designs/hugo/i18n/en.json index 25325541209..6fa1376795d 100644 --- a/designs/hugo/i18n/en.json +++ b/designs/hugo/i18n/en.json @@ -19,9 +19,9 @@ "cutCuff.t": "The cuff is not shown", "cutCuff.d": "The **Cuff** (9) is a rectangular piece of ribbing fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the width.", "cutHoodCenter.t": "The hood center is not shown", - "cutHoodCenter.d": "The **Hood center** (7) is a rectangular piece of ribbing fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the width.", + "cutHoodCenter.d": "The **Hood center** (7) is a rectangular piece of main fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the width.", "cutNeckBinding.t": "The neck binding is not shown", - "cutNeckBinding.d": "The **Neck Binding** (10) is a rectangular piece of ribbing fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the length.", + "cutNeckBinding.d": "The **Neck Binding** (10) is a rectangular piece of main fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the length.", "cutWaistband.t": "The waistband is not shown", "cutWaistband.d": "The **Waistband** (8) is a rectangular piece of ribbing fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the width." }, diff --git a/designs/hugo/i18n/index.mjs b/designs/hugo/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/hugo/i18n/index.mjs +++ b/designs/hugo/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/jaeger/i18n/index.mjs b/designs/jaeger/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/jaeger/i18n/index.mjs +++ b/designs/jaeger/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/jane/i18n/index.mjs b/designs/jane/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/jane/i18n/index.mjs +++ b/designs/jane/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/legend/i18n/index.mjs b/designs/legend/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/legend/i18n/index.mjs +++ b/designs/legend/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/lily/i18n/index.mjs b/designs/lily/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/lily/i18n/index.mjs +++ b/designs/lily/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/lucy/i18n/index.mjs b/designs/lucy/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/lucy/i18n/index.mjs +++ b/designs/lucy/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/lumina/i18n/index.mjs b/designs/lumina/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/lumina/i18n/index.mjs +++ b/designs/lumina/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/lumira/i18n/index.mjs b/designs/lumira/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/lumira/i18n/index.mjs +++ b/designs/lumira/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/lunetius/i18n/index.mjs b/designs/lunetius/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/lunetius/i18n/index.mjs +++ b/designs/lunetius/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/magde/i18n/index.mjs b/designs/magde/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/magde/i18n/index.mjs +++ b/designs/magde/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/naomiwu/i18n/index.mjs b/designs/naomiwu/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/naomiwu/i18n/index.mjs +++ b/designs/naomiwu/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/noble/i18n/index.mjs b/designs/noble/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/noble/i18n/index.mjs +++ b/designs/noble/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/noble/src/options.mjs b/designs/noble/src/options.mjs index 55649ccf375..72c7217553e 100644 --- a/designs/noble/src/options.mjs +++ b/designs/noble/src/options.mjs @@ -4,6 +4,9 @@ import { pctBasedOn } from '@freesewing/core' export const shoulderToShoulderCorrection = 0.995 export const bustDartCurve = 1 export const bustDartLength = 0.9 +export const bustDartAngle = 0 +export const bustDartMinimumFabric = 0 +export const waistDartCurve = 1 // Percentages export const bustSpanEase = { pct: 0, min: -5, max: 20, ...pctBasedOn('bustSpan'), menu: 'fit' } export const backHemSlope = { deg: 2.5, min: 0, max: 5, menu: 'advanced' } diff --git a/designs/octoplushy/i18n/index.mjs b/designs/octoplushy/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/octoplushy/i18n/index.mjs +++ b/designs/octoplushy/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/onyx/i18n/index.mjs b/designs/onyx/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/onyx/i18n/index.mjs +++ b/designs/onyx/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/opal/i18n/index.mjs b/designs/opal/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/opal/i18n/index.mjs +++ b/designs/opal/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/otis/i18n/index.mjs b/designs/otis/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/otis/i18n/index.mjs +++ b/designs/otis/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/paco/i18n/index.mjs b/designs/paco/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/paco/i18n/index.mjs +++ b/designs/paco/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/penelope/i18n/index.mjs b/designs/penelope/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/penelope/i18n/index.mjs +++ b/designs/penelope/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/plugintest/i18n/index.mjs b/designs/plugintest/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/plugintest/i18n/index.mjs +++ b/designs/plugintest/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/rendertest/i18n/index.mjs b/designs/rendertest/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/rendertest/i18n/index.mjs +++ b/designs/rendertest/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/sandy/i18n/index.mjs b/designs/sandy/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/sandy/i18n/index.mjs +++ b/designs/sandy/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/sandy/src/skirt.mjs b/designs/sandy/src/skirt.mjs index 1c1b90e2964..e01a07738c6 100644 --- a/designs/sandy/src/skirt.mjs +++ b/designs/sandy/src/skirt.mjs @@ -113,9 +113,13 @@ function sandySkirt({ if (sa) { paths.hemBase = new Path() .move(points.ex2Flipped) - .circleSegment(angle, points.center) + .curve(points.ex2cFlipped, points.ex1cFlipped, points.ex1) + .curve(points.ex1c, points.ex2c, points.ex2) .offset(store.get('fullLength') * options.lengthBonus * options.hemWidth) - paths.saBase = new Path().move(points.in2).circleSegment(-angle, points.center) + paths.saBase = new Path() + .move(points.in2) + .curve(points.in2c, points.in1c, points.in1) + .curve(points.in1cFlipped, points.in2cFlipped, points.in2Flipped) if (!options.seamlessFullCircle) paths.saBase = new Path().move(points.ex2).line(points.ex2).join(paths.saBase) diff --git a/designs/shelly/i18n/index.mjs b/designs/shelly/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/shelly/i18n/index.mjs +++ b/designs/shelly/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/shin/i18n/index.mjs b/designs/shin/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/shin/i18n/index.mjs +++ b/designs/shin/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/simon/i18n/index.mjs b/designs/simon/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/simon/i18n/index.mjs +++ b/designs/simon/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/simone/i18n/index.mjs b/designs/simone/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/simone/i18n/index.mjs +++ b/designs/simone/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/simone/src/fba-front.mjs b/designs/simone/src/fba-front.mjs index 9f2911635fb..5b475b7482c 100644 --- a/designs/simone/src/fba-front.mjs +++ b/designs/simone/src/fba-front.mjs @@ -24,6 +24,12 @@ function simoneFbaFront({ * Once drafted, we add the FBA, which is what happens in this file */ + /* + * Locate bust point + */ + points.bust = new Point(measurements.bustSpan / 2, points.neck.y + measurements.hpsToBust) + points.cfBust = new Point(0, points.bust.y) + /* * How much room to we need to create to fit the breasts? * Note that: @@ -37,18 +43,13 @@ function simoneFbaFront({ * If the FBA is negative, that means the high bust measurement is higher than the * front bust. That's not uncommon for people who don't have much breast tissue but * it generates a negative dart which is confusing and incorrect. So in that case, just - * return the original part from simon + * return the part from Simon without any adjustments. */ if (FBA < 0) { log.info('No FBA required, using unaltered Simon front') return part } - /* - * Locate bust point - */ - points.bust = new Point(measurements.bustSpan / 2, points.neck.y + measurements.hpsToBust) - /* * Figure out how much do we need to open a dart to create the required FBA room */ diff --git a/designs/skully/i18n/index.mjs b/designs/skully/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/skully/i18n/index.mjs +++ b/designs/skully/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/sven/i18n/index.mjs b/designs/sven/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/sven/i18n/index.mjs +++ b/designs/sven/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/tamiko/i18n/index.mjs b/designs/tamiko/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/tamiko/i18n/index.mjs +++ b/designs/tamiko/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/teagan/i18n/index.mjs b/designs/teagan/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/teagan/i18n/index.mjs +++ b/designs/teagan/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/tiberius/i18n/index.mjs b/designs/tiberius/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/tiberius/i18n/index.mjs +++ b/designs/tiberius/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/titan/i18n/index.mjs b/designs/titan/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/titan/i18n/index.mjs +++ b/designs/titan/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/trayvon/i18n/index.mjs b/designs/trayvon/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/trayvon/i18n/index.mjs +++ b/designs/trayvon/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/tristan/i18n/index.mjs b/designs/tristan/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/tristan/i18n/index.mjs +++ b/designs/tristan/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/tristan/src/peplumFront.mjs b/designs/tristan/src/peplumFront.mjs index 2f7a324463b..ec98a96a89a 100644 --- a/designs/tristan/src/peplumFront.mjs +++ b/designs/tristan/src/peplumFront.mjs @@ -17,10 +17,9 @@ export const CreateShape = ({ const double = type == options.zipperLocation || (true == options.lacing && type == options.lacingLocation) - const angle = (options.peplumFullness / 2) * ratio * (double ? 0.5 : 1) macro('ringsector', { id: type + 'Peblum', - angle: angle, + angle: (options.peplumFullness / 2) * ratio * (double ? 0.5 : 1), insideRadius: radius, outsideRadius: radius + width, rotate: false, @@ -53,9 +52,27 @@ export const CreateShape = ({ .join( new Path() .move(points['__macro_ringsector_' + type + 'Peblum_ex2Flipped']) - .circleSegment(angle, points['__macro_ringsector_' + type + 'Peblum_center']) + .curve( + points['__macro_ringsector_' + type + 'Peblum_ex2cFlipped'], + points['__macro_ringsector_' + type + 'Peblum_ex1cFlipped'], + points['__macro_ringsector_' + type + 'Peblum_ex1'] + ) + .curve( + points['__macro_ringsector_' + type + 'Peblum_ex1c'], + points['__macro_ringsector_' + type + 'Peblum_ex2c'], + points['__macro_ringsector_' + type + 'Peblum_ex2'] + ) .line(points['__macro_ringsector_' + type + 'Peblum_in2']) - .circleSegment(-angle, points['__macro_ringsector_' + type + 'Peblum_center']) + .curve( + points['__macro_ringsector_' + type + 'Peblum_in2c'], + points['__macro_ringsector_' + type + 'Peblum_in1c'], + points['__macro_ringsector_' + type + 'Peblum_in1'] + ) + .curve( + points['__macro_ringsector_' + type + 'Peblum_in1cFlipped'], + points['__macro_ringsector_' + type + 'Peblum_in2cFlipped'], + points['__macro_ringsector_' + type + 'Peblum_in2Flipped'] + ) .offset(sa) ) .line(points['__macro_ringsector_' + type + 'Peblum_in2Flipped']) diff --git a/designs/uma/i18n/index.mjs b/designs/uma/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/uma/i18n/index.mjs +++ b/designs/uma/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/umbra/i18n/index.mjs b/designs/umbra/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/umbra/i18n/index.mjs +++ b/designs/umbra/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/wahid/i18n/index.mjs b/designs/wahid/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/wahid/i18n/index.mjs +++ b/designs/wahid/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/walburga/i18n/index.mjs b/designs/walburga/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/walburga/i18n/index.mjs +++ b/designs/walburga/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/waralee/i18n/index.mjs b/designs/waralee/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/waralee/i18n/index.mjs +++ b/designs/waralee/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/designs/yuri/i18n/index.mjs b/designs/yuri/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/designs/yuri/i18n/index.mjs +++ b/designs/yuri/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/i18n/designs.mjs b/i18n/designs.mjs new file mode 100644 index 00000000000..29b5c9ca341 --- /dev/null +++ b/i18n/designs.mjs @@ -0,0 +1,133 @@ +/* + * This file is auto-generated by the reconfigure script + * Any changes will be overwritten next time the repo is reconfigured + */ +import { i18n as aaron } from '@freesewing/aaron' +import { i18n as albert } from '@freesewing/albert' +import { i18n as bee } from '@freesewing/bee' +import { i18n as bella } from '@freesewing/bella' +import { i18n as benjamin } from '@freesewing/benjamin' +import { i18n as bent } from '@freesewing/bent' +import { i18n as bibi } from '@freesewing/bibi' +import { i18n as bob } from '@freesewing/bob' +import { i18n as breanna } from '@freesewing/breanna' +import { i18n as brian } from '@freesewing/brian' +import { i18n as bruce } from '@freesewing/bruce' +import { i18n as carlita } from '@freesewing/carlita' +import { i18n as carlton } from '@freesewing/carlton' +import { i18n as cathrin } from '@freesewing/cathrin' +import { i18n as charlie } from '@freesewing/charlie' +import { i18n as cornelius } from '@freesewing/cornelius' +import { i18n as diana } from '@freesewing/diana' +import { i18n as examples } from '@freesewing/examples' +import { i18n as florence } from '@freesewing/florence' +import { i18n as florent } from '@freesewing/florent' +import { i18n as gozer } from '@freesewing/gozer' +import { i18n as hi } from '@freesewing/hi' +import { i18n as holmes } from '@freesewing/holmes' +import { i18n as hortensia } from '@freesewing/hortensia' +import { i18n as huey } from '@freesewing/huey' +import { i18n as hugo } from '@freesewing/hugo' +import { i18n as jaeger } from '@freesewing/jaeger' +import { i18n as jane } from '@freesewing/jane' +import { i18n as legend } from '@freesewing/legend' +import { i18n as lily } from '@freesewing/lily' +import { i18n as lucy } from '@freesewing/lucy' +import { i18n as lumina } from '@freesewing/lumina' +import { i18n as lumira } from '@freesewing/lumira' +import { i18n as lunetius } from '@freesewing/lunetius' +import { i18n as magde } from '@freesewing/magde' +import { i18n as noble } from '@freesewing/noble' +import { i18n as octoplushy } from '@freesewing/octoplushy' +import { i18n as onyx } from '@freesewing/onyx' +import { i18n as opal } from '@freesewing/opal' +import { i18n as otis } from '@freesewing/otis' +import { i18n as paco } from '@freesewing/paco' +import { i18n as penelope } from '@freesewing/penelope' +import { i18n as plugintest } from '@freesewing/plugintest' +import { i18n as rendertest } from '@freesewing/rendertest' +import { i18n as sandy } from '@freesewing/sandy' +import { i18n as shelly } from '@freesewing/shelly' +import { i18n as shin } from '@freesewing/shin' +import { i18n as simon } from '@freesewing/simon' +import { i18n as simone } from '@freesewing/simone' +import { i18n as skully } from '@freesewing/skully' +import { i18n as sven } from '@freesewing/sven' +import { i18n as tamiko } from '@freesewing/tamiko' +import { i18n as teagan } from '@freesewing/teagan' +import { i18n as tiberius } from '@freesewing/tiberius' +import { i18n as titan } from '@freesewing/titan' +import { i18n as trayvon } from '@freesewing/trayvon' +import { i18n as tristan } from '@freesewing/tristan' +import { i18n as uma } from '@freesewing/uma' +import { i18n as umbra } from '@freesewing/umbra' +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' + +export const designs = { + aaron: aaron.en, + albert: albert.en, + bee: bee.en, + bella: bella.en, + benjamin: benjamin.en, + bent: bent.en, + bibi: bibi.en, + bob: bob.en, + breanna: breanna.en, + brian: brian.en, + bruce: bruce.en, + carlita: carlita.en, + carlton: carlton.en, + cathrin: cathrin.en, + charlie: charlie.en, + cornelius: cornelius.en, + diana: diana.en, + examples: examples.en, + florence: florence.en, + florent: florent.en, + gozer: gozer.en, + hi: hi.en, + holmes: holmes.en, + hortensia: hortensia.en, + huey: huey.en, + hugo: hugo.en, + jaeger: jaeger.en, + jane: jane.en, + legend: legend.en, + lily: lily.en, + lucy: lucy.en, + lumina: lumina.en, + lumira: lumira.en, + lunetius: lunetius.en, + magde: magde.en, + noble: noble.en, + octoplushy: octoplushy.en, + onyx: onyx.en, + opal: opal.en, + otis: otis.en, + paco: paco.en, + penelope: penelope.en, + plugintest: plugintest.en, + rendertest: rendertest.en, + sandy: sandy.en, + shelly: shelly.en, + shin: shin.en, + simon: simon.en, + simone: simone.en, + skully: skully.en, + sven: sven.en, + tamiko: tamiko.en, + teagan: teagan.en, + tiberius: tiberius.en, + titan: titan.en, + trayvon: trayvon.en, + tristan: tristan.en, + uma: uma.en, + umbra: umbra.en, + wahid: wahid.en, + walburga: walburga.en, + waralee: waralee.en, + yuri: yuri.en, +} diff --git a/i18n/measurements.yaml b/i18n/measurements.yaml new file mode 100644 index 00000000000..6656bfe21a9 --- /dev/null +++ b/i18n/measurements.yaml @@ -0,0 +1,39 @@ +measurements: Measurements +ankle: Ankle circumference +biceps: Biceps circumference +bustFront: Bust front +bustPointToUnderbust: Bust point to underbust +bustSpan: Bust span +chest: Chest circumference +crossSeam: Cross seam +crossSeamFront: Cross seam front +head: Head circumference +heel: Heel circumference +highBustFront: High bust front +highBust: High bust +hips: Hips circumference +hpsToBust: HPS to bust +hpsToWaistBack: HPS to waist back +hpsToWaistFront: HPS to waist front +inseam: Inseam +knee: Knee circumference +neck: Neck circumference +seat: Seat circumference +seatBack: Seat back +crotchDepth: Crotch depth +shoulderSlope: Shoulder slope +shoulderToElbow: Shoulder to elbow +shoulderToShoulder: Shoulder to shoulder +shoulderToWrist: Shoulder to wrist +underbust: Underbust +upperLeg: Upper leg circumference +waist: Waist circumference +waistBack: Waist back +waistToArmpit: Waist to armpit +waistToFloor: Waist to floor +waistToHips: Waist to hips +waistToKnee: Waist to knee +waistToSeat: Waist to seat +waistToUnderbust: Waist to underbust +waistToUpperLeg: Waist to upper leg +wrist: Wrist circumference diff --git a/i18n/optiongroups.yaml b/i18n/optiongroups.yaml new file mode 100644 index 00000000000..c3c4653ea3d --- /dev/null +++ b/i18n/optiongroups.yaml @@ -0,0 +1,15 @@ +advanced: Advanced +backPockets: Back pockets +closure: Closure +collar: Collar +conditional: Conditional +construction: Construction +cuffs: Cuffs +darts: Darts +elastic: Elastic +fit: Fit +frontPockets: Front pockets +length: Length +pockets: Pockets +style: Style +test: Test diff --git a/markdown/dev/contribute/en.md b/markdown/dev/contribute/en.md deleted file mode 100644 index bf5f9560f42..00000000000 --- a/markdown/dev/contribute/en.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Contribute ---- - -Looking to contribute to FreeSewing? That's wonderful. - -## Ways to contribute - -There are many ways to contribute, here's some examples: - - - -## Code of Conduct - -All FreeSewing contributors must respect and uphold our Code of Conduct: - - - diff --git a/markdown/dev/design/en.md b/markdown/dev/design/en.md deleted file mode 100644 index be836439f0f..00000000000 --- a/markdown/dev/design/en.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Design ---- - -If you are looking to use FreeSewing to design parametric sewing patterns, -below are the most relevant materials on this site for you: - -## Before you start - -Outlines the minimal prerequisites you should understand before you dive in, including: - -- - - -## Pattern design best practices - -In design as in code, there's often many different ways to accomplish the same -result. We have a list of best practices that we recommend you follow. Even if -in the end you make your own choices, we recommend you at least ready through -them once. They include: - -- - - -## Design guide - -We've so far been talking about *patterns* but what you're really be creating is a *design*. -What the difference is, and what goes into a design to generate a pattern is explained in our design guide: - -- - - -## Pattern design tutorial - -This is our pattern design tutorial. If you're new to designing patterns with -FreeSewing, following the tutorial is the fastest way to get started: - -- - - -## Plugin guide - -FreeSewing can be extended with plugins. We provide a range of plugins that you can use. -However, if you'd like to write your own plugins, you should also read the guide on how they work: - -- - - -## Common design challenges - -This is a list of common challenges in designing parametric sewing patterns, and tips on how to tackle them: - -- - - -## Common code challenges - -While designing patterns in code has a lot of benefits, there might be times -where things that are intuitive on paper don't come naturally to you. This is -a list of common code challenges and how to tackle them: - -- - - -## Core API - -This is the reference documentation for FreeSewing's core library. -This is where you can look up every possible API call with examples: - -- - - -## Macros - -This is the reference documentation for macros provided by FreeSewing's own plugins: - -- - - -## Snippets - -This is the reference documentation for snippets provided by FreeSewing's own plugins: - -- - - -## Plugins - -This is the list of all plugins we provide: - -- - - - - -##### Missing something? - -If you are missing something or have questions not covered here, the `#pattern-design` channel -on [discord.freesewing.org](https://discord.freesewing.org/) is the best place to ask questions. - - diff --git a/markdown/dev/guides/best-practices/en.md b/markdown/dev/guides/best-practices/en.md deleted file mode 100644 index fca2f03113b..00000000000 --- a/markdown/dev/guides/best-practices/en.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Pattern design best practices ---- - -Here is a list of best practices when designing patterns: - - diff --git a/markdown/dev/guides/best-practices/go-counter-clockwise/en.md b/markdown/dev/guides/best-practices/go-counter-clockwise/en.md deleted file mode 100644 index f371758ad52..00000000000 --- a/markdown/dev/guides/best-practices/go-counter-clockwise/en.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Construct paths counter-clockwise -order: 70 ---- - -Construct your paths _counter-clockwise_ (anti-clockwise). You have to pick a direction anyway, and going -counter-clockwise is a bit of a convention. - -This applies both to naming points (specifically the control points of curves) -and the order in which you define your points. - -Obviously, the order in which you add points to your code needs to take a backseat -to the logic of your code. But typically what you're doing is constructing an outline -of (a part of) a garment. - -So pick a point, and make your way around counter-clockwise. - -When naming control points for curves, re-use the name of the point they are attached to -and add `Cp1` to the control point before and `Cp2` to the control point after the point if, -once again, you follow your path counter-clockwise. - -For example: - -```js -part.paths.seam = new Path() - .move(points.hemCenter) - .line(points.hemSide) - .line(points.waistSide) - .curve(points.waistSideCp2, points.armholeCp1, points.armhole) -``` - - - -##### This convention helps with `Path.offset()` too - -Constructing a path counter-clockwise will also ensure that the path offset goes outwards -rather than inwards. - - diff --git a/markdown/dev/guides/best-practices/respect-draft-settings/en.md b/markdown/dev/guides/best-practices/respect-draft-settings/en.md deleted file mode 100644 index a21013d0b2c..00000000000 --- a/markdown/dev/guides/best-practices/respect-draft-settings/en.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Respect draft settings -order: 40 ---- - -Apart from the pattern options that you configure for your pattern, -all FreeSewing patterns have a set of [draft settings](/reference/settings) that can be tweaked -by the user. - -While many of these will automatically be handled by FreeSewing, there are some -that you will need to take into account while developing your pattern. They are: - -## Complete - -The [`complete`](/reference/settings/complete) setting is a boolean that is either true or false. - -Its goal is to determine whether we should draft a _complete_ pattern which -includes elements such as seam allowance lines, labels, and markings for -buttons and notches, -or if the pattern should include the part outlines only. - -It is your job when developing your pattern to ensure that the pattern -checks the `complete` setting and includes or omits the appropriate elements -based on the setting's value. - -## Paperless - -The [`paperless`](/reference/settings/paperless) setting is a boolean that is either true or false. - -A _paperless_ pattern is a pattern that has extra dimension markings so -users can trace or transfer the pattern onto fabric or paper without having -the need to print it. - -It is your job when developing your pattern to ensure that the pattern -checks the `paperless` setting and includes or omits the dimensions -based on the setting's value. - -## Seam allowance - -The [`sa`](/reference/settings/sa) setting is a number that controls the seam allowance width. - -Unless `sa` is zero, patterns are drafted with seam allowance lines included. - -It is your job when developing your pattern to ensure that the pattern -checks the `sa` setting and includes or omits the seam allowance lines -based on the setting's value. - - - -##### Use a multiple of `sa` for your hem allowance - -Resist the temptation to use an absolute value for any seam allowance, -including at the hem. - -Instead, always use a multiple of the `sa` value. -This will help to ensure that the seam allowances will scale to appropriate -values when the pattern is scaled up or down to giant or doll sizes. - - - -## Example - -To respect the `complete`, `paperless`, and `sa` draft settings, structure your parts as such: - -```js -export default function(part) { - let { complete, sa, paperless } = part.shorthand() - // Your paths and points here - - if (complete) { - // Your snippets, text, helplines and so on here - - if (sa) { - // Your seam allowance here - } - - if (paperless) { - // Your dimensions - } - } - - return part -} -``` diff --git a/markdown/dev/guides/best-practices/reuse-css-classes/en.md b/markdown/dev/guides/best-practices/reuse-css-classes/en.md deleted file mode 100644 index 37666b869f5..00000000000 --- a/markdown/dev/guides/best-practices/reuse-css-classes/en.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Re-use CSS classes -order: 30 ---- - -While you can style your pattern however you want, try to re-use the -[CSS class names](/reference/css) that -are in use in our default `@freesewing/plugin-theme` plugin. - -Doing so will ensure consistent styling for patterns. diff --git a/markdown/dev/guides/best-practices/reuse-measurements/en.md b/markdown/dev/guides/best-practices/reuse-measurements/en.md deleted file mode 100644 index ed2cc073bd9..00000000000 --- a/markdown/dev/guides/best-practices/reuse-measurements/en.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Re-use measurements -order: 10 ---- - -When designing patterns, re-use the measurements that are already in use as much as possible. -Nobody wins when every pattern requires its own set of measurements, or names -certain measurements differently. - - - -###### See our measurements page for standard measurement names - -The [measurements reference page](/reference/measurements/) -contains all our standard measurement names. - - diff --git a/markdown/dev/guides/best-practices/reuse-options/en.md b/markdown/dev/guides/best-practices/reuse-options/en.md deleted file mode 100644 index 9d818093072..00000000000 --- a/markdown/dev/guides/best-practices/reuse-options/en.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Re-use options -order: 20 ---- - -The same arguments for re-using measurements are also (somewhat) true for options. - -While your pattern may require some very specific -options, there's probably a bunch that are similar to other patterns. Re-use those names. - -As in, `bicepsEase` exists. So don't go creating an `upperArmEase` option. diff --git a/markdown/dev/guides/best-practices/use-percentages/en.md b/markdown/dev/guides/best-practices/use-percentages/en.md deleted file mode 100644 index 211bd3cf5ec..00000000000 --- a/markdown/dev/guides/best-practices/use-percentages/en.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Use percentage options where possible -order: 50 ---- - -When designing patterns, you should refrain from using absolute values. - -That 6 cm ease you add might be fine for all scenarios you tested. -But, then somebody comes around who is twice your size or who is making clothes for a doll, -and things will go off the rails. - -Don't be tempted to add absolute values to your patterns, as they don't scale. -Instead, embrace percentages as options. -By using values that are percentages of measurements, the values will scale -and continue to work as the measurements scale up or down. - - - -##### Use the doll and giant tests - -To check how well your pattern scales, you can -use the _doll_ and _giant_ tests by sampling the pattern for 3 measurements sets: - -1. A set of measurements from an average person (the person) -2. A set of measurements 1/10th of an average person (the doll) -3. A set of measurements 3 times that of an average person (the giant) - -A well-designed pattern will scale a factor 10 down or 3 up and still hold its shape. -If your pattern makes assumptions about size, these tests will show that. - -FreeSewing's development environment provides these tests out of the box, -so you can see their results at the click of a button. - - diff --git a/markdown/dev/guides/best-practices/use-translation-keys/en.md b/markdown/dev/guides/best-practices/use-translation-keys/en.md deleted file mode 100644 index c13dd7478b1..00000000000 --- a/markdown/dev/guides/best-practices/use-translation-keys/en.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Use translation keys, not text -order: 60 ---- - -Don't insert literal text in your patterns. Instead, insert a key that can then be translated. - -For example, if you want to put "_Finish with bias tape_" on your pattern, don't be -tempted to do this: - -```js -path.seam.attr("data-text", "Finish with bias tape"); -``` - -That (English) string is now hard-coded in your pattern. As FreeSewing supports -translation out of the box, it would be a real shame not to make use of it. - -Instead, insert a key to identify the string: - -```js -path.seam.attr("data-text", "finishWithBiasTape"); -``` - -This way, different strings for different languages can be associated with -the key, allowing translated text to be used. - -You can find and browse the translations and available translation keys for each design in the design's -[i18n folder on GitHub][1]. - -[1]: https://github.com/freesewing/freesewing/tree/develop/designs/aaron/i18n diff --git a/markdown/dev/guides/code-of-conduct/en.md b/markdown/dev/guides/code-of-conduct/en.md deleted file mode 100644 index ce800fa7314..00000000000 --- a/markdown/dev/guides/code-of-conduct/en.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Code of Conduct ---- - -All FreeSewing contributors must respect and uphold our Code of Conduct: - - - - - -##### Attribution - -This Code of Conduct is an almost verbatim copy of the [Contributor Covenant][homepage], version 2.0, -available at [http://contributor-covenant.org/version/2/0][version] - -[homepage]: http://contributor-covenant.org - -[version]: http://contributor-covenant.org/version/2/0/ - - diff --git a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/correction/en.md b/markdown/dev/guides/code-of-conduct/enforcement-guidelines/correction/en.md deleted file mode 100644 index 82691a2983c..00000000000 --- a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/correction/en.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Correction -order: 10 ---- - -##### Community Impact - -Use of inappropriate language or other behavior -deemed unprofessional or unwelcome in the community. - -##### Consequence - -A private, written warning from community leaders, -providing clarity around the nature of the violation and an -explanation of why the behavior was inappropriate. - -A public apology may be requested. diff --git a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/en.md b/markdown/dev/guides/code-of-conduct/enforcement-guidelines/en.md deleted file mode 100644 index 1ac87e26ca0..00000000000 --- a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/en.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Enforcement Guidelines -order: 60 ---- - -Community leaders will follow these Community Impact Guidelines -in determining the consequences for any action they deem -in violation of FreeSewing's Code of Conduct: - - diff --git a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/permanent-ban/en.md b/markdown/dev/guides/code-of-conduct/enforcement-guidelines/permanent-ban/en.md deleted file mode 100644 index 1c44452a7cd..00000000000 --- a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/permanent-ban/en.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Permanent ban -order: 40 ---- - -##### Community Impact - -Demonstrating a pattern of violation of -community standards, including sustained inappropriate behavior, -harassment of an individual, or aggression toward or -disparagement of classes of individuals. - -##### Consequence - -A permanent ban from any sort of public interaction within the community. diff --git a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/temporary-ban/en.md b/markdown/dev/guides/code-of-conduct/enforcement-guidelines/temporary-ban/en.md deleted file mode 100644 index 6ccccfdbf4b..00000000000 --- a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/temporary-ban/en.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Temporary ban -order: 30 ---- - -##### Community Impact - -A serious violation of community standards, -including sustained inappropriate behavior. - -##### Consequence - -A temporary ban from any sort of interaction or -public communication with the community for a specified period -of time. - -No public or private interaction with the people -involved, including unsolicited interaction with those enforcing -the Code of Conduct, is allowed during this period. - -Violating these terms may lead to a permanent ban. diff --git a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/warning/en.md b/markdown/dev/guides/code-of-conduct/enforcement-guidelines/warning/en.md deleted file mode 100644 index 082c5c06bce..00000000000 --- a/markdown/dev/guides/code-of-conduct/enforcement-guidelines/warning/en.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Warning -order: 20 ---- - -##### Community Impact - -A violation through a single incident or series of actions. - -##### Consequence - -A warning with consequences for continued behavior. - -No interaction with the people involved, including unsolicited -interaction with those enforcing the Code of Conduct, for a -specified period of time. This includes avoiding interactions -in community spaces as well as external channels like social -media. - -Violating these terms may lead to a temporary or permanent ban. diff --git a/markdown/dev/guides/code-of-conduct/enforcement-responsibilities/en.md b/markdown/dev/guides/code-of-conduct/enforcement-responsibilities/en.md deleted file mode 100644 index eb795eb7b7b..00000000000 --- a/markdown/dev/guides/code-of-conduct/enforcement-responsibilities/en.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Enforcement responsibilities -order: 30 ---- - -Community leaders are responsible for clarifying and enforcing our standards -of acceptable behavior and will take appropriate and fair corrective action -in response to any behavior that they deem inappropriate, threatening, -offensive, or harmful. - -Community leaders have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, and will communicate reasons -for moderation decisions when appropriate. diff --git a/markdown/dev/guides/code-of-conduct/enforcement/en.md b/markdown/dev/guides/code-of-conduct/enforcement/en.md deleted file mode 100644 index 87ac952879b..00000000000 --- a/markdown/dev/guides/code-of-conduct/enforcement/en.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Enforcement -order: 50 ---- - -Instances of abusive, harassing, or otherwise unacceptable behavior -may be reported to the community leaders responsible for enforcement: - -- Joost De Cock (joost@joost.at) -- Sorcha Ní Dhubhghaill (nidhubhs@gmail.com) - -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and -security of the reporter of any incident. diff --git a/markdown/dev/guides/code-of-conduct/our-pledge/en.md b/markdown/dev/guides/code-of-conduct/our-pledge/en.md deleted file mode 100644 index f0492375fde..00000000000 --- a/markdown/dev/guides/code-of-conduct/our-pledge/en.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Our pledge -order: 10 ---- - -We as members, contributors, and leaders of the FreeSewing community pledge -to make participation in our community a harassment-free experience for everyone. - -Everyone, regardless of age, body size, visible or invisible disability, -ethnicity, sex characteristics, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, race, -religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. diff --git a/markdown/dev/guides/code-of-conduct/our-standards/en.md b/markdown/dev/guides/code-of-conduct/our-standards/en.md deleted file mode 100644 index ca7e3876e72..00000000000 --- a/markdown/dev/guides/code-of-conduct/our-standards/en.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Our standards -order: 20 ---- - -Examples of behavior that contributes to a positive environment for our community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others’ private information, such as a physical or email address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a professional setting diff --git a/markdown/dev/guides/code-of-conduct/scope/en.md b/markdown/dev/guides/code-of-conduct/scope/en.md deleted file mode 100644 index 9f7bbc0c8d1..00000000000 --- a/markdown/dev/guides/code-of-conduct/scope/en.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Scope -order: 40 ---- - -This Code of Conduct applies within all FreeSewing community spaces and also applies -when an individual is officially representing the FreeSewing community in public spaces. - -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed representative -at an online or offline event. diff --git a/markdown/dev/guides/content/en.md b/markdown/dev/guides/content/en.md deleted file mode 100644 index 127c95c4340..00000000000 --- a/markdown/dev/guides/content/en.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Content guides ---- diff --git a/markdown/dev/guides/content/mdx/en.md b/markdown/dev/guides/content/mdx/en.md deleted file mode 100644 index 3a4dd133915..00000000000 --- a/markdown/dev/guides/content/mdx/en.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: MDX Guide ---- - -Explain MDX content diff --git a/markdown/dev/guides/content/sanity/en.md b/markdown/dev/guides/content/sanity/en.md deleted file mode 100644 index 0816e8fd903..00000000000 --- a/markdown/dev/guides/content/sanity/en.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: Sanity Content Guide ---- - -FreeSewing uses Sanity content needs to be edited/written by non-technical contributors, -and for images uploaded by users, such as for their profile image and so on. - - - -You can manage FreeSewing's Sanity content at -[cms.freesewing.org](https://cms.freesewing.org/) - - -By *content that needs to be edited/written by non-technical contributors* we mean: - -- Newsletter posts -- Blog posts in all languages -- Showcase posts in all languages - -## Why we use Sanity - -The (historical) reason that we use a (headless) CMS for this lies with **the -showcase posts**. Our documentation is still hosted in git as MDX, and -historically this was also the case for our blog posts and showcase posts. - -However, while documentation is written by contributors who are familiar with -how we work, and blog posts are typically written by Joost, showcase posts are -often provided by users of the site for whom submitting a pull request is a -steep learning curve. - -So for this reason, we started using an external CMS to host the showcase -posts. And, since blog posts and showcase posts are so similar, we decided to -use this platform for both. Later, we added newsletter content to this list -because this too is sometimes provided by people not so familiar with the git -workflow. - -Prior to version 3, we used a self-hosted version of -[Strapi](https://strapi.io/) for this. And while that did what we needed, -self-hosting adds workload to people and our backend systems, so it's not -without its drawbacks. Then, with the release of Strapi v4, they dropped -support for MongoDB, which was the database we are using, so we were stuck on -v3 of Strapi. - -So for FreeSewing v3 we started looking for alternatives, and after trying -various solutions Sanity came out as the best solution for our needs. It's a -SaaS solution -- which is nice because it means we don't have to host anything --- but the flip side of the coin is that as a communal open source project, we -obviously cannot afford it. - -Fortunately for us, the same reasons that mean we don't have any money also -mean that Sanity took pity on us, and they agreed to waive their fees and let -us use their service free of charge. So, Sanity is now a FreeSewing sponsor, -and since everything is in place already, we also use them to host user images -because honestly it's a really nice service. - -## How to manage Sanity content - -As Sanity is a headless CMS, you essentially have to talk to the API to manage -your content. - -Fear not though, we don't expect you to do that. The Sanity Studio is a -web-based frontend that allows you to manage the content in a web environment, -and we have an instance of it deployed at https://cms.freeseiwng.org/ that is -pre-configured to manage FreeSewing's content. - -## For developers - -If you're looking to learn more about how to interact with the Sanity API, -please refer to [the Sanity reference documentation](/reference/sites/sanity). - diff --git a/markdown/dev/guides/docs/docs.png b/markdown/dev/guides/docs/docs.png deleted file mode 100644 index 5c32a3a98b4..00000000000 Binary files a/markdown/dev/guides/docs/docs.png and /dev/null differ diff --git a/markdown/dev/guides/docs/docs.svg b/markdown/dev/guides/docs/docs.svg deleted file mode 100644 index 91cd0e55f0d..00000000000 --- a/markdown/dev/guides/docs/docs.svg +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - Guides - Howtos - Reference - Tutorials - - - discovering - learning - working - double-checking - Discord & Github - - I want to learn about... - I want to learn about... - - - I want to do this common thing - I want to do this common thing... - - - What even is this thing??? - What even is this thing??? - - - What was that parameter again... - What was that parameter again... - - - I'm stuck; Help! - I'm stuck; Help! - - - diff --git a/markdown/dev/guides/docs/en.md b/markdown/dev/guides/docs/en.md deleted file mode 100644 index b305ea0f6db..00000000000 --- a/markdown/dev/guides/docs/en.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: How we structure our documentation ---- - -Whether you're writing documentation for FreeSewing or merely trying -to find what you are looking for, understanding how we structure our -documentation can help you find your feet and figure out what goes where. - -## Types of documentation - -Our documentation is divided into four different types: - -- [**Tutorials**](/tutorials) are lessons that lead you through a series of steps to complete a project. -- [**Guides**](/guides) tell a story to further your understanding of a specific topic. -- [**Howtos**](/howtos) give you concrete steps to solve a common problem or challenge. -- [**Reference**](/reference) holds technical descriptions of the underlying technology and how to make use of it. - -Each time you write documentation, you have to ask yourself: Is it a tutorial? Is it a Guide? -Is it a Howto? Or, is it Reference documentation? - -If you find it hard to answer that question, the illustration below might help you figure out -where your documentation should go based on what it's trying to accomplish: - -![A graphic showing a visual representation of our documentation -structure](docs.png "A visual representation of how our documentation is structured") - -- Write a **Tutorial** is your aim is to help people learn the platform -- Write a **Guide** if your aim is to further people's understanding of a topic by going a bit deeper -- Write a **Howto** if your aim is to help people accomplish a task -- Write **Reference** documentation to detail how things work under the hood -- Refer people to **Discord** or **GitHub** for things that are not (yet) covered in our documentation - - - -##### Based on a talk by Daniele Procida - -This structure is loosely based -on [this talk by Daniele Procida](https://www.youtube.com/watch?v=t4vKPhjcMZg) at -PyCon AU 2017. - - diff --git a/markdown/dev/guides/en.md b/markdown/dev/guides/en.md deleted file mode 100644 index 46e3fd8b018..00000000000 --- a/markdown/dev/guides/en.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Guides -order: zbb ---- - -You can find a list of all FreeSewing guides below: - -## Main sections - - - - - -##### What makes a guide a guide? - -Guides tell a story to further your understanding of a specific topic. - -Guides and Howtos are on a spectrum with Howtos being terse _do-this-then-that_ recipes, whereas -guides take more time to explain in-depth what is being done and why. - -For more details, refer to [How we structure our documentation](/guides/docs). - - - -## Full list - - - diff --git a/markdown/dev/guides/markdown/code-blocks/en.md b/markdown/dev/guides/markdown/code-blocks/en.md deleted file mode 100644 index 1eac70964e8..00000000000 --- a/markdown/dev/guides/markdown/code-blocks/en.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Code and code blocks -order: 80 ---- - -Especially for our developer documentation, there's a lot of times we include source code -in the documentation. -You can make these look pretty by using a code block. - -The basic use is to wrap your code in three backtick characters on a line: - -````markdown -``` -let me = 'you' -``` -```` - -Gives you: - -```text -let me = 'you' -``` - -This is a generic code block. But we also support syntax highlighting. -To do so, add the language specifier after the opening backticks: - -````markdown -```js -let me = 'you' -``` -```` - -To get: - -```js -let me = 'you' -``` - -The following language codes are supported: - -- `js` for JavaScript code -- `markdown` for Markdown -- `html` for HTML -- `svg` for SVG -- `bash` for Bash or shell scripts -- `mdx` for MDX -- `jsx` for JSX -- `json` for JSON - - - -Note that `mermaid` code blocks will be rendered as -[Mermaid](https://mermaid.js.org/) diagrams. Refer to the docs on [custom -tags](/guides/markdown/custom-components#mermaid) for an example. - - diff --git a/markdown/dev/guides/markdown/custom-components/en.md b/markdown/dev/guides/markdown/custom-components/en.md deleted file mode 100644 index 08b2884de49..00000000000 --- a/markdown/dev/guides/markdown/custom-components/en.md +++ /dev/null @@ -1,850 +0,0 @@ ---- -title: Custom tags -order: 90 ---- - -The way we render Markdown on our websites is through the use of -[MDX](https://mdxjs.com/). This allows us to extend Markdown with our own -tags. These tags are custom React components. - -Such custom components allow us to put things in Markdown content that would -typically require a lot more complexity. - -Below is a list of custom tags that we support in our Markdown-based -documentation, both for freesewing.dev as freesewing.org. - -## Summary and Availability - -This is a summary of the available custom tags and where each tag -can be used. -- **sde** tags can be used in the standalone development environment -(provided by the [new-design](/reference/packages/new-design) package). -- **dev** and **org** tags can be used on the -freesewing.dev and freesewing.org sites, respectively. -- For convenience, tags with similar functionality have been grouped together. - -### Text popouts - -These are markdown tags used to display text in a colored _popout_ box, -to make the text stand out and to quickly convey what type of -information is being presented. - -| Tag | sde | dev | org | -| ------: | :---: | :---: | :---: | -| [Comment](#comment) | X | X | X | -| [Fixme](#fixme) | X | X | X | -| [Link](#link) | X | X | X | -| [Note](#note) | X | X | X | -| [Related](#related) | X | X | X | -| [Tip](#tip) | X | X | X | -| [Tldr](#tldr) | X | X | X | -| [Warning](#warning) | X | X | X | - -### Features and Formatting - -These tags provide special features or ways to format content. - -| Tag | sde | dev | org | -| --------------------: | :---: | :---: | :---: | -| [ControlTip](#controltip) | | X | X | -| [DocsTitle](#docstitle) | | X | X | -| [DocsLink](#docslink) | | X | X | -| [Example](#example) | | X | X | -| [Legend](#legend) | | | X* | -| [MeasieImage](#measieimage) | | | X* | -| [(Mermaid)](#mermaid) | | X | X | -| [Method](#method) | | X | | -| [StatusCode](#statuscode) | | X | | -| [Tab](#tab) | | X | X | -| [Tabs](#tabs) | | X | X | -| [Youtube](#youtube) | | X | X | - - - -- **Legend** is available to use only on the -[Pattern Notation Guide](https://freesewing.org/docs/about/notation) and -[On the Fold](https://freesewing.org/docs/sewing/on-the-fold) -documentation pages. - -- **MeasieImage** is available to use only on the immediate subpages in the -[Measurements](https://freesewing.org/docs/measurements) -section of the documentation. - - - -### Documentation Generators - -These tags generate documentation-related content related to designs -and documentation files. -This prevents the need to write and edit the documentation manually, -making it easier to write and to maintain when changes occur. - -| Tag | sde | dev | org | -| -----------------: | :---: | :---: | :---: | -| [DesignInfo](#designinfo) | | | X* | -| [DesignMeasurements](#designmeasurements) | | | X* | -| [DesignOptions](#designoptions) | | | X* | -| [ReadMore](#readmore) | X | X | X | - - - -- **DesignInfo** is available to use only on an individual design's -main documentation page, for example -[Aaron A-Shirt](https://freesewing.org/docs/designs/aaron). - -- **DesignMeasurements** is available to use only on an individual design's -Required Measurements documentation page, for example -[Aaron A-Shirt: Required Measurements](https://freesewing.org/docs/designs/aaron/measurements). - -- **DesignMeasurements** is available to use only on an individual design -Design Options documentation page, for example -[Aaron A-Shirt: Design Options](https://freesewing.org/docs/designs/aaron/options). - - - -*** - -## Details - -All custom tags are listed alphabetically below. - -### Comment - -Use a **Comment** when you want to illustrate something that is a personal opinion -or advice rather than the sort more neutral voice used throughout -our documentation. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `by` | yes | | Name of the commenter | -| `hideable` | | `false` | Allows popout to be hidden | - - - -MDX is essentially Markdown + (React) components - - It can be helpful to be able to hide long comments that might take up - too much space on the page _(hideable)_ - - - -```markdown -MDX is essentially Markdown + (React) components - - It can be helpful to hide long comments that might take up too much - space on the page _(hideable)_ - - -``` - - - -### ControlTip - -The **ControlTip** tag provides a popout box containing pre-written, -formatted text describing the -[User Experience](https://freesewing.org/account/control) -account setting and explaining what it does. - - - - - - -```markdown - -``` - - - -### DesignInfo - -**DesignInfo** generates a detailed web page for a given FreeSewing -design with information including line drawings, example photos, -required measurements, design options, and links to documentation. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `design` | yes | | Name of the design | -| `docs` | | `false` | Generates content suitable for a documentation page | - - - -(Please see the -[Aaron A-Shirt documentation](https://freesewing.org/docs/designs/aaron) -page for an example of this tag.) - - -```markdown - -``` - - - - -Because design documentation pages are the only place this tag can -be used, you should always include the `docs` attribute when using -this tag. -(Omitting it will generate different content, less suited for -documentation.) - - -### DesignMeasurements - -**DesignMeasurements** generates a list of required and optional -measurements for a given FreeSewing design. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `design` | yes | | Name of the design | - - - -(Please see -[Aaron A-Shirt: Requirement Measurements](https://freesewing.org/docs/designs/aaron/measurements) -for an example of this tag.) - - -```markdown - -``` - - - -### DesignOptions - -**DesignOptions** generates a list of design options and settings -for a given FreeSewing design. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `design` | yes | | Name of the design | - - - -(Please see -[Aaron A-Shirt: Design Options](https://freesewing.org/docs/designs/aaron/options) -for an example of this tag.) - - -```markdown - -``` - - - -### DocsLink - -The **DocsLink** tag creates a formatted link from a given slug -(a relative URL path). -It also looks up the title of the linked web page and uses it as -the link text. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `slug` | yes | | Relative path for the link | - - - - - - -```markdown - -``` - - - -### DocsTitle - -The **DocsTitle** tag looks up the title of a web page from a -given slug (a relative URL path) and provides the title as formatted -text. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `slug` | yes | | Relative path of the link | -| `className` | | | CSS classes to style the text | -| `format` | | defaultFormater | Formatter used to format the text | - - - - - - - -```markdown - -``` - - - - -### Example - -The **Example** tag allows you to embed a FreeSewing code example and have it rendered in the browser. -Specifically, you should write a [draft method](/reference/api/part/draft) which will then be rendered. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `caption` | | | The caption to go under the example | -| `tutorial` | | `false` | Set this to show the Code tab first, rather than the default Preview tab. Also, additional options are made available for use in pattern examples | -| `previewFirst` | | `false` | Set this to always show the Preview tab first, regardless of the value of `tutorial` | -| `withHead` | | `false` | Set this to include a head measurement (for tutorial pattern examples) | -| `paperless` | | `false` | Set this to enable paperless mode | -| `settings` | | | A YAML string of settings to take into account | - - - - -```js -({ Point, points, Path, paths, part }) => { - - points.from = new Point(10, 20) - points.cp1 = new Point(40, 0) - points.cp2 = new Point(60, 40) - points.to = new Point(90, 20) - - paths.line = new Path() - .move(points.from) - .curve(points.cp1, points.cp2, points.to) - .setText("Path.curve()", "text-sm center fill-note") - - return part -} -``` - - - -````markdown - -```js -({ Point, points, Path, paths, part }) => { - - points.from = new Point(10, 20) - points.cp1 = new Point(40, 0) - points.cp2 = new Point(60, 40) - points.to = new Point(90, 20) - - paths.line = new Path() - .move(points.from) - .curve(points.cp1, points.cp2, points.to) - .setText("Path.curve()", "text-sm center fill-note") - - return part -} -``` - -```` - - - - -### Fixme - -Use **Fixme** to indicate something needs attention/work but you don't have time -or can't fix it now. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `compact` | | `false` | Renders compact variant | -| `hideable` | | `false` | Allows popout to be hidden | - - - - -##### ToDo -- Include link to roadmap -- Fix style for text outside paragraphs - -Proofread documentation _(compact)_ - - Proofread it a second time _(hideable)_ - - - -```markdown - -##### ToDo -- Include link to roadmap -- Fix style for text outside paragraphs - -Proofread documentation _(compact)_ - - Proofread it a second time _(hideable)_ - -``` - - - -### Legend - -The **Legend** tag is used to display parts from a pattern of the -Legend design (a non-public design in the FreeSewing repository -created to provide examples of pattern features). - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `part` | yes | | The Legend part to display | - - - -(Please see -[On the fold](https://freesewing.org/docs/sewing/on-the-fold) -for an example of this tag, used to display the _cut-on-fold_ indicator -on that page.) - - -```markdown - -``` - - - -### Link - -Use **Link** for URLs. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `compact` | | `false` | Renders compact variant | -| `hideable` | | `false` | Allows popout to be hidden | - - - - -https://freesewing.org/ - -https://freesewing.org/ _(compact)_ -https://freesewing.org/ _(hideable)_ - - -```markdown - -https://freesewing.org - -https://freesewing.org/ _(compact)_ -https://freesewing.org/ _(hideable)_ -``` - - - -### MeasieImage - -**MeasieImage** will show images of a FreeSewing measurement. -The name of the directory in which the tag is used is the -measurement which will be shown. - - - -(Please see -[Biceps circumference](https://freesewing.org/docs/measurements/biceps) -for an example of this tag, used to display the image showing the -biceps circumference measurement. - - -```markdown - -``` - - - - -### (Mermaid) - -There is no actual "Mermaid" custom tag. -However, by using a fenced [code block](/guides/markdown/code-blocks) -and specifying the `mermaid` language, you can generate -[Mermaid](https://mermaid.js.org/) diagrams. Like this: - - - -```mermaid -graph LR; - A--> B & C & D; - B--> A & E; - C--> A & E; - D--> A & E; - E--> B & C & D; -``` - - -````markdown -```mermaid -graph LR; - A--> B & C & D; - B--> A & E; - C--> A & E; - D--> A & E; - E--> B & C & D; -``` -```` - - - -### Method - -**Method** is used to format HTTP methods. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `get` | | `false` | Display the HTTP `GET` method | -| `post` | | `false` | Display the HTTP `POST` method | -| `put` | | `false` | Display the HTTP `PUT` method | -| `delete` | | `false` | Display the HTTP `DELETE` method | - - - - -
- -
- -```markdown -
- -``` -
-
- - - -- It is required that you provide one of the `get`, `post`, `put`, -or `delete` attributes when using **Method**. -- If more than one of those attributes is provided, only the first -one that gets processed will be used. - - - -### Note - -Use **Note** to add something that stands out to draw attention. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `compact` | | `false` | Renders compact variant | -| `hideable` | | `false` | Allows popout to be hidden | - - - - -##### Also available in black -This style also comes in black, which we can all agree is the superior color - -And in pink _(compact)_ -Yet another note _(hideable)_ - - -```markdown - -##### Also available in black -This style also comes in black, which we can all agree is the superior color - -And in pink _(compact)_ -Yet another note _(hideable)_ -``` - - - -### ReadMore - -The **ReadMore** tag allows you to insert a list of child-pages. -The list is automatically generated from the pages in the subdirectories -of the documentation page's directory. -This tag is typically used on overview pages, such as our [Markdown guide](/guides/markdown) page. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `asMenu` | | `false` | Start from the parent directory | -| `depth` | | 99 | Maximum levels to recurse | -| `recurse` | |`false` | Include all child-pages and sub-child-pages in the entire directory tree | -| `root` | | `false` | Start from the root directory | - - - - - - -```markdown - -``` - - - -### Related - -Use **Related** to add something that is relevant to the current topic. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `compact` | | `false` | Renders compact variant | -| `hideable` | | `false` | Allows popout to be hidden | - - - - - This snippet is provided by [the annotations plugin](/reference/plugins/annotations) - -See [snippets](/reference/snippets) _(compact)_ - - See [snippets](/reference/snippets) _(hideable)_ - - - -```markdown - - This snippet is provided by [the annotations plugin](/reference/plugins/annotations) - -See [snippets](/reference/snippets) _(compact)_ - - See [snippets](/reference/snippets) _(hideable)_ - -``` - - - -### StatusCode - -**StatusCode** is used to format HTTP response status codes. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `status` | yes | | The HTTP response status code to format | - - - - -
- -
- -```markdown -
- -``` -
-
- - -### Tab - -**Tabs** and **Tab** tags are used to present content in a tabbed view. -This is a view where only the active tab content is shown, with -content in other tabs hidden. -Selecting a different tab shows its contents while hiding -the others. - -The **Tab** tag is used to add content for a tab. - - - - - - Content for tab one. - - - This is tab two content. - - - - -```markdown - - - Content for tab one. - - - Content for tab two. - - -``` - - - - - -- The content of **Tabs** is individual **Tab** tags. -- The content of **Tab** is content for that tab. -- There should be one **Tab** for every tab defined in the `tabs` attribute of **Tabs**. - - - -### Tabs - -**Tabs** and **Tab** tags are used to present content in a tabbed view. -This is a view where only the active tab content is shown, with -content in other tabs hidden. -Selecting a different tab shows its contents while hiding -the others. - -The **Tabs** tag is used to set up the tabbed view. -It specifies how many tabs are in the view and what their names -are. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `tabs` | yes | | Comma-separated list of tab names | - - - - - - - Content for tab one. - - - This is tab two content. - - - - -```markdown - - - Content for tab one. - - - Content for tab two. - - -``` - - - - - -- The content of **Tabs** is individual **Tab** tags. -- The content of **Tab** is content for that tab. -- There should be one **Tab** for every tab defined in the `tabs` attribute of **Tabs**. - - - - -### Tip - -Use **Tip** for, you know, tips. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `compact` | | `false` | Renders compact variant | -| `hideable` | | `false` | Allows popout to be hidden | - - - - - The notches on the shoulder and sleeve parts are used to help with - alignment when attaching the sleeve. - -Align the notches so they match _(compact)_ - - Yet another tip _(hideable)_ - - - -```markdown - - The notches on the shoulder and sleeve parts are used to help with - alignment when attaching the sleeve. - -Align the notches so they match _(compact)_ - - Yet another tip _(hideable)_ - -``` - - - -### Tldr - -"TL;DR" stands for "Too long; didn't read", and the **Tldr** tag used -to provide a short summary for readers who might not want to read -the full text. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `compact` | | `false` | Renders compact variant | -| `hideable` | | `false` | Allows popout to be hidden | - - - - - This page lists all the custom tags you can use. - -This page lists custom tags _(compact)_ - - Yet another TL;DR summary _(hideable)_ - - - -```markdown - - This page lists all the custom tags you can use. - -This page lists custom tags _(compact)_ - - Yet another TL;DR summary _(hideable)_ - -``` - - - - -### Warning - -Use **Warning** when you want to warn the reader of potential danger or unintended side-effects. - -| Attribute | Required? | Default | Description | -| ---------: | :-------: | ------- | ----------- | -| `compact` | | `false` | Renders compact variant | -| `hideable` | | `false` | Allows popout to be hidden | - - - - - ##### Please make a backup - Following these instructions will remove all your data - -Take it slow _(compact)_ - - Yet another warning _(hideable)_ - - - -```markdown - - ##### Please make a backup - Following these instructions will remove all your data - -Take it slow _(compact)_ - - Yet another warning _(hideable)_ - -``` - - - -### YouTube - -The **YouTube** tag will embed YouTube videos or YouTube playlists responsively. - -| Attribute | Required? | Default | Description | -| ----:| :---: | ------- | ----------- | -| `id` | yes | | ID of the YouTube video or playlist | -| `playlist` | | `false` | Set this when embedding a playlist | - - - -#### Video - -#### Playlist - - - -```markdown -### Video - -### Playlist - -``` - - diff --git a/markdown/dev/guides/markdown/en.md b/markdown/dev/guides/markdown/en.md deleted file mode 100644 index 055bf5a9f9c..00000000000 --- a/markdown/dev/guides/markdown/en.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Markdown guide -order: 900 ---- - -Markdown is a lightweight markup language with plain text formatting syntax. -It is designed to be easily readable by humans and computers alike. - -Markdown is often used to format documentation, online comments, -or anywhere where you want rich text while using a plain text editor. - -In this guide, we'll look at the following topics: - - - -This will be enough to get you started. If you'd like to learn more, -visit [markdownguide.org](https://www.markdownguide.org/). diff --git a/markdown/dev/guides/markdown/frequent-mistakes/en.md b/markdown/dev/guides/markdown/frequent-mistakes/en.md deleted file mode 100644 index d14708d0abf..00000000000 --- a/markdown/dev/guides/markdown/frequent-mistakes/en.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Avoiding frequent mistakes -order: zzz ---- - -Some things to keep in mind when working in Markdown are: - -## Use remark-jargon for glossary terms - -There is no need to add a _glossary_ section to documentation. -We use a plugin called [rehype-jargon][rj] to explain terms. -Information can be found at the link. - -[rj]: https://github.com/freesewing/freesewing/blob/develop/packages/rehype-jargon/README.md - -## Let lists be lists - -Please make sure to use Markdown proper, doing things such as hardcoding -numbers for lists and using `·` for bulleted lists won't be rendered -properly and will be styled differently. -Using Markdown in the same way for everything ensures the site and -documentation look clean and professional. You can use a Markdown editor -like [StackEdit](https://stackedit.io/) to preview your text. - - -GitHub itself also allows working in Markdown and will give you a handy preview! - - -## Create links with meaningful link text - -When adding links please do not create them using a structure like: -"Link [here][yt]". Instead use relevant terms for the link text. -An example of meaningful link text is this link to a -[famous 80s pop song video][yt]. - -[yt]: https://www.youtube.com/watch?v=dQw4w9WgXcQ - -## Make sure your links lead where you think they do - -### Linking within the same website - -When you are linking within freesewing.dev or freesewing.org you can use a relative link from -the site root. -Use: - -```text -/guides/markdown/frequent-mistakes -``` - -instead of - -```text -https://freesewing.dev/guides/markdown/frequent-mistakes -``` - -### Linking images - -Images can be put in the same folder you are working on with a link -to the filename. For example: - -```markdown -This is [a picture of a banana](banana.jpg) -``` - -## Avoid ambiguity when listing a number of steps - -If you're writing documentation that involves steps, please do not mix levels -of steps. Steps written out in documentation are there to facilitate brainless -execution. Don't be afraid to repeat yourself. - -If you use substeps we want those substeps to take away ambiguity rather -than introduce it into your instructions. In the next example the substep -introduces something that ought to be done before the previous steps. -This creates confusion about when that step ought to be executed. - -An example of what not to do: - -```md -1. cut collar -2. cut collar stand -3. sew collar stand to collar - 1. sewing staystitch collar and collar stand -4. sew collar stand to neckline -``` - -## Be mindful of white space and whitespace characters - -Markdown syntax for white space in text is a little unintuitive. - -- If you want a line break after a line but no white space between it and -the next line, you need to add two space characters at the end of the -first line. - -- If you want a paragraph break with white space between the two lines, -you need to add at least one blank line after the first line. - -- If you don't have two space characters at the end of the first line or -any blank lines between it and the second line, then no white space or -line break will be generated. -Instead, the two lines will be part of the same continuous paragraph in the -resulting page even though they are on two separate lines in your document. - -It may be helpful to experiment and keep checking the preview or resulting -page to see how things look. Not all the empty lines and white space in your -document will render in the preview or result. - -## Using custom tag components - -When you're using custom tag components you want to leave an empty line before -and after the tags. - -```markdown -Lorem ipsum dolor sit amet, - - -consectetur adipisci elit, - - -sed eiusmod tempor incidunt ut labore et dolore magna aliqua. -``` - -If you're using any Markdown syntax within a custom component you want to also -leave an empty line at the start and end of your component. - -```markdown -Lorem ipsum dolor sit amet, - - - -*consectetur adipisci elit,* - - - -sed eiusmod tempor incidunt ut labore et dolore magna aliqua. -``` - -## Don't be shy to ask a friend - -Learning a new language can be intimidating, whether its JavaScript, Norse, or -Markdown, but everyone in the Freesewing community is glad you're here and -helping us make the site even more awesome. - -If you get lost or have a question about how to do something, feel free to come -[ask on the Discord](https://discord.freesewing.org/). -We've all had to learn Markdown at some point and would be -delighted to pass knowledge on. diff --git a/markdown/dev/guides/markdown/headings/en.md b/markdown/dev/guides/markdown/headings/en.md deleted file mode 100644 index c908981af4f..00000000000 --- a/markdown/dev/guides/markdown/headings/en.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Headings -order: 40 ---- - -Prefix your line with a number of `#` characters to determine the header level. - -```md -### This is a H3 heading - -#### This is a H4 heading - -##### This is a H5 heading -``` - -### This is a H3 heading - -#### This is a H4 heading - -##### This is a H5 heading - - - -Keep in mind that you should never use an H1 element, for that will be the page title. - - diff --git a/markdown/dev/guides/markdown/images/en.md b/markdown/dev/guides/markdown/images/en.md deleted file mode 100644 index 2a09f062412..00000000000 --- a/markdown/dev/guides/markdown/images/en.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Images -order: 70 ---- - -Images are like links, but you prefix them with an exclamation mark. - -The part between square brackets is the image alt text. - -Between the curly brackets you place the location of the image file -followed by a space and the image title between quotes. - -```md -![This is the alt text](image.jpg "This is the image title") -``` - -![This is the alt text & title](image.jpg "This is the image title") - - - -##### Images go in the same folder as your Markdown file - -The convention is to always place your images in the same folder as the -text where you are including the image. That way, you just need to specify -the image name, and not the path to its location. - - diff --git a/markdown/dev/guides/markdown/images/image.jpg b/markdown/dev/guides/markdown/images/image.jpg deleted file mode 100644 index ba6c01b7b0f..00000000000 Binary files a/markdown/dev/guides/markdown/images/image.jpg and /dev/null differ diff --git a/markdown/dev/guides/markdown/italic-and-bold/en.md b/markdown/dev/guides/markdown/italic-and-bold/en.md deleted file mode 100644 index 9bb71543191..00000000000 --- a/markdown/dev/guides/markdown/italic-and-bold/en.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Italics and bold -order: 30 ---- - -```md -You can make text *italic* or **bold** -by wrapping it in 1 or 2 asterisk respectively. -``` - -You can make text _italic_ or **bold** by wrapping it in 1 or 2 asterisk respectively: - -```md -Alternatively, you can also use underscores to mark _italic_ or __bold__. -``` - -Alternatively, you can also use underscores to mark _italic_ or **bold**. diff --git a/markdown/dev/guides/markdown/jargon/en.md b/markdown/dev/guides/markdown/jargon/en.md deleted file mode 100644 index 87722e31cbc..00000000000 --- a/markdown/dev/guides/markdown/jargon/en.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Using jargon and terms ---- - -Jargon or terms is anything that could throw off new users. -Rather than create a glossary on every page, we use MDX to manage -jargon/terms for us. This page shows you how to use it. - -Think of jargon as glossary terms - -## Defining terms - -To define a term, we need to establish a link between the term itself, and the documentation page that defines it. - -In the most common scenario, the term is the title of the page. -For example, the title of this page is `Using jargon and terms`: - -```mdx ---- -title: Using jargon and terms ---- -``` - -If we wanted to make it available as jargon, we only need to add the `jargon` frontmatter: - -```mdx ---- -title: Using jargon and terms -jargon: true ---- -``` - -## Multiple terms for the same page - -We can add additional terms that point to the same page by setting the `terms` in frontmatter to a comma-seperated list of terms. - -For example to make both `jargon` and `term` point to this page, we can do this: - - -```mdx ---- -title: Using jargon and terms -jargon: true -terms: jargon, term ---- -``` - -## Terminology per site - -The following pages show a list of all terminology per site: - -| Site | Terminology List | -| ---- | ---------------- | -| FreeSewing.dev | [/reference/terminology](/reference/terms) | -| FreeSewing.org | [/docs/about/terminology](https://freesewing.org/docs/about/terms) | - -All of the terms listed in the pages above can be used in the markdown/mdx -content of those websites. - -## Using jargon terms in MDX content - -To use jargon inside MDX content (like the markdown of our documentation, blog -posts, and so on), it's sufficient to emphasize the term: - -```md -We are migrating from _cjs_ to _esm_ modules -``` - -Which renders as: - -We are migrating from _cjs_ to _esm_ modules - -## Using jargon terms outside MDX content - -Outside MDX content -- more precisely, in React components -- you can achieve the same effect with the `Term` component: - -```mjs -import { Term } from 'site/components/jargon.mjs' - -export const MyComponent = () => ( -

Look, it works here too: esm

-) -``` - diff --git a/markdown/dev/guides/markdown/line-breaks/en.md b/markdown/dev/guides/markdown/line-breaks/en.md deleted file mode 100644 index ff0e13bac53..00000000000 --- a/markdown/dev/guides/markdown/line-breaks/en.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Line breaks -order: 20 ---- - -If you want to force a line break but not a new paragraph, -simply leave 2 spaces at the end of the line. - -```md -Like -this. -``` - -Like -this. diff --git a/markdown/dev/guides/markdown/links/en.md b/markdown/dev/guides/markdown/links/en.md deleted file mode 100644 index 0d45b0096d9..00000000000 --- a/markdown/dev/guides/markdown/links/en.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Links -order: 60 ---- - -Links combine square brackets for the link text with round brackets for the destination. - -```md -[Like this](https://freesewing.org) -``` - -[Like this](https://freesewing.org) - -An alternative notation allows you to include the links as such: - -```md -See [the reference documentation][1] on [freesewing.dev][2] - -[1]: https://freesewing.dev/reference -[2]: https://freesewing.dev/reference -``` - -See [the reference documentation][1] on [freesewing.dev][2] - -[1]: https://freesewing.dev/reference - -[2]: https://freesewing.dev/reference - -You don't have to use numbers, but can also use named references. - -```md -We moved the Markdown content to [our monorepo][monorepo] - -[monorepo]: https://github.com/freesewing/freesewing -``` - -We moved the Markdown content to [our monorepo][monorepo] - -[monorepo]: https://github.com/freesewing/freesewing diff --git a/markdown/dev/guides/markdown/lists/en.md b/markdown/dev/guides/markdown/lists/en.md deleted file mode 100644 index 96ad9e7b128..00000000000 --- a/markdown/dev/guides/markdown/lists/en.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Lists -order: 50 ---- - -To make a list, just do as you would in plain text: - -```md -- a bullet -- list - - a sublist - - item -``` - -- a bullet -- list - - a sublist - - item - -If you want an numbered list, just write numbers. -They don't even have to be the correct numbers: - -```md - -1. Item 1 -2. Item 2 -2. Item 3 -``` - -1. Item 1 -2. Item 2 -3. Item 3 diff --git a/markdown/dev/guides/markdown/tables/en.md b/markdown/dev/guides/markdown/tables/en.md deleted file mode 100644 index 2bd2a8c51a6..00000000000 --- a/markdown/dev/guides/markdown/tables/en.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Tables -order: 70 ---- - -If you need them, you can create tables too, using a structure as shown below: - -```md -| Name | Description | -| ---- | ----------- | -| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight | -| Mixture | Two or more substances that are not chemically united, such as air | -| Solution | A uniform mixture of varying proportions of a solvent and a solute | -``` - -| Name | Description | -| ---- | ----------- | -| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight | -| Mixture | Two or more substances that are not chemically united, such as air | -| Solution | A uniform mixture of varying proportions of a solvent and a solute | - -You can change the alignment of the columns by using a colon (`:`) on the line below the column title: - -```md -| Align-right | Align-center | -| -----------:|:------------:| -| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight | -| Mixture | Two or more substances that are not chemically united, such as air | -| Solution | A uniform mixture of varying proportions of a solvent and a solute | -``` - -| Align-right | Align-center | -| -----------:|:------------:| -| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight | -| Mixture | Two or more substances that are not chemically united, such as air | -| Solution | A uniform mixture of varying proportions of a solvent and a solute | diff --git a/markdown/dev/guides/markdown/text-and-paragraphs/en.md b/markdown/dev/guides/markdown/text-and-paragraphs/en.md deleted file mode 100644 index ffa00063d4d..00000000000 --- a/markdown/dev/guides/markdown/text-and-paragraphs/en.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Text and paragraphs -order: 10 ---- - -For the most part, you can just write as you would in any other format. - -```md -You can just start writing. - -An empty line starts a new paragraph. -``` - -You can just start writing. - -An empty line starts a new paragraph. diff --git a/markdown/dev/guides/plugins/en.md b/markdown/dev/guides/plugins/en.md deleted file mode 100644 index 637adad57b0..00000000000 --- a/markdown/dev/guides/plugins/en.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Plugin guide ---- - -Plugins allow you to extend FreeSewing with new features and functionality. -A FreeSewing plugin can extend FreeSewing in 3 different ways: - -- It can [provide macros](/guides/plugins/macros), which are a way to automate a number of steps into a - single command. -- It can [hook into the pattern](/guides/plugins/hooks), which allows you to manipulate the pattern or - interact with it at various stages of it's lifecycle. -- It can [provide store methods](/guides/plugins/store), which allows you to add new ways to handle data - in the pattern, including providing a custom logger. - -We have [a list of plugins](/reference/plugins/) that we maintain, but -if you can't find what you're looking for, you can write your own plugin. - -If you plan on doing that or if you would like to understand how plugins work, -this guide is for you. - -We'll cover the following topics: - - diff --git a/markdown/dev/guides/plugins/hooks/en.md b/markdown/dev/guides/plugins/hooks/en.md deleted file mode 100644 index b6210588ce8..00000000000 --- a/markdown/dev/guides/plugins/hooks/en.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Lifecycle hook methods -order: 110 ---- - -FreeSewing plugins can provide hooks, which is a way to hook into the pattern's -lifecycle. - -## Signature - -To provide one or more hooks, your plugin should have a `hooks` property that -is an object where the keys are the lifecycle hook name and the value holds a -method. When the lifecycle hook is triggered, your method will be called. - -```mjs -const myPlugin = { - name: 'example', - version: '0.0.1', - hooks: { - hookName: function (obj, data = {}) { - } - } -} -``` - -If you want to attach multiple methods to the same lifecycle hook, you can pass -them as an array: - -```mjs -const myPlugin = { - name: 'example', - version: '0.0.1', - hooks: { - hookName: [ - function one (obj, data = {}) { }, - function two (obj, data = {}) { } - ] - } -} -``` - -## Arguments - -All lifecycle methods will receive two parameters: - -- An object relevant to the lifecycle hook. See the [hooks API reference](/reference/hooks/) for details. -- Data passed when the hook was registered (optional) - -## Notes - -Refer to the [hooks API reference](/reference/hooks/) for a list of all -available lifecycle hooks. - diff --git a/markdown/dev/guides/plugins/loading/en.md b/markdown/dev/guides/plugins/loading/en.md deleted file mode 100644 index a6ab9089121..00000000000 --- a/markdown/dev/guides/plugins/loading/en.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Loading plugins -order: 140 ---- - -Plugins can be loaded at build time and added to the design. -Or, they can be added at run time and added to an instantiated pattern. - -To load a plugin at build time, it should be added to [the `plugins` key of the part configuration](/reference/api/part/config/plugins). - -To load a plugin at run time, it should be loaded with a call to [`Pattern.use()`](/reference/api/pattern/use). - -Please refer to the relevant documentation for more details. diff --git a/markdown/dev/guides/plugins/macros/en.md b/markdown/dev/guides/plugins/macros/en.md deleted file mode 100644 index f7578a275cb..00000000000 --- a/markdown/dev/guides/plugins/macros/en.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Macro methods -order: 120 ---- - -FreeSewing plugins can provide macros, which is a way to automate multiple -steps into a single command. - -## Signature - -To provide one or more macros, your plugin should have a `macros` property that -is an object where the keys are the macro name, and the value holds a method to -run when the macro is executed. - -```mjs -const myPlugin = { - name: 'example', - version: '0.0.1', - macros: { - example: function(so, { log }) { - log.info('Running the example macro') - } - } -} -``` - -## Arguments - -All macros receive two arguments: - -- `so`: A plain object holding configuration object passed to the macro -- `props`: The same object as passed to the [`Part.draft()`](/reference/api/part/draft) method that you can destructure - - -###### Macros take only 1 argument - -When writing a macro, keep in mind that all information that needs to be passed -to a macro needs to be contained in a single argument. - -Typically, you use a single plain object to configure the macro. - - - -## Return value - -Macros do not need to return anything. If they do, it will be ignored. diff --git a/markdown/dev/guides/plugins/store/en.md b/markdown/dev/guides/plugins/store/en.md deleted file mode 100644 index 77100c2caf5..00000000000 --- a/markdown/dev/guides/plugins/store/en.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Store methods -order: 130 ---- - -FreeSewing plugins can provide store methods, which facilitate data handling -within a pattern. - -## Signature - -To provide one or more store methods, your plugin should have a `store` property that -is an array where each member is itself an array with two members: - -- The first member holds the key to attach the method to (in dot notation) -- The second member holds the method to attach - -```mjs -const myPlugin = { - name: 'example', - version: '0.0.1', - store: [ - [ - 'log.panic', - function(store, ...params) { - store.setIfUnset('logs.panic', new Array()) - store.push(...params) - } - ] - } -} -``` - -## Arguments - -All store methods receive at least two arguments: - -- `store`: The store object itself -- `...params`: All additional plugins that were passed to the store method - -## Overwriting store methods - -You are allowed to overwrite existing store methods. -As it happens, this is how you should implement a custom logging solution, -by overwriting the logging methods under the store's `log` key, - -However, the following store methods cannot be overwritten: - -- `extend()` -- `get()` -- `push()` -- `set()` -- `setIfUnset()` -- `unset()` - -## Return value - -Store methods do not need to return anything. If they do, it will be ignored. diff --git a/markdown/dev/guides/plugins/structure/en.md b/markdown/dev/guides/plugins/structure/en.md deleted file mode 100644 index 66f54d8e29e..00000000000 --- a/markdown/dev/guides/plugins/structure/en.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Plugin structure -order: 100 ---- - -A FreeSewing plugin is a plain object with the following structure: - -```mjs -Object plugin = { - String name, - String version, - Object hooks, - Object macros, - Array store, -} -``` - -A plugin **must** have the `name` and `version` properties. -The other properties are optional, and they map to the three different functionalities macros can provide: - -- [`hooks`](/guides/plugins/hooks): Holds an object with lifecycle hooks the plugin wants to hook into -- [`macros`](/guides/plugins/macros): Holds and object with macros the plugin provides -- [`store`](/guides/plugins/store): Holds and Array with store methods the plugin provides. - -Click on the links above for more details on the structure of these properties. diff --git a/markdown/dev/guides/prerequisites/bezier-curves/en.md b/markdown/dev/guides/prerequisites/bezier-curves/en.md deleted file mode 100644 index 97fa9120f76..00000000000 --- a/markdown/dev/guides/prerequisites/bezier-curves/en.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Understanding Bézier curves -order: 50 ---- - -While lines on computers are easy to store with a start and end point, -curves require more information. -In FreeSewing — as in SVG and countless of other computer applications — -curves are stored as [Bézier curves](https://en.wikipedia.org/wiki/B%C3%A9zier_curve), -named after French engineer [Pierre Bézier](https://en.wikipedia.org/wiki/Pierre_B%C3%A9zier) who -popularized their use back in the 1960s. - -In FreeSewing, we use so-called cubic Bézier curves which have: - -- A start point -- A first control point that’s linked to the start point -- A second control point that’s linked to the end point -- An end point - - -```js -({ Point, points, Path, paths, part }) => { - - points.from = new Point(10, 20) - points.cp1 = new Point(40, 0) - points.cp2 = new Point(60, 40) - points.to = new Point(90, 20) - - paths.line = new Path() - .move(points.from) - .curve(points.cp1, points.cp2, points.to) - .setText("Path.curve()", "text-sm center fill-note") - - return part -} -``` - - -Bézier curves and their _handles_ or _control points_ are surprisingly intuitive. -The following illustration does a great job at explaining how they are constructed: - -![How Bézier curves are constructed](bezier.gif) - -You don't need to understand the mathematics behind Bézier Curves. -As long as you intuitively _get_ how the control points influence the curve, you're good to go. - - - -###### More on Bézier curves - -Wikipedia has a good [introduction to Bézier curves](https://en.wikipedia.org/wiki/B%C3%A9zier_curve). -For a deep-dive into the subject, check out [A Primer on Bézier Curves](https://pomax.github.io/bezierinfo/) by -[Pomax](https://github.com/Pomax). - - diff --git a/markdown/dev/guides/prerequisites/coordinate-system/en.md b/markdown/dev/guides/prerequisites/coordinate-system/en.md deleted file mode 100644 index a62407ac207..00000000000 --- a/markdown/dev/guides/prerequisites/coordinate-system/en.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: The coordinate system -order: 30 ---- - -The coordinate system in FreeSewing -- and in SVG -- follows the same rules as text on a page. -You start at the top-left, and as you go to the right, the X-coordinate will increase. -As you go down the Y-coordinate will increase. - - -```mjs -({ Point, points, paths, Path, part }) => { - points.origin = new Point(10, 10) - points.x = new Point(100, 10) - points.y = new Point(10, 50) - points.textX = new Point(85, 20).addText('X', 'text-lg') - points.textY = new Point(12, 43).addText('Y', 'text-lg') - paths.coords = new Path() - .move(points.y) - .line(points.origin) - .line(points.x) - .addClass('mark') - .attr('marker-start', 'url(#dimensionFrom)') - .attr('marker-end', 'url(#dimensionTo)') - - return part -} -``` - - -The image above illustrates both the X-axis and Y-axis. -On the X-axis, `20` is further to the right than `10`. -On the Y-axis, `50` is lower than `20`. - - - -The Y-axis is inverted in many drawing programs, with the origin -`(0,0)` being the lower left corner, rather than the upper left corner. - -This is a common point of confusion so keep in mind that the Y-axis may -not behave as you would have intuitively expected. - - diff --git a/markdown/dev/guides/prerequisites/en.md b/markdown/dev/guides/prerequisites/en.md deleted file mode 100644 index 79adbe514fb..00000000000 --- a/markdown/dev/guides/prerequisites/en.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Before you start ---- - -Drawing lines and curves on paper is a skill most people have been practicing since kindergarten. -In FreeSewing, we draw lines and curves with code, which is a bit more abstract -but doesn't have to be complicated once you understand a few basic building blocks. - -Understanding the concepts that are involved in designing sewing patterns in code will pay dividends later. -That is why we recommend you familiarize yourself with the following topics: - - - - - -##### There's no need to know everything - -FreeSewing sits at the intersection of the world of makers and developers. -If your background is in development, you will need no explaining what SVG is but might not -know much about designing sewing patterns. -If on the other hand your background is in sewing or pattern design, you might wonder what -the heck NodeJS is and why you should care. - -Few people straddle both worlds, so as you start using FreeSewing, chances are -you'll learn a few new things along the way. - -And if you get stuck [our chatrooms on Discord](https://discord.freesewing.org/) are the best place to get help. - diff --git a/markdown/dev/guides/prerequisites/svg/en.md b/markdown/dev/guides/prerequisites/svg/en.md deleted file mode 100644 index 7439442af48..00000000000 --- a/markdown/dev/guides/prerequisites/svg/en.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Scalable Vector Graphics -order: 20 ---- - -Patterns are rendered as **SVG** — short -for [Scalable Vector Graphics](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) — -an XML-based vector image format and an open standard. -While you don’t need to be an SVG expert, a basic understanding of the format -will greatly help you to understand FreeSewing. - -For example, the coordinate system and the way paths -are structured are all related to the SVG drawing system, which is closely related -to other 2D drawing technologies such as PostScript or PDF. diff --git a/markdown/dev/guides/prerequisites/units/en.md b/markdown/dev/guides/prerequisites/units/en.md deleted file mode 100644 index 2e14ba72a9e..00000000000 --- a/markdown/dev/guides/prerequisites/units/en.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Units in FreeSewing -order: 40 ---- - -FreeSewing uses _millimeter (mm)_ for all its internal units. -We do support both imperial and metrics units, which are displayed -as _cm_ or _inch_, but under the hood everything is handled in millimeter. - -So as a pattern designer, you will work with mm. -When you write `1`, that’s one millimeter. When you write `7.8`, that’s 7.8 mm. - -While you can use cm or inch on the FreeSewing website, that is merely a layer of -abstraction on top of the internal units, which are always mm. diff --git a/markdown/dev/guides/translation/en.md b/markdown/dev/guides/translation/en.md deleted file mode 100644 index 69dd34361ff..00000000000 --- a/markdown/dev/guides/translation/en.md +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: Translation guide ---- - -Supporting multiple languages is one of the best way to promote inclusion and -accessibility. Thanks to the efforts of our community, FreeSewing is proudly -multilingual. - -This translation guide covers everything you need to know to join the effort of -translating FreeSewing into other languages. - -## Supported Languages - -FreeSewing is currently available in the following languages: - -| Code | Language | Website | -| ----:|:-------------- |:------- | -| `de` | **German** | https://freesewing.org/de | -| `en` | **English** | https://freesewing.org/ | -| `es` | **Spanish** | https://freesewing.org/es | -| `fr` | **French** | https://freesewing.org/fr | -| `nl` | **Dutch** | https://freesewing.org/nl | -| `uk` | **Ukrainian** | https://freesewing.org/uk | - - -English is the translation source language and the working language of the FreeSewing project - - -## Become a FreeSewing translator - -To gain access as a FreeSewing translator, you will need an invite. -You can request a translator invite with the link below. -When you do, we will send you an email with all further instructions. - - - -###### [Request a FreeSewing translator invite](https://freesewing.org/translation/join) - - - - -We also have [a dedicated __Translation__ channel on -Discord](https://discord.freesewing.org) for any questions that may remain. - - -## Adding a new language - -We would love to make FreeSewing available in more languages. If you are -interested in starting a new translation effort, that is great. - -We ask that you familiarize yourself with this translation guide to understand -what it takes to add a new language. Then if you can submit your request to setup -a new language with the link below. - - - -###### [Suggest a new FreeSewing language](https://freesewing.org/translation/suggest-language) - - - - -##### Get the band together - -We recommend finding some like-minded people who can help translating. - -While the core materials of FreeSewing can realistically be handled by one -person, translating all of FreeSewing's documentation and content realistically -is a job you should not undertake on your own. - - - - - -##### Do or do not. There is no try. - -There is a certain cost to adding a new language. It's not a cost in money, -but rather in increased bandwidth, storage requirements, build times, -repository size, test times, and so on. - -It's a cost we are __more than happy__ to pay for the benefit gaining another -langauge. But it is also a cost that needs to be paid up front, at the start -of the effort. - -So, without wanting to discourage anyone, I would really like to avoid a -scenario where people enthusiastically start working on a new languages, only -to lose interest days or weeks later and see the effort falter. - -With that out of the way, I hope to see many more languages being added in the -future. - - - -## Translation status - -The status of the ongoing translation work is available at -[FreeSewing.org/translation](https://freesewing.org/translation). - -It's a good place to check what languages need extra help, and which are -leading the scoreboard. - -## Translation priorities - -To fully translate FreeSewing, the following types of content needs to be -translated: - -### Top priority: UX Translations -These are translations the directly impact -the user experience (_UX_). They include the content used in design, the names -of options, translations of menus, emails, and so on. - -This is a relatively small amount of text, and makes up less than 10% of the -top & high priority content. It's an effort that a motivated translator can -complete over the course of a weekend. - - -The top-priority translations in Crowdin are everything under the `packages` -and `sites` folder. Do this first. - - -### High priority: Translation of Documentation -This includes all the documentation on FreeSewing.org. - -This is a significant amount of text that makes up more than 90% of the top & -high priority content. It's an effort you should probably not take on by -yourself, but rather tackle with a team of translators. - - -The high-priory translations in Crowdin is everything under the -`markdown/org/docs` folder. - - -### Low Priority: Content of blog and showcase posts, and newsletters -This is _nice to have_ as people can use and navigate FreeSewing even when this -content remains untranslated. - - -The low-priory translations in Crowdin is everything under the -`markdown/org/blog`, `markdown/org/showcase`, and `markdown/org/newsletter` folders. - - -## Translation through Crowdin - -All of our translation work is handled through [Crowdin](https://crowdin.com/), -an online platform to facilitate translation. - - - -You can reach the FreeSewing project on Crowdin directly via -[translate.freesewing.org](https://translate.freesewing.org). - - -Crowdin is configured to automatically detect all of the various translation -files in our repository, upload them to the platform, and break them apart into -bite-sized portions that you can translate in a collaborative way. -Rather than work on one large block of text, various people can jump in and -translate smaller snippets, - -Once translated, there is a proofreading step that will be handled by one of -our proofreaders. This is often a formality, but it's an extra step to allow -quality assurance and avoid any mistakes from slipping in. Much like the code -review process when you submit a pull request on GitHub. - -Once your translation is approved, Crowdin will automatically submit a pull -request on GitHub to update the translation files in our repository. And the -next time our website or software packages get built, they will include the new -translations. - -## Machine translation - -While everybody knows that translation is best when it's done by a human being, -we also have to be realistic that the growing body of documentation and other -FreeSewing content can be a daunting task to take on for translators, especially -when you want to start a new language. - -Fortunately, machine translation has gotten rather good so we can get some help. -Our Crowdin project is integrated with a [DeepL](https://www.deepl.com) -subscription, and this can be a great help to translators. - -You can use the DeepL suggestions when translating, or there is also the possibility -to machine-translate entire files or folders. For example, you may start a new -language by machine-translating everything, and then focus on proofreading the -top-priority content, and then move on to the high-priority content. - -## Syntax - -Most strings are just text, but sometimes you'll find a little markup sprinkled in. - -### HTML formatting - -When you encounter HTML tags, simply translate around them. For example: - -```yaml -No, never. -``` - -looks like this in Spanish: - -```yaml -No, nunca. -``` - -### Placeholders - -When you encounter a `{key}` between curly braces, leave it as-is. -These will be filled in later with the correct value. For example: - -```yaml -{field} saved -``` - -looks like this in Spanish - -```yaml -{field} guardado -``` - -## Questions, Suggestions, Discussion - -If you have questions, suggestions, or would like to discuss -translation-related matters, please join -[discord.freesewing.org](https://discord.freesewing.org/) and head to the -__Translation__ channel. - diff --git a/markdown/dev/howtos/design/cutlist/en.md b/markdown/dev/howtos/design/cutlist/en.md deleted file mode 100644 index 323784e5a71..00000000000 --- a/markdown/dev/howtos/design/cutlist/en.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: "Include Cutting Instructions" ---- - -To include cutting instructions with your part, use the [annotations plugin](/reference/plugins/annotations) (included by default via [core-plugins](/reference/plugins/core)) to add the `cutlist.addCut` method to your part's [`store`](/reference/api/store/extend). - -The [grainline macro](/reference/macros/grainline) and the [cutonfold macro](/reference/macros/cutonfold) will automatically add grain and fold information to the cutting instructions - -These cutting instructions get used by the [title macro](/reference/macros/title), so be sure to add them before adding your part's title. - - -
- addCut() Parameters - -Pass an object to the `store.cutlist.addCut` method with any of the following keys; any you don't provide will be filled with the defaults: - -| Key | Type | Default | Description | -| :-- | :--- | :------ | :---------- | -| cut | Number\|false | 2 | the number of pieces to cut from the specified material. Pass `false` to clear all cutting instructions for the material | -| material | String | 'fabric' | the translation key of the material to cut from | -| identical | Boolean | false | should even numbers of pieces be cut in the same direction? false for mirrored | -| bias | Boolean | false | should the pieces in these cutting instructions be cut on the bias? 'false' uses grainline instruction or leaves orientation as is | -| ignoreOnFold | Boolean | false | should these cutting instructions ignore any cutOnFold information set by the part | - - -You can use any `string` you want for your material, but here are some standard ones we have translation for - -| Key | Translation | -|:--|:--| -| fabric | Main Fabric | -| lining | Lining | -| canvas | Canvas | -| lmhCanavas | Light to Medium Hair Canvas | -| heavyCanvas | Heavyweight Hair Canvas | -| interfacing | Interfacing | -| plastic | Plastic | -| ribbing | Ribbing | - -
-
- - -## Basic Usage -For simple cutting instructions, you can rely on the default method parameters - -```js -const part = { - name: 'example.front', - draft: ({part, store}) => { - // add instructions to cut two mirrored from main fabric - store.cutlist.addCut() - } -} -``` - -## Intermediate Usage -For many designs, you'll want more than just "Cut 2 mirrored from Main Fabric" - -### Specifying materials, number of pieces, orientation - -You can override the default values to specify different materials, number of pieces to cut, and whether they should be mirrored or identical - -```js -const part = { - name: 'example.front', - draft: ({part, store}) => { - // add instructions to cut three identical from lining - store.cutlist.addCut({cut: 3, material: 'lining', identical: true}) - } -} -``` - -### Instructions for multiple materials -You can add as many sets of instructions as you need - -```js -const part = { - name: 'example.front', - draft: ({part, store}) => { - // add instructions to cut four mirrored from main fabric - store.cutlist.addCut({cut: 4}) - // add instructions to cut three identical from lining - store.cutlist.addCut({cut: 3, material: 'lining', identical: true}) - } -} -``` - -## Advanced usage - -### Cut some on the fold, some not -Sometimes you want some pieces cut on the fold and others cut as halves to seam together. - -```js -const part = { - name: 'example.front', - draft: ({part, points, Point, macro, store}) => { - // set the cut on fold line - points.p1 = new Point(0, 0) - points.p2 = new Point(0, 10) - - // pieces should be cut on the fold - macro('cutonfold', {from: points.p1, to: points.p2}) - - // cut two on the fold - store.cutlist.addCut() - // cut two, not on the fold - store.cutlist.addCut({cut: 2, ignoreOnFold: true}) - } -} -``` - - -### Cut some on the grain, some on the bias -You set the grainline on a piece, but you also need some to be cut on the bias - -```js -const part = { - name: 'example.front', - draft: ({part, points, Point, macro, store}) => { - // set the cut on fold line - points.p1 = new Point(0, 0) - points.p2 = new Point(0, 10) - - // the grain runs from p1 to p2 - macro('grainline', {from: points.p1, to: points.p2}) - - // cut two mirrored on the grain - store.cutlist.addCut() - // cut two mirrored on the bias - store.cutlist.addCut({cut: 2, bias: true}) - } -} -``` diff --git a/markdown/dev/howtos/ways-to-contribute/body-ambassador/en.md b/markdown/dev/howtos/ways-to-contribute/body-ambassador/en.md deleted file mode 100644 index e0fd4dccd30..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/body-ambassador/en.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Body ambassador ---- - -Maybe you’re unusually short or tall. -Maybe you have a bit of a pot belly or very large breasts. -Maybe you have a disability that requires fit adjustments. - -Whatever it is, if you represent a minority fitting issue you could -represent this minority to make sure their needs are heard and understood. - - - -Join the `#pattern-design` channel on the Discord server and help us understand how we can design patterns that fit people with your body type. - - diff --git a/markdown/dev/howtos/ways-to-contribute/community-building/en.md b/markdown/dev/howtos/ways-to-contribute/community-building/en.md deleted file mode 100644 index 1331f00a489..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/community-building/en.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Community building ---- - -The FreeSewing community resides [on Discord](https://discord.freesewing.org/). -Just being there to answer questions and chat with other people is a valuable part of community building. - -We also can be found in plenty of other places where we'd love to have you join us: - -* [Instagram](https://instagram.com/freesewing_org) -* [freesewing.social](https://freesewing.social/@freesewing) (our Mastodon instance) -* [Facebook](https://www.facebook.com/groups/627769821272714/) -* [Reddit](https://www.reddit.com/r/freesewing) - -Apart from being present in chat rooms and social media, you could also take on some responsibility on one or more platforms. diff --git a/markdown/dev/howtos/ways-to-contribute/design-patterns/en.md b/markdown/dev/howtos/ways-to-contribute/design-patterns/en.md deleted file mode 100644 index 9b4090d28e3..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/design-patterns/en.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Design sewing patterns ---- - -Everybody wants us to add more patterns. But somebody has to design them. - -That somebody could be you. -We can help you with the development side of things. diff --git a/markdown/dev/howtos/ways-to-contribute/develop-patterns/en.md b/markdown/dev/howtos/ways-to-contribute/develop-patterns/en.md deleted file mode 100644 index ad8bcdb8a6d..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/develop-patterns/en.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Develop sewing patterns ---- - -You could program new designs for FreeSewing. -If you're not afraid of JavaScript and are happy to team up with a designer, -you could work on a new pattern together. diff --git a/markdown/dev/howtos/ways-to-contribute/devops/en.md b/markdown/dev/howtos/ways-to-contribute/devops/en.md deleted file mode 100644 index a7f30b19283..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/devops/en.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Devops ---- - -We have use a lot of automation from GitHub actions to automated deployment on Vercel. -We also have some Ansible playbooks to run maintenance tasks. - -There's also other technical tasks like database or server administration, certificate renewal, and so on. - -If that's your kind of thing, we could use your help. diff --git a/markdown/dev/howtos/ways-to-contribute/en.md b/markdown/dev/howtos/ways-to-contribute/en.md deleted file mode 100644 index bd2d2eefb19..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/en.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Ways to contribute ---- - -Thank you for being part of our community, and for wanting to contribute! ❤️ -FreeSewing is an open source project ran by volunteers from different corners of the world. -We would love to have you on board, and this page lists everything you need to know to get started. - -## Requirements - -The only requirement we ask from our contributors is that they are the kind of people who -value a safe and welcoming environment for all members of the FreeSewing community. - -To that extend, we impose the following requirements to ensure everyone feels safe and welcome: - -- Any member of our community must respect [our community standards](https://freesewing.org/docs/about/community-standards/) -- As a contributor, you must uphold [our Code of Conduct](/guides/code-of-conduct/) - -Go ahead and read those, we'll wait. - -## Good to know - -With that out of the way, here's a few more things that are _good to know_: - -- Nobody gets paid to work on/for FreeSewing. We are a 100% volunteer organisation. -- We have patrons who support us financially, but all the money that comes in goes to charity — - See our [revenue pledge](https://freesewing.org/docs/about/pledge/) for details -- FreeSewing follows the [all-contributors](https://allcontributors.org/) specification. - Contributions of any kind are welcome. - -## Where to begin - -Below is a list of ideas or roles you could take up. -If you're not sure what to do, or if you have questions, [please reach out to -us](https://discord.freesewing.org/). - - - - - -##### Who wants a job in the tech sector? - -For many in our community, contributing to FreeSewing marked their -first steps into the world of open source software development. - -I (joost) am happy to provide guidance or mentorship to anyone who -wants to learn, especially when doing so enables upwards social mobility. - -[Reach out](https://discord.freesewing.org/) and we let's do this. - - diff --git a/markdown/dev/howtos/ways-to-contribute/illustrations/en.md b/markdown/dev/howtos/ways-to-contribute/illustrations/en.md deleted file mode 100644 index 137b81d1853..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/illustrations/en.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Make illustrations ---- - -Our documentation can always use some more/better illustrations to help people figure out how -to make our patterns into garments. diff --git a/markdown/dev/howtos/ways-to-contribute/language-ambassador/en.md b/markdown/dev/howtos/ways-to-contribute/language-ambassador/en.md deleted file mode 100644 index c86fe12b3e5..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/language-ambassador/en.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Language ambassador ---- - -You could represent FreeSewing in a non-English community. -There, you can help answer questions or triage problem reports. -Or you can point out where translations are missing. diff --git a/markdown/dev/howtos/ways-to-contribute/pattern-ambassador/en.md b/markdown/dev/howtos/ways-to-contribute/pattern-ambassador/en.md deleted file mode 100644 index ca1e7dc3a10..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/pattern-ambassador/en.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Pattern ambassador ---- - -You could take charge of a specific FreeSewing design/pattern. - -You’ll be the person to ask questions about how to make that pattern. -You’ll make sure the documentation is not forgotten. -And you can help with questions or triage problem reports to developers or designers. diff --git a/markdown/dev/howtos/ways-to-contribute/pattern-testing/en.md b/markdown/dev/howtos/ways-to-contribute/pattern-testing/en.md deleted file mode 100644 index fc9f6bec356..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/pattern-testing/en.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Pattern testing ---- - -You could make (a muslin for) our patterns prior to release to make sure everything is ok. - - - -Join the `#pattern-design` channel on the Discord server and let us know you would like to help. Here you will find people designing new patterns and reviewing existing patterns. Feedback is very welcome! - - diff --git a/markdown/dev/howtos/ways-to-contribute/project-management/en.md b/markdown/dev/howtos/ways-to-contribute/project-management/en.md deleted file mode 100644 index d8d53c5fdc8..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/project-management/en.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Project management ---- - -There's a lot going on within the FreeSewing project and it's easy to forget about something. - -A project manager would be helpful to prioritize tasks, makes sure all tasks have an issue, -organize milestones, and so on. - -This is helpful in more than one way: - -- It reduces the cognitive load of the people implementing changes because they don't have to worry about forgetting things -- It increases transparency by making it clear what sort of things are being worked on -- It gives us that good feeling of closing the issue when the task is done diff --git a/markdown/dev/howtos/ways-to-contribute/proofreading/en.md b/markdown/dev/howtos/ways-to-contribute/proofreading/en.md deleted file mode 100644 index 4ed056059fe..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/proofreading/en.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Proofreading ---- - -You could check the original English text or translations for typos and/or grammar mistakes. -You could propose improvements and watch over a consistent style and tone across FreeSewing’s documentation and written text. diff --git a/markdown/dev/howtos/ways-to-contribute/report-bugs/en.md b/markdown/dev/howtos/ways-to-contribute/report-bugs/en.md deleted file mode 100644 index 071d174b5a7..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/report-bugs/en.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Report bugs ---- - -Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). -Create an issue [in our monorepo](https://github.com/freesewing/freesewing/issues/new?assignees=\&labels=%F0%9F%90%9B+bug\&template=bug-report.md\&title=Bug+report) if you've found one. - -Explain the problem and include additional details to help maintainers reproduce the problem: - -- **Use a clear and descriptive title** for the issue to identify the problem. -- **Describe the exact steps which reproduce the problem** in as many details as possible. -- **Include relevant information** such as your username on the site, or the person you drafted a pattern for. - -Provide more context by answering these questions: - -- **Did the problem start happening recently** (e.g. it worked fine before but since the latest update it doesn't) -- **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens. diff --git a/markdown/dev/howtos/ways-to-contribute/showcase-our-patterns/en.md b/markdown/dev/howtos/ways-to-contribute/showcase-our-patterns/en.md deleted file mode 100644 index b8ae3beff82..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/showcase-our-patterns/en.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: Showcase our patterns ---- - -Anytime somebody has made one of our patterns, we like to Showcase it on [freesewing.org](https://freesewing.org/showcase/). - -## How to get your pictures to us - -If you've got pictures, there's a few ways you can get them on the site: - -- [FreeSewing](#freesewing) -- [Instagram](#instagram) -- [Mastodon](#mastodon) -- [Facebook](#facebook) -- [Discord](#discord) -- [Reddit](#reddit) -- [GitHub](#github) -- [Email](#email) - -### FreeSewing - -You can share something you (or someone else, with permission) made based on our designs at [FreeSewing.org/new/showcase](https://freesewing.org/new/showcase). - -### Instagram - -Post your pictures on Instagram, and tag or mention [@freesewing\_org](https://instagram.com/freesewing_org). - -### Mastodon - -Post your pictures — or a link to them — on freesewing.social (our Mastodon instance), and tag or mention [@freesewing](https://freesewing.social/@freesewing). - -### Facebook - -Post your pictures — or a link to them — on Facebook, and tag or mention the [@FreeSewing](https://www.facebook.com/groups/627769821272714/) group. - -### Discord - -Post your pictures — or a link to them — in the `#pattern-showcase` channel [on our Discord](https://discord.freesewing.org). - -### Reddit - -Post your pictures — or a link to them — in [r/freesewing](https://www.reddit.com/r/freesewing). - -### GitHub - -Create an issue [on GitHub](https://github.com/freesewing/freesewing/issues/new?assignees=&labels=:%2B1:+good+first+issue%2C+:camera_flash:+showcase%2C+:hugs:+community&template=04_showcase-template.yaml&title=%5Bshowcase%5D%3A+Found+a+great+project+to+showcase) and attach your pictures to it, or include a link to the pictures. - -### Email - -Email your pictures — or a link to them — to showcase@freesewing.org. - -## Tips for great pictures - -Below are just a few easy tips and tricks for your Showcase post. -Of course, any Showcase is infinitely better than nothing, so go ahead and send us those low-light mirror selfies - we love them. - -But if you want to take things to the next level, a few things to consider: - -### Show it all - -Show the whole garment. From multiple angles, if possible. -It's awesome to see garments from the front, but back and side views can be really helpful, too. -Bonus points for adding in a seated picture, which are especially great for sewists who use a wheelchair. - -### Embrace the light - -Take pictures in the best light you can — that might be next to a bright window, -in a room where you've turned on all the extra lamps you could find, -or that elusive "golden hour" outdoors. -Bonus points if you can make it bright enough to not need a flash. - -### Background - -A neutral background can be helpful for seeing details. -Try to avoid black on black or another setting that makes it hard to see what is what. - -And remember that the outdoors is often the best background. - -### Close-ups - -If you nailed that welt pocket or hand-stitched all your buttonholes, go ahead and show them off. -Close-up pictures make the showcase so much more relevant for people looking to make the same thing. diff --git a/markdown/dev/howtos/ways-to-contribute/technical-writing/code/en.md b/markdown/dev/howtos/ways-to-contribute/technical-writing/code/en.md deleted file mode 100644 index eabdb17dd93..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/technical-writing/code/en.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Writing for freesewing.dev ---- - -You could write documentation for freesewing.dev, our developers website. - -You would need good writing skills and a familiarity with code (JavaScript). diff --git a/markdown/dev/howtos/ways-to-contribute/technical-writing/en.md b/markdown/dev/howtos/ways-to-contribute/technical-writing/en.md deleted file mode 100644 index ba6435334aa..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/technical-writing/en.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Technical writing ---- - - diff --git a/markdown/dev/howtos/ways-to-contribute/technical-writing/patterns/en.md b/markdown/dev/howtos/ways-to-contribute/technical-writing/patterns/en.md deleted file mode 100644 index 1611bcb0700..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/technical-writing/patterns/en.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Writing for freesewing.org ---- - -You could write documentation for freesewing.org, our makers website. - -You would need good writing skills and a familiarity with sewing. diff --git a/markdown/dev/howtos/ways-to-contribute/translation/en.md b/markdown/dev/howtos/ways-to-contribute/translation/en.md deleted file mode 100644 index fdf3c0c33f7..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/translation/en.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Translation ---- - -You could translate FreeSewing into one of its additional languages -(French, German, Dutch, Spanish, Ukrainian). Or if you’re ambitious, add a new one. diff --git a/markdown/dev/howtos/ways-to-contribute/triage-issues/en.md b/markdown/dev/howtos/ways-to-contribute/triage-issues/en.md deleted file mode 100644 index bb59c8cacde..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/triage-issues/en.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Triage issues ---- - -Triaging issues is a great way to get involved in FreeSewing. You can do tasks such as: - -- Making sure issues are properly labeled -- Ensuring they have a good title that explains the issue in brief -- Assigning issues to people to make sure they are tended to -- Keeping an eye on stale issues, and either updating or closing them -- Assigning issues to milestones so we can plan our releases - -All FreeSewing contributors have triage permissions that allows them to do this. -If you don't have the rights, or bump into any issues, [reach out to us on Discord](https://discord.freesewing.org). diff --git a/markdown/dev/howtos/ways-to-contribute/webdesign/en.md b/markdown/dev/howtos/ways-to-contribute/webdesign/en.md deleted file mode 100644 index 84547393a05..00000000000 --- a/markdown/dev/howtos/ways-to-contribute/webdesign/en.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: UI / UX Webdesign ---- - -You could help us make our website and tools pretty and improve the user experience. diff --git a/markdown/dev/i18n/en.md b/markdown/dev/i18n/en.md deleted file mode 100644 index 2e2affc3578..00000000000 --- a/markdown/dev/i18n/en.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Translate ---- - -FreeSewing is proudly multilingual. For that, we rely on the -support of our translators. - -FreeSewing currently is available in the following languages: - -- English -- Dutch -- French -- Spanish -- German -- Ukrainian - -## Translation guide - -This guide for translators covers everything you need to know about (helping out with) the translation of FreeSewing. - -- - diff --git a/markdown/dev/reference/api/path/close/en.md b/markdown/dev/reference/api/path/close/en.md deleted file mode 100644 index 4908b4a0906..00000000000 --- a/markdown/dev/reference/api/path/close/en.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Path.close() ---- - -The `Path.close()` method closes a path by drawing a straight line from the current position to the path's start. - -## Signature - -```js -Path path.close() -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, part }) => { - - points.from = new Point(10, 20) - points.cp2 = new Point(60, 30) - points.to = new Point(90, 20) - - paths.line = new Path() - .move(points.from) - ._curve(points.cp2, points.to) - .close() - .reverse() // To keep text from being upside-down - .setText('Path._close()', 'text-sm right fill-note') - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/curve/en.md b/markdown/dev/reference/api/path/curve/en.md deleted file mode 100644 index 8cab6c113cc..00000000000 --- a/markdown/dev/reference/api/path/curve/en.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Path.curve() ---- - -The `Path.curve()` method draws a cubic Bézier curve from the current position -via two control points to a given endpoint. - -## Signature - -```js -Path path.curve(Point cp1, Point cp2, Point to) -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, part }) => { - - points.from = new Point(10, 20) - points.cp1 = new Point(40, 0) - points.cp2 = new Point(60, 40) - points.to = new Point(90, 20) - - paths.line = new Path() - .move(points.from) - .curve(points.cp1, points.cp2, points.to) - .setText("Path.curve()", "text-sm center fill-note") - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/end/en.md b/markdown/dev/reference/api/path/end/en.md deleted file mode 100644 index edd73a6dfa8..00000000000 --- a/markdown/dev/reference/api/path/end/en.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Path.end() ---- - -The `Path.end()` method returns the Point object at the end of the path. - -## Signature - -```js -Point path.end() -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, snippets, Snippet, part }) => { - - points.A = new Point(45, 60) - points.B = new Point(10, 30) - points.BCp2 = new Point(40, 20) - points.C = new Point(90, 30) - points.CCp1 = new Point(50, -30) - - paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - - snippets.end = new Snippet("notch", paths.demo.end()) - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/hide/en.md b/markdown/dev/reference/api/path/hide/en.md deleted file mode 100644 index e191eec3fcd..00000000000 --- a/markdown/dev/reference/api/path/hide/en.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Path.hide() ---- - -The `Path.hide()` hides the path so it does not appear in the output. - -## Signature - -```js -Path path.hide() -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, part }) => { - - points.top = new Point(50, 0) - points.left = new Point (20,50) - points.right = new Point (80,50) - - paths.a = new Path().move(points.top).line(points.right).setText('a') - paths.b = new Path().move(points.right).line(points.left).setText('b').hide() - paths.c = new Path().move(points.left).line(points.top).setText('c') - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/insop/en.md b/markdown/dev/reference/api/path/insop/en.md deleted file mode 100644 index a07637d61e1..00000000000 --- a/markdown/dev/reference/api/path/insop/en.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Path.insop() ---- - -The `Path.insop()` method injects a Path into the [`noop` -operation](/reference/api/path/noop) with id `id`. - -## Signature - -```js -Path path.insop(string id, Path path) -``` - -This method is chainable as it returns the `Path` object - - - -```js -({ Point, points, Path, paths, part }) => { - - points.left = new Point(10,10) - points.dartLeft = new Point(40, 10) - points.dartTip = new Point(50, 50) - points.dartRight = new Point(60, 10) - points.right = new Point(90, 10) - - paths.withoutDart = new Path() - .move(points.left) - .line(points.dartLeft) - .noop('dart') - .line(points.right) - - paths.withDart = paths.withoutDart - .clone() - .insop( - 'dart', - new Path() - .line(points.dartTip) - .line(points.dartRight) - ) - .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') - - return part -} -``` - - -## Notes - -This is often used to insert darts into a path. diff --git a/markdown/dev/reference/api/path/noop/en.md b/markdown/dev/reference/api/path/noop/en.md deleted file mode 100644 index a4b8f349d6b..00000000000 --- a/markdown/dev/reference/api/path/noop/en.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: Path.noop() ---- - -The `Path.noop()` method adds a placeholder path operation. -A `noop` operation does nothing, but is intended to be replaced later -with [`Path.insop()`](/reference/api/path/insop). - -## Signature - -```js -Path path.noop(string id) -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, part }) => { - - points.left = new Point(10,10) - points.dartLeft = new Point(40, 10) - points.dartTip = new Point(50, 50) - points.dartRight = new Point(60, 10) - points.right = new Point(90, 10) - - paths.withoutDart = new Path() - .move(points.left) - .line(points.dartLeft) - .noop('dart') - .line(points.right) - - paths.withDart = paths.withoutDart - .clone() - .insop( - 'dart', - new Path() - .line(points.dartTip) - .line(points.dartRight) - ) - .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/sethidden/en.md b/markdown/dev/reference/api/path/sethidden/en.md deleted file mode 100644 index f5aef358873..00000000000 --- a/markdown/dev/reference/api/path/sethidden/en.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Path.setHidden() ---- - -The `Path.setHidden()` method either hides or unhides the path depending on the -value you pass it. - -## Signature - -```js -Path path.setHidden(bool hidden = false) -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, part }) => { - - points.top = new Point(50, 0) - points.left = new Point (20,50) - points.right = new Point (80,50) - - paths.a = new Path().move(points.top).line(points.right).setText('a') - paths.b = new Path().move(points.right).line(points.left).setText('b').setHidden(true) - paths.c = new Path().move(points.left).line(points.top).setText('c') - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/smurve/en.md b/markdown/dev/reference/api/path/smurve/en.md deleted file mode 100644 index 3ca5367c1e6..00000000000 --- a/markdown/dev/reference/api/path/smurve/en.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Path.smurve() ---- - -The `Path.smurve()` method draws a smooth curve from the current point via a control point to an endpoint. -A smooth curve means it will use the reflection of the end control point of the previous curve. - -## Signature - -```js -Path path.smurve(Point cp2, Point end) -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, part }) => { - - points.aFrom = new Point(10, 10) - points.aCp1 = new Point(40, 40) - points.aCp2 = new Point(70, -20) - points.aTo = new Point(100, 10) - - points.bCp2 = new Point(50,50) - points.bTo = new Point(10,50) - - paths.smurve = new Path() - .move(points.aFrom) - .curve(points.aCp1, points.aCp2,points.aTo) - .smurve(points.bCp2, points.bTo) - .reverse() // Puts text at the end - .setText('Path.smurve()') - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/start/en.md b/markdown/dev/reference/api/path/start/en.md deleted file mode 100644 index f79e2ef085b..00000000000 --- a/markdown/dev/reference/api/path/start/en.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Path.start() ---- - -The `Path.start()` method returns the Point object at the start of the path. - -## Signature - -```js -Point path.start() -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, snippets, Snippet, part }) => { - - points.A = new Point(45, 60) - points.B = new Point(10, 30) - points.BCp2 = new Point(40, 20) - points.C = new Point(90, 30) - points.CCp1 = new Point(50, -30) - - paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - - snippets.end = new Snippet("notch", paths.demo.start()) - - return part -} -``` - diff --git a/markdown/dev/reference/api/path/unhide/en.md b/markdown/dev/reference/api/path/unhide/en.md deleted file mode 100644 index 9ea89dca286..00000000000 --- a/markdown/dev/reference/api/path/unhide/en.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Path.unhide() ---- - -The `Path.unhide()` method unhides the path so it appears in the output. By -default, paths are not hidden. So you should only call this on path previously -hidden via `Path.hide()`. - -## Signature - -```js -Path path.unhide() -``` - -This method is chainable as it returns the `Path` object - -## Example - - -```js -({ Point, points, Path, paths, part }) => { - - points.top = new Point(50, 0) - points.left = new Point (20,50) - points.right = new Point (80,50) - - paths.a = new Path().move(points.top).line(points.right).setText('a') - paths.b = new Path().move(points.right).line(points.left).setText('b').hide().unhide() - paths.c = new Path().move(points.left).line(points.top).setText('c') - - return part -} -``` - diff --git a/markdown/dev/reference/api/point/dist/en.md b/markdown/dev/reference/api/point/dist/en.md deleted file mode 100644 index 54210137b13..00000000000 --- a/markdown/dev/reference/api/point/dist/en.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Point.dist() ---- - -The `Point.dist()` method returns the distance (in mm) between this point and -the point you pass it. - -## Signature - -```js -float point.dist(Point point) -``` - -## Example - - -```js -({ Point, points, Path, paths, units, part }) => { - - points.from = new Point(10, 10) - points.to = new Point(80, 70) - - points.text = points.from - .shiftFractionTowards(points.to, 0.6) - .setText(units(points.from.dist(points.to)), 'text-sm fill-note center') - - paths.line = new Path() - .move(points.from) - .line(points.to) - .setClass('dashed') - - return part -} -``` - diff --git a/markdown/dev/reference/api/stack/generateTransform/en.md b/markdown/dev/reference/api/stack/generateTransform/en.md deleted file mode 100644 index 025c4672d17..00000000000 --- a/markdown/dev/reference/api/stack/generateTransform/en.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Stack.generateTransform() ---- - -The `Stack.generateTransform()` method generates SVG transforms for the stack, -sets them as attributes, and returns the original stack. - - -## Stack.generateTransform() signature - -```js -Stack stack.generateTransforms(Object transforms) -``` - -The `Stack.generateTransforms()` method takes a single argument, -an object with the following properties containing the transforms -to apply: - -| Property | Type |Description | -|----------|------|------------| -| `move` | Object | `move.x` and `move.y` are coordinates to which the stack should be translated -| `rotate` | Number | The number of degrees to rate the stack around its center | -| `flipX` | Boolean | Whether to flip the stack along the X axis | -| `flipY` | Boolean | Whether to flip the stack along the Y axis | - -This method is chainable as it returns the Stack object diff --git a/markdown/dev/reference/api/store/unset/en.md b/markdown/dev/reference/api/store/unset/en.md deleted file mode 100644 index a8ee934e62b..00000000000 --- a/markdown/dev/reference/api/store/unset/en.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Store.unset() ---- - -The `Store.unset()` value removes a `key` from the store. - -## Signature - -```js -Store store.unset(string key) -``` - -This method is chainable as it returns the `Store` object - -## Example - -```js -const store = new Store() - .set('example', 'I will be gone before you know it') - .unset('example') -``` diff --git a/markdown/dev/reference/backend/account/confirm/en.md b/markdown/dev/reference/backend/account/confirm/en.md deleted file mode 100644 index e1c39c4d675..00000000000 --- a/markdown/dev/reference/backend/account/confirm/en.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Confirm an account ---- - -Confirms a newly created User account. -If confirmation is successful this will also result in a (passwordless) sign-in. - -## Endpoints - -Confirming a new User account is possible via this endpoint: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/confirm/signup/:id` | None | - -This endpoint requires no authentication - -## Request URL - -The URL should contain the confirmation ID that was E-mailed to the E-mail -address used for the signup. It replaces the `:id` placeholder in the -[endpoint listed above](#endpoints). - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `consent` | Number | An integer representing the consent given by the user to process their data | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the confirmation was not found | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `token` | String | A JSON web token (JWT) token to authenticate with | -| `account.id` | Number | The ID of the User | -| `account.bio` | String | The bio of the User | -| `account.consent` | Number | The consent given by the User | -| `account.control` | Number | The control desired by the User | -| `account.createdAt` | String | Date string indicating the moment the User was created | -| `account.email` | String | The E-mail address currently tied to the User | -| `account.github` | String | The GitHub username of the User | -| `account.img` | String | The URL to the image stored with this User | -| `account.imperial` | Boolean| Whether or not the User prefers imperial units | -| `account.initial` | String | The E-mail address that the User was created with | -| `account.language` | String | The language preferred by the user | -| `account.lastSignIn`| String | Date string indicating them moment the User last signed in | -| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled | -| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter | -| `account.patron` | Number | The level of patronage the user provides to FreeSewing | -| `account.role` | String | The role of the User | -| `account.status` | Number | The status of the user | -| `account.updatedAt` | String | Date string indicating the last time the User was updated | -| `account.username` | String | The username of the User | -| `account.lusername` | String | A lowercased version of the username of the User | - -## Example request - -```js -const confirm = await axios.post( - 'https://backend.freesewing.org/confirm/signup/3985f312-e407-458a-a78c-4596c361d284', - { consent: 2 }, -) -``` - -## Example response -```200.json -{ - "result": "success", - "token": "eyJhbGciOiJIUzI1NiIsInR5c...truncated", - "account": { - "id": 14, - "bio": "", - "consent": 1, - "control": 1, - "createdAt": "2022-11-19T18:15:22.642Z", - "email": "test_54c6856275aaa8a1@freesewing.dev", - "github": "", - "img": "https://freesewing.org/avatar.svg", - "imperial": false, - "initial": "test_54c6856275aaa8a1@freesewing.dev", - "language": "en", - "lastSignIn": "2022-11-19T18:15:22.668Z", - "mfaEnabled": false, - "newsletter": false, - "patron": 0, - "role": "user", - "status": 1, - "updatedAt": "2022-11-19T18:15:22.668Z", - "username": "user-14", - "lusername": "user-14" - } -} -``` - -[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme diff --git a/markdown/dev/reference/backend/account/create/en.md b/markdown/dev/reference/backend/account/create/en.md deleted file mode 100644 index 1ae884282f7..00000000000 --- a/markdown/dev/reference/backend/account/create/en.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Create an account ---- - -Creates a new User account. The User account will remain inactive -until [it is confirmed](/reference/backend/account/confirm). - -## Endpoints - -Creating a new User account is possible via this endpoint: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/signup` | None | - -This endpoint requires no authentication - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `email` | `string` | The E-mail address of the User | -| `language` | `boolean`| The language code for the User | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `email` | String | The E-mail address where the confirmation email was sent to | - -## Example request - -```js -const signup = await axios.post( - 'https://backend.freesewing.org/signup', - { - email: "joost@joost.at", - language: "en" - } -) -``` - -## Example response -```201.json -{ - "result": "success", - "email": "joost@joost.at" -} -``` diff --git a/markdown/dev/reference/backend/account/en.md b/markdown/dev/reference/backend/account/en.md deleted file mode 100644 index 8f8ba4ec505..00000000000 --- a/markdown/dev/reference/backend/account/en.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: Account ---- - -From an end-user's point of view, their account holds all of their data. From -an API point of view, these endpoints deal with data in the User table. - -As the endpoints typically use `/account` we tend to use _account_ more often -than _user_. - -## Endpoints - - - -## Notes - -### The `consent` field is about data protection - -The `consent` field holds a number indicating to which level the user has -agreed to the processing of their data: - -- `0` : No consent given (yet) -- `1` : Consent given for processing profile data -- `2` : Consent given for processing profile & people data -- `3` : Consent given for processing profile & people data, and for publishing - anonymized measurements as open data - -Providing a consent value (that is higher than `0`) is a requirement for -confirming a User account. In other words, without sufficient consent, you -can't sign up. - -### The `control` field is about keeping it simple - -The `control` field holds a number indicating to which level the user wants to -be in control of the FreeSewing platform. It was added as a way to allow for -progressive disclosure of (more) advanced features and settings on the -FreeSewing website. - -Possible values are: - -- `1` : Hide all but the most crucial features. Make it as simple as possible. -- `2` : Hide the majority of features. Make it simple, but not too much. -- `3` : Reveal the majority of features, but not all. Balance simplicity with - power. -- `4` : Reveal everything, but keep handrails and safety checks. Only intervene - when I'm about to do something dangerous. -- `5` : Reveal everything, remove the handrails and safety checks. Get out of - my way, I know what I'm doing. - -### The `ihash` and `ehash` fields are for search - -Because we encrypt a lot of data at rest, it can be difficult for support or -administrators to find users when they don't know or remember their username -because we cannot search on their E-mail address since that data is encrypted. - -That is why we store a hash of the (lowercased) email address. This way, we can -hash the email provided to us, and search the hash instead. - -The `ehash` and `ihash` fields hold the hash for the `email` and `initial` -fields. - -### The `imperial` property is a Boolean - -If the `imperial` property is `false`, the user wants metric units. - -If the `imperial` property is `true`, the user wants imperial units. - -### The `initial` field guards against account takeover - -The `initial` field will be set to the E-mail address the account was -registered with. It can never be changed. - -This ensures that when there's an account takeover dispute, we can always know -what E-mail address was used to create the account, even if the E-mail address -associated with the account was changed. - -### The `lusername` field should be unique - -For the backend users `Joost` and `joost` are -- strictly speaking -- two -different users. This tends to lead to confusion and possible impersonation. -So we enforce uniqueness on the `lusername` field which holds a lowercased -version of the `username` field.. - -In other words, lowercased username must be unique. - -### The `status` field holds the account status - -Possible values are: - -- `0` : The account is not active (yet) -- `1` : The account is active -- `-1` : The account was disabled by the user -- `-2` : The account was administratively disabled - diff --git a/markdown/dev/reference/backend/account/mfa/en.md b/markdown/dev/reference/backend/account/mfa/en.md deleted file mode 100644 index 0b2067d56a7..00000000000 --- a/markdown/dev/reference/backend/account/mfa/en.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: MFA ---- - -Enable of disable Multi-Factor Authentication (MFA) on the User account. - -- [Setup MFA](#setup-mfa) -- [Confirm MFA](#confirm-mfa) -- [Disable MFA](#disable-mfa) - -## Endpoints - -Enabling, confirming, and disabling MFA is all possible via this endpoint: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/account/mfa/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/account/mfa/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Setup MFA - -### Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `mfa` | `boolean`| Set to `true` to enable MFA | - -### Response status codes - -Possible status codes for this endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | authentication failed | -| | access denied | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -### Response body - -| Value | Type | Description | -| -------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `mfa.secret` | String | The shared secret for generating one-time password (OTP) tokens | -| `mfa.otpauth` | String | The OTP Auth URI that is encoded in the QR code | -| `mfa.qrcode` | String | SVG to display a QR code with the otpauth URI encoded | - - -##### Styling the SVG -The SVG returned by the backend uses `currentColor` for the QR code, so you can -style it with CSS if you embed it in the page. - - -### Example request - -```js -const mfa = await axios.post( - 'https://backend.freesewing.org/account/mfa/jwt', - { mfa: true }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -### Example response -```200.json -{ - "result": "success", - "mfa": { - "secret": "KBTSKUKRDJPEGCZK", - "otpauth": "otpauth://totp/FreeSewing:user-294?secret=KBTSKUKRDJPEGCZK&period=30&digits=6&algorithm=SHA1&issuer=FreeSewing", - "qrcode": "\n" - } -} -``` - -## Confirm MFA - -To confirm the MFA, we need to provide an MFA token to ensure the user can -generate them. - -### Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `mfa` | `boolean`| Must be set to `true` to confirm MFA | -| `secret` | `boolean`| The secret returned when setting up MFA | -| `token` | `boolean`| Must be set to `true` to confirm MFA | - -### Response status codes - -Possible status codes for this endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | authentication failed | -| | access denied | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -### Response body - -| Value | Type | Description | -| -------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | - -### Example request - -```js -import { authenticator } from '@otplib/preset-default' - -const confirm = await axios.post( - 'https://backend.freesewing.org/account/mfa/jwt', - { - mfa: true, - secret: mfa.secret, - token: authenticator.generate(mfa.secret) - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -### Example response - -```200.json -{ - "result": "success", -} -``` -## Disable MFA - -To disable MFA, you need to provide both the account password and a valid token. - -### Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `mfa` | `boolean`| Must be set to `false` to disable MFA | -| `password` | `boolean`| The User's password | -| `token` | `boolean`| Must be set to `true` to confirm MFA | - -### Response status codes - -Possible status codes for this endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | authentication failed | -| | access denied | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -### Response body - -| Value | Type | Description | -| -------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | - -### Example request - -```js -import { authenticator } from '@otplib/preset-default' - -const confirm = await axios.post( - 'https://backend.freesewing.org/account/mfa/jwt', - { - mfa: false, - password: "I like big bewbs and I just can't lie", - token: authenticator.generate(mfa.secret) - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -### Example response - -```200.json -{ - "result": "success", -} -``` diff --git a/markdown/dev/reference/backend/account/signin/en.md b/markdown/dev/reference/backend/account/signin/en.md deleted file mode 100644 index f1ae7c68b1a..00000000000 --- a/markdown/dev/reference/backend/account/signin/en.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Sign In ---- - -Sign in as a User with username and password, and optional MFA token. - -## Endpoints - -Password-based sign-in is possible via this endpoint: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/signin` | None | - -This endpoint requires no authentication - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `username` | `string` | The E-mail address of the User | -| `password` | `boolean`| The language code for the User | -| `token` | `boolean`| The MFA token | - -An MFA token is required (only) when the User enabled MFA - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | authentication failed | -| | MFA token missing | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `token` | String | A JSON web token (JWT) token to authenticate with | -| `account.id` | Number | The ID of the User | -| `account.bio` | String | The bio of the User | -| `account.consent` | Number | The consent given by the User | -| `account.control` | Number | The control desired by the User | -| `account.createdAt` | String | Date string indicating the moment the User was created | -| `account.email` | String | The E-mail address currently tied to the User | -| `account.github` | String | The GitHub username of the User | -| `account.img` | String | The URL to the image stored with this User | -| `account.imperial` | Boolean| Whether or not the User prefers imperial units | -| `account.initial` | String | The E-mail address that the User was created with | -| `account.language` | String | The language preferred by the user | -| `account.lastSignIn`| String | Date string indicating them moment the User last signed in | -| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled | -| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter | -| `account.patron` | Number | The level of patronage the user provides to FreeSewing | -| `account.role` | String | The role of the User | -| `account.status` | Number | The status of the user | -| `account.updatedAt` | String | Date string indicating the last time the User was updated | -| `account.username` | String | The username of the User | -| `account.lusername` | String | A lowercased version of the username of the User | - -## Example request - -```js -const signup = await axios.post( - 'https://backend.freesewing.org/signup', - { - username: "jimmy", - language: "I like big bewbs and I just can't lie", - token: 231586 - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "token": "eyJhbGciOiJIUzI1NiIsInR5c...truncated", - "account": { - "id": 14, - "bio": "", - "consent": 1, - "control": 1, - "createdAt": "2022-11-19T18:15:22.642Z", - "email": "test_54c6856275aaa8a1@freesewing.dev", - "github": "", - "img": "https://freesewing.org/avatar.svg", - "imperial": false, - "initial": "test_54c6856275aaa8a1@freesewing.dev", - "language": "en", - "lastSignIn": "2022-11-19T18:15:22.668Z", - "mfaEnabled": false, - "newsletter": false, - "patron": 0, - "role": "user", - "status": 1, - "updatedAt": "2022-11-19T18:15:22.668Z", - "username": "jimmy", - "lusername": "jimmy" - } -} -``` diff --git a/markdown/dev/reference/backend/account/update/en.md b/markdown/dev/reference/backend/account/update/en.md deleted file mode 100644 index e216d9d38b0..00000000000 --- a/markdown/dev/reference/backend/account/update/en.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: Update account ---- - -Updates an existing User account. - -## Access control - -- [Permission level](/reference/backend/rbac) `4` or higher is required to update your own User account -- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** account - -## Endpoints - -Updating an existing User account is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/account/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/account/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `bio` | `string` | The User's bio | -| `consent` | `string` | A number that indicates [the consent given by the user](/reference/backend/account#the-consent-field-is-about-data-protection) | -| `control` | `string` | A number that indicates [the level of control the user prefers](/reference/backend/account#the-control-field-is-about-keeping-it-simple) | -| `github` | `string` | The User's username on GitHub | -| `imperial` | `boolean`| Whether or not the User prefers imperial units | -| `newsletter`| `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) | -| `img` | `string` | An image [data-uri][duri] to store with this Person | -| `password` | `string` | The (new) password for the User | -| `username` | `string` | The (new) username for the User | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `account.id` | Number | The ID of the User | -| `account.bio` | String | The bio of the User | -| `account.consent` | Number | The consent given by the User | -| `account.control` | Number | The control desired by the User | -| `account.createdAt` | String | Date string indicating the moment the User was created | -| `account.email` | String | The E-mail address currently tied to the User | -| `account.github` | String | The GitHub username of the User | -| `account.img` | String | The URL to the image stored with this User | -| `account.imperial` | Boolean| Whether or not the User prefers imperial units | -| `account.initial` | String | The E-mail address that the User was created with | -| `account.language` | String | The language preferred by the user | -| `account.lastSignIn`| String | Date string indicating them moment the User last signed in | -| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled | -| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter | -| `account.patron` | Number | The level of patronage the user provides to FreeSewing | -| `account.role` | String | The role of the User | -| `account.status` | Number | The status of the user | -| `account.updatedAt` | String | Date string indicating the last time the User was updated | -| `account.username` | String | The username of the User | -| `account.lusername` | String | A lowercased version of the username of the User | - -## Example request - -```js -const udpate = await axios.put( - 'https://backend.freesewing.org/account/jwt', - { - bio: "I like imperial now", - imperial: true, - username: "ImperialLover" - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "account": { - "id": 14, - "bio": "I like imperial now", - "consent": 1, - "control": 1, - "createdAt": "2022-11-19T18:15:22.642Z", - "email": "test_54c6856275aaa8a1@freesewing.dev", - "github": "", - "img": "https://freesewing.org/avatar.svg", - "imperial": true, - "initial": "test_54c6856275aaa8a1@freesewing.dev", - "language": "en", - "lastSignIn": "2022-11-19T18:15:22.668Z", - "mfaEnabled": false, - "newsletter": false, - "patron": 0, - "role": "user", - "status": 1, - "updatedAt": "2022-11-19T18:15:22.668Z", - "username": "ImperialLover", - "lusername": "imperiallover" - } -} -``` - -[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme diff --git a/markdown/dev/reference/backend/apikeys/create/en.md b/markdown/dev/reference/backend/apikeys/create/en.md deleted file mode 100644 index abcd26f0a27..00000000000 --- a/markdown/dev/reference/backend/apikeys/create/en.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Create an API key ---- - -Creates a new API key. An API key can be used to authenticate against the -backend API. - -## Access control - -- [Permission level](/reference/backend/rbac) `4` or higher is required to create an API key - -## Endpoints - -Creating a new API key is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/apikeys/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/apikeys/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `name` | `string` | A name for the API key | -| `level` | `number` | A privilege level from 0 to 8. | -| `expiresIn` | `number` | The number of seconds until the API key expires | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - - -##### Make sure to save the secret -The response body is the only time the API key's secret will be revealed. - - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | `string` | Either `success` or `error` | -| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. | -| `apikey.key` | `string` | The API key | -| `apikey.secret` | `string` | The API secret | -| `apikey.level` | `number` | The privilege level of the API key | -| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires | -| `apikey.name` | `string` | The name of the API key | -| `apikey.userId` | `number` | The ID of the user who created the API key | - - - -## Example request - -```js -const apiKey = axios.post( - 'https://backend.freesewing.org/apikeys/jwt', - { - name: 'My first API key', - level: 2, // Read only - expiresIn: 3600, // One hour - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```201.json -{ - "result": "success", - "apikey": { - "key": "7ea12968-7758-40b6-8c73-75cc99be762b", - "secret": "503d7adbdb3ec18ab27adfcd895d8b47a8d6bc8307d548500fbf9c05a5a8820e", - "level": 3, - "expiresAt": "2022-11-06T15:57:30.190Z", - "name": "My first API key", - "userId": 61 - } -} -``` diff --git a/markdown/dev/reference/backend/apikeys/delete/en.md b/markdown/dev/reference/backend/apikeys/delete/en.md deleted file mode 100644 index 02b95146e9a..00000000000 --- a/markdown/dev/reference/backend/apikeys/delete/en.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Delete an API key ---- - -Deletes an existing API key. - -## Access control - -- [Permission level](/reference/backend/rbac) `4` or higher is required to delete an API key - -## Endpoints - -Deleting an API key is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/apikeys/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/apikeys/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the API key you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - -## Example request - -```js -await axios.delete( - 'https://backend.freesewing.org/apikeys/7ea12968-7758-40b6-8c73-75cc99be762b/jwt', - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response - -```204.json -``` - -These endpoints return status code (no content) on -success, with no response body. - - diff --git a/markdown/dev/reference/backend/apikeys/en.md b/markdown/dev/reference/backend/apikeys/en.md deleted file mode 100644 index 745e3b54f49..00000000000 --- a/markdown/dev/reference/backend/apikeys/en.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: API Keys ---- - -API keys are a way to authenticate to the API with basic authentication. -They are intended to be used when interacting with the API in an automated -way such as from a script or a CI/CD pipeline. - -They are an alternative to JSON Web Tokens (JWT) which is typically used -to authenticate users in a browser session. - -The FreeSewing backend REST API supports authentication both with JSON Web -Tokens (JWT) as with API keys (KEY). This describes the endpoints that deal -with creating, reading, and removing API keys. For authentication details, -refer to [the section on -authenticating](/reference/backend/authentication). - -## Endpoints - - - -## Notes - -The following is good to keep in mind when working with API keys: - -### API keys are immutable - -Once created, API keys cannot be updated. -You should remove them and re-create a new one if you want to make a change. - -### API keys have an expiry - -API keys have an expiry date. The maximum validity for an API key is 1 year. - -### API keys have a permission level - -API keys have a permission level. You can never create an API key with a higher -permission level than your own permission level. - -### Circumstances that will trigger your API keys to be revoked - -As a precaution, all your API keys will be revoked when: - -- Your role is downgraded to a role with fewer privileges -- Your account is (b)locked -- You revoke your consent for FreeSewing to process your data - - -This is not an exhaustive list. For example, if we find your use of our API to -be excessive, we might also revoke your API keys to shield us from the -financial impact of your use of our API. - - diff --git a/markdown/dev/reference/backend/apikeys/read/en.md b/markdown/dev/reference/backend/apikeys/read/en.md deleted file mode 100644 index de6cc862fc1..00000000000 --- a/markdown/dev/reference/backend/apikeys/read/en.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Read an API key ---- - -Reads an existing API key. Note that the API secret can only be retrieved at -the moment the API key is created. - -## Access control - -- [Permission level](/reference/backend/rbac) `4` or higher is required to read an API key - -## Endpoints - -Reading an API key is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/apikeys/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/apikeys/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the API key you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | API key not found | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | `string` | `success` on success, and `error` on error | -| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. | -| `apikey.key` | `string` | The API key | -| `apikey.level` | `number` | The privilege level of the API key | -| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires | -| `apikey.name` | `string` | The name of the API key | -| `apikey.userId` | `number` | The ID of the user who created the API key | - -## Example request - -```js -const keyInfo = await axios.get( - 'https://backend.freesewing.org/apikeys/7ea12968-7758-40b6-8c73-75cc99be762b/jwt', - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "apikey": { - "key": "7ea12968-7758-40b6-8c73-75cc99be762b", - "level": 3, - "expiresAt": "2022-11-06T15:57:30.190Z", - "name": "My first API key", - "userId": 61 - } -} -``` diff --git a/markdown/dev/reference/backend/apikeys/whoami/en.md b/markdown/dev/reference/backend/apikeys/whoami/en.md deleted file mode 100644 index 541bb72b847..00000000000 --- a/markdown/dev/reference/backend/apikeys/whoami/en.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Read the current API key ---- - -Reads the current API key used to authenticate the request. -For obvious reasons, this endpoint is only available with API key authentication. -However, there's an equivalent endpoint for JWT authentication. - -## Access control - -- [Permission level](/reference/backend/rbac) `0` or higher is required to read the current API key - -## Endpoints - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/whoami/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | `string` | `success` on success, and `error` on error | -| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. | -| `apikey.key` | `string` | The API key | -| `apikey.level` | `number` | The privilege level of the API key | -| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires | -| `apikey.name` | `string` | The name of the API key | -| `apikey.userId` | `number` | The ID of the user who created the API key | - -## Example request - -```js -const keyInfo = await axios.get( - 'https://backend.freesewing.org/whoami/key', - { - auth: { - username: apikey.key, - password: apikey.secret, - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "apikey": { - "key": "7ea12968-7758-40b6-8c73-75cc99be762b", - "level": 3, - "expiresAt": "2022-11-06T15:57:30.190Z", - "name": "My first API key", - "userId": 61 - } -} diff --git a/markdown/dev/reference/backend/authentication/en.md b/markdown/dev/reference/backend/authentication/en.md deleted file mode 100644 index 951fbf1fc7c..00000000000 --- a/markdown/dev/reference/backend/authentication/en.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Authentication ---- - -The FreeSewing backend API requires authentication for all but a handful of -endpoints. - -The API supports two different types of authentication: - -| Type | Name | Description | -| ---- | ---- | ----------- | -| [JSON Web Tokens](#jwt-authentication) | `jwt` | This is typically used to authenticate humans in a browser session. | -| [API Keys](#key-authentication) | `key` | This is typically used to interact with the API in an automated way. Like in a script, a CI/CD context, a serverless runner, and so on. | - -While the API supports both, they are not supported on the same endpoint. -Instead, add the authentication type you want to use as the final part of -endpoint: - -- `/some/endpoint/jwt` : Authenticate with a JSON Web Token -- `/some/endpoint/key` : Authenticate with an API key and secret - -## `jwt` authentication - -The use of JSON Web Tokens ([jwt](https://jwt.io)) is typically used in a -browser context where we want to establish a *session*. - -To get a token, you must first authenticate at the [`/signin`](/reference/backend/account/signin) endpoint. -You will receive a JSON Web Token (jwt) as part of the response. - -In subsequent API calls, you must then include this token in the -`Authorization` header prefixed by `Bearer `. Like his: - -```js -const account = await axios.get( - `https://backend.freesewing.org/account/jwt`, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## `key` authentication - -The combination of API key & secret serves as a username & password for [HTTP -basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). - - -In basic authentication, the password is sent -unencrypted. To guard against this, this API should only be served over a -connection that is encrypted with TLS. (a URL starting with `https://`). - - -Sending a username and password with a request like this is supported -pretty much everywhere. In addition, there is no need to establish a session -first, so this make the entire transaction stateless. - -Below is an example using curl: - -```sh -curl -u api-key-here:api-secret-here \ - https://backend.freesewing.org/account/key -``` diff --git a/markdown/dev/reference/backend/patterns/clone/en.md b/markdown/dev/reference/backend/patterns/clone/en.md deleted file mode 100644 index 2be6b6a9f4d..00000000000 --- a/markdown/dev/reference/backend/patterns/clone/en.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: Clone a Pattern ---- - -Create a new Pattern by cloning an existing one. - -## Access control - -The [Permission level](/reference/backend/rbac) required to clone a -Pattern depends on: - -- Whether the Pattern is `public` -- Who created the Pattern - -The details are outlined in the table below: - -| | Public Patterns | Non-Public Patterns | -| ---------------: | :-------------: | :-----------------: | -| **Your own** | `0` or higher | `3` or higher | -| **Other user's** | `0` or higher | `5` or higher | - -## Endpoints - -Creating a new Person is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/patterns/:id/clone/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/patterns/:id/clone/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the Pattern you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `pattern.id` | Number | The ID of the Pattern | -| `pattern.createdAt` | String | Date string indicating the moment the pattern was created | -| `pattern.data` | Object | Any additional data that was stored with Pattern data | -| `pattern.design` | String | The name of the design of which this Pattern is an instance | -| `pattern.img` | String | The URL to the image stored with this Pattern | -| `pattern.name` | String | The name of the Pattern | -| `pattern.notes` | String | The notes stored with the Pattern | -| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created | -| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not | -| `pattern.settings` | Object | The settings used to (re-)create the Pattern | -| `pattern.userId` | Number | The ID of the user who created the Pattern | -| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated | - -## Example request - -```js -const clone = axios.post( - 'https://backend.freesewing.org/patterns/10/clone/jwt', - null, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "pattern": { - "id": 19, - "createdAt": "2022-11-19T16:29:33.346Z", - "data": { - "some": "value" - }, - "design": "aaron", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "name": "Just a test", - "notes": "These are my notes", - "personId": 17, - "public": true, - "settings": { - "sa": 5 - }, - "userId": 10, - "updatedAt": "2022-11-19T16:29:33.346Z" - } -} -``` diff --git a/markdown/dev/reference/backend/patterns/create/en.md b/markdown/dev/reference/backend/patterns/create/en.md deleted file mode 100644 index fb621cf0647..00000000000 --- a/markdown/dev/reference/backend/patterns/create/en.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Create a Pattern ---- - -Creates a new Pattern. This is typically used when users choose to save a pattern. - -## Access control - -- [Permission level](/reference/backend/rbac) `3` or higher is required to create a Pattern - -## Endpoints - -Creating a new Pattern is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/patterns/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/patterns/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request body -The request body is a JSON object with the following properties: - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `data` | `object` | Any additional data to store with the pattern | -| `design` | `string` | The name of the design this Pattern is an instance of | -| `img` | `object` | An image [data-uri][duri] to store with this Pattern | -| `name` | `string` | A name for the Pattern | -| `notes` | `string` | User notes for the pattern | -| `person` | `object` | The ID of the person to associate with this pattern | -| `settings` | `object` | The settings object to (re-)create the Pattern | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `pattern.id` | Number | The ID of the Pattern | -| `pattern.createdAt` | String | Date string indicating the moment the pattern was created | -| `pattern.data` | Object | Any additional data that was stored with Pattern data | -| `pattern.design` | String | The name of the design of which this Pattern is an instance | -| `pattern.img` | String | The URL to the image stored with this Pattern | -| `pattern.name` | String | The name of the Pattern | -| `pattern.notes` | String | The notes stored with the Pattern | -| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created | -| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not | -| `pattern.settings` | Object | The settings used to (re-)create the Pattern | -| `pattern.userId` | Number | The ID of the user who created the Pattern | -| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated | - -## Example request - -```js -const pattern = await axios.post( - 'https://backend.freesewing.org/patterns/jwt', - { - data: { - some: 'value', - } - design: "aaron", - img: "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...truncated", - name: "Just a test", - notes: "These are my notes", - person: 17, - public: true, - settings: { - sa: 5, - }, - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```201.json -{ - "result": "success", - "pattern": { - "id": 10, - "createdAt": "2022-11-19T16:29:33.346Z", - "data": { - "some": "value" - }, - "design": "aaron", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "name": "Just a test", - "notes": "These are my notes", - "personId": 17, - "public": true, - "settings": { - "sa": 5 - }, - "userId": 10, - "updatedAt": "2022-11-19T16:29:35.023Z" - } -} -``` - -[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme diff --git a/markdown/dev/reference/backend/patterns/delete/en.md b/markdown/dev/reference/backend/patterns/delete/en.md deleted file mode 100644 index 40daa793aed..00000000000 --- a/markdown/dev/reference/backend/patterns/delete/en.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Delete a Pattern ---- - -Deletes an existing Pattern. - -## Access control - -- [Permission level](/reference/backend/rbac) `3` or higher is required to delete a Pattern -- [Permission level](/reference/backend/rbac) `8` is required to delete **another user's** Pattern - -## Endpoints - -Deleting a Pattern is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the Pattern you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - -## Example request - -```js -await axios.delete( - 'https://backend.freesewing.org/patterns/10/jwt', - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response - -```204.json -``` - -These endpoints return status code (no content) on -success, with no response body. - diff --git a/markdown/dev/reference/backend/patterns/en.md b/markdown/dev/reference/backend/patterns/en.md deleted file mode 100644 index e63b1e73280..00000000000 --- a/markdown/dev/reference/backend/patterns/en.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Patterns ---- - -Patterns hold information on and settings for a user's patterns. - -## Endpoints - - - -## Notes - -### The `design` property should hold the design - -The `design` property should hold the name of the FreeSewing design. -For example, `aaron`. - -### The `notes` vs `data` properties - -Both the `data` and `notes` properties can hold additional information about -the pattern. - -Keep in mind that: -- The `notes` property is intended to be used by the user to add notes about - their pattern. It will only accept data of type `string`. -- The `data` property is intended to allow frontend developers to store - additional data about the pattern. It will only accept data of type `object`. - -### The `settings` property should hold the pattern settings - -The `settings` property should hold [a settings object](/reference/settings) -that can be passed to [the Pattern -constructor](/reference/api/pattern#creating-a-pattern). diff --git a/markdown/dev/reference/backend/patterns/read/en.md b/markdown/dev/reference/backend/patterns/read/en.md deleted file mode 100644 index 17c168aef2b..00000000000 --- a/markdown/dev/reference/backend/patterns/read/en.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: Read a Pattern ---- - -Reads an existing Pattern. - -## Access control - -The [Permission level](/reference/backend/rbac) required to read a -Pattern depends on: - -- Whether the Pattern is `public` -- Who created the Pattern - -The details are outlined in the table below: - -| | Public Patterns | Non-Public Patterns | -| ---------------: | :-------------: | :-----------------: | -| **Your own** | `0` or higher | `1` or higher | -| **Other user's** | `0` or higher | `5` or higher | - -## Endpoints - -Reading a Pattern is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the Pattern you wish to read. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | API key not found | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `pattern.id` | Number | The ID of the Pattern | -| `pattern.createdAt` | String | Date string indicating the moment the pattern was created | -| `pattern.data` | Object | Any additional data that was stored with Pattern data | -| `pattern.design` | String | The name of the design of which this Pattern is an instance | -| `pattern.img` | String | The URL to the image stored with this Pattern | -| `pattern.name` | String | The name of the Pattern | -| `pattern.notes` | String | The notes stored with the Pattern | -| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created | -| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not | -| `pattern.settings` | Object | The settings used to (re-)create the Pattern | -| `pattern.userId` | Number | The ID of the user who created the Pattern | -| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated | - -## Example request - -```js -const pattern = await axios.get( - 'https://backend.freesewing.org/patterns/10/jwt', - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "pattern": { - "id": 10, - "createdAt": "2022-11-19T16:29:33.346Z", - "data": { - "some": "value" - }, - "design": "aaron", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "name": "Just a test", - "notes": "These are my notes", - "personId": 17, - "public": true, - "settings": { - "sa": 5 - }, - "userId": 10, - "updatedAt": "2022-11-19T16:29:35.023Z" - } -} -``` diff --git a/markdown/dev/reference/backend/patterns/update/en.md b/markdown/dev/reference/backend/patterns/update/en.md deleted file mode 100644 index 349dce70486..00000000000 --- a/markdown/dev/reference/backend/patterns/update/en.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Update a Pattern ---- - -Updates an existing Pattern. - -## Access control - -- [Permission level](/reference/backend/rbac) `3` or higher is required to update a Pattern -- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** Pattern - -## Endpoints - -Updating an existing Pattern is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the Pattern you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `data` | `object` | Any additional data to store with the pattern | -| `design` | `string` | The name of the design this Pattern is an instance of | -| `img` | `object` | An image [data-uri][duri] to store with this Pattern | -| `name` | `string` | A name for the Pattern | -| `notes` | `string` | User notes for the pattern | -| `person` | `object` | The ID of the person to associate with this pattern | -| `settings` | `object` | The settings object to (re-)create the Pattern | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `pattern.id` | Number | The ID of the Pattern | -| `pattern.createdAt` | String | Date string indicating the moment the pattern was created | -| `pattern.data` | Object | Any additional data that was stored with Pattern data | -| `pattern.design` | String | The name of the design of which this Pattern is an instance | -| `pattern.img` | String | The URL to the image stored with this Pattern | -| `pattern.name` | String | The name of the Pattern | -| `pattern.notes` | String | The notes stored with the Pattern | -| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created | -| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not | -| `pattern.settings` | Object | The settings used to (re-)create the Pattern | -| `pattern.userId` | Number | The ID of the user who created the Pattern | -| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated | - -## Example request - -```js -const udpate = await axios.put( - 'https://backend.freesewing.org/patterns/10/jwt', - { - data: { - some: 'new value', - } - public: false, - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "pattern": { - "id": 10, - "createdAt": "2022-11-19T16:29:33.346Z", - "data": { - "some": "new value" - }, - "design": "aaron", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "name": "Just a test", - "notes": "These are my notes", - "personId": 17, - "public": false, - "settings": { - "sa": 5 - }, - "userId": 10, - "updatedAt": "2022-11-19T16:43:39.223Z" - } -} -``` - -[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme diff --git a/markdown/dev/reference/backend/people/clone/en.md b/markdown/dev/reference/backend/people/clone/en.md deleted file mode 100644 index 7d46cdeb516..00000000000 --- a/markdown/dev/reference/backend/people/clone/en.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Clone a Person ---- - -Create a new Person by cloning an existing one. - -## Access control - -The [Permission level](/reference/backend/rbac) required to clone a -Person depends on: - -- Whether the Person is `public` -- Who created the Pattern - -The details are outlined in the table below: - -| | Public Patterns | Non-Public Patterns | -| ---------------: | :-------------: | :-----------------: | -| **Your own** | `0` or higher | `3` or higher | -| **Other user's** | `0` or higher | `5` or higher | - -## Endpoints - -Creating a new Person is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/people/:id/clone/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/people/:id/clone/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the Person you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `person.id` | Number | The ID of the Person | -| `person.createdAt` | String | Date string indicating the moment the Person was created | -| `person.img` | String | The URL to the image stored with this Person | -| `person.name` | String | The name of the Person | -| `person.notes` | String | The notes stored with the Person | -| `person.userId` | Number | The ID of the user who created the Person | -| `person.measies` | Object | The measurements of the Person | -| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not | -| `person.updatedAt` | String | Date string indicating the last time the Person was updated | - -## Example request - -```js -const clone = axios.post( - 'https://backend.freesewing.org/people/27/clone/jwt', - null, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "person": { - "id": 32, - "createdAt": "2022-11-19T17:36:41.342Z", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "imperial": false, - "name": "Someone", - "notes": "These are some notes", - "userId": 12, - "measies": { - "chest": 930, - "neck": 360 - }, - "public": true, - "updatedAt": "2022-11-19T17:36:41.342Z" - } -} -``` diff --git a/markdown/dev/reference/backend/people/create/en.md b/markdown/dev/reference/backend/people/create/en.md deleted file mode 100644 index d4dae9c4dcf..00000000000 --- a/markdown/dev/reference/backend/people/create/en.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Create a Person ---- - -Creates a new Person. - -## Access control - -- [Permission level](/reference/backend/rbac) `3` or higher is required to create a Person - -## Endpoints - -Creating a new Person is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/people/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/people/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `img` | `string` | An image [data-uri][duri] to store with this Person | -| `imperial` | `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) | -| `name` | `string` | A name for the Person | -| `notes` | `string` | User notes for the person | -| `measies` | `object` | The measurements for this person | -| `public` | `string` | The name of the design this Pattern is an instance of | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `person.id` | Number | The ID of the Person | -| `person.createdAt` | String | Date string indicating the moment the Person was created | -| `person.img` | String | The URL to the image stored with this Person | -| `person.name` | String | The name of the Person | -| `person.notes` | String | The notes stored with the Person | -| `person.userId` | Number | The ID of the user who created the Person | -| `person.measies` | Object | The measurements of the Person | -| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not | -| `person.updatedAt` | String | Date string indicating the last time the Person was updated | - -## Example request - -```js -const person = await axios.post( - 'https://backend.freesewing.org/people/jwt', - { - name: "Someone", - notes: "These are some notes", - measies: { - "chest": 930, - "neck": 360 - }, - public: true, - imperial: false, - img: "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...truncated" - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```201.json -{ - "result": "success", - "person": { - "id": 27, - "createdAt": "2022-11-19T17:36:41.342Z", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "imperial": false, - "name": "Someone", - "notes": "These are some notes", - "userId": 12, - "measies": { - "chest": 930, - "neck": 360 - }, - "public": true, - "updatedAt": "2022-11-19T17:36:41.342Z" - } -} -``` - -[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme diff --git a/markdown/dev/reference/backend/people/delete/en.md b/markdown/dev/reference/backend/people/delete/en.md deleted file mode 100644 index 0c687dc54ea..00000000000 --- a/markdown/dev/reference/backend/people/delete/en.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Delete a Person ---- - -Deletes an existing Person. - -## Access control - -- [Permission level](/reference/backend/rbac) `3` or higher is required to delete a Person -- [Permission level](/reference/backend/rbac) `8` is required to delete **another user's** Person - -## Endpoints - -Deleting a Person is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the Person you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - -## Example request - -```js -await axios.delete( - 'https://backend.freesewing.org/people/27/jwt', - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response - -```204.json -``` - -These endpoints return status code (no content) on -success, with no response body. - diff --git a/markdown/dev/reference/backend/people/en.md b/markdown/dev/reference/backend/people/en.md deleted file mode 100644 index 429e72b2ac1..00000000000 --- a/markdown/dev/reference/backend/people/en.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: People ---- - -A Person hold information and measurements on the people we generate patterns -for. - -## Endpoints - - - -## Notes - -### The `imperial` property is a Boolean - -- If the `imperial` property is `false`, the person wants metric units. -- If the `imperial` property is `true`, the person wants imperial units. - -### The `measies` property holds measurements - -These measurements should be structured as an object that can be used for the -`measurements` key in the [pattern settings -object](/reference/settings/measurements). - -The backend will only accept known measurements listed in the configuration file. - - -##### Why we use measies instead of measurements -First of all, _measies_ is a cute and adorable alternative for _measurements_ -coined by Karen. She deserves all the credit. - -But also, I am slightly dyslexic and for some reason, I often drop the middle -_e_ when typing measurements' (sic). - -Those typos lead to bugs and I find it much easier to write _measies_. -So because fewer bugs, plus did I mention it's cute? - - - -### The `settings` property should hold the pattern settings - -The `settings` property should hold [a settings object](/reference/settings) -that can be passed to [the Pattern -constructor](/reference/api/pattern#creating-a-pattern). diff --git a/markdown/dev/reference/backend/people/read/en.md b/markdown/dev/reference/backend/people/read/en.md deleted file mode 100644 index 2954b3c2ff9..00000000000 --- a/markdown/dev/reference/backend/people/read/en.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Read a Person ---- - -Reads an existing Person. - -## Access control - -The [Permission level](/reference/backend/rbac) required to read a -Person depends on: - -- Whether the Person is `public` -- Who created the Person - -The details are outlined in the table below: - -| | Public People | Non-Public People | -| ---------------: | :-------------: | :-----------------: | -| **Your own** | `0` or higher | `4` or higher | -| **Other user's** | `0` or higher | `5` or higher | - -## Endpoints - -Reading a Person is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request url - -The url should contain the ID of the Person you wish to read. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | API key not found | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `person.id` | Number | The ID of the Person | -| `person.createdAt` | String | Date string indicating the moment the Person was created | -| `person.img` | String | The URL to the image stored with this Person | -| `person.name` | String | The name of the Person | -| `person.notes` | String | The notes stored with the Person | -| `person.userId` | Number | The ID of the user who created the Person | -| `person.measies` | Object | The measurements of the Person | -| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not | -| `person.updatedAt` | String | Date string indicating the last time the Person was updated | - -## Example request - -```js -const person = await axios.get( - 'https://backend.freesewing.org/people/27/jwt', - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "person": { - "id": 27, - "createdAt": "2022-11-19T17:36:41.342Z", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "imperial": false, - "name": "Someone", - "notes": "These are some notes", - "userId": 12, - "measies": { - "chest": 930, - "neck": 360 - }, - "public": true, - "updatedAt": "2022-11-19T17:36:41.342Z" - } -} -``` diff --git a/markdown/dev/reference/backend/people/update/en.md b/markdown/dev/reference/backend/people/update/en.md deleted file mode 100644 index 32ecba825e6..00000000000 --- a/markdown/dev/reference/backend/people/update/en.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: Update a Person ---- - -Updates an existing Person. - -## Access control - -- [Permission level](/reference/backend/rbac) `3` or higher is required to update a Person -- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** Person - -## Endpoints - -Updating an existing Person is possible via these endpoints: - -| Method | Path | Authentication | -| --------: | :--- | :------------- | -| | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) | -| | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) | - -## Request URL - -The URL should contain the ID of the Person you wish to remove. -It replaces the `:id` placeholder in the [endpoints listed above](#endpoints). - -## Request body - -| Property | Type | Description | -| ----------: | :------- | :---------- | -| `img` | `string` | An image [data-uri][duri] to store with this Person | -| `imperial` | `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) | -| `name` | `string` | A name for the Person | -| `notes` | `string` | User notes for the person | -| `measies` | `object` | The measurements for this person | -| `public` | `string` | The name of the design this Pattern is an instance of | - -## Response status codes - -Possible status codes for these endpoints are: - -| Status code | Description | -| ----------: | :---------- | -| | success | -| | the request was malformed | -| | the request lacks authentication | -| | authentication failed | -| | server error | - - -If the status code is not the `error` property -in the response body should indicate the nature of the problem. - - -## Response body - -| Value | Type | Description | -| ------------------- | -------- | ----------- | -| `result` | String | Either `success` or `error` | -| `error` | String | Will give info on the nature of the error. Only set if an error occurred. | -| `person.id` | Number | The ID of the Person | -| `person.createdAt` | String | Date string indicating the moment the Person was created | -| `person.img` | String | The URL to the image stored with this Person | -| `person.name` | String | The name of the Person | -| `person.notes` | String | The notes stored with the Person | -| `person.userId` | Number | The ID of the user who created the Person | -| `person.measies` | Object | The measurements of the Person | -| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not | -| `person.updatedAt` | String | Date string indicating the last time the Person was updated | - -## Example request - -```js -const udpate = await axios.put( - 'https://backend.freesewing.org/people/27/jwt', - { - notes: "Turns out some people like imperial", - imperial: true, - }, - { - headers: { - Authorization: `Bearer ${token}` - } - } -) -``` - -## Example response -```200.json -{ - "result": "success", - "person": { - "id": 27, - "createdAt": "2022-11-19T17:36:41.342Z", - "img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png", - "imperial": true, - "name": "Someone", - "notes": "Turns out some people like imperial", - "userId": 12, - "measies": { - "chest": 930, - "neck": 360 - }, - "public": true, - "updatedAt": "2022-11-19T17:36:41.342Z" - } -} -``` - -[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme diff --git a/markdown/dev/reference/backend/rbac/en.md b/markdown/dev/reference/backend/rbac/en.md deleted file mode 100644 index c5ad1da3ea6..00000000000 --- a/markdown/dev/reference/backend/rbac/en.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Access control ---- - -The backend API implements role-based access control (RBAC). Each -user has a role and that role determines what they can and cannot do. - -## Roles vs levels - -In practice, the different user roles map to a permission level between -`0` and `8`. -The available roles and their privilege levels are: - -- **user**: `4` -- **bughunter**: `5` -- **support**: `6` -- **admin**: `8` - -We offer more fine-grained control over the permission level when -authenticating with API keys. When you create an API key, you can choose any -permissioning level that is equal or lower than your own role's permission level. - -This allows you to -- for example -- generate an API key that only have read -access to your data. - -## Permission levels - -The table below lists the privilege of all levels as well as their -corresponding `role` - -| Level | Abilities | `user` | `bughunter` | `support` | `admin` | -| --: | -- | :--: | :--: | :--: | :--: | -| `0` | authenticate | ✅ | ✅ | ✅ | ✅ | -| `1` | **read** people and patterns | ✅ | ✅ | ✅ | ✅ | -| `2` | **read all** account data | ✅ | ✅ | ✅ | ✅ | -| `3` | **write** people or patterns | ✅ | ✅ | ✅ | ✅ | -| `4` | **write all** account data | ✅ | ✅ | ✅ | ✅ | -| `5` | **read** people or patterns of **other users** | ❌ | ✅ | ✅ | ✅ | -| `6` | **read all** account data of **other users** | ❌ | ❌ | ✅ | ✅ | -| `7` | **write** account data of **other users** through **specific support methods** | ❌ | ❌ | ✅ | ✅ | -| `8` | impersonate other users, **full write access** | ❌ | ❌ | ❌ | ✅ | - diff --git a/markdown/dev/reference/sites/sanity/en.md b/markdown/dev/reference/sites/sanity/en.md deleted file mode 100644 index fd0848752f4..00000000000 --- a/markdown/dev/reference/sites/sanity/en.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Sanity ---- - -FreeSewing uses [Sanity](https://www.sanity.io/) -- a headless CMS, or a SaaS -platform for structure content -- to host various types of content. - -For background information, please refer to [the Sanity content -guide](/guides/content/sanity). - -## Content schema - -The Sanity content scheme is stored in `sites/sanity/schema` in our monorepo. - -## Datasets - -We use two datasets: - -- `site-data` holds blog and showcase posts in all languages, as well as - newsletter editions. This dataset is publicly available. -- `user-data` holds images uploaded by users, such as for their account image, - or measurements set image. This dataset is not publicly available. - -## Sanity studio - -The `sites/sanity` folder holds an instance of Sanity Studio -- the frontend to -manage the content -- preconfigured to work with our content. This site is -published at https://cms.freesewing.org/ where editors can work on our content. - -### Authentication - -To be able to use the Sanity Studio with FreeSewing's data, you need to be -added as an editor. Sanity supports using your GitHub account to authenticate, -so if you want to become an editor, you can ask joost to grant you access. - -### Local development - -After setting up the monorepo with `yarn kickstart` in the root folder, change your working directory to `sites/sanity` and run `yarn dev`: - -```sh -git clone git@github.com:freesewing/freesewing.git -cd freesewing -yarn kickstart -cd sites/sanity -yarn dev -``` - -The Sanity Studio UI will open at http://localhost:3333 - - -This instance is setup to work with our production data. - - -## Sanity API - -The following data is required to interact with Sanity: - -- Project ID: `hl5bw8cj` -- Dataset: `site-content` - -With that and [the API reference -documentation](https://www.sanity.io/docs/reference) you should be able to get -started. - diff --git a/markdown/dev/reference/terms/cjs/en.md b/markdown/dev/reference/terms/cjs/en.md deleted file mode 100644 index 7d9da894f6d..00000000000 --- a/markdown/dev/reference/terms/cjs/en.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: cjs -jargon: true ---- - -**cjs** stands for **CommonJS**. It is a module system for JavaScript that was -popularized by NodeJS, and as such typically used in server-side JavaScript. - -CommonJS uses the **require** keyword to import modules: - -```js -const fs = require('fs') -``` - -In recent years, **cjs** is increasingly being replaced by **esm**, or ECMA -Script Modules which is the official module system of the JavaScript language, -and the future-proof choice. - -Since version 3, FreeSewing is ESM-only. diff --git a/markdown/dev/reference/terms/esm/en.md b/markdown/dev/reference/terms/esm/en.md deleted file mode 100644 index 0d4f6b611fa..00000000000 --- a/markdown/dev/reference/terms/esm/en.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: esm -jargon: true ---- - -**esm** stands for **ECMAScript Modules** and is the official module system of -the JavaScript language, supported both in the browser, and on the server. - -While ESM is the official standard, before it existed people would typically use CJS outside the browser, as it was popularized by NodeJS. -Some libraries still are not available in ESM, but FreeSewing has been ESM-only since version 3. - - -ESM uses the **import** keyword to import modules: - -```js -import fs from 'fs' -``` - diff --git a/markdown/dev/reference/terms/variadic/en.md b/markdown/dev/reference/terms/variadic/en.md deleted file mode 100644 index eea9f7f4471..00000000000 --- a/markdown/dev/reference/terms/variadic/en.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Variadic -jargon: true ---- - -A **variadic** function is a function that accepts a variable number of arguments. - -For example, JavaScript's `console.log` method is variadic: - -```js -console.log('one') -console.log('one', 'two') -console.log('one', 'two', 'three') -console.log('It', 'works', 'regardless', 'of', 'how', 'many', 'arguments', 'you', 'pass') -``` diff --git a/markdown/dev/reference/trust/en.md b/markdown/dev/reference/trust/en.md deleted file mode 100644 index a7315972fc5..00000000000 --- a/markdown/dev/reference/trust/en.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Web of Trust ---- - -In the wake of [the March 2024 supply-chain attack on XZ -Utils](https://www.wired.com/story/xz-backdoor-everything-you-need-to-know/) -- -which attempted to smuggle a backdoor into Linux distributions -- FreeSewing has -taken steps to guard against the attack vector where a contributor gains trust -over a long period of time, with the end goal to smuggle malicious code into the project. - -__Elevated permissions or access will only be granted to people who are in FreeSewing's web of trust__. - -We have established an initial web of trust (more on this below) and have -revoked elevated permissions from all other contributors. - - - -##### Paranoia much? - -We appreciate that -- given to the nature of software FreeSewing provides -- the chances of a supply chain attack by an adversary willing to invest months or even years to gain our trust are vanishingly small. - -Still, we are a small part of the larger open source ecosystem, and we cannot foresee the ways in which others may end up using our software. -In addition, we want to help normalize this approach, and help raise awareness of the risks involved in trusting pseudo-anonymous contributions. - - - -## Defining trust - -To understand what we mean by a _web of trust_, we need to keep in mind what we want to guard against. -In other words, the web of trust should prevent: - -**Someone attempting to gain our trust -- possibly over a prolonged period of time -- to achieve a malicious goal.** - -Right from the start, you can see that this is impossible. There is no real way to know people's true intentions, so we cannot guard against that. -However, if we assume people try to pull this off without giving up their real identity, we can instead just focus on identity instead. - -The FreeSewing community exists almost exclusively online. -In contrast, **FreeSewing's web of trust is made up of people who know and have verified each others _real_ identities**. - -In other words, to gain elevated permissions or access in FreeSewing, we need to know who you are and where you live. - -## Joining the web of trust - -To join FreeSewing's web of trust, you should: - -- Be a contributor -- Reach out to one of the current trustees -- Meet up with them -- physically, in the real world -- and verify each other's identities. -- Once the current trustee vouches for your identity, you can be added to the web of trust - - -Being a trustee is a requirement to be granted elevated privileges. It ddoes not automatically grant them. - - -## FreeSewing's web of trust - - - -## Trustees - - - diff --git a/markdown/dev/sitemap/en.md b/markdown/dev/sitemap/en.md deleted file mode 100644 index 45c24f6710d..00000000000 --- a/markdown/dev/sitemap/en.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Sitemap ---- - - diff --git a/markdown/dev/support/en.md b/markdown/dev/support/en.md deleted file mode 100644 index 985a34771b8..00000000000 --- a/markdown/dev/support/en.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Support FreeSewing ---- - -FreeSewing is fuelled by a voluntary subscription model - -If you think what we do is worthwhile, and if you can spare a few coins each -month without hardship, please support our work and [become a -patron](https://freesewing.org/patrons/join). - - - -##### Need help? -If it's not support for FreeSewing you're looking for, but rather -support for yourself, then the [support page](https://freesewing.org/support) is for you. - diff --git a/markdown/dev/tutorials/pattern-design/part2/creating-the-closure/en.md b/markdown/dev/tutorials/pattern-design/part2/creating-the-closure/en.md deleted file mode 100644 index 298fb527992..00000000000 --- a/markdown/dev/tutorials/pattern-design/part2/creating-the-closure/en.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -title: Creating the closure -order: 91 ---- - -Things are starting to look good, but we can't fit the bib over the baby's head like this. -So we must create a closure. We'll let the straps overlap at the end, and put in a snap -later. - -## Using macros - -To round the straps, we'll use something new: **a macro**. To use macros, we -need the `macro` method, which we can destructure to get access to it. - -Macros are little helpers that automate things that would otherwise get rather -tedious. There are macros to add titles to our pattern, or grainline -indicators, a scalebox, and there's a macro to round corners. The `round` -macro. - - You can find more information on the `round` macro in [the macros docs](/reference/macros/round/). - -We need a half circle here, but the `round` macro works on 90° angles, so -we'll use it twice. As such, we'll add some points to guide the macro, and -then put it to work. - -Like our neck opening, we've only drawn half since we can simply copy the -points to the other side. - - -```design/src/bib.mjs -function draftBib({ - Path, - Point, - paths, - points, - measurements, - options, - // highlight-start - macro, - // highlight-end - part, -}) { - - /* - * Construct the quarter neck opening - */ - let tweak = 1 - let target = (measurements.head * options.neckRatio) /4 - let delta - do { - points.right = new Point( - tweak * measurements.head / 10, - 0 - ) - points.bottom = new Point( - 0, - tweak * measurements.head / 12 - ) - - points.rightCp1 = points.right.shift( - 90, - points.bottom.dy(points.right) / 2 - ) - points.bottomCp2 = points.bottom.shift( - 0, - points.bottom.dx(points.right) / 2 - ) - - paths.quarterNeck = new Path() - .move(points.right) - .curve( - points.rightCp1, - points.bottomCp2, - points.bottom - ) - .hide() - - delta = paths.quarterNeck.length() - target - if (delta > 0) tweak = tweak * 0.99 - else tweak = tweak * 1.02 - } while (Math.abs(delta) > 1) - - /* - * Construct the complete neck opening - */ - points.rightCp2 = points.rightCp1.flipY() - points.bottomCp1 = points.bottomCp2.flipX() - points.left = points.right.flipX() - points.leftCp1 = points.rightCp2.flipX() - points.leftCp2 = points.rightCp1.flipX() - points.top = points.bottom.flipY() - points.topCp1 = points.bottomCp2.flipY() - points.topCp2 = points.bottomCp1.flipY() - - paths.neck = new Path() - .move(points.top) - .curve(points.topCp2, points.leftCp1, points.left) - .curve(points.leftCp2, points.bottomCp1, points.bottom) - .curve(points.bottomCp2, points.rightCp1, points.right) - .curve(points.rightCp2, points.topCp1, points.top) - .close() - .addClass('fabric') - - /* - * Drawing the bib outline - */ - const width = measurements.head * options.widthRatio - const length = measurements.head * options.lengthRatio - - points.topLeft = new Point( - width / -2, - points.top.y - (width / 2 - points.right.x) - ) - points.topRight = points.topLeft.shift(0, width) - points.bottomLeft = points.topLeft.shift(-90, length) - points.bottomRight = points.topRight.shift(-90, length) - - /* - * Shape the straps - */ - points.edgeLeft = new Point(points.topLeft.x, points.left.y) - points.edgeRight = new Point(points.topRight.x, points.right.y) - points.edgeTop = new Point(0, points.topLeft.y) - - points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) - points.edgeRightCp = points.edgeLeftCp.flipX() - points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( - points.topLeft, - 0.5 - ) - points.edgeTopRightCp = points.edgeTopLeftCp.flipX() - - // highlight-start - // Round the straps - const strap = points.edgeTop.dy(points.top) - - points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) - points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) - points.tipRightBottom = new Point(points.tipRight.x, points.top.y) - - macro("round", { - id: "tipRightTop", - from: points.edgeTop, - to: points.tipRight, - via: points.tipRightTop, - hide: false - }) - macro("round", { - id: "tipRightBottom", - from: points.tipRight, - to: points.top, - via: points.tipRightBottom, - hide: false - }) - // highlight-end - - /* - * Now, adapt our `rect` path so it's no longer a rectangle: - */ - paths.rect = new Path() - .move(points.edgeTop) - .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) - .line(points.bottomLeft) - .line(points.bottomRight) - .line(points.edgeRight) - .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) - .close() - - return part -} -``` - - -Notice that we always draw our path at the end after we've manipulated our points. \ No newline at end of file diff --git a/markdown/dev/tutorials/pattern-design/part3/i18n/en.md b/markdown/dev/tutorials/pattern-design/part3/i18n/en.md deleted file mode 100644 index cd97a3adcad..00000000000 --- a/markdown/dev/tutorials/pattern-design/part3/i18n/en.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Supporting translation -order: 80 ---- - -Write this section for v3 - diff --git a/markdown/org/docs/about/faq/measurements-issues/en.md b/markdown/org/docs/about/faq/measurements-issues/en.md index a97ea64a284..bc6853e56ba 100644 --- a/markdown/org/docs/about/faq/measurements-issues/en.md +++ b/markdown/org/docs/about/faq/measurements-issues/en.md @@ -12,7 +12,11 @@ In the meantime, here are some places to start looking if you're having trouble Trouser problems are almost always caused by vertical measurements that determine the room we have to construct the pants top. For example, waist to upper leg *must* be longer than waist to seat; otherwise there is negative room to construct the pants. -The waist measurement is an important vertical plane of reference. It doesn't matter that much where you take it, as long as you consistently measure all vertical measurements (waist to seat, waist to hips, HPS to waist, waist to floor, ...) from that same horizontal plane. +The [waist](#waist) measurement location is an important vertical reference +that should remain consistent during the measurement process. +You should be measuring all waist-related vertical measurements +(waist to seat, waist to hips, HPS to waist, waist to floor, ...) +from that same horizontal plane. ### Trouble measurements @@ -22,7 +26,12 @@ There are a few measurements we've noticed tend to cause problems. The [waist to armpit](https://freesewing.org/docs/measurements/waisttoarmpit) is a straight vertical measure, not curvilinear (following the curve of the body). It should be at the bottom edge of your armpit, only as high as a shirt would be comfortable sitting (not digging in). -![Waist to armpit](waisttoarmpit.jpg) +![Waist to armpit](waisttoarmpit.jpg) + +The waist to armpit measurement is used to calculate where the bottom +of the sleeve opening is located. +An incorrect waist to armpit measurement can affect the shape of the +sleevecap and size of the sleeve opening. #### High point shoulder (HPS) @@ -32,19 +41,19 @@ Here are two approaches. One way is to take a pencil, pen, or small dowel to find the point where your neck meets your shoulder, as well as the highest point as that's where the pencil or dowel will touch the shoulder. If you use that method, you ideally want the tool you're using to be parallel with the floor so you can find that high point. -![High point shoulder with dowel](hps2.jpg) +![High point shoulder with dowel](hps2.jpg) Another way is with a ribbon. Take a longer ribbon and put it over your neck/shoulder like a cross body bag. It helps to be able to feel where the neck ends and the shoulder begins with a small amount of pressure on the ribbon. You'll need to determine where the shoulder seam should sit, but the ribbon will tell you where the HPS should sit once you have the shoulder seam determined as it will be where the two lines cross. -![High point shoulder with riibbon](hps.jpg) +![High point shoulder with riibbon](hps.jpg) #### High bust [High bust](https://freesewing.org/docs/measurements/highbust) is a horizontal measurement that does not need to be perfectly horizontal. It should go around your torso at the narrowest part of the upper chest, over the bust, under the arms, and across the back, but does not need to be parallel to the ground all the way around. -![High bust from the side](highbust.jpg) +![High bust from the side](highbust.jpg) -![High bust from the front](highbust2.jpg) +![High bust from the front](highbust2.jpg) #### Shoulder slope @@ -58,8 +67,60 @@ In FreeSewing terms, hips is measured at the upper point of the hip bones. Some Seat is across the fullest part of your butt. Some other sources call this the "hip". -##### Waist +For FreeSewing patterns and measurements, +the seat is always located below the hips. -Where you take the [waist](https://freesewing.org/docs/measurements/waist) measurements is not necessarily connected to where, for instance, a waistband is. +#### Waist + +The [waist](https://freesewing.org/docs/measurements/waist) measurement +is important, and unfortunately it is also one of the most difficult +measurements to locate and take correctly. + +##### Description + +When people hear "waist", they might think of where the waistband on +trousers sits on the body. +However, the "waist" is entirely different when referring to the +sewing measurement. +Instead, it is is the location on the body that is sometimes known as +the "natural waist". + +- Typically it is above the hip bone and below the bottom of the ribcage. +For some this is a very small area, and for others there's a much larger +gap between the two. + +- It is sometimes described as the point at which your upper body bends +when you bend sideways. + +- It is sometimes described as the narrowest part of your torso, +(although this description will be unhelpful for people with larger +stomachs, whose waists might _not_ be the narrowest part). + +- Often it is higher up on the torso than people expect, +nearer to the ribcage than to the hips and above the navel. + +Again, thinking about trousers waistbands is often misleading and +results in incorrect measurements. +Trousers, slacks, and jeans that are not "high rise" have waistbands +that sit well below the natural waist. +Only high rise jeans sit close to, sometimes at, the natural waist. + +##### Measuring Tips Try bending sideways and noting the point where your body creases. (For bonus points, put your hand on your waist and sing "I'm a little teapot".) + +Or, take a length of 1/4-to-3/4-inch wide elastic and +tie or sew the ends together to form a band around your waist, +snug enough not to slide off, but loose enough to not change the +waist circumference measurement. +Now try bending from side to side (think "I'm a little teapot" movements), +or otherwise moving and walking around to see if the elastic band +naturally slips into place at the natural waist. +Or, if this is uncomfortable or does not work, you can simply place +the elastic band at the location you think most accurately denotes +your natural waist. + +Keep wearing this elastic band as you take other measurements, as +a consistent reference for the location of the waistline. +It will make it easier to take other waist-related measurements +like waist to floor, waist to armpit, etc. diff --git a/markdown/org/docs/about/faq/printing-issues/en.md b/markdown/org/docs/about/faq/printing-issues/en.md new file mode 100644 index 00000000000..c96dfcec79a --- /dev/null +++ b/markdown/org/docs/about/faq/printing-issues/en.md @@ -0,0 +1,57 @@ +--- +title: Printed PDFs are incorrectly sized/scaled? +--- + +It is important that PDF patterns be printed at the correct +size and scale so that the resulting garments are also correctly-sized. + +## Verifying size and scale + +Our printed patterns include rulers at the upper left corner +of each page as an aid to verify that the printed pattern has been +printed at the correct size and scale. + +Many of our patterns also include a scale box as a similar aid. +For example, the scale box might say that its outer dimensions +are 4" x 2" and its inner dimensions are 10 cm x 5 cm. + +If you measure the ruler or scale box on your printed pattern and +discover that they are different than the expected dimensions, +then the size and scale of your pattern was incorrectly changed. +This can happen somewhere during either: +a. the PDF generating/export process or b. the printing process. + +## Troubleshooting steps + +Please make sure that: + +1. You are generating or exporting a PDF using the correct paper size. +The default paper size is A4, and you should change it if you wish +to use a different paper size. +(For example, if you want to use Letter size paper instead.) + +2. You are printing the PDF to the correct paper size. +If you have an A4 PDF, make sure the printing program is set to +print to A4 paper. + +3. The paper loaded into your printer is the correct size, +If you have an A4 PDF, verify that your printer actually has +A4-sized paper loaded in it. + +4. You are printing at "Actual size" or at 100% scale. +By default, many printing programs are set to "Fit" or +"Shrink oversize pages" which will produce incorrectly-scaled printouts. + +## Further troubleshooting + +If you have followed the above troubleshooting steps but your printed +patterns are still incorrectly scaled, it may be possible that +your printer has been configured to print all documents +(not just our patterns) at a non-100% scale. + +If this is the case, you might want to try reconfiguring your printer +or updating drivers to see if either helps. +If you are unable to resolve the issue, you may simply need to use +a different printer. +Or, experiment with adjusting the scale at which you print so the +resulting printouts end up at the correct scale. diff --git a/markdown/org/docs/designs/bella/options/bustdartangle/en.md b/markdown/org/docs/designs/bella/options/bustdartangle/en.md new file mode 100644 index 00000000000..5388455faaa --- /dev/null +++ b/markdown/org/docs/designs/bella/options/bustdartangle/en.md @@ -0,0 +1,13 @@ +--- +title: "Bust dart angle" +--- + +*** + + + +The **bust dart angle** option controls the angle of the bust dart. +It attempts to set the angle of the top leg of the dart at the +requested angle. +However, the angle may be limited to ensure that a minimum +amount of fabric is left above and below the dart. diff --git a/markdown/org/docs/designs/bella/options/bustdartcurve/en.md b/markdown/org/docs/designs/bella/options/bustdartcurve/en.md index 39532bbe719..752c5e96021 100644 --- a/markdown/org/docs/designs/bella/options/bustdartcurve/en.md +++ b/markdown/org/docs/designs/bella/options/bustdartcurve/en.md @@ -7,7 +7,7 @@ title: "Bust dart curve" ![The effect of the bust dart curve option on the pattern](sample.png) The **bust dart curve** option controls the curvature of the bust dart. -From straight to slightly curved. +From slightly curved convex, to straight, to slightly curved concave. diff --git a/markdown/org/docs/designs/bella/options/bustdartminimumfabric/en.md b/markdown/org/docs/designs/bella/options/bustdartminimumfabric/en.md new file mode 100644 index 00000000000..c2b002bdc17 --- /dev/null +++ b/markdown/org/docs/designs/bella/options/bustdartminimumfabric/en.md @@ -0,0 +1,10 @@ +--- +title: "Bust dart minimum fabric" +--- + +*** + + + +The **bust dart minimum fabric** option controls the minimum amount +of fabric to leave above and below the bust dart. diff --git a/markdown/org/docs/designs/bella/options/waistdartcurve/en.md b/markdown/org/docs/designs/bella/options/waistdartcurve/en.md new file mode 100644 index 00000000000..f430cdc9b20 --- /dev/null +++ b/markdown/org/docs/designs/bella/options/waistdartcurve/en.md @@ -0,0 +1,10 @@ +--- +title: "Waist dart curve" +--- + +*** + + + +The **waist dart curve** option controls the curvature of the waist dart. +From slightly concave, to straight, to slightly convex. diff --git a/markdown/org/docs/designs/huey/options/pocketopening/en.md b/markdown/org/docs/designs/huey/options/pocketopening/en.md new file mode 100644 index 00000000000..4b7b9cdacf9 --- /dev/null +++ b/markdown/org/docs/designs/huey/options/pocketopening/en.md @@ -0,0 +1,7 @@ +--- +title: "Pocket opening" +--- + + + +Controls the opening size of the front pocket. diff --git a/markdown/org/newsletter/2024q4/de.md b/markdown/org/newsletter/2024q4/de.md new file mode 100644 index 00000000000..07607b5aa77 --- /dev/null +++ b/markdown/org/newsletter/2024q4/de.md @@ -0,0 +1,344 @@ +--- +date: "2024-10-01" +edition: "2024q4" +intro: "Willkommen zur Herbstausgabe 2024 des FreeSewing-Newsletters." +title: "24 Herbstausgabe" +--- + +Willkommen zur Herbstausgabe 2024 des FreeSewing-Newsletters. + +Hier ist, was wir für Sie zusammengeschustert haben: + +- 🕵️ Hinter den Nähten: Vili (7-minütige Lesung von Vili & Karen) +- 🛟 Highlights aus dem Need Help-Kanal auf Discord (2-minütige Lesung von Ben) +- 🏋️ Sechs Sprachen wiegen mehr als eine (5-Minuten-Lesung von Joost) + +Sollen wir loslegen? + +  + +  + +  + +  + + +## 🕵️ Behind the Seams: Vili + +Wir haben mit Vili geplaudert, um ein wenig mehr über ihren Hintergrund und ihren Weg zu erfahren +um ein FreeSewing-Mitarbeiter zu werden! Vili hat uns immer wieder beeindruckt, sowohl mit +ihrem Enthusiasmus bei der Beseitigung von Fehlern, Tippfehlern und toten Links auf FreeSewing, als auch +als auch mit ihrer Hingabe für eine handgefertigte Garderobe. Und wir meinen wirklich handgemacht - +Vili hat sich durch eine Reihe von Simon's gearbeitet, die komplett +ohne eine Nähmaschine. (Anmerkung von Vili: Ich habe mich inzwischen mit der Idee angefreundet +meine Handnäherei durch eine Maschine zu ergänzen.) + +Das folgende Interview wurde der Länge wegen bearbeitet, und etwaige Fehler, Versehen etc, +etc. sind ausschließlich die Schuld des Interviewers. + +### Wie haben Sie von FreeSewing erfahren? + +Ich habe vor etwa zwei Jahren mit dem Nähen angefangen und hatte ein ebook über Dinge, die man +ohne Schnittmuster machen kann. Ich glaube, es hieß Radical Sewing. Am Ende gab es Ressourcen +am Ende wurde FreeSewing erwähnt. Open Source, programmatisch, parametrisch +Schnittmuster? Verkauft. + +### Wie sind Sie dazu gekommen, einen Beitrag zu leisten? + +Ich studiere Informatik mit den Schwerpunkten Netzwerke und Systemadministration +und Systemadministration. Ich war schon früh daran interessiert, etwas zu dem Projekt beizutragen +Projekt beizutragen, und bemerkte dann einen Fehler, bei dem einige Links zur +Dokumentation nicht angezeigt wurden. Ich habe einen Fehler gemeldet und erwähnt, dass ich +und Joost, der Joost ist, kam mit einer super detaillierten Liste zurück +was falsch war und wie man es beheben kann. Das habe ich also getan. + +### Was haben Sie bisher beigetragen? + +Meistens habe ich kleinere Verbesserungen der Lebensqualität beigetragen. Wenn es einen Fehler in einem Muster gibt +einem Muster gibt, der einen Absturz verursacht und der leicht zu beheben ist, schaue ich mir das an. +Außerdem habe ich eine Menge toter Links beseitigt. Mein Favorit war, als es viele tote Links +Links auf der Entwicklerseite gab, die zu einer 404-Seite führten, und der "Lass es uns wissen +Der "Lass es uns wissen"-Link auf der 404-Seite war ebenfalls ein toter Link. + +### Wie verbringst du deine Zeit außerhalb von FreeSewing? + +Neben FreeSewing und dem Nähen verbringe ich meine Zeit mit einer Menge Computerkram. I +hoste eine Menge Sachen für meinen persönlichen Gebrauch. + +### Woran arbeitest du derzeit? Hast du kürzlich irgendwelche Projekte abgeschlossen? + +Auf der FreeSewing-Seite ist es immer das Gleiche: Fehlerbehebung, Hausarbeit, +und die Beseitigung von toten Links auf der freesewing.org-Seite der Website. + +Auf der Nähseite... Simons! Ich habe mir eine kleine Pause gegönnt, aber ich bin wieder dabei +mit etwas, das langsam einem Hemd ähnelt. Ich habe 26,5 Stunden an +an diesem aktuellen Simon gearbeitet. Es ist mir eigentlich egal, wie lange es dauert, aber ich will +aber ich will es wissen, und ich bin neugierig, ob ich schneller werde. Für meinen ersten Simon habe ich 60 Stunden gebraucht, also +Ich habe also noch viel Zeit, um das zu unterschreiten. + +### Hast du nach deinem letzten Simon irgendwelche Updates gemacht? Hast du Pläne, andere Muster zu nähen? + +Nun, zuerst habe ich alle meine Maße neu genommen. +Überraschenderweise werden die Schnittmuster schöner, wenn die Maße nicht totaler Müll sind. Als ich +Maße hatte, die genauer (oder überhaupt genauer) waren, wurden all die Dinge, von denen ich wusste, dass ich sie +die ich am Schnittmuster zu korrigieren hatte, in vielen Fällen von selbst erledigt. + +Über diesen Simon hinaus möchte ich noch weitere Teagans und Bruces nähen, und ich habe noch vier +weitere Simons nähen (ich habe den Stoff dafür). + +### Auf welches Näh-/Codierprojekt bist du am meisten stolz? + +Ich dachte, das wäre eine einfache Frage, denn du sagst einfach "der letzte Simon, den ich +gemacht habe." Ich glaube, es könnte immer noch der letzte Simon sein, den ich gemacht habe, und wenn ich mit diesem fertig bin +mit diesem hier fertig bin, wird es dieser Simon sein. Ich denke, der Stolz auf ein Projekt kommt daher +"Wir haben hier etwas Cooles gemacht", aber der Spaß... wenn ich bei einem Projekt etwas Neues lerne +bei einem Projekt etwas Neues lerne, macht das mehr Spaß. + +### Worauf sind Sie in Ihrem Leben am meisten stolz? + +Im Allgemeinen versuche ich, einen positiven Einfluss auf die Menschen um mich herum zu haben. I +Es macht mir viel Spaß, anderen zu helfen und die Menschen um mich herum zu unterstützen. + +### Was lieben Sie am meisten am Nähen? + +Ich glaube, was ich am meisten liebe, ist die Freiheit, selbst zu entscheiden, was man +was genau man anziehen will. Wenn ich ein bestimmtes Kleidungsstück möchte, bin ich nicht +Ich bin nicht davon abhängig, dass jemand anderes entscheidet, dass es sich lohnt, sondern ich kann einfach das Kleidungsstück machen +Ich will. + +### Was hasst du am meisten am Nähen? + +Das Abpausen und Ausschneiden von Schnittmustern - Wenn ich meine Schnittmuster einfach aus dem gewünschten Stoff zuschneiden lassen könnte +von dem Stoff, den ich haben möchte, dann wäre das schon ziemlich gut. Ich arbeite oft mit +Stoffen, bei denen der Fadenlauf sehr deutlich ist, und jede Unvollkommenheit wird +sofort auffällt. Ich versuche, die Muster bis zu einem gewissen Grad anzugleichen, die Vorder- und +Vorder- und Rückseiten übereinstimmen, und das ist alles, was ich mache. + +### Was ist für dich das Schwierigste am Nähen? + +Entweder das Abpausen und Ausschneiden der Schnittmusterteile aus dem Stoff, oder +oder einfach nur die Schnittmuster passend zu machen. Bei meinem zweiten Simon habe ich keine Anprobe gemacht, +weil ich die Schnittmusterteile mit denen des ersten vergleichen konnte. Ich sah mir die +Unterschiede und war mir ziemlich sicher, dass sie die Probleme beheben würden, die ich hatte. Für den +ersten Simon habe ich fünf oder sechs Musselinstoffe durchgesehen, die Teile ausgeschnitten und eine +Kombination aus Lauf- und Rückstich hier und da, damit es nicht ewig dauert. +nicht ewig dauerte. Aber es hat trotzdem sehr lange gedauert. + +### Was würdest du Nähanfängern raten? + +Es kommt vor allem darauf an, die eigene Motivation zum Nähen zu finden, und +ein Projekt auszuwählen, das einen motiviert. Es gibt eine Menge anfänger +anfängerfreundliche Projekte, aber wenn man kein Interesse daran hat, wird man einfach +aufhören, es zu tun. Finde heraus, was dich interessiert, und finde dann heraus, welche Fähigkeiten +du dafür brauchst. + +Meine ersten beiden Kleidungsstücke waren handgenähte Teagans - es war eine Frage von Versuch und Irrtum, um herauszufinden +um herauszufinden, welche Stiche tatsächlich funktionieren, und es hat schließlich gut geklappt. +aber das erste Stück ist viel gröber, ich glaube, es gibt drei oder vier Arten von Stichen +auf der ersten Teagan. Irgendwann wird etwas hängen bleiben. + +### Nähen Sie hauptsächlich für sich selbst oder für andere wie Freunde und Familie? + +Ich habe noch keine Kleidungsstücke für andere genäht. Ich habe drei Spucktücher für die +für die Babyparty der Kinder meines Bruders gemacht, aber das war auch schon alles. + +### Sind Sie ein Hunde- oder ein Katzenmensch? + +Ich bin eher ein Hundetyp, aber ich streichle und kuschle gerne mit beiden. + +### Wenn es eine Sache gäbe, die du auf eine unbewohnte Insel mitnehmen könntest, was würde das sein? Und warum? + +Handelt es sich um eine Überlebenssituation oder um eine Flucht aus der Zivilisation? + +Für eine Flucht aus der Zivilisation würde ich ein Nähprojekt mitnehmen. +Projekt sein. Das ist das Einzige, was ich tue, bei dem ich wirklich von allem abgeschnitten bin. +Eines der Dinge, die ich am Nähen mit der Hand liebe, ist, dass ich einfach den Stoff und ein paar Kleinigkeiten nehmen kann +Ich kann einfach den Stoff und ein paar minimale Dinge nehmen und so ziemlich überall nähen. + +Vor kurzem habe ich mit einer Freundin ein super-minimalistisches Nähset zusammengestellt, und ich bin +ziemlich stolz darauf. Ein Nahttrenner, dessen Hülle eine Nadel, eine Nadel und +etwas Garn, das um den Schaft des Nahttrenners gewickelt ist. Er wiegt absolut +nichts, nimmt keinen Platz weg, hat alles, was ich brauche, und man kann es überallhin mitnehmen. +Und wenn man doch mal etwas abschneiden muss, ist ein Nahttrenner besser als nichts. + +### Wenn es eine Person gäbe, die Sie auf eine unbewohnte Insel mitnehmen könnten, wer wäre das? Und warum? + +Jede einzelne Person, die du mitnimmst, wirst du nach ein paar Wochen hassen. +Wochen hassen. Aber wenn du allein gehst, wirst du auch verrückt werden. Ich würde mir am ehesten +einen Freiwilligen aus meinem Freundes- oder Familienkreis auszuwählen. + +### Können wir dich in den sozialen Medien finden? + +Ich bin nicht in den sozialen Medien vertreten, aber du kannst dir eine meiner FreeSewing +Showcases [hier](https://freesewing.org/showcase/hand-sewn-test-of-florence) +und bleiben Sie dran für einige Simon-Showcases. + + + +  + +--- + +  + +## 🛟 Highlights aus dem Need Help-Kanal auf Discord + +FreeSewing-Superstar Ben F. hat einige aktuelle Highlights aus dem +`#need-help`-Kanal auf dem [FreeSewing +Discord](https://discord.freesewing.org/). + +Wenn Sie Probleme mit einem Muster haben, könnte Ihre Antwort eine der folgenden sein +diese. Wenn Sie auf ein Problem gestoßen sind, gehen Sie zum Discord, um Unterstützung und +Diskussion über Möglichkeiten zur Fehlerbehebung. + +### Jaeger Ärmelumfang + +Ein Ärmel, der nicht passt, weil der Ärmelumfang kleiner ist als der Bizeps +Umfang? Für v3 FreeSewing-Designs wurde festgestellt, dass die Werte "Taille bis +Achselhöhle", "HPS bis Taille" und "HPS bis Oberweite" sehr wichtig geworden sind. +wichtig geworden sind. Ungenaue Messungen können zu falschen Armausschnitten und Ärmel +Ärmelumfang führen. + +### Bitte helfen Sie! Verpatzte Hugo-Maße + +Zu kleine Ärmelkappe und Armumfang? Ein weiteres Problem mit v3 FreeSewing Ärmeln aufgrund +aufgrund einer ungenauen Messung "Taille bis Achselhöhle". Aktivieren Sie die Option "Legacy armhole +Armlochtiefe" zu aktivieren, um v2-Armlöcher zu verwenden (anstatt das Maß "Taille bis Achselhöhle" zu verwenden) +Messung) ist eine weitere mögliche Lösung. + +### Meine Bruce-Hosen sind... Hosen! + +Ein erster Versuch, Bruce Boxershorts zu machen, führte zu einem zu kurzen +Kleidungsstück? Die Lösung bestand darin, die Position der Taille korrekt zu bestimmen und die +die Messung "Taille bis Oberschenkel". + +### Ungleiche Schultermasse + +Wie geht man mit einem medizinischen Problem um, das dazu führt, dass die linke und rechte Schulter +deutlich unterschiedlich ausfallen? Ideen für die Erstellung von Kleidungsstücken, die +diesem Problem Rechnung zu tragen, könnte die Erstellung separater Schnittmuster für die linke und +für die linke und rechte Seite (unter Verwendung von zwei verschiedenen Maßsätzen), die Anfertigung von +Reißverschluss in der Mitte und die Verwendung eines diagonalen/asymmetrischen Saums. + +### Leder nähen auf einer Singer + +Mit einer Jeansnadel werden erfolgreich Löcher in das Leder gestochen, aber der Faden +scheint keine Stiche zu erzeugen? Tipps zur Verwendung einer Microtex- oder Ledernadel +und um sicherzustellen, dass der Lederstoff richtig transportiert wird. + +### Quernahtmessung: + +Wie messen Sie das Quernahtmaß: nackt, mit eng anliegender +Unterwäsche oder mit einer gut sitzenden Hose? Zu den Vorschlägen gehört das Messen mit +mit der Unterwäsche, die zum Kleidungsstück getragen werden soll, ein Band um die Taille zu binden +ein Band um die Taille zu binden und ein zweites Band entlang der Quernaht zu verwenden, sowie die +Messung im Gehen. Überprüfen Sie auch Ihre vertikalen Maße, wenn +Ihr Muster im Schrittbereich nicht richtig sitzt. + + +  + +--- + +  + + +## 🏋️ Sechs Sprachen wiegen mehr als eine + +Ohne jemanden beunruhigen zu wollen, habe ich kürzlich eine kleine Krise durchgemacht +Ich fühlte mich völlig überfordert von all der Arbeit, die in meinem Posteingang liegt. +Es ist wohl nicht wirklich neu, und ich glaube nicht, dass irgendjemand auf einen weiteren +Open-Source-Betreuer, der sich dafür entschuldigt, beschäftigt zu sein. + +Dies war jedoch das erste Mal, dass dieses Gefühl von _Puh, das ist +viel_ in den Bereich _ich kann das nicht mehr_. + +Vor der Morgendämmerung ist es immer am dunkelsten, und jetzt, wo ich erkannt habe, dass es ein Problem gibt +Problem erkannt und einen Plan entwickelt habe, wie ich es angehen kann (dazu komme ich gleich) +Es geht mir schon viel besser, also kein Grund zur Sorge um mich. Ich möchte jedoch +offen und ehrlich darüber sein, woher diese Veränderungen kommen und warum ich sie +sie mache. + +Welche Änderungen? Nun, ab sofort werde ich mich dafür einsetzen, dass +FreeSewing einfacher zu halten und strengere Grenzen zu setzen, was wir tun +und was wir nicht tun. + +Ich habe bereits [FreeSewing.dev](https://freesewing.dev/) auf +[Docusaurus](https://docusaurus.io/) portiert, was die Wartung sehr viel einfacher macht. +Es wird weitere Änderungen wie diese geben, die uns das Leben leichter machen, +ohne einen wesentlichen Unterschied für unsere Benutzer zu schaffen. + +Leider wird das allein nicht ausreichen, daher habe ich auch vor, die Unterstützung für +für Übersetzungen einzustellen und von nun an nur noch Englisch anzubieten. +Auch dies wird für die große Mehrheit unserer Benutzer unbemerkt bleiben, aber natürlich +nicht für alle von ihnen. + +Im Mai 2018 habe ich zu diesem Thema Folgendes geschrieben: + +> *Ich habe beschlossen, dem Mix eine neue Herausforderung hinzuzufügen: i18n. +> +> * Falls du dich fragst, i18n ist die Abkürzung für Internationalisierung, d.h. die +> Website in verschiedenen Sprachen verfügbar zu machen.* +> +> Ja, der 25. Mai ist bald da, und ja, ich brauche mehr Arbeit, als ich ein Loch in meinem Kopf brauche. +> ein weiteres Loch in meinem Kopf. Aber ich denke, es ist ein wichtiges Projekt, zu versuchen +> freesewing.org für so viele Menschen wie möglich verfügbar zu machen. Und dafür müssen wir +> die Sprachbarriere beseitigen. + +Sechseinhalb Jahre später glaube ich immer noch, dass die Beseitigung der Sprachbarriere +Sprachbarriere wichtig ist, um so viele Menschen wie möglich zu erreichen. Aber ich denke auch, dass +wenn wir _weniger_ tun wollen, dann ist dies der offensichtliche Kandidat für die +Kandidaten für eine Streichung. + +Um die Dinge ins rechte Licht zu rücken: 87,9% der FreeSewing-Nutzer haben Englisch +als ihre bevorzugte Sprache gewählt und sind daher von einem solchen Schritt nicht betroffen. Von den +verbleibenden Nutzer bilden diejenigen, die Französisch bevorzugen, das größte Kontingent (7%) +gefolgt von Spanisch (3,2%), Deutsch (1,7%), Niederländisch (1,1%) und schließlich Ukrainisch +(weniger als 0,1%). Ich habe keine einfache Möglichkeit, ähnliche Daten für unsere +aber ich kann mit Sicherheit sagen, dass, wenn man die USA, Kanada, das Vereinigte Königreich, Irland, +und Australien zusammenfasst, ist die große Mehrheit der Nutzer ebenfalls betroffen. + +Für die betroffenen Nutzer tut es mir leid, dass es so weit gekommen ist. Während +die Übersetzung als solche keinen allzu großen Aufwand bedeutet (obwohl ich den Großteil der +der niederländischen Übersetzung übernehme, ist der Hauptverursacher die technische +Komplexität, die durch die Unterstützung mehrerer Sprachen entsteht. +Das ist auch der Grund, warum das Weglassen einer oder mehrerer Sprachen keinen nennenswerten +Unterschied macht. + +Ich stelle diese Zahlen zur Verfügung, weil sie den Rahmen für diese Änderungen abstecken. +Sie sind keine Rechtfertigung für diese Änderungen. Alle Nutzer sind wichtig, und alle +Gönner sind mir sehr wichtig. +Nur weil eine Gruppe kleiner ist als eine andere, heißt das nicht, dass wir sie vor den Bus werfen sollten. +sie vor den Bus werfen. Ich hoffe, das ist etwas, das nicht erklärt werden muss. Das +Aber wenn man etwas nachgeben muss, dann ist die Einstellung der Übersetzung das +am wenigsten auswirkt, weil ich nicht überzeugt bin, dass es in der Praxis so viel ausmacht. + +Die heutigen Browser übersetzen die Seiten im Handumdrehen, und ich habe mehr als einmal gesehen +Ich habe mehr als einmal gesehen, wie Leute mit der Website in einer anderen Sprache interagiert haben, nicht weil sie sich für eine andere +eine andere Sprache entschieden haben, sondern weil ihr Browser die Gewohnheit hat +alle englischen Inhalte in die von ihnen bevorzugte Sprache zu übersetzen. +Außerdem ist trotz der großartigen Arbeit unserer vielen freiwilligen Übersetzerinnen und Übersetzer ein +ein beträchtlicher Teil der FreeSewing-Inhalte maschinell übersetzt, weil +weil es einfach _viel_ davon gibt. Ist es wirklich so wichtig, ob wir +wir die (maschinelle) Übersetzung liefern oder der Browser? +Ich glaube nicht, dass es so viel ausmacht. + +Um den Kreis zu schließen, möchte ich darauf hinweisen, dass mich noch niemand gebeten hat +mich gebeten hat, FreeSewing mit einer Übersetzung auszustatten. Ich habe mich dazu entschlossen, weil ich der Meinung war, dass in einer +einer perfekten Welt jeder FreeSewing in der Sprache seiner Wahl nutzen könnte. +Sprache seiner Wahl zugreifen könnte. So wie sich das maschinelle Lernen (oder _AI_, wenn Sie wollen) entwickelt, ist diese +ist diese Realität vielleicht schon da. + +Ich entschuldige mich bei denjenigen unter Ihnen, für die dies eine schlechte Nachricht ist, und wenn Sie +FreeSewing in Ihren eigenen Projekten verwenden, seien Sie versichert, dass dies nicht bedeutet, dass wir +dass wir die Übersetzungsunterstützung aus unserer Kernbibliothek entfernen. + +Lange Rede, kurzer Sinn: Mir ist klar geworden, dass ich mehr abgebissen habe, als ich kauen kann, +und ich nehme Anpassungen vor, um die Last zu verringern. +Wenn Sie eine bessere Idee haben, wie man das machen kann, bin ich ganz Ohr. + + +joost + + diff --git a/markdown/org/newsletter/2024q4/en.md b/markdown/org/newsletter/2024q4/en.md new file mode 100644 index 00000000000..2e4b783fe22 --- /dev/null +++ b/markdown/org/newsletter/2024q4/en.md @@ -0,0 +1,343 @@ +--- +date: "2024-10-01" +edition: "2024q4" +intro: "Welcome to the 2024 Autumn edition of the FreeSewing newsletter." +title: "2024 Autumn edition" +--- + +Welcome to the 2024 Autumn edition of the FreeSewing newsletter. + +Here's what we've got for you for our last newsletter of this year: + +- 🕵️ Behind the Seams: Vili (7-minute read by Vili & Karen) +- 🛟 Highlights from the Need Help channel on Discord (2-minute read by Ben) +- 🏋️ Six languages weigh more than one (5-minute read buy Joost) + +Shall we get started? + +  + +  + +  + +  + + +## 🕵️ Behind the Seams: Vili + +We chatted with Vili to learn a little more about their background and journey +to becoming a FreeSewing contributor! Vili has consistently wowed us, both with +their enthusiasm for tackling bugs, typos, and dead links on FreeSewing, as +well as their dedication to a handmade wardrobe. And we mean truly handmade - +Vili’s been working their way through a series of Simon’s created entirely +without a sewing machine. (Note from Vili: I’ve since come around to the idea +of supplementing my hand sewing with a machine.) + +The interview below has been edited for length, and any errors, oversights, +etc. are entirely the fault of the interviewer. + +### How did you learn about FreeSewing? + +I started sewing about two years ago, and I had an ebook on things you can do +without a pattern. I think it was called Radical Sewing. There were resources +at the end that mentioned FreeSewing. Open source, programmatic, parametric +patterns? Sold. + +### How did you become a contributor? + +I’m studying computer science, focusing on networking and system +administration. I was interested early in contributing something back to the +project, and then noticed a bug where some links to pattern option +documentation weren’t showing up. I submitted an issue, and mentioned I could +take a stab at it, and Joost being Joost came back with a super detailed list +of what was wrong and how to fix it. So I did. + +### What has been your contributor work so far? + +Mostly I’ve contributed minor quality of life improvements. If there’s a bug in +a pattern that’s causing a crash that’s easy to fix, I’ll take a look at it. +Also a lot of dead links. My favorite was when there were quite a few dead +links on the dev side of things, which went to a 404 page, and the “let us +know” link on the 404 page was also a dead link. + +### How do you spend your time outside of FreeSewing? + +Besides FreeSewing and sewing, I spend my time on a lot of computer stuff. I +host a lot of stuff for my own personal use. + +### What are you currently working on? Finish any projects recently? + +On the FreeSewing side of things, more of the same: fixing bugs, housekeeping, +and dead link extermination on the freesewing.org side of the site. + +On the sewing side of things… Simons! I took a bit of a break, but am back at +it with something that is starting to resemble a shirt. I’m 26.5 hours into +making this current Simon. I don’t actually care how long it takes, but I want +to know, plus I’m curious if I’m getting faster. My first one took 60 hours, so +still plenty of time to come in under that. + +### Did you make any updates after your last Simon? Do you have plans to sew any other patterns? + +Well, first I retook all my measurements.Surprisingly enough, when your +measurements aren’t complete garbage, the patterns come out nicer. When I had +measurements that were more (or at all) accurate, all the things that I knew I +needed to fix about the pattern kind of fixed themselves in a lot of cases. + +Beyond this Simon, I want to sew more Teagans, some Bruces, and I have four +more Simons to go (I have the fabric for them). + +### What sewing/coding project are you most proud of? + +I thought this would be an easy question because you just say “the last Simon I +made.” I think it still might be the last Simon I made, and when I get done +with this one, it’s gonna be this Simon. I think the pride in a project comes +from “we did something cool here,” but the enjoyment… if I learn something new +on a project, that’s more enjoyable. + +### What in your life are you most proud of? + +In general, I try to have an overall positive impact on the people around me. I +get a lot out of helping others, and supporting the people around me. + +### What do you love the most about sewing? + +I think what I love the most is the freedom to just decide for yourself what +exactly you’re going to be wearing. If I want a specific garment, I’m not +depending on someone else deciding it’s profitable, I can just make the garment +I want. + +### What do you hate the most about sewing? + +Tracing and cutting out pattern pieces – If I could just get my patterns precut +from the fabric I want, I think that’d be pretty good. I’m often working with +fabrics where the grainline is extremely obvious, and any imperfection is going +to show up immediately. I try to pattern match to an extent, the fronts and +backs match, and that’s about as far as I will go. + +### What’s the hardest part of sewing to you? + +Actually, either getting the pattern pieces traced and cut out of fabric, or +just getting the patterns to fit. For my second Simon, I didn’t do any fitting, +because I could compare the pattern pieces to the first one. I looked at the +differences, and felt pretty sure they’d fix the issues I was having. For the +first Simon, I went through five or six muslins, cut out the pieces, and did a +combination of running stitch and backstitch here and there to lock it in so it +didn’t take forever. But it still took a long time. + +### What would be your advice for starting sewists? + +A lot of it is going to come down to finding your motivation for sewing, and +picking a project that is going to motivate you. There’s a lot of beginner +friendly projects, but if you’re not interested in it, you’re just going to +stop doing it. Find out what you’re interested in, then figure out what skills +you need to do it. + +My first two garments were hand-sewn Teagans – it was trial and error to figure +out what stitches actually worked, and it eventually worked great, but the +first one is a lot rougher, I think there are three or four types of stitches +on the first Teagan. Eventually something is gonna stick. + +### Do you sew mostly for yourself, or for others like friends and family? + +I haven’t sewn any garments for anyone else. I did make three burp cloths for +my brothers kids baby shower, but that’s the only thing. + +### Are you a dog person or a cat person? + +More of a dog person, but I will happily pet and cuddle both. + +### If there was one thing you could take with you to an uninhabited island, what would it be? Why? + +Is this a survival situation, or a get-away-from-civilization situation? + +For a get-away-from-civilization situation, I think it’s going to be a sewing +project. That’s the one thing I do that’s properly unplugged from everything. +One of the things I love about sewing by hand, I can just grab the fabric and a +very minimal set of things and sew pretty much anywhere. + +I recently came up with a super-minimal sewing kit with a friend, and I’m +pretty proud of it. A seam ripper, with the cover holding a pin, a needle, and +some thread wrapped around the shaft of the seam ripper. Weighs absolutely +nothing, takes up no space, has everything I need, you can take it anywhere. +And if you do need to cut something, a seam ripper is better than nothing. + +### If there was one person you could take with you to an uninhabited island, who would it be? Why? + +Any single person you bring with you, you’re gonna hate by the end of a couple +of weeks. But going alone, you’re also going to go insane. I’d gravitate most +to picking a volunteer out of my friends or family. + +### Can we find you on social media? + +I’m not on any social media, but you can check out one of my FreeSewing +showcases [here](https://freesewing.org/showcase/hand-sewn-test-of-florence) +and stay tuned for some Simon showcases. + + +  + +--- + +  + +## 🛟 Highlights from the Need Help channel on Discord + +FreeSewing superstar Ben F. pulled together some recent highlights from the +`#need-help` channel on the [FreeSewing +Discord](https://discord.freesewing.org/). + +If you've run into trouble with a pattern, your answer might just be one of +these. If you've run into an issue, hop on over to the Discord for support and +discussion about ways to troubleshoot. + +### Jaeger sleeve circumference + +A sleeve that doesn't fit because sleeve circumference is smaller than biceps +circumference? For v3 FreeSewing designs, it was noted that the "Waist to +armpit", "HPS to waist", and "HPS to bust" measurements have become very +important. Inaccurate measurements can result in incorrect armseye and sleeve +circumferences. + +### Please help! Messed up Hugo measurements + +Too small sleevecap and armscye? Another issue with v3 FreeSewing sleeves due +to an inaccurate "Waist to armpit" measurement. Enabling the "Legacy armhole +depth" option to use v2 armholes (instead of using the "Waist to armpit" +measurement) is another possible remedy. + +### My Bruce Pants are... Pants! + +An initial attempt at making Bruce boxer briefs resulted in a too-short +garment? The fix was to correctly locate the location of the waist and retake +the "Waist to upper leg" measurement. + +### Uneven shoulder measurements + +How to deal with a medical issue causing the left and right shoulder +measurements to be significantly different? Ideas for creating garments to +accommodate this issue could include generating separate patterns for left and +right sides (using two different measurement sets), making garments with a +center separating zipper, and using a diagonal/asymmetrical hem. + +### Sewing leather on a Singer + +Using a jeans needle successfully pokes holes in the leather, but the thread +doesn't seem to be creating stitches? Tips to use a microtex or leather needle +and to make sure the leather fabric is feeding properly. + +### Cross seam measurement: + +How do you measure the cross seam measurement: nude, with tight-fitting +underwear, or with good-fitting pants on? Suggestions included measuring while +wearing the underwear intended to be worn with the garment, tying a ribbon +around the waist and using a second ribbon along the cross seam, and taking the +measurement while walking. Also, double-check your vertical measurements if +your pattern isn't fitting correctly in the crotch area. + + +  + +--- + +  + + +## 🏋️ Six languages weigh more than one + +Without wanting to alarm anyone, I recently suffered a bit of a crisis +feeling completely overwhelmed by all the work that is sitting in my inbox. +It's arguably not really new, and I don't think anyone is waiting for yet another +open source maintainer apologizing for being busy. + +However, this was the first time this feeling crossed over from _phew, this is +a lot_ into _I can't do this any longer_ territory. + +It's always darkest before dawn, and now that I've acknowledged that there's a +problem and came up with a plan to deal with it (which I'll get to in a second) +I'm feeling much better already, so no need to worry about me. However, I want +to be open and honest about where these changes are coming from and why I'm +making them. + +What changes? Well, effective immediately, I will work towards making +FreeSewing simpler to maintain, and put more strict boundaries and what we do +and what we don't do. + +I've already ported [FreeSewing.dev](https://freesewing.dev/) to +[Docusaurus](https://docusaurus.io/), which makes it a lot easier to maintain. +There will be more under-the-hood changes like these that make our life easier, +without creating a material difference to our users. + +Unfortunately, that alone won't cut it, so I also intent to drop support +for translation, and only maintain English from now onward. +This too will go unnoticed for the vast majority of our users, but obviously +not for all of them. + +In May 2018, I wrote the following on the subject: + +> *I’ve decided to add a new challenge to the mix: i18n.* +> +> *In case you’re wondering, i18n is short for internationalization, aka making +> the site available in different languages.* +> +> *Yes, May 25th will be here soon, and yes I need more work like I need +> another hole in my head. But I feel it’s an important project to try and make +> freesewing.org available to as many people as possible. And for this, we need +> to get rid of the language barrier.* + +Six and a half years later, I still believe that removing the language +barrier is important to reach as many people as possible. But I also think that +it's fair to say that if we are looking to do _less_ then this is the obvious +candidate of things to drop. + +To put things in perspective: 87.9% of FreeSewing users have selected English +as their language of choice and thus will be unaffected by such a move. Of the +remaining users, those who prefer French form the largest contingent (7%) +followed by Spanish (3.2%), German (1.7%), Dutch (1.1%) and finally Ukrainian +(less then 0.1%). I don't have an easy way to extract similar data for our +patrons, but I can safely say that if you combine the US, Canada, UK, Ireland, +and Australia you have covered the vast majority of patrons too. + +To those users who are affected, I am sorry that it has come to this. While +translation as such does not add too much overhead (although I handle most of +the Dutch translation so it's not nothing), the main culprit is the technical +complexity that comes from supporting multiple languages. +This is also why dropping one or more languages does not make a meaningful +difference. + +I'm sharing these numbers because they provide context to frame these changes. +They are not a justification for these changes. All users matter, and all +patrons matter the world to me. +Just because one group is smaller than another does not mean we should throw +them under the bus. I hope that's something that needs no explaining. That +being said, when something's gotta give, I feel dropping translation is the +least impactful because in practice, I'm not convinced it matters all that much. + +Today's browsers will translate pages on the fly, and I've more than once seen +people interact with the site in non-English, not because they opted for a +different language, but rather because their browser is in the habit of +translating all English content to whatever is their preferred language. +Furthermore, despite the great work of our many volunteer translators, a +significant amount of FreeSewing content remains machine-translated because +there's just _a lot_ of it. Does it really matter all that much whether it's +us providing the (machine) translation or the browser? +I don't believe it matters all that much. + +To come full circle, I feel it's worth pointing out that nobody has ever asked +me to add translation to FreeSewing. I decided to add it because I felt that in +a perfect world, everyone could access FreeSewing in the language of their +choice. With the way machine learning (or _AI_ if you want) is going, that +reality is perhaps already upon us. + +I apologize to those of you for which this is bad news, and if you are using +FreeSewing in your own projects, rest assured that this does not mean we are +removing translation support from our core library. + +Long story short: I have come to realize I've bitten of more than I can chew, +and I am making adjustments to lighten the load. +If you have a better idea on how to do that, I'm all ears. + + +joost + + diff --git a/markdown/org/newsletter/2024q4/es.md b/markdown/org/newsletter/2024q4/es.md new file mode 100644 index 00000000000..cc9f860d561 --- /dev/null +++ b/markdown/org/newsletter/2024q4/es.md @@ -0,0 +1,341 @@ +--- +fecha: "2024-10-01" +edición: "2024q4" +intro: "Bienvenidos a la edición de otoño 2024 del boletín FreeSewing". +título: "2024 edición de otoño" +--- + +Bienvenidos a la edición de otoño 2024 del boletín FreeSewing. + +Esto es lo que hemos preparado para ti: + +- 🕵️ Detrás de las costuras: Vili (lectura de 7 minutos por Vili y Karen) +- 🛟 Lo más destacado del canal Need Help en Discord (lectura de 2 minutos por Ben) +- 🏋️ Seis idiomas pesan más que uno (lectura de 5 minutos por Joost) + +¿Empezamos? + +  + +  + +  + +  + + +## 🕵️ Detrás de las costuras: Vili + +Charlamos con Vili para saber un poco más sobre su trayectoria y su viaje +¡hasta convertirse en colaboradora de FreeSewing! Vili nos ha cautivado constantemente, tanto con +su entusiasmo para hacer frente a los errores, errores tipográficos, y enlaces muertos en FreeSewing, así como +así como su dedicación a un armario hecho a mano. Y queremos decir realmente hecho a mano - +Vili ha estado trabajando su camino a través de una serie de Simon creado enteramente +sin una máquina de coser. (Nota de Vili: Desde entonces me he hecho a la idea de +de complementar mi costura a mano con una máquina). + +La entrevista a continuación ha sido editada por razones de longitud, y cualquier error, descuido, +etc. son enteramente culpa del entrevistador. + +### ¿Cómo conociste FreeSewing? + +Empecé a coser hace unos dos años, y tenía un ebook sobre cosas que se pueden hacer +sin patrón. Creo que se llamaba Radical Sewing. Había recursos +al final que mencionaba FreeSewing. Código abierto, programático, paramétrico +¿Patrones? Vendido. + +### ¿Cómo te convertiste en colaborador? + +Estoy estudiando ciencias de la computación, centrándose en la creación de redes y el sistema de +administración de sistemas. Yo estaba interesado desde el principio en contribuir algo a la +proyecto, y luego se dio cuenta de un error donde algunos enlaces a la opción de patrón +no aparecían. Presenté una cuestión, y mencionó que podría +una puñalada en él, y Joost siendo Joost regresó con una lista super detallada +de lo que estaba mal y cómo solucionarlo. Así que lo hice. + +### ¿Cuál ha sido tu trabajo como colaborador hasta ahora? + +Principalmente he contribuido con pequeñas mejoras en la calidad de vida. Si hay un error en +un patrón que está causando un accidente que es fácil de arreglar, voy a echar un vistazo a él. +También un montón de enlaces muertos. Mi favorito era cuando había un buen número de muertos +enlaces muertos en el lado dev de las cosas, que fue a una página 404, y el "háganoslo saber +saber" en la página 404 era también un enlace muerto. + +### ¿Cómo pasas tu tiempo fuera de FreeSewing? + +Además de FreeSewing y la costura, paso mi tiempo en un montón de cosas de la computadora. I +alojo un montón de cosas para mi uso personal. + +### ¿En qué estás trabajando actualmente? ¿Has terminado algún proyecto recientemente? + +En el lado FreeSewing de las cosas, más de lo mismo: la fijación de errores, limpieza, +y exterminación de enlaces muertos en el lado freesewing.org del sitio. + +En cuanto a la costura... ¡Simons! Tomé un poco de descanso, pero estoy de vuelta en +con algo que está empezando a parecerse a una camisa. Estoy 26,5 horas en +haciendo este Simon actual. En realidad no me importa cuánto tiempo se tarda, pero quiero +para saber, además tengo curiosidad si me estoy volviendo más rápido. Mi primera tomó 60 horas, por lo que +todavía un montón de tiempo para venir en menos de eso. + +### ¿Has hecho alguna actualización después de tu último Simon? ¿Tienes planes de coser algún otro patrón? + +Bueno, primero volví a tomarme todas las medidas. +sorprendentemente, cuando tus medidas no son una basura, los patrones salen mejor. Cuando +Cuando tuve medidas que eran más (o nada) precisas, todas las cosas que sabía que tenía que arreglar sobre el patrón se volvieron más fáciles. +que tenía que arreglar del patrón se arreglaban solas en muchos casos. + +Más allá de este Simon, quiero coser más Teagans, algunos Bruces, y tengo cuatro +más Simons para ir (tengo la tela para ellos). + +### ¿De qué proyecto de costura/codificación estás más orgullosa? + +Pensé que sería una pregunta fácil porque sólo dices "el último Simón que +hice". Creo que todavía podría ser el último Simon que hice, y cuando termine +con este, va a ser este Simon. Creo que el orgullo en un proyecto viene +de "hicimos algo fresco aquí", pero el disfrute ... si aprendo algo nuevo +en un proyecto, que es más agradable. + +### ¿De qué aspecto de tu vida estás más orgulloso? + +En general, intento tener un impacto positivo en la gente que me rodea. I +Me gusta mucho ayudar a los demás y apoyar a la gente que me rodea. + +### ¿Qué es lo que más le gusta de la costura? + +Creo que lo que más me gusta es la libertad de decidir por ti misma lo que +exactamente te vas a poner. Si quiero una prenda específica, no estoy +depender de que otra persona decida que es rentable, simplemente puedo hacer la prenda +que quiero. + +### ¿Qué es lo que más odias de la costura? + +Trazar y cortar las piezas del patrón - Si pudiera conseguir mis patrones precortados +de la tela que quiero, creo que estaría muy bien. A menudo trabajo con +con telas en las que la veta es muy evidente y cualquier imperfección se +aparecer inmediatamente. Trato de igualar el patrón hasta cierto punto, los frentes y +los delanteros y los traseros, y hasta ahí llego. + +### ¿Cuál es para ti la parte más difícil de la costura? + +En realidad, o bien conseguir las piezas del patrón trazadas y cortadas de tela, o +conseguir que los patrones encajen. Para mi segundo Simon, no hice ninguna prueba, +porque podía comparar las piezas del patrón con el primero. Me fijé en las +diferencias, y me sentí bastante seguro de que iban a solucionar los problemas que estaba teniendo. Para el primer +primera Simon, pasé por cinco o seis muselinas, recorté las piezas e hice una +una combinación de puntadas y pespuntes aquí y allá para que no se +para que no tardara una eternidad. Pero aun así llevó mucho tiempo. + +### ¿Cuál sería tu consejo para las costureras principiantes? + +Gran parte de ello se reduce a encontrar tu motivación para coser y a elegir un proyecto que te motive. +elegir un proyecto que te motive. Hay un montón de principiantes +principiantes, pero si no te interesa, dejarás de hacerlo. +dejarás de hacerlo. Averigua qué es lo que te interesa y, a continuación, averigua qué habilidades +necesitas para hacerlo. + +Mis dos primeras prendas fueron Teagans cosidas a mano. +fue un proceso de prueba y error para averiguar qué puntadas funcionaban, y al final todo salió bien. +primero es mucho más áspero, creo que hay tres o cuatro tipos de puntos de sutura +en el primer Teagan. Al final algo se va a pegar. + +### ¿Coses sobre todo para ti, o para otros como amigos y familia? + +No he cosido ninguna prenda para nadie más. Hice tres paños de eructo para +baby shower de los hijos de mis hermanos, pero eso es lo único. + +### ¿Te gustan más los perros o los gatos? + +Me gustan más los perros, pero me gusta acariciar y abrazar a ambos. + +### Si hubiera algo que pudieras llevarte a una isla deshabitada, ¿qué sería? ¿Por qué? + +¿Es una situación de supervivencia o de huida de la civilización? + +Para una situación de escapada de la civilización, creo que va a ser una costura +costura. Es lo único que hago bien desconectada de todo. +Una de las cosas que me encanta de coser a mano, puedo simplemente tomar la tela y un +conjunto muy mínimo de cosas y coser prácticamente en cualquier lugar. + +Hace poco me inventé un kit de costura superminimal con una amiga, y estoy +muy orgullosa de él. Un abridor de costuras, con la tapa que sostiene un alfiler, una aguja, y +un poco de hilo envuelto alrededor del eje de la rasgadora de costura. Pesa absolutamente +nada, no ocupa espacio, tiene todo lo que necesito, se puede llevar a cualquier parte. +Y si necesitas cortar algo, un descosedor es mejor que nada. + +### Si hubiera una persona que pudieras llevar contigo a una isla deshabitada, ¿quién sería? ¿A quién? + +Cualquier persona que lleves contigo, vas a odiarla al final de un par +de semanas. Pero yendo solo, también te vas a volver loco. Yo gravitaría más +a elegir un voluntario entre mis amigos o familiares. + +### ¿Podemos encontrarte en las redes sociales? + +No estoy en ninguna red social, pero puedes ver uno de mis escaparates de FreeSewing +aquí](https://freesewing.org/showcase/hand-sewn-test-of-florence) +y estad atentos a los escaparates de Simon. + +  + +--- + +  + +## 🛟 Lo más destacado del canal Need Help en Discord + +La superestrella de FreeSewing Ben F. ha reunido algunos de los momentos más destacados del canal +canal `#necesito-ayuda` en el [FreeSewing +Discord](https://discord.freesewing.org/). + +Si has tenido problemas con un patrón, la respuesta puede ser uno de estos. +estas. Si te has encontrado con un problema, salta al Discord para obtener ayuda y +discusión sobre las formas de solucionar problemas. + +### Circunferencia de la manga + +¿Una manga que no encaja porque la circunferencia de la manga es menor que la circunferencia del bíceps? +bíceps? En los diseños v3 de FreeSewing, se ha observado que los valores "Cintura a +axila", "HPS a la cintura" y "HPS al busto" se han vuelto muy importantes. +importantes. Las mediciones imprecisas pueden dar lugar a circunferencias incorrectas de brazo y manga. +incorrectas. + +### Por favor, ¡ayuda! Medidas de Hugo incorrectas + +¿Manga y contorno de brazo demasiado pequeños? Otro problema con la v3 FreeSewing mangas debido a +debido a una medición inexacta de la "Cintura a la axila". Activando la opción "Legacy armhole +para utilizar las sisas de la v2 (en lugar de utilizar la medida "de la cintura a la axila"). +) es otro posible remedio. + +### My Bruce Pants are... ### Mis Pantalones Bruce son... ¡Pantalones! + +Un intento inicial de hacer calzoncillos Bruce resultó en un demasiado corto +demasiado cortos. La solución fue localizar correctamente la ubicación de la cintura y volver a tomar +la medida de la "cintura a la parte superior de la pierna". + +### Medidas desiguales de los hombros + +¿Cómo solucionar un problema médico que hace que las medidas de los hombros izquierdo y derecho sean muy diferentes? +izquierda y derecha sean muy diferentes? Algunas ideas para crear prendas +prendas que se adapten a este problema podrían incluir la generación de patrones +izquierdo y derecho (utilizando dos conjuntos de medidas diferentes), confeccionar prendas con una cremallera +cremallera de separación central, y utilizar un dobladillo diagonal/asimétrico. + +### Coser cuero en una Singer + +Usando una aguja vaquera agujerea con éxito el cuero, pero el hilo +no parece crear puntadas? Consejos para utilizar una aguja microtex o de cuero +y para asegurarse de que la tela de cuero se alimenta correctamente. + +### Medición de la costura transversal: + +¿Cómo se mide la costura transversal? +ropa interior ajustada, o con pantalones bien ajustados? Las sugerencias incluyen medir mientras +con la ropa interior que se va a llevar con la prenda, atando una cinta +alrededor de la cintura y utilizar una segunda cinta a lo largo de la costura transversal, y tomar la +medida mientras caminas. Compruebe también las medidas verticales si +el patrón no se ajusta correctamente en la zona de la entrepierna. + + +  + +--- + +  + + +## 🏋️ Seis idiomas pesan más que uno + +Sin ánimo de alarmar a nadie, hace poco sufrí una pequeña crisis +sintiéndome completamente abrumado por todo el trabajo que hay en mi bandeja de entrada. +Podría decirse que no es realmente nuevo, y no creo que nadie esté esperando a otro +mantenedor de código abierto disculpándose por estar ocupado. + +Sin embargo, esta ha sido la primera vez que esta sensación ha pasado de ser +mucho_ a _no puedo seguir con esto_. + +Siempre es más oscuro antes del amanecer, y ahora que he reconocido que hay un +problema y se me ocurrió un plan para lidiar con él (que voy a llegar a en un segundo) +Ya me encuentro mucho mejor, así que no hay que preocuparse por mí. Sin embargo, quiero +Sin embargo, quiero ser abierto y honesto acerca de dónde estos cambios vienen y por qué estoy +los estoy haciendo. + +¿Qué cambios? Bueno, con efecto inmediato, voy a trabajar para hacer +FreeSewing más simple de mantener, y poner límites más estrictos y lo que hacemos +y lo que no hacemos. + +Ya he portado [FreeSewing.dev](https://freesewing.dev/) a +[Docusaurus](https://docusaurus.io/), lo que lo hace mucho más fácil de mantener. +Habrá más cambios como estos que nos harán la vida más fácil, +sin crear una diferencia material para nuestros usuarios. + +Desgraciadamente, esto por sí solo no basta, así que también tengo la intención de dejar de dar soporte a la traducción y mantener únicamente el inglés de la versión en inglés. +para la traducción, y sólo mantener Inglés a partir de ahora. +Esto también pasará desapercibido para la gran mayoría de nuestros usuarios, pero obviamente +no para todos. + +En mayo de 2018 escribí lo siguiente sobre el tema: + +> *He decidido añadir un nuevo reto a la mezcla: i18n.* +> +> *En caso de que te lo estés preguntando, i18n es la abreviatura de internacionalización, es decir, hacer que el sitio esté disponible en diferentes idiomas.* +> +> *Sí, el 25 de mayo llegará pronto, y sí, necesito más trabajo como necesito +> otro agujero en la cabeza. Pero creo que es un proyecto importante intentar hacer que +> que freesewing.org esté disponible para tanta gente como sea posible. Y para ello, necesitamos +> deshacernos de la barrera del idioma.* + +Seis años y medio después, sigo creyendo que eliminar la barrera del idioma es importante para llegar al mayor número de personas posible. +idioma es importante para llegar al mayor número de personas posible. Pero también creo que +Pero también creo que es justo decir que si queremos hacer _menos_, ésta es la +candidato obvio. + +Para poner las cosas en perspectiva: el 87,9% de los usuarios de FreeSewing han seleccionado el inglés +como su idioma de elección y por lo tanto no se verán afectados por este movimiento. De los +francés forman el contingente más numeroso (7%), seguidos del español (3,2%). +seguido del español (3,2%), el alemán (1,7%), el neerlandés (1,1%) y, por último, el ucraniano (menos del 0,1%). +(menos del 0,1%). No me resulta fácil extraer datos similares de nuestros +pero puedo afirmar que si se combinan EE.UU., Canadá, Reino Unido, Irlanda y Australia, se cubre la gran mayoría de la población, +y Australia se ha cubierto también la gran mayoría de los usuarios. + +A los usuarios afectados, lamento que se haya llegado a esta situación. Aunque +traducción como tal no añade demasiada sobrecarga (aunque yo me encargo de la mayor parte de la +de la traducción al holandés, así que no es nada), el principal culpable es la complejidad +complejidad técnica que conlleva el uso de varios idiomas. +Por eso, prescindir de una o varias lenguas no supone una diferencia significativa. +significativa. + +Comparto estas cifras porque sirven de contexto para enmarcar estos cambios. +No son una justificación para estos cambios. Todos los usuarios importan, y todos +todos los usuarios son importantes. +El hecho de que un grupo sea más pequeño que otro no significa que debamos tirarlos debajo del autobús. +debajo del autobús. Espero que esto no necesite explicación. En +dicho esto, cuando algo tiene que ceder, creo que dejar de traducir es lo menos +menos impactante porque, en la práctica, no estoy convencido de que importe demasiado. + +Los navegadores actuales traducen las páginas sobre la marcha, y en más de una ocasión he visto +personas interactuar con el sitio en no Inglés, no porque optaron por una +idioma, sino más bien porque su navegador tiene por costumbre +traducir todo el contenido en inglés a su idioma preferido. +Además, a pesar del gran trabajo de nuestros muchos traductores voluntarios, una +cantidad significativa de contenido FreeSewing sigue siendo máquina-traducido porque +porque es _mucho_. ¿Realmente importa tanto si la traducción (automática) la hacemos +la traducción (automática) o el navegador? +No creo que importe mucho. + +Para cerrar el círculo, creo que vale la pena señalar que nadie me ha pedido nunca +que añadiera la traducción a FreeSewing. Decidí añadirlo porque sentí que en +un mundo perfecto, todo el mundo podría acceder FreeSewing en el idioma de su +idioma de su elección. Con la forma en que el aprendizaje automático (o _AI_ si lo desea) va, que +realidad es tal vez ya sobre nosotros. + +Pido disculpas a aquellos de ustedes para los que esta es una mala noticia, y si usted está usando +FreeSewing en sus propios proyectos, tenga la seguridad de que esto no significa que estamos +de nuestra biblioteca principal. + +Resumiendo: me he dado cuenta de que he mordido más de lo que puedo masticar, +y estoy haciendo ajustes para aligerar la carga. +Si tienes una idea mejor de cómo hacerlo, soy todo oídos. + + +joost + + diff --git a/markdown/org/newsletter/2024q4/fr.md b/markdown/org/newsletter/2024q4/fr.md new file mode 100644 index 00000000000..670f99edf19 --- /dev/null +++ b/markdown/org/newsletter/2024q4/fr.md @@ -0,0 +1,341 @@ +--- +date : "2024-10-01" +édition : "2024q4" +intro : "Bienvenue dans l'édition d'automne 2024 de la lettre d'information de FreeSewing". +title : "2024 Autumn edition" +--- + +Bienvenue dans l'édition d'automne 2024 de la newsletter de FreeSewing. + +Voici ce que nous avons concocté pour vous: + +- 🕵️ Derrière les coutures : Vili (lecture de 7 minutes par Vili & Karen) +- 🛟 Highlights from the Need Help channel on Discord (lecture de 2 minutes par Ben) +- 🏋️ Six langues pèsent plus qu'une (lecture de 5 minutes par Joost) + +Pouvons-nous commencer ? + +  + +  + +  + +  + + +## 🕵️ Derrière les coutures : Vili + +Nous avons discuté avec Vili pour en savoir un peu plus sur son parcours et son cheminement pour devenir un contributeur de FreeSewing ! +pour devenir une contributrice de FreeSewing ! Vili nous a toujours impressionnés, à la fois par +son enthousiasme à s'attaquer aux bugs, aux fautes de frappe et aux liens morts sur FreeSewing, ainsi que son +ainsi que par son attachement à une garde-robe faite à la main. Et nous voulons dire vraiment fait à la main - +Vili a travaillé sur une série de Simon's créés entièrement sans machine à coudre. +sans machine à coudre. (Note de Vili : j'ai depuis adopté l'idée de compléter mes +de compléter ma couture à la main par une machine). + +L'entretien ci-dessous a été édité pour des raisons de longueur, et toute erreur, omission, etc, +etc. sont entièrement de la faute de l'intervieweur. + +### Comment avez-vous découvert FreeSewing ? + +J'ai commencé à coudre il y a environ deux ans, et j'avais un ebook sur les choses que l'on peut faire sans patron. +sans patron. Je crois qu'il s'appelait Radical Sewing. Il y avait des ressources +à la fin qui mentionnaient FreeSewing. Source ouverte, programmatique, paramétrique +paramétriques ? Vendu. + +### Comment es-tu devenue contributrice ? + +J'étudie l'informatique, en me concentrant sur les réseaux et l'administration des systèmes. +système. J'ai été très tôt intéressé par l'idée de contribuer au projet. +projet, puis j'ai remarqué un bogue où certains liens vers la documentation des options de +n'apparaissaient pas. J'ai soumis un problème, et j'ai mentionné que je pourrais +et Joost, étant Joost, est revenu avec une liste super détaillée de ce qui n'allait pas et de +de ce qui n'allait pas et comment le corriger. C'est ce que j'ai fait. + +### Quel a été ton travail de contributeur jusqu'à présent ? + +J'ai surtout contribué à des améliorations mineures de la qualité de vie. S'il y a un bug dans +s'il y a un bug dans un pattern qui cause un crash et qui est facile à corriger, j'y jetterai un coup d'oeil. +Il y a aussi beaucoup de liens morts. Ce que je préfère, c'est quand il y avait beaucoup de liens morts du côté des développeurs. +liens morts du côté des développeurs, qui menaient à une page 404, et le lien "laissez-nous savoir" sur la page 404. +le lien "let us know" sur la page 404 était également un lien mort. + +### Comment passes-tu ton temps en dehors de FreeSewing ? + +En dehors de FreeSewing et de la couture, je passe mon temps à faire beaucoup d'informatique. I +J'héberge beaucoup de choses pour mon usage personnel. + +### Sur quoi travailles-tu en ce moment ? As-tu terminé un projet récemment ? + +Du côté de FreeSewing, c'est un peu la même chose : correction de bugs, ménage, +et extermination des liens morts sur le site freesewing.org. + +Du côté de la couture... Simons ! J'ai fait une petite pause, mais je me suis remise au travail avec quelque chose qui commence à ressembler à la réalité. +avec quelque chose qui commence à ressembler à une chemise. J'en suis à 26,5 heures +la réalisation de ce Simon. Je me fiche de savoir combien de temps ça prend, mais je veux le savoir. +savoir, et je suis curieux de savoir si je deviens plus rapide. Mon premier a pris 60 heures, donc +Il y a encore beaucoup de temps pour arriver en dessous de ce temps. + +### Avez-vous fait des mises à jour après votre dernier Simon ? As-tu prévu de coudre d'autres modèles ? + +Eh bien, j'ai d'abord repris toutes mes mesures. +Etonnamment, quand vos mesures ne sont pas complètement nulles, les patrons sont plus beaux. Lorsque j'ai eu +Lorsque j'ai eu des mesures plus (ou pas du tout) précises, toutes les choses que je savais que je devais corriger à propos du patron ont été plus ou moins bien faites. +que je savais devoir corriger sur le patron se sont arrangées d'elles-mêmes dans beaucoup de cas. + +Au-delà de ce Simon, je veux coudre d'autres Teagans, quelques Bruces, et il me reste quatre Simons à faire (j'en ai déjà un). +Simons à faire (j'ai le tissu pour eux). + +### Quel est le projet de couture/codage dont vous êtes le plus fier ? + +Je pensais que ce serait une question facile parce que vous dites simplement "le dernier Simon que j'ai fait". +que j'ai fait". Je pense que c'est encore le dernier Simon que j'ai fait, et quand j'en aurai fini avec celui-là +avec celui-ci, ce sera ce Simon. Je pense que la fierté d'un projet vient +de "nous avons fait quelque chose de cool ici", mais le plaisir... si j'apprends quelque chose de nouveau sur un projet, c'est encore plus important. +sur un projet, c'est plus agréable. + +### De quoi êtes-vous le plus fier dans votre vie ? + +En général, j'essaie d'avoir un impact positif sur les gens qui m'entourent. I +J'éprouve beaucoup de plaisir à aider les autres et à soutenir les personnes qui m'entourent. + +### Qu'aimez-vous le plus dans la couture ? + +Je pense que ce que j'aime le plus, c'est la liberté de décider par soi-même de ce que l'on va porter. +exactement ce que vous allez porter. Si je veux un vêtement spécifique, je ne dépend pas de quelqu'un d'autre qui décide que c'est le bon. +je ne dépend pas de quelqu'un d'autre qui décide que c'est rentable, je peux juste faire le vêtement que je veux. +Je veux. + +### Qu'est-ce que vous détestez le plus dans la couture ? + +Tracer et découper les pièces du patron - Si je pouvais avoir mes patrons prédécoupés dans le tissu que je veux, je pense que je serais plus à l'aise. +dans le tissu que je veux, je pense que ce serait déjà bien. Je travaille souvent avec des +Je travaille souvent avec des tissus où la ligne de grain est extrêmement évidente, et toute imperfection va +toute imperfection va se voir immédiatement. J'essaie de faire correspondre les motifs dans une certaine mesure. +dos sont assortis, et c'est à peu près tout ce que je peux faire. + +### Quelle est la partie la plus difficile de la couture pour vous ? + +En fait, c'est soit de tracer les pièces du patron et de les découper dans le tissu, soit de faire en sorte que les patrons s'adaptent. +les patrons pour qu'ils s'ajustent. Pour mon deuxième Simon, je n'ai pas fait d'essayage, +parce que je pouvais comparer les pièces du patron à celles du premier. J'ai regardé les +différences, et j'étais presque sûre qu'elles résoudraient les problèmes que je rencontrais. Pour le +premier Simon, j'ai passé cinq ou six mousselines, j'ai découpé les pièces et j'ai fait une +une combinaison de points courants et de points arrière ici et là pour verrouiller le tout afin que cela ne prenne pas une éternité. +ne prenait pas une éternité. Mais cela a quand même pris beaucoup de temps. + +### Quel serait votre conseil pour les débutants en couture ? + +Il s'agit en grande partie de trouver sa motivation pour la couture, et de +choisir un projet qui va vous motiver. Il y a beaucoup de projets adaptés aux débutants. +débutants, mais si vous n'êtes pas intéressée, vous arrêterez de le faire. +arrêter de le faire. Trouvez ce qui vous intéresse, puis déterminez les compétences dont vous avez besoin pour le réaliser. +pour le faire. + +Mes deux premiers vêtements étaient des Teagans cousus à la main. +pour trouver les points qui fonctionnaient, et ça a fini par marcher à merveille. +mais le premier est beaucoup plus rude, je pense qu'il y a trois ou quatre types de points sur le premier Teagan. +sur le premier Teagan. Un jour ou l'autre, quelque chose va coller. + +### Couds-tu surtout pour toi-même, ou pour d'autres personnes, comme tes amis ou ta famille ? + +Je n'ai jamais cousu de vêtements pour quelqu'un d'autre. J'ai fait trois serviettes hygiéniques pour la fête prénatale des enfants de mon frère, mais c'était pour la première fois. +pour la fête prénatale des enfants de mon frère, mais c'est la seule chose que j'ai faite. + +### Êtes-vous plutôt chien ou plutôt chat ? + +Je préfère les chiens, mais j'aime bien les caresser et les câliner tous les deux. + +### Si vous pouviez emporter une chose sur une île inhabitée, quelle serait-elle ? Pourquoi ? + +S'agit-il d'une situation de survie ou de fuite de la civilisation ? + +Pour une situation de fuite de la civilisation, je pense que ce sera un projet de couture. +couture. C'est la seule chose que je fais qui me permette de me déconnecter de tout. +L'une des choses que j'aime dans la couture à la main, c'est que je peux simplement prendre le tissu et un ensemble de choses très minimes et coudre. +un minimum de choses et coudre à peu près n'importe où. + +J'ai récemment mis au point un kit de couture super-minimal avec une amie, et j'en suis assez fière. +et j'en suis assez fière. Un découseur, dont le couvercle contient une épingle, une aiguille et du fil enroulé autour de la tige du découseur. +du fil enroulé autour de la tige du découseur. Il ne pèse absolument rien, ne prend pas de place +ne pèse absolument rien, ne prend pas de place, contient tout ce dont j'ai besoin et peut être emporté partout. +Et si vous devez couper quelque chose, un découseur est mieux que rien. + +### Si vous pouviez emmener une personne sur une île inhabitée, qui serait-elle ? Pourquoi ? + +Toute personne que vous emmenez avec vous, vous allez la détester au bout de quelques semaines. +semaines. Mais si vous y allez seul, vous deviendrez fou. J'aurais tendance à choisir +à choisir un volontaire parmi mes amis ou ma famille. + +### Peut-on vous trouver sur les médias sociaux ? + +Je ne suis sur aucun média social, mais vous pouvez consulter l'une de mes vitrines FreeSewing +ici](https://freesewing.org/showcase/hand-sewn-test-of-florence) +et restez à l'écoute pour des présentations de Simon. + + +  + +--- + +  + + +## 🛟 Faits marquants du canal Need Help sur Discord + +La superstar de FreeSewing, Ben F., a rassemblé quelques moments forts du canal +`#need-help` sur le [FreeSewing +Discord] (https://discord.freesewing.org/). + +Si vous avez rencontré des problèmes avec un modèle, votre réponse pourrait bien être l'un de ces points. +ceci. Si vous rencontrez un problème, rendez-vous sur le Discord pour obtenir de l'aide et discuter des moyens de résoudre le problème. +pour obtenir de l'aide et discuter des moyens de résoudre les problèmes. + +#### Circonférence de la manche de Jaeger + +Une manche qui ne va pas parce que la circonférence de la manche est plus petite que la circonférence du biceps ? +du biceps ? Pour les modèles FreeSewing v3, il a été noté que les paramètres "Taille à l'aisselle", "HPS" et "Biceps" ne sont pas respectés. +aisselles", "HPS à la taille" et "HPS au buste" sont devenues très importantes. +très importantes. Des mesures inexactes peuvent entraîner des circonférences de bras et de manche incorrectes. +des manches. + +### Aidez-moi ! Mesures Hugo erronées + +Capuchon de manche et emmanchure trop petits ? Un autre problème avec les manches de la v3 FreeSewing à cause d'une +d'une mesure imprécise de la taille à l'aisselle. L'activation de l'option "Legacy armhole +pour utiliser les emmanchures de la v2 (au lieu d'utiliser la mesure "de la taille à l'aisselle") est un autre remède possible. +est une autre solution possible. + +### Mon pantalon Bruce est... Des pantalons ! + +Une première tentative de fabrication d'un caleçon Bruce a abouti à un vêtement trop court ? +trop court ? La solution consistait à localiser correctement l'emplacement de la taille et à prendre à nouveau la mesure "de la taille à la partie supérieure de la jambe". +la mesure "de la taille à la partie supérieure de la jambe". + +### Mesures inégales des épaules + +Comment faire face à un problème médical qui fait que les mesures de l'épaule gauche et de l'épaule droite sont sensiblement différentes ? +sont très différentes ? Les idées pour créer des vêtements +pour tenir compte de ce problème pourraient inclure la création de patrons distincts pour les côtés gauche et droit (en utilisant deux ensembles de mesures différents). +gauche et le côté droit (en utilisant deux ensembles de mesures différents), créer des vêtements avec une +une fermeture à glissière centrale, et l'utilisation d'un ourlet diagonal/asymétrique. + +### Coudre du cuir sur une Singer + +L'utilisation d'une aiguille à jeans permet de faire des trous dans le cuir, mais le fil ne semble pas créer de piqûres. +ne semble pas créer de points ? Conseils pour utiliser une aiguille à microtex ou à cuir +et pour s'assurer que le tissu en cuir est correctement alimenté. + +### Mesure de la couture transversale : + +Comment mesurez-vous la mesure de la couture transversale : nu, avec des sous-vêtements serrés ou avec des sous-vêtements bien ajustés ? +nus, avec des sous-vêtements serrés ou avec un pantalon bien ajusté ? Il a été suggéré de prendre la mesure en +en portant les sous-vêtements prévus pour le vêtement, en nouant un ruban autour de la taille et en utilisant un second ruban. +ruban autour de la taille et utiliser un second ruban le long de la couture transversale, et prendre la mesure en marchant. +en marchant. Vérifiez également vos mesures verticales si +si votre patron ne s'ajuste pas correctement au niveau de l'entrejambe. + + +  + +--- + +  + +## 🏋️ Six langues pèsent plus lourd qu'une seule + +Sans vouloir alarmer qui que ce soit, j'ai récemment traversé une crise. +Je me suis sentie complètement dépassée par tout le travail qui se trouve dans ma boîte de réception. +Ce n'est pas vraiment nouveau, et je ne pense pas que quiconque attende qu'un énième mainteneur de logiciel libre s'excuse d'être occupé. +mainteneur open source s'excusant d'être occupé. + +Cependant, c'était la première fois que ce sentiment passait de _phew, this is +c'est beaucoup_ à _je ne peux plus faire ça_. + +Il est toujours plus sombre avant l'aube, et maintenant que j'ai reconnu qu'il y avait un problème et que j'ai élaboré un plan pour y remédier, je me suis dit qu'il fallait faire quelque chose. +problème et que j'ai élaboré un plan pour y remédier (j'y reviendrai dans une seconde), je me sens déjà beaucoup mieux. +Je me sens déjà beaucoup mieux, il n'y a donc pas lieu de s'inquiéter pour moi. Cependant, je veux +être ouvert et honnête sur l'origine de ces changements et sur les raisons qui me poussent à les faire. +pourquoi je les fais. + +Quels changements ? Eh bien, à partir de maintenant, je vais m'efforcer de rendre +FreeSewing plus simple à maintenir, et mettre des limites plus strictes sur ce que nous faisons et ce que nous ne faisons pas. +et ce que nous ne faisons pas. + +J'ai déjà porté [FreeSewing.dev](https://freesewing.dev/) vers +[Docusaurus](https://docusaurus.io/), ce qui le rend beaucoup plus facile à maintenir. +Il y aura d'autres changements sous le capot comme ceux-ci qui nous faciliteront la vie, +sans créer de différence matérielle pour nos utilisateurs. + +Malheureusement, cela ne suffira pas, c'est pourquoi j'ai également l'intention d'abandonner la prise en charge de la traduction, et de ne maintenir que l'anglais à partir de la version française. +pour la traduction, et de ne maintenir que l'anglais à partir de maintenant. +Cela aussi passera inaperçu pour la grande majorité de nos utilisateurs, mais évidemment pas pour tous. + +En mai 2018, j'ai écrit ce qui suit sur le sujet : + +> *J'ai décidé d'ajouter un nouveau défi au mélange : i18n.* +> +> *Au cas où vous vous poseriez la question, i18n est l'abréviation d'internationalisation, c'est-à-dire le fait de rendre le site disponible dans différentes langues. +> le site dans différentes langues.* + +> Oui, le 25 mai sera bientôt là, et oui, j'ai besoin de plus de travail comme j'ai besoin d'un autre trou dans ma tête. +> d'un autre trou dans la tête. Mais je pense que c'est un projet important d'essayer de rendre +> freesewing.org disponible pour le plus grand nombre de personnes possible. Et pour cela, nous devons +> de nous débarrasser de la barrière de la langue. + +Six ans et demi plus tard, je pense toujours qu'il est important de supprimer la +de la langue est importante pour atteindre le plus grand nombre de personnes possible. Mais je pense aussi que +qu'il est juste de dire que si nous cherchons à en faire _moins_, c'est le candidat le plus +de ce qu'il faut laisser tomber. + +Pour mettre les choses en perspective : 87.9% des utilisateurs de FreeSewing ont choisi l'anglais +comme leur langue de prédilection et ne seront donc pas affectés par un tel changement. Parmi les +restants, ceux qui préfèrent le français forment le contingent le plus important (7%) +suivi de l'espagnol (3,2 %), de l'allemand (1,7 %), du néerlandais (1,1 %) et enfin de l'ukrainien (moins de 0,1 %). +(moins de 0,1 %). Je n'ai pas de moyen facile d'extraire des données similaires pour nos patrons, mais je peux dire sans risque de me tromper qu'il n'y a pas de problème. +mais je peux affirmer que si l'on combine les États-Unis, le Canada, le Royaume-Uni, l'Irlande et l'Australie, on couvre la grande majorité des pays de l'Union européenne, +et l'Australie, vous avez également couvert la grande majorité des patrons. + +Aux utilisateurs concernés, je suis désolé d'en arriver là. Bien que la traduction en tant que telle n'ajoute pas trop de frais généraux +traduction en tant que telle n'ajoute pas trop de frais généraux (bien que je m'occupe de la plupart des +la traduction néerlandaise, ce n'est donc pas rien), le principal coupable est la complexité +complexité technique liée à la prise en charge de plusieurs langues. + +C'est également la raison pour laquelle l'abandon d'une ou de plusieurs langues ne fait pas de différence significative.significative. + +Je partage ces chiffres parce qu'ils fournissent un contexte pour encadrer ces changements. +Ils ne constituent pas une justification de ces changements. Tous les utilisateurs sont importants, et tous les +Tous les utilisateurs sont importants, et tous les usagers sont importants pour moi. +Ce n'est pas parce qu'un groupe est plus petit qu'un autre qu'il faut le jeter sous le bus. +que nous devrions les jeter sous le bus. J'espère que cela n'a pas besoin d'être expliqué. Cela dit, quand il faut faire quelque chose, il faut le faire. +Cela étant dit, lorsque quelque chose doit changer, j'ai le sentiment que l'abandon de la traduction est la solution la moins impactante. +l'impact le plus faible car, dans la pratique, je ne suis pas convaincu que cela ait beaucoup d'importance. + +Les navigateurs d'aujourd'hui traduisent les pages à la volée, et j'ai plus d'une fois vu +des personnes interagir avec le site dans une langue autre que l'anglais, non pas parce qu'elles ont opté pour une +langue, mais plutôt parce que leur navigateur a pris l'habitude de traduire tous les +traduire tout le contenu anglais dans la langue qu'ils préfèrent. +De plus, malgré l'excellent travail de nos nombreux traducteurs bénévoles, une grande partie du contenu de FreeSewing est en anglais. +de FreeSewing reste traduit mécaniquement parce qu'il y a tout simplement +parce qu'il y en a _beaucoup_. Est-ce si important que cela de savoir si c'est +que ce soit nous qui fournissions la traduction (automatique) ou le navigateur ? +Je ne crois pas que ce soit le cas. + +Pour faire le tour de la question, je pense qu'il est bon de souligner que personne ne m'a jamais demandé d'ajouter une traduction à FreeSewing. +d'ajouter la traduction à FreeSewing. J'ai décidé de l'ajouter parce que j'ai pensé que dans un monde +dans un monde parfait, tout le monde pourrait accéder à FreeSewing dans la langue de son choix. +langue de son choix. Avec la façon dont l'apprentissage automatique (ou _AI_ si vous voulez) évolue, cette réalité est peut-être déjà à nos portes. + +réalité est peut-être déjà à nos portes.Je m'excuse auprès de ceux pour qui c'est une mauvaise nouvelle, et si vous utilisez +FreeSewing dans vos propres projets, soyez assurés que cela ne signifie pas que nous +que cela ne signifie pas que nous supprimons la prise en charge des traductions dans notre bibliothèque de base. + +Pour faire court : je me suis rendu compte que j'avais pris plus que ce que je pouvais mâcher, +et je fais des ajustements pour alléger la charge. +Si vous avez une meilleure idée sur la façon de procéder, je suis tout ouïe. + + +joost + + diff --git a/markdown/org/newsletter/2024q4/nl.md b/markdown/org/newsletter/2024q4/nl.md new file mode 100644 index 00000000000..fa3e6d2f740 --- /dev/null +++ b/markdown/org/newsletter/2024q4/nl.md @@ -0,0 +1,339 @@ +--- +datum: "2024-10-01" +uitgave: "2024q4" +intro: "Welkom bij de 2024 herfsteditie van de FreeSewing nieuwsbrief." +titel: "2024 Herfsteditie" +--- + +Welkom bij de 2024 herfst editie van de FreeSewing nieuwsbrief. + +Dit is wat we hebben bij elkaar gesprokkeld: + +- 🕵️ Achter de Naden: Vili (7-minuten lezing door Vili & Karen) +- Hoogtepunten van het Need Help-kanaal op Discord (2 minuten gelezen door Ben) +- 🏋️ Zes talen wegen meer dan één (5-minuten lezen door Joost) + +Zullen we beginnen? + +  + +  + +  + +  + + +## 🕵️ Achter de naden: Vili + +We spraken met Vili om wat meer te weten te komen over hun achtergrond en reis +om een FreeSewing medewerkster te worden! Vili heeft ons altijd versteld doen staan, zowel met +hun enthousiasme voor het aanpakken van bugs, typefouten en dode links op FreeSewing, maar ook +maar ook met hun toewijding aan een handgemaakte garderobe. En dan bedoelen we ook echt handgemaakt. +Vili is bezig geweest met een serie Simon's die helemaal zijn gemaakt +zonder naaimachine. (Opmerking van Vili: ik ben sindsdien op het idee gekomen +om mijn handnaaiwerk aan te vullen met een machine). + +Het onderstaande interview is bewerkt voor de lengte en eventuele fouten, vergissingen enz, +etc. zijn geheel de schuld van de interviewer. + +### Hoe heeft u FreeSewing leren kennen? + +Ik ben ongeveer twee jaar geleden begonnen met naaien en ik had een ebook over dingen die je zonder patroon kunt doen. +zonder patroon. Ik geloof dat het Radical Sewing heette. Er stonden hulpmiddelen +aan het eind waarin FreeSewing werd genoemd. Open source, programmatisch, parametrische +patronen? Verkocht. + +### Hoe bent u medewerker geworden? + +Ik studeer computerwetenschappen, met de nadruk op netwerken en systeembeheer. +administratie. Ik was al vroeg geïnteresseerd om iets bij te dragen aan het +aan het project, en merkte toen een bug op waarbij sommige links naar patroonoptie +niet werden weergegeven. Ik diende een probleem in en zei dat ik +een poging kon wagen, en Joost als Joost kwam terug met een super gedetailleerde lijst +van wat er mis was en hoe het te repareren. Dus dat deed ik. + +### Wat heeft u tot nu toe bijgedragen? + +Meestal heb ik bijgedragen aan kleine verbeteringen van de levenskwaliteit. Als er een bug in +in een patroon dat een crash veroorzaakt die eenvoudig te verhelpen is, dan kijk ik ernaar. +Ook veel dode links. Mijn favoriet was toen er heel wat dode +links waren aan de ontwikkel kant, die naar een 404 pagina gingen, en de "laat het ons weten +laat het ons weten" op de 404-pagina was ook een dode link. + +### Hoe besteedt u uw tijd buiten FreeSewing? + +Naast FreeSewing en naaien besteed ik mijn tijd aan veel computerdingen. I +Ik host veel dingen voor persoonlijk gebruik. + +### Waar werkt u momenteel aan? Onlangs nog projecten afgerond? + +Aan de kant van FreeSewing, meer van hetzelfde: bugs repareren, het huishouden doen, +en dode links uitroeien aan de freesewing.org kant van de site. + +Aan de naaikant... Simons! Ik heb even een pauze ingelast, maar ik ben weer terug bij +met iets dat op een shirt begint te lijken. Ik ben nu 26,5 uur bezig +het maken van deze huidige Simon. Het maakt me eigenlijk niet uit hoe lang het duurt, maar ik wil het weten. +weten en ik ben benieuwd of ik sneller word. Mijn eerste duurde 60 uur, dus +nog genoeg tijd om daar onder te komen. + +### Hebt u nog updates gemaakt na uw laatste Simon? Hebt u plannen om nog andere patronen te naaien? + +Nou, eerst heb ik al mijn maten opnieuw opgemeten. Verrassend genoeg, als je +Verrassend genoeg komen de patronen mooier uit als je metingen niet helemaal klote zijn. Toen ik +metingen had die meer (of helemaal niet) nauwkeurig waren, alle dingen waarvan ik wist dat ik ze +waarvan ik wist dat ik ze moest repareren aan het patroon zichzelf in veel gevallen opgelost. + +Naast deze Simon wil ik nog meer Teagans naaien, een paar Bruces, en ik heb nog vier +nog vier Simons te gaan (ik heb de stof ervoor). + +### Op welk naai-/codeerproject bent u het meest trots? + +Ik dacht dat dit een makkelijke vraag zou zijn omdat u gewoon zegt "de laatste Simon die ik +maakte." Ik denk dat het nog steeds de laatste Simon is die ik heb gemaakt en als ik klaar ben met deze +met deze, zal het deze Simon zijn. Ik denk dat de trots op een project komt +van "we hebben hier iets cools gedaan", maar het plezier... als ik iets nieuws leer +bij een project, dat is leuker. + +### Waar bent u het meest trots op in uw leven? + +In het algemeen probeer ik een positieve impact te hebben op de mensen om me heen. I +Ik haal er veel uit om anderen te helpen en de mensen om me heen te steunen. + +### Wat vindt u het leukste aan naaien? + +Ik denk dat ik het meest hou van de vrijheid om zelf te beslissen wat je precies gaat dragen. +je precies gaat dragen. Als ik een specifiek kledingstuk wil, ben ik niet +afhankelijk van iemand anders die beslist dat het geschikt is, ik kan gewoon het kledingstuk maken dat ik wil. + +### Wat haat u het meest aan naaien? + +Het overtrekken en uitknippen van patroondelen - Als ik mijn patronen gewoon voorgeknipt kon krijgen +van de stof die ik wil, dan zou dat al heel goed zijn. Ik werk vaak met +stoffen waar de nerflijn heel duidelijk te zien is en elke onvolkomenheid +meteen te zien. Ik probeer het patroon tot op zekere hoogte te matchen, de voor- en +De voor- en achterkant komen overeen en verder ga ik niet. + +### Wat vindt u het moeilijkste aan naaien? + +De patroondelen overtrekken en uit stof knippen, of +de patronen laten passen. Voor mijn tweede Simon heb ik niet gepast, +omdat ik de patroondelen kon vergelijken met de eerste. Ik keek naar de +verschillen en was er vrij zeker van dat ze de problemen die ik had zouden oplossen. Voor de +eerste Simon ging ik door vijf of zes mousselins, knipte de delen uit en deed een +combinatie van een rijgsteek en een stiksteek hier en daar om het vast te zetten zodat het +het niet eeuwig duurde. Maar het duurde nog steeds lang. + +### Wat zou uw advies zijn voor beginnende naaisters? + +Veel komt neer op het vinden van uw motivatie om te naaien en +een project kiezen dat u motiveert. Er zijn veel beginners +vriendelijke projecten, maar als je er niet in geïnteresseerd bent, dan stop je er gewoon mee. +stoppen. Zoek uit waarin je geïnteresseerd bent en zoek dan uit welke vaardigheden je daarvoor nodig hebt. + +Mijn eerste twee kledingstukken waren met de hand genaaide Teagans. +om erachter te komen welke steken echt werkten, en uiteindelijk werkte het geweldig, maar de +eerste is veel ruwer, ik denk dat er drie of vier soorten steken zijn +op de eerste Teagan. Uiteindelijk blijft er iets plakken. + +### Naait u meestal voor uzelf of voor anderen, zoals vrienden en familie? + +Ik heb geen kledingstukken voor anderen gemaakt. Ik heb wel drie washandjes gemaakt voor +voor de babyborrel van mijn broers kinderen, maar dat is het enige. + +### Bent u een honden- of kattenliefhebber? + +Ik hou meer van honden, maar ik aai en knuffel ze allebei graag. + +### Als u één ding mee zou kunnen nemen naar een onbewoond eiland, wat zou dat dan zijn? Waarom? + +Is dit een overlevingssituatie of een weg-van-de-beschaving situatie? + +Voor een weg-van-de-beschaving situatie, denk ik dat het een naaiproject wordt. +project wordt. Dat is het enige wat ik doe dat goed losgekoppeld is van alles. +Een van de dingen die ik zo leuk vind aan naaien met de hand, is dat ik gewoon de stof en een +minimale spullen pakken en vrijwel overal naaien. + +Onlangs heb ik samen met een vriendin een superminimale naaiset samengesteld en ik ben er best trots op. +behoorlijk trots op. Een tornmesje, met in het deksel een speld, een naald en +wat draad om de schacht van de tornmesje. Weegt absoluut +Weegt absoluut niets, neemt geen ruimte in, heeft alles wat ik nodig heb en je kunt het overal mee naartoe nemen. +En als je toch iets moet knippen, is een tornmesje beter dan niets. + +### Als je één persoon mee mocht nemen naar een onbewoond eiland, wie zou dat dan zijn? Waarom? + +Elke persoon die je meeneemt, ga je haten na een paar weken. +weken. Maar als je alleen gaat, word je ook gek. Ik zou het meest geneigd zijn +om een vrijwilliger uit mijn vrienden of familie te kiezen. + +### Kunnen we u vinden op sociale media? + +Ik ben niet actief op sociale media, maar u kunt een van mijn FreeSewing +showcases [hier] (https://freesewing.org/showcase/hand-sewn-test-of-florence) +en blijf op de hoogte voor een aantal Simon showcases. + +  + +--- + +  + +## 🛟 Hoogtepunten van het Need Help-kanaal op Discord + +FreeSewing superster Ben F. heeft wat recente hoogtepunten verzameld van het +`#nood-help`-kanaal op de [FreeSewing +Discord] (https://discord.freesewing.org/). + +Als je problemen hebt met een patroon, zou het antwoord wel eens een van deze kunnen zijn. +deze. Als je tegen een probleem aanloopt, ga dan naar de Discord voor ondersteuning en +discussie over manieren om problemen op te lossen. + +### Jaeger mouwomtrek + +Een mouw die niet past omdat de mouwomtrek kleiner is dan de bicepsomtrek? +omtrek? Voor v3 FreeSewing ontwerpen werd opgemerkt dat de "Taille tot +oksel", "HPS tot taille" en "HPS tot buste" erg belangrijk zijn geworden. +belangrijk zijn geworden. Onnauwkeurige metingen kunnen resulteren in onjuiste arm-oog en mouw +omtrekken. + +### Help alstublieft! Verkeerde Hugo-maten + +Te kleine mouwomslag en armscye? Nog een probleem met v3 FreeSewing mouwen door +door een onnauwkeurige "Taille tot oksel" meting. Het inschakelen van de "Legacy armsgat +diepte" optie om v2 armsgaten te gebruiken (in plaats van de "Taille tot oksel" meting) is een andere mogelijke oplossing. +meting) is een andere mogelijke oplossing. + +### Mijn Bruce broek is... Broek! + +Een eerste poging om Bruce boxerslips te maken resulteerde in een te kort +kledingstuk? De oplossing was om de plaats van de taille correct te bepalen en de "Taille tot bovenbeen" meting opnieuw uit te voeren. + +### Ongelijke schouderafmetingen + +Hoe om te gaan met een medisch probleem waardoor de linker- en rechterschouder +maten aanzienlijk verschillen? Ideeën voor het maken van kledingstukken +om dit probleem op te lossen zijn bijvoorbeeld het maken van aparte patronen voor de linker- en +rechts (met behulp van twee verschillende maatsets), kledingstukken maken met een +ritssluiting in het midden en een diagonale/asymmetrische zoom gebruiken. + +### Leer naaien op een Singer + +Het gebruik van een jeansnaald prikt met succes gaten in het leer, maar de draad +lijkt geen steken te maken? Tips om een microtex- of leernaald te gebruiken +en om ervoor te zorgen dat de leren stof goed wordt getransporteerd. + +### De dwarsnaad meten: + +Hoe meet u de kruisnaad: naakt, met nauwsluitend +ondergoed, of met een goed passende broek aan? Suggesties zijn onder andere +terwijl u het ondergoed draagt dat bedoeld is om bij het kledingstuk te dragen, een lint rond de taille binden en een tweede lint gebruiken. +rond de taille en een tweede lint langs de kruisnaad gebruiken en de +meten tijdens het lopen. Controleer ook uw verticale maten als +het patroon niet goed past in het kruisgebied. + + +  + +--- + +  + + +## 🏋️ Zes talen wegen meer dan één + +Zonder iemand te willen alarmeren, heb ik onlangs een beetje een crisis doorgemaakt +Ik voelde me volledig overweldigd door al het werk dat in mijn inbox zit. +Het is aantoonbaar niet echt nieuw en ik denk niet dat iemand zit te wachten op de zoveelste +open source beheerder die zich verontschuldigt omdat hij het druk heeft. + +Dit was echter de eerste keer dat dit gevoel overging van _phew, dit is +veel_ naar _ik kan dit niet langer_ teritory. + +Het is altijd het donkerst voor zonsopgang, en nu ik heb erkend dat er een probleem is en een plan heb bedacht om het op te lossen. +probleem heb en een plan heb bedacht om het aan te pakken (waar ik zo op terugkom) +Ik voel me al veel beter, dus je hoeft je over mij geen zorgen te maken. Maar ik wil +open en eerlijk zijn over waar deze veranderingen vandaan komen en waarom ik ze doorvoer. +ze maak. + +Welke veranderingen? Nou, met onmiddellijke ingang zal ik eraan werken om +FreeSewing eenvoudiger te maken om te onderhouden, en om meer strikte grenzen te stellen aan wat we doen +en wat we niet doen. + +Ik heb [FreeSewing.dev](https://freesewing.dev/) al overgezet naar +[Docusaurus](https://docusaurus.io/), wat het een stuk eenvoudiger maakt om te onderhouden. +Er zullen meer van dit soort veranderingen onder de motorkap zijn die ons leven makkelijker maken, +zonder een wezenlijk verschil te maken voor onze gebruikers. + +Helaas is dat alleen niet genoeg, dus ik ben ook van plan om de ondersteuning +voor vertalingen te laten vallen en vanaf nu alleen Engels te onderhouden. +Ook dit zal onopgemerkt blijven voor de overgrote meerderheid van onze gebruikers, maar natuurlijk +niet voor allemaal. + +In mei 2018 schreef ik het volgende over dit onderwerp: + +> *Ik heb besloten een nieuwe uitdaging aan de mix toe te voegen: i18n.* +> +> *Voor het geval je het je afvraagt, i18n is een afkorting voor internationalisatie, aka het beschikbaar maken van +> de site beschikbaar maken in verschillende talen.* +> +> *Ja, 25 mei komt eraan, en ja, ik heb meer werk nodig zoals ik een +> nog een gat in mijn hoofd nodig heb. Maar ik vind het een belangrijk project om te proberen +> freesewing.org beschikbaar te maken voor zoveel mogelijk mensen. En daarvoor moeten we +> de taalbarrière op te heffen.* + +Zes en een half jaar later geloof ik nog steeds dat het verwijderen van de taalbarrière > belangrijk is om zoveel mogelijk mensen te bereiken. +barrière belangrijk is om zoveel mogelijk mensen te bereiken. Maar ik denk ook dat +het eerlijk is om te zeggen dat als we _minder_ willen doen, dit de voor de hand liggende +kandidaat is om te laten vallen. + +Om de dingen in perspectief te zetten: 87,9% van de FreeSewing gebruikers hebben Engels gekozen +als de taal van hun keuze en zullen dus niet beïnvloed worden door zo'n verandering. Van de +overige gebruikers vormen degenen die de voorkeur geven aan Frans het grootste contingent (7%) +gevolgd door Spaans (3,2%), Duits (1,7%), Nederlands (1,1%) en tot slot Oekraïens +(minder dan 0,1%). Ik heb geen gemakkelijke manier om vergelijkbare gegevens te verzamelen voor onze +maar ik kan gerust zeggen dat als je de VS, Canada, het VK, Ierland, +en Australië je ook de overgrote meerderheid van de gebruikers dekt. + +Het spijt me voor de getroffen gebruikers dat het zover heeft moeten komen. Hoewel +vertaling op zich niet al te veel overhead toevoegt (hoewel ik het grootste deel van de +de Nederlandse vertaling, dus het is niet niks), is de grootste boosdoener de technische +complexiteit die komt kijken bij het ondersteunen van meerdere talen. +Dit is ook de reden waarom het schrappen van een of meer talen geen zinvol +verschil. + +Ik deel deze cijfers omdat ze context bieden voor deze veranderingen. +Ze zijn geen rechtvaardiging voor deze veranderingen. Alle gebruikers zijn belangrijk en alle +begunstigers zijn heel belangrijk voor mij. +Het is niet omdat de ene groep kleiner is dan de andere dat we ze onder de +onder de bus moeten gooien. Ik hoop dat dit geen uitleg behoeft. Dat +gezegd hebbende, als er iets gegeven moet worden, vind ik het laten vallen van de vertaling het +de minste impact heeft omdat ik er in de praktijk niet van overtuigd ben dat het veel uitmaakt. + +De browsers van tegenwoordig vertalen pagina's direct en ik heb meer dan eens gezien dat +mensen interactie met de site in het niet-Engels, niet omdat ze kozen voor een +een andere taal kozen, maar eerder omdat hun browser de gewoonte heeft om +om alle Engelse inhoud te vertalen naar de taal van hun voorkeur. +Bovendien, ondanks het geweldige werk van onze vele vrijwillige vertalers, is een +blijft een aanzienlijk deel van de FreeSewing-inhoud machinaal vertaald omdat +er gewoon _veel_ van is. Maakt het echt zoveel uit of het +machinevertaling of de browser? +Ik geloof niet dat het veel uitmaakt. + +Om terug te komen op de cirkel, vind ik het de moeite waard om erop te wijzen dat niemand mij ooit heeft gevraagd +om vertaling toe te voegen aan FreeSewing. Ik besloot het toe te voegen omdat ik het gevoel had dat in +een perfecte wereld, iedereen toegang zou hebben tot FreeSewing in de taal van hun +van hun keuze. Met de manier waarop machine learning (of _AI_ als je wilt) gaat, is die +realiteit misschien al op ons afkomen. + +Ik verontschuldig me voor diegenen voor wie dit slecht nieuws is, en als je gebruik maakt van +FreeSewing gebruikt in uw eigen projecten, wees gerust dat dit niet betekent dat we +dat we vertaalondersteuning uit onze kernbibliotheek verwijderen. + +Om een lang verhaal kort te maken: ik ben tot de ontdekking gekomen dat ik meer heb afgebeten dan ik kan kauwen, +en ik maak aanpassingen om de last te verlichten. +Als u een beter idee heeft over hoe dat te doen, dan ben ik een en al oor. + + +joost + + diff --git a/markdown/org/newsletter/2024q4/uk.md b/markdown/org/newsletter/2024q4/uk.md new file mode 100644 index 00000000000..353982ad143 --- /dev/null +++ b/markdown/org/newsletter/2024q4/uk.md @@ -0,0 +1,343 @@ +--- +date: "2024-10-01" +edition: "2024q4" +intro: "Welcome to the 2024 Autumn edition of the FreeSewing newsletter." +title: "2024 Autumn edition" +--- + +Welcome to the 2024 Autumn edition of the FreeSewing newsletter. + +Here's what we've cobbled together for you: + +- 🕵️ Behind the Seams: Vili (7-minute read by Vili & Karen) +- 🛟 Highlights from the Need Help channel on Discord (2-minte read by Ben) +- 🏋️ Six languages weigh more than one (5-minute read buy Joost) + +Shall we get started? + +  + +  + +  + +  + + +## 🕵️ Behind the Seams: Vili + +We chatted with Vili to learn a little more about their background and journey +to becoming a FreeSewing contributor! Vili has consistently wowed us, both with +their enthusiasm for tackling bugs, typos, and dead links on FreeSewing, as +well as their dedication to a handmade wardrobe. And we mean truly handmade - +Vili’s been working their way through a series of Simon’s created entirely +without a sewing machine. (Note from Vili: I’ve since come around to the idea +of supplementing my hand sewing with a machine.) + +The interview below has been edited for length, and any errors, oversights, +etc. are entirely the fault of the interviewer. + +### How did you learn about FreeSewing? + +I started sewing about two years ago, and I had an ebook on things you can do +without a pattern. I think it was called Radical Sewing. There were resources +at the end that mentioned FreeSewing. Open source, programmatic, parametric +patterns? Sold. + +### How did you become a contributor? + +I’m studying computer science, focusing on networking and system +administration. I was interested early in contributing something back to the +project, and then noticed a bug where some links to pattern option +documentation weren’t showing up. I submitted an issue, and mentioned I could +take a stab at it, and Joost being Joost came back with a super detailed list +of what was wrong and how to fix it. So I did. + +### What has been your contributor work so far? + +Mostly I’ve contributed minor quality of life improvements. If there’s a bug in +a pattern that’s causing a crash that’s easy to fix, I’ll take a look at it. +Also a lot of dead links. My favorite was when there were quite a few dead +links on the dev side of things, which went to a 404 page, and the “let us +know” link on the 404 page was also a dead link. + +### How do you spend your time outside of FreeSewing? + +Besides FreeSewing and sewing, I spend my time on a lot of computer stuff. I +host a lot of stuff for my own personal use. + +### What are you currently working on? Finish any projects recently? + +On the FreeSewing side of things, more of the same: fixing bugs, housekeeping, +and dead link extermination on the freesewing.org side of the site. + +On the sewing side of things… Simons! I took a bit of a break, but am back at +it with something that is starting to resemble a shirt. I’m 26.5 hours into +making this current Simon. I don’t actually care how long it takes, but I want +to know, plus I’m curious if I’m getting faster. My first one took 60 hours, so +still plenty of time to come in under that. + +### Did you make any updates after your last Simon? Do you have plans to sew any other patterns? + +Well, first I retook all my measurements.Surprisingly enough, when your +measurements aren’t complete garbage, the patterns come out nicer. When I had +measurements that were more (or at all) accurate, all the things that I knew I +needed to fix about the pattern kind of fixed themselves in a lot of cases. + +Beyond this Simon, I want to sew more Teagans, some Bruces, and I have four +more Simons to go (I have the fabric for them). + +### What sewing/coding project are you most proud of? + +I thought this would be an easy question because you just say “the last Simon I +made.” I think it still might be the last Simon I made, and when I get done +with this one, it’s gonna be this Simon. I think the pride in a project comes +from “we did something cool here,” but the enjoyment… if I learn something new +on a project, that’s more enjoyable. + +### What in your life are you most proud of? + +In general, I try to have an overall positive impact on the people around me. I +get a lot out of helping others, and supporting the people around me. + +### What do you love the most about sewing? + +I think what I love the most is the freedom to just decide for yourself what +exactly you’re going to be wearing. If I want a specific garment, I’m not +depending on someone else deciding it’s profitable, I can just make the garment +I want. + +### What do you hate the most about sewing? + +Tracing and cutting out pattern pieces – If I could just get my patterns precut +from the fabric I want, I think that’d be pretty good. I’m often working with +fabrics where the grainline is extremely obvious, and any imperfection is going +to show up immediately. I try to pattern match to an extent, the fronts and +backs match, and that’s about as far as I will go. + +### What’s the hardest part of sewing to you? + +Actually, either getting the pattern pieces traced and cut out of fabric, or +just getting the patterns to fit. For my second Simon, I didn’t do any fitting, +because I could compare the pattern pieces to the first one. I looked at the +differences, and felt pretty sure they’d fix the issues I was having. For the +first Simon, I went through five or six muslins, cut out the pieces, and did a +combination of running stitch and backstitch here and there to lock it in so it +didn’t take forever. But it still took a long time. + +### What would be your advice for starting sewists? + +A lot of it is going to come down to finding your motivation for sewing, and +picking a project that is going to motivate you. There’s a lot of beginner +friendly projects, but if you’re not interested in it, you’re just going to +stop doing it. Find out what you’re interested in, then figure out what skills +you need to do it. + +My first two garments were hand-sewn Teagans – it was trial and error to figure +out what stitches actually worked, and it eventually worked great, but the +first one is a lot rougher, I think there are three or four types of stitches +on the first Teagan. Eventually something is gonna stick. + +### Do you sew mostly for yourself, or for others like friends and family? + +I haven’t sewn any garments for anyone else. I did make three burp cloths for +my brothers kids baby shower, but that’s the only thing. + +### Are you a dog person or a cat person? + +More of a dog person, but I will happily pet and cuddle both. + +### If there was one thing you could take with you to an uninhabited island, what would it be? Why? + +Is this a survival situation, or a get-away-from-civilization situation? + +For a get-away-from-civilization situation, I think it’s going to be a sewing +project. That’s the one thing I do that’s properly unplugged from everything. +One of the things I love about sewing by hand, I can just grab the fabric and a +very minimal set of things and sew pretty much anywhere. + +I recently came up with a super-minimal sewing kit with a friend, and I’m +pretty proud of it. A seam ripper, with the cover holding a pin, a needle, and +some thread wrapped around the shaft of the seam ripper. Weighs absolutely +nothing, takes up no space, has everything I need, you can take it anywhere. +And if you do need to cut something, a seam ripper is better than nothing. + +### If there was one person you could take with you to an uninhabited island, who would it be? Why? + +Any single person you bring with you, you’re gonna hate by the end of a couple +of weeks. But going alone, you’re also going to go insane. I’d gravitate most +to picking a volunteer out of my friends or family. + +### Can we find you on social media? + +I’m not on any social media, but you can check out one of my FreeSewing +showcases [here](https://freesewing.org/showcase/hand-sewn-test-of-florence) +and stay tuned for some Simon showcases. + + +  + +--- + +  + +## 🛟 Highlights from the Need Help channel on Discord + +FreeSewing superstar Ben F. pulled together some recent highlights from the +`#need-help` channel on the [FreeSewing +Discord](https://discord.freesewing.org/). + +If you've run into trouble with a pattern, your answer might just be one of +these. If you've run into an issue, hop on over to the Discord for support and +discussion about ways to troubleshoot. + +### Jaeger sleeve circumference + +A sleeve that doesn't fit because sleeve circumference is smaller than biceps +circumference? For v3 FreeSewing designs, it was noted that the "Waist to +armpit", "HPS to waist", and "HPS to bust" measurements have become very +important. Inaccurate measurements can result in incorrect armseye and sleeve +circumferences. + +### Please help! Messed up Hugo measurements + +Too small sleevecap and armscye? Another issue with v3 FreeSewing sleeves due +to an inaccurate "Waist to armpit" measurement. Enabling the "Legacy armhole +depth" option to use v2 armholes (instead of using the "Waist to armpit" +measurement) is another possible remedy. + +### My Bruce Pants are... Pants! + +An initial attempt at making Bruce boxer briefs resulted in a too-short +garment? The fix was to correctly locate the location of the waist and retake +the "Waist to upper leg" measurement. + +### Uneven shoulder measurements + +How to deal with a medical issue causing the left and right shoulder +measurements to be significantly different? Ideas for creating garments to +accommodate this issue could include generating separate patterns for left and +right sides (using two different measurement sets), making garments with a +center separating zipper, and using a diagonal/asymmetrical hem. + +### Sewing leather on a Singer + +Using a jeans needle successfully pokes holes in the leather, but the thread +doesn't seem to be creating stitches? Tips to use a microtex or leather needle +and to make sure the leather fabric is feeding properly. + +### Cross seam measurement: + +How do you measure the cross seam measurement: nude, with tight-fitting +underwear, or with good-fitting pants on? Suggestions included measuring while +wearing the underwear intended to be worn with the garment, tying a ribbon +around the waist and using a second ribbon along the cross seam, and taking the +measurement while walking. Also, double-check your vertical measurements if +your pattern isn't fitting correctly in the crotch area. + + +  + +--- + +  + + +## 🏋️ Six languages weigh more than one + +Without wanting to alarm anyone, I recently suffered a bit of a crisis +feeling completely overwhelmed by all the work that is sitting in my inbox. +It's arguably not really new, and I don't think anyone is waiting for yet another +open source maintainer apologizing for being busy. + +However, this was the first time this feeling crossed over from _phew, this is +a lot_ into _I can't do this any longer_ teritory. + +It's always darkest before dawn, and now that I've acknowledged that there's a +problem and came up with a plan to deal with it (which I'll get to in a second) +I'm feeling much better already, so no need to worry about me. However, I want +to be open and honest about where these changes are coming from and why I'm +making them. + +What changes? Well, effective immediately, I will work towards making +FreeSewing simpler to maintain, and put more strict boundaries and what we do +and what we don't do. + +I've already ported [FreeSewing.dev](https://freesewing.dev/) to +[Docusaurus](https://docusaurus.io/), which makes it a lot easier to maintain. +There will be more under-the-hood changes like these that make our life eaiser, +without creating a material difference to our users. + +Unfortunately, that alone won't cut it, so I also intent to drop support +for translation, and only maintain English from now onwards. +This too will go unnoticed for the vast majority of our users, but obviously +not for all of them. + +In May 2018, I wrote the following on the subject: + +> *I’ve decided to add a new challenge to the mix: i18n.* +> +> *In case you’re wondering, i18n is short for internationalisation, aka making +> the site available in different languages.* +> +> *Yes, May 25th will be here soon, and yes I need more work like I need +> another hole in my head. But I feel it’s an important project to try and make +> freesewing.org available to as many people as possible. And for this, we need +> to get rid of the language barrier.* + +Six and a half years later, I still believe that removing the language +barrier is important to reach as many people as possible. But I also think that +it's fair to say that if we are looking to do _less_ then this is the obvious +candidate of things to drop. + +To put things in perspective: 87.9% of FreeSewing users have selected English +as their language of choice and thus will be unaffected by such a move. Of the +remaining users, those who prefer French form the largest contingent (7%) +followed by Spanish (3.2%), German (1.7%), Dutch (1.1%) and finally Ukranian +(less then 0.1%). I don't have an easy way to extract similar data for our +patrons, but I can safely say that if you combine the US, Canada, UK, Ireland, +and Australia you have covered the vast majority of patrons too. + +To those users who are affected, I am sorry that it has come to this. While +translation as such does not add too much overhead (although I handle most of +the Dutch translation so it's not nothing), the main culprit is the technical +complexity that comes from supporting multiple languages. +This is also why dropping one or more languages does not make a meaningful +difference. + +I'm sharing these numbers because they provide context to frame these changes. +They are not a justification for these changes. All users matter, and all +patrons matter the world to me. +Just because one group is smaller than another does not mean we should throw +them under the bus. I hope that's something that needs no explaining. That +being said, when something's gotta give, I feel dropping translation is the +least impactful because in practice, I'm not convinced it matters all that much. + +Today's browsers will translate pages on the fly, and I've more than once seen +people interact with the site in non-English, not because they opted for a +different language, but rather because their browser is in the habit of +translating all English content to whatever is their prefered language. +Furthermore, despite the great work of our many volunteer translators, a +significant amount of FreeSewing content remains machine-translated because +there's just _a lot_ of it. Does it really matter all that much whether it's +us providing the (machine) translation or the browser? +I don't believe it matters all that much. + +To come full cirlce, I feel it's worth pointing out that nobody has ever asked +me to add translation to FreeSewing. I decided to add it because I felt that in +a perfect world, everyone could access FreeSewing in the language of their +choice. With the way machine learning (or _AI_ if you want) is going, that +reality is perhaps already upon us. + +I apologize to those of you for which this is bad news, and if you are using +FreeSewing in your own projects, rest assured that this does not mean we are +removing translation support from our core library. + +Long story short: I have come to realize I've bitten of more than I can chew, +and I am making adjustments to lighten the load. +If you have a better idea on how to do that, I'm all ears. + + +joost + + diff --git a/markdown/org/showcase/colorful-hi-by-zag/en.md b/markdown/org/showcase/colorful-hi-by-zag/en.md index ab85c293446..3bed8a392d8 100644 --- a/markdown/org/showcase/colorful-hi-by-zag/en.md +++ b/markdown/org/showcase/colorful-hi-by-zag/en.md @@ -5,6 +5,7 @@ date: "2023-01-22" intro: "Super Colorful Hi by Zag" title: "Super Colorful Hi by Zag" designs: ["hi"] +author: 28322 --- FreeSewing user Zag shared this about their new teeny tiny Hi: "I made an itty bitty Hi (I'm renting so can't fit a full size one 😆), with loads of colours to fit my gender! I did it by hand so I made everything way more difficult for myself, and it was hard doing it so small (20%), but got there in the end." diff --git a/markdown/org/showcase/doll-cathrin/en.md b/markdown/org/showcase/doll-cathrin/en.md index aab13996e7d..1047bd38f48 100644 --- a/markdown/org/showcase/doll-cathrin/en.md +++ b/markdown/org/showcase/doll-cathrin/en.md @@ -5,6 +5,7 @@ date: "2021-10-23" intro: "The brilliant MagicantAce is back with another doll pattern, this tiny Cathrin corset!" title: "A doll version of Cathrin" designs: ["cathrin"] +author: 24546 --- The brilliant MagicantAce is back with another doll pattern, this tiny Cathrin corset! diff --git a/markdown/org/showcase/gender-euphoric-bruces/en.md b/markdown/org/showcase/gender-euphoric-bruces/en.md index 1e7f7f3bafd..2ea3c10fea6 100644 --- a/markdown/org/showcase/gender-euphoric-bruces/en.md +++ b/markdown/org/showcase/gender-euphoric-bruces/en.md @@ -5,6 +5,7 @@ date: "2022-07-29" intro: "Gender euphoric Bruces" title: "Gender euphoric Bruces" designs: ["bruce"] +author: 28322 --- Zag (she/they/any) made these Bruce boxers with a flat front and rainbow elastic! They reported "Gender euphoria to the max, thank you for this pattern!" which is just about the best compliment we could ask for. diff --git a/markdown/org/showcase/short-sleeved-simon/en.md b/markdown/org/showcase/short-sleeved-simon/en.md new file mode 100644 index 00000000000..84e1c27a8c7 --- /dev/null +++ b/markdown/org/showcase/short-sleeved-simon/en.md @@ -0,0 +1,13 @@ +--- +title: "Short-sleeved Simon" +caption: "Photo of the shirt on a hanger." +date: 20240922 +intro: " I saw this fun Halloween fabric and knew I needed to make a shirt!" +author: starfirebird +designs: ["simon"] +--- + + + +![The image alt goes here](https://imagedelivery.net/ouSuR9yY1bHt-fuAokSA5Q/showcase-short-sleeved-simon-1/public "Photo of the shirt being worn") + diff --git a/markdown/org/showcase/sleeveless-simon-by-lasermonkey12/en.md b/markdown/org/showcase/sleeveless-simon-by-lasermonkey12/en.md index 8774c043ff3..a78bd717c48 100644 --- a/markdown/org/showcase/sleeveless-simon-by-lasermonkey12/en.md +++ b/markdown/org/showcase/sleeveless-simon-by-lasermonkey12/en.md @@ -5,7 +5,7 @@ date: 20240106 intro: "Maker lasermonkey12 has made lots of great Simon shirts, including this sleeveless one." designs: ["simone"] maker: lasermonkey12 -author: 22007 +author: 31287 --- Maker lasermonkey12 has made lots of great Simon and Simone shirts. This sleeveless one is a Simone. We love the fresh look, well-suited for hot weather! This was shared on [Discord](https://discord.freesewing.org/) and is reposted here with permission. diff --git a/markdown/org/showcase/watermelon-charlie-chinos/en.md b/markdown/org/showcase/watermelon-charlie-chinos/en.md index eb1034f02f3..8f725dd6d89 100644 --- a/markdown/org/showcase/watermelon-charlie-chinos/en.md +++ b/markdown/org/showcase/watermelon-charlie-chinos/en.md @@ -3,7 +3,7 @@ title: "Watermelon Charlie Chinos" caption: "Splash of green on the right, splash of pink on the left" date: 20240615 intro: "Watermelon 🍉 Themed Pants!" -author: null +author: 61987 designs: ["charlie"] --- diff --git a/package.json b/package.json index bc53ae97453..6669e52ee65 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-mongo": "^1.0.5", "eslint-plugin-yaml": "^0.5.0", + "execa": "^9.3.1", "husky": "^9.0.10", "js-yaml": "^4.0.0", "lerna": "^8.0.0", diff --git a/packages/new-design/lib/download-list.mjs b/packages/new-design/lib/download-list.mjs index d73fb0b799f..e8c60c24feb 100644 --- a/packages/new-design/lib/download-list.mjs +++ b/packages/new-design/lib/download-list.mjs @@ -1,5 +1,5 @@ export const downloads = { - sites: [ + 'sites': [ 'sde/README.md', 'sde/env.local', 'sde/i18n.config.mjs', @@ -22,7 +22,6 @@ export const downloads = { 'sde/mock/youtube.mjs', 'sde/pkgs/.gitkeep', 'sde/prebuild/.gitkeep', - 'sde/prebuild/sitenav.de.mjs', 'sde/prebuild/sitenav.en.mjs', 'sde/prebuild/sitenav.es.mjs', 'sde/prebuild/sitenav.fr.mjs', @@ -30,111 +29,222 @@ export const downloads = { 'sde/prebuild/sitenav.nl.mjs', 'sde/prebuild/sitenav.uk.mjs', 'sde/prebuild/sluglut.mjs', + 'sde/prebuild/sitenav.de.mjs', 'sde/components/design-examples.mjs', 'sde/components/dynamic-org-docs.mjs', 'sde/components/feeds.mjs', 'sde/components/search.mjs', - 'sde/components/header/design-picker.mjs', 'sde/components/header/index.mjs', + 'sde/components/header/design-picker.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/components/navigation/modal-menu.mjs', + 'sde/pages/_app.mjs', + 'sde/pages/account.mjs', + 'sde/pages/design.mjs', + 'sde/pages/index.mjs', + 'sde/pages/design/[design].mjs', + 'sde/pages/sde/en.yaml', + 'sde/pages/sde/es.yaml', + 'sde/pages/sde/de.yaml', + 'sde/pages/sde/fr.yaml', + 'sde/pages/sde/index.mjs', + 'sde/pages/sde/uk.yaml', + 'sde/pages/sde/nl.yaml', + 'sde/pages/signup/index.mjs', + 'sde/pages/signin/index.mjs', + 'sde/pages/signin/callback/[provider].mjs', 'sde/design/from-bella/en.json', - 'sde/design/from-bella/i18n/de.json', - 'sde/design/from-bella/i18n/en.json', - 'sde/design/from-bella/i18n/es.json', - 'sde/design/from-bella/i18n/fr.json', - 'sde/design/from-bella/i18n/index.mjs', - 'sde/design/from-bella/i18n/nl.json', - 'sde/design/from-bella/i18n/uk.json', 'sde/design/from-bella/src/back.mjs', 'sde/design/from-bella/src/front.mjs', 'sde/design/from-bella/src/index.mjs', + 'sde/design/from-bella/i18n/de.json', + 'sde/design/from-bella/i18n/en.json', + 'sde/design/from-bella/i18n/es.json', + 'sde/design/from-bella/i18n/index.mjs', + 'sde/design/from-bella/i18n/fr.json', + 'sde/design/from-bella/i18n/nl.json', + 'sde/design/from-bella/i18n/uk.json', '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/index.mjs', '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/back.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/src/top-sleeve.mjs', 'sde/design/from-breanna/i18n/de.json', 'sde/design/from-breanna/i18n/en.json', - 'sde/design/from-breanna/i18n/es.json', - 'sde/design/from-breanna/i18n/fr.json', 'sde/design/from-breanna/i18n/index.mjs', 'sde/design/from-breanna/i18n/nl.json', + 'sde/design/from-breanna/i18n/fr.json', + 'sde/design/from-breanna/i18n/es.json', 'sde/design/from-breanna/i18n/uk.json', 'sde/design/from-breanna/src/back.mjs', '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/i18n/de.json', - 'sde/design/from-brian/i18n/en.json', - 'sde/design/from-brian/i18n/es.json', - 'sde/design/from-brian/i18n/fr.json', - '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', - 'sde/design/from-scratch/i18n/fr.json', - 'sde/design/from-scratch/i18n/index.mjs', - 'sde/design/from-scratch/i18n/nl.json', - 'sde/design/from-scratch/i18n/uk.json', - 'sde/design/from-scratch/src/bib.mjs', - 'sde/design/from-scratch/src/index.mjs', 'sde/design/from-titan/i18n/de.json', - 'sde/design/from-titan/i18n/en.json', 'sde/design/from-titan/i18n/es.json', - 'sde/design/from-titan/i18n/fr.json', + 'sde/design/from-titan/i18n/en.json', 'sde/design/from-titan/i18n/index.mjs', - 'sde/design/from-titan/i18n/nl.json', + 'sde/design/from-titan/i18n/fr.json', 'sde/design/from-titan/i18n/uk.json', + 'sde/design/from-titan/i18n/nl.json', 'sde/design/from-titan/src/back.mjs', 'sde/design/from-titan/src/front.mjs', 'sde/design/from-titan/src/index.mjs', - 'sde/design/tutorial/i18n/de.json', - 'sde/design/tutorial/i18n/en.json', 'sde/design/tutorial/i18n/es.json', + 'sde/design/tutorial/i18n/en.json', + 'sde/design/tutorial/i18n/de.json', 'sde/design/tutorial/i18n/fr.json', 'sde/design/tutorial/i18n/index.mjs', 'sde/design/tutorial/i18n/nl.json', 'sde/design/tutorial/i18n/uk.json', 'sde/design/tutorial/src/bib.mjs', 'sde/design/tutorial/src/index.mjs', - 'sde/pages/_app.mjs', - 'sde/pages/account.mjs', - 'sde/pages/design.mjs', - 'sde/pages/index.mjs', - 'sde/pages/design/[design].mjs', - 'sde/pages/sde/de.yaml', - 'sde/pages/sde/en.yaml', - 'sde/pages/sde/es.yaml', - 'sde/pages/sde/fr.yaml', - 'sde/pages/sde/index.mjs', - 'sde/pages/sde/nl.yaml', - 'sde/pages/sde/uk.yaml', - 'sde/pages/signup/index.mjs', - 'sde/pages/signin/index.mjs', - 'sde/pages/signin/callback/[provider].mjs', - 'sde/public/brands/algolia.svg', + 'sde/design/from-scratch/i18n/de.json', + 'sde/design/from-scratch/i18n/en.json', + 'sde/design/from-scratch/i18n/nl.json', + 'sde/design/from-scratch/i18n/uk.json', + 'sde/design/from-scratch/i18n/index.mjs', + 'sde/design/from-scratch/i18n/es.json', + 'sde/design/from-scratch/i18n/fr.json', + 'sde/design/from-scratch/src/bib.mjs', + 'sde/design/from-scratch/src/index.mjs', + 'sde/design/from-brian/i18n/de.json', + 'sde/design/from-brian/i18n/en.json', + 'sde/design/from-brian/i18n/fr.json', + 'sde/design/from-brian/i18n/nl.json', + 'sde/design/from-brian/i18n/es.json', + 'sde/design/from-brian/i18n/index.mjs', + '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/public/brands/bugsnag.svg', - 'sde/public/brands/crowdin.svg', + 'sde/public/brands/algolia.svg', 'sde/public/brands/netlify.svg', 'sde/public/brands/vercel.svg', + 'sde/public/brands/crowdin.svg', 'sde/public/img/lineup-backdrop.svg', + '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/fromscratch.json', + 'sde/public/locales/es/fromtitan.json', + 'sde/public/locales/es/frombrian.json', + 'sde/public/locales/es/gdpr.json', + 'sde/public/locales/es/hodl.json', + 'sde/public/locales/es/header.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/sde.json', + 'sde/public/locales/es/roles.json', + 'sde/public/locales/es/sections.json', + 'sde/public/locales/es/sets.json', + 'sde/public/locales/es/sponsors.json', + 'sde/public/locales/es/stats.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/fr/account.json', + 'sde/public/locales/fr/auth.json', + 'sde/public/locales/fr/bella.json', + 'sde/public/locales/fr/bent.json', + 'sde/public/locales/fr/breanna.json', + 'sde/public/locales/fr/brian.json', + 'sde/public/locales/fr/common.json', + 'sde/public/locales/fr/core-settings.json', + 'sde/public/locales/fr/curate.json', + 'sde/public/locales/fr/cut.json', + 'sde/public/locales/fr/designs.json', + 'sde/public/locales/fr/docs.json', + 'sde/public/locales/fr/errors.json', + 'sde/public/locales/fr/flag.json', + 'sde/public/locales/fr/design-options.json', + 'sde/public/locales/fr/footer.json', + 'sde/public/locales/fr/frombella.json', + 'sde/public/locales/fr/frombent.json', + 'sde/public/locales/fr/frombreanna.json', + 'sde/public/locales/fr/frombrian.json', + 'sde/public/locales/fr/fromscratch.json', + 'sde/public/locales/fr/fromtitan.json', + 'sde/public/locales/fr/gdpr.json', + 'sde/public/locales/fr/hodl.json', + 'sde/public/locales/fr/header.json', + 'sde/public/locales/fr/lab.json', + 'sde/public/locales/fr/locales.json', + 'sde/public/locales/fr/logs.json', + 'sde/public/locales/fr/homepage.json', + 'sde/public/locales/fr/measurements.json', + 'sde/public/locales/fr/modal.json', + 'sde/public/locales/fr/newsletter.json', + 'sde/public/locales/fr/plugin-annotations.json', + 'sde/public/locales/fr/plugins.json', + 'sde/public/locales/fr/popout.json', + 'sde/public/locales/fr/print.json', + 'sde/public/locales/fr/sde.json', + 'sde/public/locales/fr/sections.json', + 'sde/public/locales/fr/patrons.json', + 'sde/public/locales/fr/sets.json', + 'sde/public/locales/fr/roles.json', + 'sde/public/locales/fr/status.json', + 'sde/public/locales/fr/sponsors.json', + 'sde/public/locales/fr/submissions.json', + 'sde/public/locales/fr/stats.json', + 'sde/public/locales/fr/susi.json', + 'sde/public/locales/fr/tags.json', + 'sde/public/locales/fr/techniques.json', + 'sde/public/locales/fr/themes.json', + 'sde/public/locales/fr/support.json', + 'sde/public/locales/fr/timeago.json', + 'sde/public/locales/fr/titan.json', + 'sde/public/locales/fr/tutorial.json', + 'sde/public/locales/fr/ui-settings.json', + 'sde/public/locales/fr/workbench.json', 'sde/public/locales/de/account.json', 'sde/public/locales/de/auth.json', 'sde/public/locales/de/bella.json', @@ -142,23 +252,23 @@ export const downloads = { 'sde/public/locales/de/breanna.json', 'sde/public/locales/de/brian.json', 'sde/public/locales/de/common.json', - 'sde/public/locales/de/core-settings.json', 'sde/public/locales/de/curate.json', + 'sde/public/locales/de/core-settings.json', 'sde/public/locales/de/cut.json', 'sde/public/locales/de/design-options.json', 'sde/public/locales/de/designs.json', - 'sde/public/locales/de/docs.json', - 'sde/public/locales/de/errors.json', 'sde/public/locales/de/flag.json', + 'sde/public/locales/de/docs.json', 'sde/public/locales/de/footer.json', + 'sde/public/locales/de/errors.json', 'sde/public/locales/de/frombella.json', 'sde/public/locales/de/frombent.json', - 'sde/public/locales/de/frombreanna.json', 'sde/public/locales/de/frombrian.json', - 'sde/public/locales/de/fromscratch.json', 'sde/public/locales/de/fromtitan.json', 'sde/public/locales/de/gdpr.json', 'sde/public/locales/de/header.json', + 'sde/public/locales/de/fromscratch.json', + 'sde/public/locales/de/frombreanna.json', 'sde/public/locales/de/hodl.json', 'sde/public/locales/de/homepage.json', 'sde/public/locales/de/lab.json', @@ -245,116 +355,6 @@ export const downloads = { 'sde/public/locales/en/tutorial.json', 'sde/public/locales/en/ui-settings.json', 'sde/public/locales/en/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/stats.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/fr/account.json', - 'sde/public/locales/fr/auth.json', - 'sde/public/locales/fr/bella.json', - 'sde/public/locales/fr/bent.json', - 'sde/public/locales/fr/breanna.json', - 'sde/public/locales/fr/brian.json', - 'sde/public/locales/fr/common.json', - 'sde/public/locales/fr/core-settings.json', - 'sde/public/locales/fr/curate.json', - 'sde/public/locales/fr/cut.json', - 'sde/public/locales/fr/design-options.json', - 'sde/public/locales/fr/designs.json', - 'sde/public/locales/fr/docs.json', - 'sde/public/locales/fr/errors.json', - 'sde/public/locales/fr/flag.json', - 'sde/public/locales/fr/footer.json', - 'sde/public/locales/fr/frombella.json', - 'sde/public/locales/fr/frombent.json', - 'sde/public/locales/fr/frombreanna.json', - 'sde/public/locales/fr/frombrian.json', - 'sde/public/locales/fr/fromscratch.json', - 'sde/public/locales/fr/fromtitan.json', - 'sde/public/locales/fr/gdpr.json', - 'sde/public/locales/fr/header.json', - 'sde/public/locales/fr/hodl.json', - 'sde/public/locales/fr/homepage.json', - 'sde/public/locales/fr/lab.json', - 'sde/public/locales/fr/locales.json', - 'sde/public/locales/fr/logs.json', - 'sde/public/locales/fr/measurements.json', - 'sde/public/locales/fr/modal.json', - 'sde/public/locales/fr/newsletter.json', - 'sde/public/locales/fr/patrons.json', - 'sde/public/locales/fr/plugin-annotations.json', - 'sde/public/locales/fr/plugins.json', - 'sde/public/locales/fr/popout.json', - 'sde/public/locales/fr/print.json', - 'sde/public/locales/fr/roles.json', - 'sde/public/locales/fr/sde.json', - 'sde/public/locales/fr/sections.json', - 'sde/public/locales/fr/sets.json', - 'sde/public/locales/fr/sponsors.json', - 'sde/public/locales/fr/stats.json', - 'sde/public/locales/fr/status.json', - 'sde/public/locales/fr/submissions.json', - 'sde/public/locales/fr/support.json', - 'sde/public/locales/fr/susi.json', - 'sde/public/locales/fr/tags.json', - 'sde/public/locales/fr/techniques.json', - 'sde/public/locales/fr/themes.json', - 'sde/public/locales/fr/timeago.json', - 'sde/public/locales/fr/titan.json', - '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', @@ -466,270 +466,270 @@ export const downloads = { 'sde/public/locales/uk/ui-settings.json', 'sde/public/locales/uk/workbench.json', 'shared/utils.mjs', - 'shared/components/mdx/dynamic.mjs', - 'shared/components/mdx/design-measurements.mjs', + 'shared/components/icons.mjs', 'shared/components/mdx/design-options.mjs', + 'shared/components/mdx/dynamic.mjs', 'shared/components/mdx/index.mjs', - 'shared/components/footer/index.mjs', - 'shared/components/buttons/continue-button.mjs', - 'shared/components/patrons/please-subscribe.mjs', - 'shared/components/patrons/plea.mjs', - 'shared/components/patrons/subscribe.mjs', - 'shared/components/susi/sign-in.mjs', - 'shared/components/susi/sign-up.mjs', - 'shared/components/account/shared.mjs', - 'shared/components/account/control.mjs', - 'shared/components/account/sets.mjs', - 'shared/components/popout/index.mjs', - 'shared/components/robot/index.mjs', - 'shared/components/robot/poses.mjs', - 'shared/components/inputs.mjs', - 'shared/components/collapse.mjs', - 'shared/components/wordmark.mjs', - 'shared/components/link.mjs', - 'shared/components/error/view.mjs', - 'shared/components/accordion.mjs', - 'shared/components/wrappers/mdx.mjs', - 'shared/components/wrappers/page.mjs', - 'shared/components/wrappers/swipes.mjs', - 'shared/components/wrappers/modal.mjs', - 'shared/components/wrappers/layout.mjs', - 'shared/components/wrappers/context.mjs', - 'shared/components/wrappers/chart.mjs', - 'shared/components/wrappers/auth/index.mjs', + 'shared/components/mdx/design-measurements.mjs', + 'shared/components/header.mjs', 'shared/components/wrappers/header.mjs', - 'shared/components/control/tip.mjs', - 'shared/components/control/score.mjs', - 'shared/components/choice-link.mjs', - 'shared/components/copy-to-clipboard.mjs', - 'shared/components/code-box.mjs', + 'shared/components/wrappers/context.mjs', + 'shared/components/wrappers/layout.mjs', + 'shared/components/wrappers/auth/index.mjs', + 'shared/components/wrappers/page.mjs', + 'shared/components/wrappers/modal.mjs', + 'shared/components/wrappers/swipes.mjs', + 'shared/components/wrappers/mdx.mjs', + 'shared/components/wrappers/chart.mjs', + 'shared/components/footer/index.mjs', + 'shared/components/v3-wip.mjs', 'shared/components/designs/difficulty.mjs', 'shared/components/designs/info.mjs', - 'shared/components/measurements/tim/head.svg', - 'shared/components/measurements/tim/highbust.svg', - 'shared/components/measurements/tim/upperleg.svg', - 'shared/components/measurements/tim/hpstowaistback.svg', - 'shared/components/measurements/tim/chest.svg', - 'shared/components/measurements/tim/biceps.svg', - 'shared/components/measurements/tim/inseam.svg', - 'shared/components/measurements/tim/waisttoknee.svg', - 'shared/components/measurements/tim/knee.svg', - 'shared/components/measurements/tim/shouldertowrist.svg', - 'shared/components/measurements/tim/waisttoarmpit.svg', - 'shared/components/measurements/tim/neck.svg', - 'shared/components/measurements/tim/shouldertoelbow.svg', - 'shared/components/measurements/tim/shoulderslope.svg', - 'shared/components/measurements/tim/waisttofloor.svg', - 'shared/components/measurements/tim/hips.svg', - 'shared/components/measurements/tim/bustfront.svg', - 'shared/components/measurements/tim/waisttounderbust.svg', - 'shared/components/measurements/tim/bustpointtounderbust.svg', - 'shared/components/measurements/tim/crossseam.svg', - 'shared/components/measurements/tim/underbust.svg', - 'shared/components/measurements/tim/hpstobust.svg', - 'shared/components/measurements/tim/ankle.svg', - 'shared/components/measurements/tim/wrist.svg', - 'shared/components/measurements/tim/seatback.svg', - 'shared/components/measurements/tim/waisttoseat.svg', - 'shared/components/measurements/tim/shouldertoshoulder.svg', - 'shared/components/measurements/tim/index.mjs', - 'shared/components/measurements/tim/bustspan.svg', - 'shared/components/measurements/tim/acrossback.svg', - 'shared/components/measurements/tim/hipstoupperleg.svg', - 'shared/components/measurements/tim/waist.svg', - 'shared/components/measurements/tim/heel.svg', - 'shared/components/measurements/tim/waistback.svg', - 'shared/components/measurements/tim/hpstowaistfront.svg', - 'shared/components/measurements/tim/crotchdepth.svg', - 'shared/components/measurements/tim/highbustfront.svg', - 'shared/components/measurements/tim/waisttoupperleg.svg', - 'shared/components/measurements/tim/crossseamfront.svg', - 'shared/components/measurements/tim/seat.svg', - 'shared/components/measurements/tim/waisttohips.svg', - 'shared/components/measurements/image.mjs', - 'shared/components/measurements/sarah/head.svg', - 'shared/components/measurements/sarah/highbust.svg', - 'shared/components/measurements/sarah/upperleg.svg', - 'shared/components/measurements/sarah/hpstowaistback.svg', - 'shared/components/measurements/sarah/chest.svg', - 'shared/components/measurements/sarah/biceps.svg', - 'shared/components/measurements/sarah/inseam.svg', - 'shared/components/measurements/sarah/waisttoknee.svg', - 'shared/components/measurements/sarah/knee.svg', - 'shared/components/measurements/sarah/shouldertowrist.svg', - 'shared/components/measurements/sarah/waisttoarmpit.svg', - 'shared/components/measurements/sarah/neck.svg', - 'shared/components/measurements/sarah/shouldertoelbow.svg', - 'shared/components/measurements/sarah/shoulderslope.svg', - 'shared/components/measurements/sarah/waisttofloor.svg', - 'shared/components/measurements/sarah/hips.svg', - 'shared/components/measurements/sarah/bustfront.svg', - 'shared/components/measurements/sarah/waisttounderbust.svg', - 'shared/components/measurements/sarah/bustpointtounderbust.svg', - 'shared/components/measurements/sarah/crossseam.svg', - 'shared/components/measurements/sarah/underbust.svg', - 'shared/components/measurements/sarah/hpstobust.svg', - 'shared/components/measurements/sarah/ankle.svg', - 'shared/components/measurements/sarah/wrist.svg', - 'shared/components/measurements/sarah/seatback.svg', - 'shared/components/measurements/sarah/waisttoseat.svg', - 'shared/components/measurements/sarah/shouldertoshoulder.svg', - 'shared/components/measurements/sarah/index.mjs', - 'shared/components/measurements/sarah/bustspan.svg', - 'shared/components/measurements/sarah/acrossback.svg', - 'shared/components/measurements/sarah/hipstoupperleg.svg', - 'shared/components/measurements/sarah/waist.svg', - 'shared/components/measurements/sarah/heel.svg', - 'shared/components/measurements/sarah/waistback.svg', - 'shared/components/measurements/sarah/hpstowaistfront.svg', - 'shared/components/measurements/sarah/crotchdepth.svg', - 'shared/components/measurements/sarah/highbustfront.svg', - 'shared/components/measurements/sarah/waisttoupperleg.svg', - 'shared/components/measurements/sarah/crossseamfront.svg', - 'shared/components/measurements/sarah/seat.svg', - 'shared/components/measurements/sarah/waisttohips.svg', - 'shared/components/gdpr/details.mjs', - 'shared/components/gdpr/form.mjs', - 'shared/components/breadcrumbs.mjs', - 'shared/components/v3-wip.mjs', - 'shared/components/joost.mjs', - 'shared/components/modal/theme-picker.mjs', - 'shared/components/modal/locale-picker.mjs', - 'shared/components/bookmarks.mjs', - 'shared/components/tabs.mjs', - 'shared/components/social/icons.mjs', - 'shared/components/icons.mjs', + 'shared/components/buttons/continue-button.mjs', + 'shared/components/copy-to-clipboard.mjs', + 'shared/components/patrons/plea.mjs', + 'shared/components/patrons/please-subscribe.mjs', + 'shared/components/patrons/subscribe.mjs', 'shared/components/spinner.mjs', - 'shared/components/sponsors/bugsnag.mjs', - 'shared/components/sponsors/vercel.mjs', + 'shared/components/choice-link.mjs', + 'shared/components/navigation/sections-menu.mjs', + 'shared/components/navigation/primary.mjs', + 'shared/components/navigation/sitenav.mjs', + 'shared/components/logos/freesewing.mjs', + 'shared/components/bookmarks.mjs', + 'shared/components/susi/sign-in.mjs', + 'shared/components/susi/sign-up.mjs', + 'shared/components/robot/index.mjs', + 'shared/components/robot/poses.mjs', + 'shared/components/code-box.mjs', + 'shared/components/collapse.mjs', 'shared/components/sponsors/crowdin.mjs', + 'shared/components/sponsors/vercel.mjs', 'shared/components/sponsors/algolia.mjs', 'shared/components/sponsors/index.mjs', - 'shared/components/curated-sets.mjs', + 'shared/components/sponsors/bugsnag.mjs', + 'shared/components/gdpr/form.mjs', + 'shared/components/gdpr/details.mjs', + 'shared/components/social/icons.mjs', + 'shared/components/tabs.mjs', + 'shared/components/support/support.mjs', + 'shared/components/workbench/header.mjs', 'shared/components/workbench/new.mjs', 'shared/components/workbench/pan-zoom-pattern.mjs', - 'shared/components/workbench/exporting/pdf.mjs', 'shared/components/workbench/exporting/pdf-maker.mjs', - 'shared/components/workbench/exporting/single-pdf-maker.mjs', - 'shared/components/workbench/exporting/export-handler.mjs', 'shared/components/workbench/exporting/export-worker.js', - 'shared/components/workbench/menus/shared/inputs.mjs', - 'shared/components/workbench/menus/shared/menu-wrapper.mjs', - 'shared/components/workbench/menus/shared/values.mjs', - 'shared/components/workbench/menus/shared/index.mjs', - 'shared/components/workbench/menus/shared/menu-item.mjs', - 'shared/components/workbench/menus/design-options/inputs.mjs', + 'shared/components/workbench/exporting/export-handler.mjs', + 'shared/components/workbench/exporting/pdf.mjs', + 'shared/components/workbench/exporting/single-pdf-maker.mjs', 'shared/components/workbench/menus/design-options/values.mjs', 'shared/components/workbench/menus/design-options/index.mjs', + 'shared/components/workbench/menus/design-options/inputs.mjs', 'shared/components/workbench/menus/mobile-menubar.mjs', - 'shared/components/workbench/menus/core-settings/inputs.mjs', - 'shared/components/workbench/menus/core-settings/config.mjs', 'shared/components/workbench/menus/core-settings/values.mjs', 'shared/components/workbench/menus/core-settings/index.mjs', - 'shared/components/workbench/menus/ui-settings/inputs.mjs', - 'shared/components/workbench/menus/ui-settings/config.mjs', + 'shared/components/workbench/menus/core-settings/inputs.mjs', + 'shared/components/workbench/menus/core-settings/config.mjs', 'shared/components/workbench/menus/ui-settings/values.mjs', 'shared/components/workbench/menus/ui-settings/index.mjs', - 'shared/components/workbench/views/inspect/menu.mjs', - 'shared/components/workbench/views/inspect/inspector/pattern.mjs', - 'shared/components/workbench/views/inspect/inspector/path.mjs', - 'shared/components/workbench/views/inspect/inspector/shared.mjs', - 'shared/components/workbench/views/inspect/inspector/stack.mjs', - 'shared/components/workbench/views/inspect/inspector/menu.mjs', - 'shared/components/workbench/views/inspect/inspector/point.mjs', - 'shared/components/workbench/views/inspect/index.mjs', - 'shared/components/workbench/views/pattern-with-menu.mjs', - 'shared/components/workbench/views/logs/errors.mjs', - 'shared/components/workbench/views/logs/index.mjs', - 'shared/components/workbench/views/measies/editor.mjs', - 'shared/components/workbench/views/measies/index.mjs', - 'shared/components/workbench/views/flags.mjs', - 'shared/components/workbench/views/save/index.mjs', - 'shared/components/workbench/views/exporting/index.mjs', - 'shared/components/workbench/views/docs/index.mjs', - 'shared/components/workbench/views/test/options.mjs', - 'shared/components/workbench/views/test/menu.mjs', - 'shared/components/workbench/views/test/measurements.mjs', - 'shared/components/workbench/views/test/index.mjs', - 'shared/components/workbench/views/time/index.mjs', + 'shared/components/workbench/menus/ui-settings/inputs.mjs', + 'shared/components/workbench/menus/ui-settings/config.mjs', + 'shared/components/workbench/menus/shared/menu-wrapper.mjs', + 'shared/components/workbench/menus/shared/menu-item.mjs', + 'shared/components/workbench/menus/shared/values.mjs', + 'shared/components/workbench/menus/shared/index.mjs', + 'shared/components/workbench/menus/shared/inputs.mjs', + 'shared/components/workbench/pattern/utils.mjs', + 'shared/components/workbench/pattern/pan-zoom-context.mjs', + 'shared/components/workbench/pattern/movable/stack.mjs', + 'shared/components/workbench/pattern/movable/transform-buttons.mjs', + 'shared/components/workbench/pattern/movable/index.mjs', + 'shared/components/workbench/views/draft/header.mjs', 'shared/components/workbench/views/draft/menu.mjs', 'shared/components/workbench/views/draft/index.mjs', - 'shared/components/workbench/views/draft/header.mjs', + 'shared/components/workbench/views/inspect/menu.mjs', + 'shared/components/workbench/views/inspect/inspector/menu.mjs', + 'shared/components/workbench/views/inspect/inspector/stack.mjs', + 'shared/components/workbench/views/inspect/inspector/shared.mjs', + 'shared/components/workbench/views/inspect/inspector/point.mjs', + 'shared/components/workbench/views/inspect/inspector/pattern.mjs', + 'shared/components/workbench/views/inspect/inspector/path.mjs', + 'shared/components/workbench/views/inspect/index.mjs', + 'shared/components/workbench/views/test/menu.mjs', + 'shared/components/workbench/views/test/options.mjs', + 'shared/components/workbench/views/test/index.mjs', + 'shared/components/workbench/views/test/measurements.mjs', + 'shared/components/workbench/views/flags.mjs', + 'shared/components/workbench/views/docs/index.mjs', 'shared/components/workbench/views/print/menu.mjs', - 'shared/components/workbench/views/print/settings.mjs', - 'shared/components/workbench/views/print/config.mjs', - 'shared/components/workbench/views/print/actions.mjs', 'shared/components/workbench/views/print/index.mjs', - 'shared/components/workbench/views/cut/menu.mjs', - 'shared/components/workbench/views/cut/settings.mjs', - 'shared/components/workbench/views/cut/index.mjs', - 'shared/components/workbench/views/cut/hooks.mjs', - 'shared/components/workbench/views/edit/index.mjs', + 'shared/components/workbench/views/print/settings.mjs', + 'shared/components/workbench/views/print/actions.mjs', + 'shared/components/workbench/views/print/config.mjs', + 'shared/components/workbench/views/time/index.mjs', + 'shared/components/workbench/views/exporting/index.mjs', 'shared/components/workbench/views/edit/settings-validator.mjs', - 'shared/components/workbench/pattern/utils.mjs', - 'shared/components/workbench/pattern/movable/transform-buttons.mjs', - 'shared/components/workbench/pattern/movable/stack.mjs', - 'shared/components/workbench/pattern/movable/index.mjs', - 'shared/components/workbench/pattern/pan-zoom-context.mjs', - 'shared/components/workbench/header.mjs', - 'shared/components/navigation/sitenav.mjs', - 'shared/components/navigation/primary.mjs', - 'shared/components/navigation/sections-menu.mjs', - 'shared/components/logos/freesewing.mjs', - 'shared/components/support/support.mjs', - 'shared/components/header.mjs', - 'shared/config/cloudflare.mjs', - 'shared/config/i18n.config.mjs', + 'shared/components/workbench/views/edit/index.mjs', + 'shared/components/workbench/views/logs/errors.mjs', + 'shared/components/workbench/views/logs/index.mjs', + 'shared/components/workbench/views/pattern-with-menu.mjs', + 'shared/components/workbench/views/cut/menu.mjs', + 'shared/components/workbench/views/cut/hooks.mjs', + 'shared/components/workbench/views/cut/index.mjs', + 'shared/components/workbench/views/cut/settings.mjs', + 'shared/components/workbench/views/measies/index.mjs', + 'shared/components/workbench/views/measies/editor.mjs', + 'shared/components/workbench/views/save/index.mjs', + 'shared/components/link.mjs', + 'shared/components/curated-sets.mjs', + 'shared/components/popout/index.mjs', + 'shared/components/inputs.mjs', + 'shared/components/account/sets.mjs', + 'shared/components/account/shared.mjs', + 'shared/components/account/control.mjs', + 'shared/components/breadcrumbs.mjs', + 'shared/components/modal/theme-picker.mjs', + 'shared/components/modal/locale-picker.mjs', + 'shared/components/accordion.mjs', + 'shared/components/error/view.mjs', + 'shared/components/measurements/image.mjs', + 'shared/components/measurements/tim/acrossback.svg', + 'shared/components/measurements/tim/waisttohips.svg', + 'shared/components/measurements/tim/chest.svg', + 'shared/components/measurements/tim/crotchdepth.svg', + 'shared/components/measurements/tim/shouldertowrist.svg', + 'shared/components/measurements/tim/waist.svg', + 'shared/components/measurements/tim/waisttounderbust.svg', + 'shared/components/measurements/tim/seat.svg', + 'shared/components/measurements/tim/highbustfront.svg', + 'shared/components/measurements/tim/bustspan.svg', + 'shared/components/measurements/tim/crossseamfront.svg', + 'shared/components/measurements/tim/shouldertoshoulder.svg', + 'shared/components/measurements/tim/shoulderslope.svg', + 'shared/components/measurements/tim/knee.svg', + 'shared/components/measurements/tim/seatback.svg', + 'shared/components/measurements/tim/hipstoupperleg.svg', + 'shared/components/measurements/tim/biceps.svg', + 'shared/components/measurements/tim/hpstobust.svg', + 'shared/components/measurements/tim/bustfront.svg', + 'shared/components/measurements/tim/heel.svg', + 'shared/components/measurements/tim/waistback.svg', + 'shared/components/measurements/tim/waisttoarmpit.svg', + 'shared/components/measurements/tim/hpstowaistfront.svg', + 'shared/components/measurements/tim/ankle.svg', + 'shared/components/measurements/tim/neck.svg', + 'shared/components/measurements/tim/hpstowaistback.svg', + 'shared/components/measurements/tim/index.mjs', + 'shared/components/measurements/tim/hips.svg', + 'shared/components/measurements/tim/waisttoupperleg.svg', + 'shared/components/measurements/tim/highbust.svg', + 'shared/components/measurements/tim/bustpointtounderbust.svg', + 'shared/components/measurements/tim/inseam.svg', + 'shared/components/measurements/tim/crossseam.svg', + 'shared/components/measurements/tim/head.svg', + 'shared/components/measurements/tim/waisttoknee.svg', + 'shared/components/measurements/tim/underbust.svg', + 'shared/components/measurements/tim/waisttofloor.svg', + 'shared/components/measurements/tim/waisttoseat.svg', + 'shared/components/measurements/tim/wrist.svg', + 'shared/components/measurements/tim/shouldertoelbow.svg', + 'shared/components/measurements/tim/upperleg.svg', + 'shared/components/measurements/sarah/acrossback.svg', + 'shared/components/measurements/sarah/waisttohips.svg', + 'shared/components/measurements/sarah/chest.svg', + 'shared/components/measurements/sarah/crotchdepth.svg', + 'shared/components/measurements/sarah/shouldertowrist.svg', + 'shared/components/measurements/sarah/waist.svg', + 'shared/components/measurements/sarah/waisttounderbust.svg', + 'shared/components/measurements/sarah/seat.svg', + 'shared/components/measurements/sarah/highbustfront.svg', + 'shared/components/measurements/sarah/bustspan.svg', + 'shared/components/measurements/sarah/crossseamfront.svg', + 'shared/components/measurements/sarah/shouldertoshoulder.svg', + 'shared/components/measurements/sarah/shoulderslope.svg', + 'shared/components/measurements/sarah/knee.svg', + 'shared/components/measurements/sarah/seatback.svg', + 'shared/components/measurements/sarah/hipstoupperleg.svg', + 'shared/components/measurements/sarah/biceps.svg', + 'shared/components/measurements/sarah/hpstobust.svg', + 'shared/components/measurements/sarah/bustfront.svg', + 'shared/components/measurements/sarah/heel.svg', + 'shared/components/measurements/sarah/waistback.svg', + 'shared/components/measurements/sarah/waisttoarmpit.svg', + 'shared/components/measurements/sarah/hpstowaistfront.svg', + 'shared/components/measurements/sarah/ankle.svg', + 'shared/components/measurements/sarah/neck.svg', + 'shared/components/measurements/sarah/hpstowaistback.svg', + 'shared/components/measurements/sarah/index.mjs', + 'shared/components/measurements/sarah/hips.svg', + 'shared/components/measurements/sarah/waisttoupperleg.svg', + 'shared/components/measurements/sarah/highbust.svg', + 'shared/components/measurements/sarah/bustpointtounderbust.svg', + 'shared/components/measurements/sarah/inseam.svg', + 'shared/components/measurements/sarah/crossseam.svg', + 'shared/components/measurements/sarah/head.svg', + 'shared/components/measurements/sarah/waisttoknee.svg', + 'shared/components/measurements/sarah/underbust.svg', + 'shared/components/measurements/sarah/waisttofloor.svg', + 'shared/components/measurements/sarah/waisttoseat.svg', + 'shared/components/measurements/sarah/wrist.svg', + 'shared/components/measurements/sarah/shouldertoelbow.svg', + 'shared/components/measurements/sarah/upperleg.svg', + 'shared/components/control/score.mjs', + 'shared/components/control/tip.mjs', + 'shared/components/wordmark.mjs', + 'shared/components/joost.mjs', 'shared/config/social.mjs', 'shared/config/paypal.mjs', + 'shared/config/i18n.config.mjs', 'shared/config/tailwind-force.html', 'shared/config/freesewing.config.mjs', + 'shared/config/cloudflare.mjs', 'shared/context/loading-status-context.mjs', + 'shared/context/navigation-context.mjs', 'shared/context/modal-context.mjs', 'shared/context/mobile-menubar-context.mjs', - 'shared/context/navigation-context.mjs', - 'shared/hooks/use-pattern-settings.mjs', + 'shared/hooks/use-view.mjs', 'shared/hooks/use-theme.mjs', 'shared/hooks/use-id.mjs', 'shared/hooks/use-backend.mjs', - 'shared/hooks/use-view.mjs', + 'shared/hooks/use-pattern-settings.mjs', 'shared/hooks/use-account.mjs', - 'shared/mdx/remark-github-images.mjs', 'shared/mdx/browser-compile.mjs', - 'shared/plugins/plugin-layout-part.mjs', + 'shared/mdx/remark-github-images.mjs', 'shared/plugins/plugin-cut-layout.mjs', - 'shared/styles/code.css', + 'shared/plugins/plugin-layout-part.mjs', 'shared/styles/svg-freesewing-draft.css', + 'shared/styles/code.css', 'shared/styles/globals.css', - 'shared/themes/lgbtq.mjs', + 'shared/themes/monochrome.mjs', 'shared/themes/light.mjs', - 'shared/themes/dark.mjs', + 'shared/themes/hax0r.mjs', 'shared/themes/aqua.mjs', 'shared/themes/pastel.mjs', - 'shared/themes/monochrome.mjs', - 'shared/themes/hax0r.mjs', 'shared/themes/index.mjs', - 'shared/prebuild/data/design-measurements.mjs', - 'shared/prebuild/data/designs.mjs', + 'shared/themes/dark.mjs', + 'shared/themes/lgbtq.mjs', 'shared/prebuild/data/design-options.mjs', + 'shared/prebuild/data/designs.mjs', + 'shared/prebuild/data/design-measurements.mjs' ], - pkgs: [ - 'react-components/src/pattern-xray/path.mjs', + 'pkgs': [ 'react-components/src/pattern-xray/index.mjs', 'react-components/src/pattern-xray/point.mjs', - 'react-components/src/index.mjs', - 'react-components/src/pattern/path.mjs', - 'react-components/src/pattern/grid.mjs', - 'react-components/src/pattern/group.mjs', + 'react-components/src/pattern-xray/path.mjs', 'react-components/src/pattern/stack.mjs', - 'react-components/src/pattern/snippet.mjs', - 'react-components/src/pattern/circle.mjs', - 'react-components/src/pattern/utils.mjs', - 'react-components/src/pattern/svg.mjs', - 'react-components/src/pattern/text.mjs', - 'react-components/src/pattern/index.mjs', - 'react-components/src/pattern/part.mjs', 'react-components/src/pattern/defs.mjs', + 'react-components/src/pattern/utils.mjs', + 'react-components/src/pattern/text.mjs', + 'react-components/src/pattern/snippet.mjs', + 'react-components/src/pattern/svg.mjs', + 'react-components/src/pattern/part.mjs', + 'react-components/src/pattern/index.mjs', + 'react-components/src/pattern/group.mjs', 'react-components/src/pattern/point.mjs', - ], -} + 'react-components/src/pattern/grid.mjs', + 'react-components/src/pattern/path.mjs', + 'react-components/src/pattern/circle.mjs', + 'react-components/src/editor/swizzle/components/popout.mjs' + ] +} \ No newline at end of file diff --git a/packages/react-components/package.json b/packages/react-components/package.json index ad193fe633b..1b5fcb267f0 100644 --- a/packages/react-components/package.json +++ b/packages/react-components/package.json @@ -18,17 +18,23 @@ "freesewing" ], "type": "module", - "module": "dist/index.mjs", + "module": "src/index.mjs", "exports": { ".": { "internal": "./src/index.mjs", - "default": "./dist/index.mjs" + "default": "./src/index.mjs" }, "./pattern": "./src/pattern/index.mjs", "./xray": "./src/pattern-xray/index.mjs", "./editor": "./src/editor/index.mjs", - "./icons": "./src/editor/swizzle/components/icons.mjs" - + "./icons": "./src/editor/swizzle/components/icons.mjs", + "./linedrawings": "./src/linedrawings/index.mjs", + "./popout": "./src/popout.mjs", + "./methods": "./src/editor/swizzle/methods/index.mjs" + }, + "imports": { + "#components": "./src/editor/swizzle/components/index.mjs", + "#methods": "./src/editor/swizzle/methods/index.mjs" }, "scripts": { "build": "node build.mjs", @@ -48,7 +54,7 @@ "react": "^18.2.0" }, "dependencies": { - "axios": "1.6.8", + "axios": "1.7.4", "html-react-parser": "^5.0.7", "nuqs": "^1.17.6", "react-markdown": "^9.0.1", diff --git a/packages/react-components/src/editor/swizzle/components/icons.mjs b/packages/react-components/src/editor/swizzle/components/icons.mjs index fc2952d6858..b62c5272b44 100644 --- a/packages/react-components/src/editor/swizzle/components/icons.mjs +++ b/packages/react-components/src/editor/swizzle/components/icons.mjs @@ -1,3 +1,4 @@ +import React from 'react' /* * Used inside the pattern editor */ diff --git a/packages/react-components/src/editor/swizzle/components/index.mjs b/packages/react-components/src/editor/swizzle/components/index.mjs index 9bf1262b860..f7a6dcdfdc4 100644 --- a/packages/react-components/src/editor/swizzle/components/index.mjs +++ b/packages/react-components/src/editor/swizzle/components/index.mjs @@ -434,7 +434,7 @@ const defaultComponents = { * This method returns a component that can be swizzled * So either the passed-in component, or the default one */ -export const swizzleComponents = (components = {}, Swizzled) => { +const swizzleComponents = (components = {}, Swizzled) => { /* * We need to return all resulting components, swizzled or not * So we create this object so we can pass that down @@ -451,3 +451,209 @@ export const swizzleComponents = (components = {}, Swizzled) => { */ return all } + +/* + * Named exports + */ +export { + swizzleComponents, + // Re-export all components for specific imports + Accordion, + AuthWrapper, + AuthMessageWrapper, + BackIcon, + ContactSupport, + AuthRequired, + AccountInactive, + AccountDisabled, + AccountProhibited, + AccountStatusUnknown, + AnchorLink, + AsideViewMenu, + AsideViewMenuIcons, + AsideViewMenuButton, + AsideViewMenuSpacer, + RoleLacking, + ConsentLacking, + BaseAccordion, + BookmarkedSetPicker, + ButtonFrame, + CardLink, + CircleIcon, + CoreSetting, + CoreSettingsMenu, + CuratedMeasurementsSetIcon, + CuratedMeasurementsSetLineup, + CuratedSetPicker, + DesignOption, + DesignOptionsMenu, + DesignsView, + DraftMenu, + DraftView, + ErrorView, + SaveView, + Flag, + FlagsAccordionTitle, + FlagsAccordionEntries, + FlagTypeIcon, + FormControl, + HeaderMenu, + HeaderMenuAllViews, + HeaderMenuDraftView, + HeaderMenuDraftViewDesignOptions, + HeaderMenuDraftViewCoreSettings, + HeaderMenuDraftViewUiPreferences, + HeaderMenuDraftViewFlags, + HeaderMenuDraftViewIcons, + HeaderMenuButton, + HeaderMenuDropdown, + HeaderMenuIcon, + HeaderMenuIconSpacer, + HeaderMenuSaveIcons, + HeaderMenuUndoIcons, + HtmlSpan, + LargeScreenOnly, + Link, + ListInput, + Loading, + LoadingStatus, + Markdown, + MarkdownInput, + MeasurementInput, + MeasurementsSetCard, + MeasurementsView, + MeasurementsEditor, + MenuIcon, + NumberInput, + Null, + PageLink, + Pattern, + PatternLayout, + Popout, + StringInput, + SubAccordion, + Spinner, + SpinnerIcon, + Tab, + Tabs, + TemporaryLoader, + ToggleInput, + Tooltip, + UiPreferencesMenu, + UiPreference, + UndoStep, + UndoStepTimeAgo, + UndosView, + UserSetPicker, + Ux, + HeaderMenuViewMenu, + ViewPicker, + ViewTypeIcon, + WebLink, + ZoomablePattern, + ZoomContextProvider, + // icons + ApplyIcon, + BeakerIcon, + BookmarkIcon, + BoolNoIcon, + BoolYesIcon, + CloseIcon, + DesignIcon, + DetailIcon, + DocsIcon, + DownIcon, + EditIcon, + ExpandIcon, + ExportIcon, + FailureIcon, + FlagIcon, + FlagNoteIcon, + FlagInfoIcon, + FlagTipIcon, + FlagWarningIcon, + FlagErrorIcon, + FlagFixmeIcon, + FlagExpandIcon, + FlagOtionsIcon, + GaugeIcon, + GroupIcon, + HelpIcon, + IncludeIcon, + KioskIcon, + LeftIcon, + ListIcon, + LockIcon, + MarginIcon, + MeasurementsIcon, + MeasurementsSetIcon, + NoIcon, + OkIcon, + OptionsIcon, + PaperlessIcon, + PlusIcon, + PrintIcon, + ResetAllIcon, + ResetIcon, + RightIcon, + RocketIcon, + RotateIcon, + SaIcon, + SaveIcon, + SaveAsIcon, + ScaleIcon, + SettingsIcon, + SuccessIcon, + TipIcon, + TrashIcon, + UiIcon, + UndoIcon, + UnitsIcon, + UpIcon, + UploadIcon, + UxIcon, + XrayIcon, + ViewDraftIcon, + ViewMeasurementsIcon, + ViewTestIcon, + ViewTimingIcon, + ViewPrintLayoutIcon, + ViewSaveIcon, + ViewExportIcon, + ViewEditSettingsIcon, + ViewLogsIcon, + ViewInspectIcon, + ViewDocsIcon, + ViewDesignsIcon, + ViewViewPickerIcon, + ViewUndosIcon, + // menus + MenuItem, + MenuItemGroup, + MenuItemTitle, + MenuBoolInput, + MenuConstantInput, + MenuDegInput, + MenuEditOption, + MenuListInput, + MenuListToggle, + MenuMmInput, + //MenuNumberInput, + MenuUxSettingInput, + MenuOnlySettingInput, + MenuPctInput, + MenuSliderInput, + MenuBoolValue, + MenuConstantOptionValue, + MenuCountOptionValue, + MenuDegOptionValue, + MenuHighlightValue, + MenuListOptionValue, + MenuListValue, + MenuMmOptionValue, + MenuMmValue, + MenuOnlySettingValue, + MenuPctOptionValue, + MenuScaleSettingValue, + MenuShowValue, +} diff --git a/packages/react-components/src/editor/swizzle/components/popout.mjs b/packages/react-components/src/editor/swizzle/components/popout.mjs index 7bbee39cbd8..9eab3dd7ed7 100644 --- a/packages/react-components/src/editor/swizzle/components/popout.mjs +++ b/packages/react-components/src/editor/swizzle/components/popout.mjs @@ -1,5 +1,4 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment -import { useState } from 'react' +import React, { useState } from 'react' const colors = { comment: 'secondary', @@ -35,8 +34,8 @@ export const Popout = (props) => { if (hide) return null let type = 'none' - for (const t in colors) { - if (props[t]) type = t + for (const c in colors) { + if (props[c]) type = c } const color = colors[type] const { className = '' } = props diff --git a/packages/react-components/src/editor/swizzle/methods/editor.mjs b/packages/react-components/src/editor/swizzle/methods/editor.mjs index c26134be6d1..ddbd67d3b51 100644 --- a/packages/react-components/src/editor/swizzle/methods/editor.mjs +++ b/packages/react-components/src/editor/swizzle/methods/editor.mjs @@ -705,6 +705,10 @@ export function nsMerge(Swizzled, ...args) { * @return {string} key - The input is returned */ export function t(Swizzled, key) { + /* + * Make sure this works when Swizzled is not passed in + */ + if (typeof Swizzled.components === 'undefined') key = Swizzled return Array.isArray(key) ? key[0] : key } export function settingsValueIsCustom(Swizzled, val, dflt) { diff --git a/packages/react-components/src/editor/swizzle/methods/index.mjs b/packages/react-components/src/editor/swizzle/methods/index.mjs index 6ec60661fc0..d3b9ed47f82 100644 --- a/packages/react-components/src/editor/swizzle/methods/index.mjs +++ b/packages/react-components/src/editor/swizzle/methods/index.mjs @@ -152,7 +152,7 @@ const defaultMethods = { * This method returns methods that can be swizzled * So either the passed-in methods, or the default ones */ -export const swizzleMethods = (methods, Swizzled) => { +const swizzleMethods = (methods, Swizzled) => { /* * We need to pass down the resulting methods, swizzled or not * because some methods rely on other (possibly swizzled) methods. @@ -172,3 +172,69 @@ export const swizzleMethods = (methods, Swizzled) => { */ return all } + +/* + * Named exports + */ +export { + swizzleMethods, + // Re-export all methods for specific imports + // core-settings.mjs + defaultSa, + defaultSamm, + menuCoreSettingsOnlyHandler, + menuCoreSettingsSaboolHandler, + menuCoreSettingsSammHandler, + menuCoreSettingsStructure, + // design-options.mjs + designOptionType, + findOption, + getOptionStructure, + menuDesignOptionsStructure, + // editor.mjs + addUndoStep, + cloneObject, + cloudImageUrl, + draft, + flattenFlags, + getCoreSettingUndoStepData, + getDesignOptionUndoStepData, + getUiPreferenceUndoStepData, + getUndoStepData, + initialEditorState, + menuRoundPct, + menuValidateNumericValue, + menuValueWasChanged, + noop, + notEmpty, + nsMerge, + objUpdate, + settingsValueIsCustom, + settingsValueCustomOrDefault, + statePrefixPath, + stateUpdateFactory, + t, + undoableObjUpdate, + // formatting.mjs + capitalize, + formatDesignOptionValue, + formatFraction128, + formatImperial, + formatMm, + formatPercentage, + round, + roundMm, + fractionToDecimal, + measurementAsMm, + measurementAsUnits, + shortDate, + parseDistanceInput, + // measurements.mjs + designMeasurements, + hasRequiredMeasurements, + isDegreeMeasurement, + missingMeasurements, + structureMeasurementsAsDesign, + // ui-preferences.mjs + menuUiPreferencesStructure, +} diff --git a/packages/react-components/src/index.mjs b/packages/react-components/src/index.mjs index 008aa8aabd0..bec8beed9fa 100644 --- a/packages/react-components/src/index.mjs +++ b/packages/react-components/src/index.mjs @@ -13,6 +13,8 @@ import { Svg } from './pattern/svg.mjs' import { Text, TextOnPath } from './pattern/text.mjs' // Pattern Utils import { getId, getProps, translateStrings, withinPartBounds } from './pattern/utils.mjs' +// Stand alone components +import { Popout } from './popout.mjs' /** * Translation namespaces used by these components @@ -44,4 +46,6 @@ export { withinPartBounds, // These are not React components but various helpers ns, + // Stand along components + Popout, } diff --git a/packages/react-components/src/linedrawings/aaron.mjs b/packages/react-components/src/linedrawings/aaron.mjs new file mode 100644 index 00000000000..3bf81e6cf8a --- /dev/null +++ b/packages/react-components/src/linedrawings/aaron.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Aaron = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const AaronFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const AaronBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/albert.mjs b/packages/react-components/src/linedrawings/albert.mjs new file mode 100644 index 00000000000..4961d86af4f --- /dev/null +++ b/packages/react-components/src/linedrawings/albert.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.6 + +export const Albert = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const AlbertFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const AlbertBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the front + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/bee.mjs b/packages/react-components/src/linedrawings/bee.mjs new file mode 100644 index 00000000000..995306e8a27 --- /dev/null +++ b/packages/react-components/src/linedrawings/bee.mjs @@ -0,0 +1,58 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Bee = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const BeeFront = ({ + className = 'h-full max-w-full m-auto text-base-content linedrawing', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/bella.mjs b/packages/react-components/src/linedrawings/bella.mjs new file mode 100644 index 00000000000..3b5321c44bf --- /dev/null +++ b/packages/react-components/src/linedrawings/bella.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Bella = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const BellaFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const BellaBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the front + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/benjamin.mjs b/packages/react-components/src/linedrawings/benjamin.mjs new file mode 100644 index 00000000000..f9d6f8c79d9 --- /dev/null +++ b/packages/react-components/src/linedrawings/benjamin.mjs @@ -0,0 +1,54 @@ +import React from 'react' +import { LineDrawingWrapper, regular, thin } from './shared.mjs' + +const strokeScale = 0.5 + +export const Benjamin = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const BenjaminFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/bent.mjs b/packages/react-components/src/linedrawings/bent.mjs new file mode 100644 index 00000000000..cdba8c3b5f6 --- /dev/null +++ b/packages/react-components/src/linedrawings/bent.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Bent = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const BentFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const BentBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/bibi.mjs b/packages/react-components/src/linedrawings/bibi.mjs new file mode 100644 index 00000000000..2f81c8f2aa6 --- /dev/null +++ b/packages/react-components/src/linedrawings/bibi.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Bibi = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const BibiFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const BibiBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/bob.mjs b/packages/react-components/src/linedrawings/bob.mjs new file mode 100644 index 00000000000..bfdc0533853 --- /dev/null +++ b/packages/react-components/src/linedrawings/bob.mjs @@ -0,0 +1,89 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Bob = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const BobFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const BobBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/breanna.mjs b/packages/react-components/src/linedrawings/breanna.mjs new file mode 100644 index 00000000000..cce23f46e41 --- /dev/null +++ b/packages/react-components/src/linedrawings/breanna.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Breanna = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const BreannaFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const BreannaBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/brian.mjs b/packages/react-components/src/linedrawings/brian.mjs new file mode 100644 index 00000000000..878cfb0b85d --- /dev/null +++ b/packages/react-components/src/linedrawings/brian.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Brian = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const BrianFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const BrianBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/bruce.mjs b/packages/react-components/src/linedrawings/bruce.mjs new file mode 100644 index 00000000000..3a2c4d11f30 --- /dev/null +++ b/packages/react-components/src/linedrawings/bruce.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.6 + +export const Bruce = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const BruceFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const BruceBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/carlita.mjs b/packages/react-components/src/linedrawings/carlita.mjs new file mode 100644 index 00000000000..53bf94ffed7 --- /dev/null +++ b/packages/react-components/src/linedrawings/carlita.mjs @@ -0,0 +1,375 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Carlita = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const CarlitaFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const CarlitaBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/carlton.mjs b/packages/react-components/src/linedrawings/carlton.mjs new file mode 100644 index 00000000000..71a322dd17b --- /dev/null +++ b/packages/react-components/src/linedrawings/carlton.mjs @@ -0,0 +1,357 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Carlton = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const CarltonFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const CarltonBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/cathrin.mjs b/packages/react-components/src/linedrawings/cathrin.mjs new file mode 100644 index 00000000000..577116f16f5 --- /dev/null +++ b/packages/react-components/src/linedrawings/cathrin.mjs @@ -0,0 +1,752 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Cathrin = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const CathrinFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const CathrinBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/charlie.mjs b/packages/react-components/src/linedrawings/charlie.mjs new file mode 100644 index 00000000000..857773c3f22 --- /dev/null +++ b/packages/react-components/src/linedrawings/charlie.mjs @@ -0,0 +1,285 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Charlie = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const CharlieFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const CharlieBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/cornelius.mjs b/packages/react-components/src/linedrawings/cornelius.mjs new file mode 100644 index 00000000000..9c1d5c7e70b --- /dev/null +++ b/packages/react-components/src/linedrawings/cornelius.mjs @@ -0,0 +1,480 @@ +import React from 'react' +import { LineDrawingWrapper, thin, regular, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Cornelius = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const CorneliusFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const CorneliusBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/diana.mjs b/packages/react-components/src/linedrawings/diana.mjs new file mode 100644 index 00000000000..7938f25e168 --- /dev/null +++ b/packages/react-components/src/linedrawings/diana.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Diana = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const DianaFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const DianaBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/florence.mjs b/packages/react-components/src/linedrawings/florence.mjs new file mode 100644 index 00000000000..50bcdd302ad --- /dev/null +++ b/packages/react-components/src/linedrawings/florence.mjs @@ -0,0 +1,58 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.6 + +export const Florence = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const FlorenceFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/florent.mjs b/packages/react-components/src/linedrawings/florent.mjs new file mode 100644 index 00000000000..2f0a22d5bca --- /dev/null +++ b/packages/react-components/src/linedrawings/florent.mjs @@ -0,0 +1,103 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.6 + +export const Florent = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const FlorentFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/gozer.mjs b/packages/react-components/src/linedrawings/gozer.mjs new file mode 100644 index 00000000000..d541a9b10cd --- /dev/null +++ b/packages/react-components/src/linedrawings/gozer.mjs @@ -0,0 +1,181 @@ +import React from 'react' +import { LineDrawingWrapper, regular } from './shared.mjs' + +const strokeScale = 0.5 + +export const Gozer = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const GozerFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const GozerBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/hi.mjs b/packages/react-components/src/linedrawings/hi.mjs new file mode 100644 index 00000000000..b6db0aa0847 --- /dev/null +++ b/packages/react-components/src/linedrawings/hi.mjs @@ -0,0 +1,122 @@ +import React from 'react' +import { LineDrawingWrapper, regular } from './shared.mjs' + +const strokeScale = 0.5 + +export const Hi = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const HiFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/holmes.mjs b/packages/react-components/src/linedrawings/holmes.mjs new file mode 100644 index 00000000000..d84c45891bb --- /dev/null +++ b/packages/react-components/src/linedrawings/holmes.mjs @@ -0,0 +1,157 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.6 + +export const Holmes = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const HolmesFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/hortensia.mjs b/packages/react-components/src/linedrawings/hortensia.mjs new file mode 100644 index 00000000000..e3eba6a5c0f --- /dev/null +++ b/packages/react-components/src/linedrawings/hortensia.mjs @@ -0,0 +1,53 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.6 + +export const Hortensia = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const HortensiaFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/huey.mjs b/packages/react-components/src/linedrawings/huey.mjs new file mode 100644 index 00000000000..bc3954cb092 --- /dev/null +++ b/packages/react-components/src/linedrawings/huey.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Huey = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const HueyFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const HueyBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/hugo.mjs b/packages/react-components/src/linedrawings/hugo.mjs new file mode 100644 index 00000000000..fa1d1f5bf34 --- /dev/null +++ b/packages/react-components/src/linedrawings/hugo.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Hugo = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const HugoFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const HugoBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/index.mjs b/packages/react-components/src/linedrawings/index.mjs new file mode 100644 index 00000000000..3b8ff671ab9 --- /dev/null +++ b/packages/react-components/src/linedrawings/index.mjs @@ -0,0 +1,143 @@ +import { Aaron, AaronFront, AaronBack } from './aaron.mjs' +import { Albert, AlbertFront } from './albert.mjs' +import { Bee, BeeFront } from './bee.mjs' +import { Bella, BellaFront, BellaBack } from './bella.mjs' +import { Benjamin, BenjaminFront } from './benjamin.mjs' +import { Bent, BentFront, BentBack } from './bent.mjs' +import { Bibi, BibiFront, BibiBack } from './bibi.mjs' +import { Bob, BobFront, BobBack } from './bob.mjs' +import { Breanna, BreannaFront, BreannaBack } from './breanna.mjs' +import { Brian, BrianFront, BrianBack } from './brian.mjs' +import { Bruce, BruceFront, BruceBack } from './bruce.mjs' +import { Carlita, CarlitaFront, CarlitaBack } from './carlita.mjs' +import { Carlton, CarltonFront, CarltonBack } from './carlton.mjs' +import { Cathrin, CathrinFront, CathrinBack } from './cathrin.mjs' +import { Charlie, CharlieFront, CharlieBack } from './charlie.mjs' +import { Cornelius, CorneliusFront, CorneliusBack } from './cornelius.mjs' +import { Diana, DianaFront, DianaBack } from './diana.mjs' +import { Florence, FlorenceFront } from './florence.mjs' +import { Florent, FlorentFront } from './florent.mjs' +import { Gozer, GozerFront, GozerBack } from './gozer.mjs' +import { Hi, HiFront } from './hi.mjs' +import { Holmes, HolmesFront } from './holmes.mjs' +import { Hortensia, HortensiaFront } from './hortensia.mjs' +import { Huey, HueyFront, HueyBack } from './huey.mjs' +import { Hugo, HugoFront, HugoBack } from './hugo.mjs' +import { Lucy, LucyFront } from './lucy.mjs' +import { Lumina, LuminaFront, LuminaBack } from './lumina.mjs' +import { Lumira, LumiraFront, LumiraBack } from './lumira.mjs' +import { Lunetius, LunetiusFront } from './lunetius.mjs' +import { Noble, NobleFront, NobleBack } from './noble.mjs' +import { Simon, SimonFront, SimonBack } from './simon.mjs' +import { Teagan, TeaganFront, TeaganBack } from './teagan.mjs' +import { Tristan, TristanFront, TristanBack } from './tristan.mjs' +import { Uma, UmaFront, UmaBack } from './uma.mjs' +import { Umbra, UmbraFront, UmbraBack } from './umbra.mjs' +import { Wahid, WahidFront, WahidBack } from './wahid.mjs' + +export const lineDrawingsFront = { + aaron: AaronFront, + albert: AlbertFront, + bee: BeeFront, + bella: BellaFront, + benjamin: BenjaminFront, + bent: BentFront, + bibi: BibiFront, + bob: BobFront, + breanna: BreannaFront, + brian: BrianFront, + bruce: BruceFront, + carlita: CarlitaFront, + carlton: CarltonFront, + cathrin: CathrinFront, + charlie: CharlieFront, + cornelius: CorneliusFront, + diana: DianaFront, + florence: FlorenceFront, + florent: FlorentFront, + gozer: GozerFront, + hi: HiFront, + holmes: HolmesFront, + huey: HueyFront, + hugo: HugoFront, + lucy: LucyFront, + lumina: LuminaFront, + lumira: LumiraFront, + lunetius: LunetiusFront, + noble: NobleFront, + hortensia: HortensiaFront, + simon: SimonFront, + teagan: TeaganFront, + tristan: TristanFront, + uma: UmaFront, + umbra: UmbraFront, + wahid: WahidFront, +} + +export const lineDrawingsBack = { + aaron: AaronBack, + bella: BellaBack, + bent: BentBack, + bibi: BibiBack, + bob: BobBack, + breanna: BreannaBack, + brian: BrianBack, + bruce: BruceBack, + carlita: CarlitaBack, + carlton: CarltonBack, + cathrin: CathrinBack, + charlie: CharlieBack, + cornelius: CorneliusBack, + diana: DianaBack, + gozer: GozerBack, + huey: HueyBack, + hugo: HugoBack, + lumina: LuminaBack, + lumira: LumiraBack, + noble: NobleBack, + simon: SimonBack, + teagan: TeaganBack, + tristan: TristanBack, + uma: UmaBack, + umbra: UmbraBack, + wahid: WahidBack, +} + +export const lineDrawings = { + aaron: Aaron, + albert: Albert, + bee: Bee, + bella: Bella, + benjamin: Benjamin, + bent: Bent, + bibi: Bibi, + bob: Bob, + breanna: Breanna, + brian: Brian, + bruce: Bruce, + carlita: Carlita, + carlton: Carlton, + cathrin: Cathrin, + charlie: Charlie, + cornelius: Cornelius, + diana: Diana, + florence: Florence, + florent: Florent, + gozer: Gozer, + hi: Hi, + holmes: Holmes, + huey: Huey, + hugo: Hugo, + lucy: Lucy, + lumina: Lumina, + lumira: Lumira, + lunetius: Lunetius, + noble: Noble, + hortensia: Hortensia, + simon: Simon, + teagan: Teagan, + tristan: Tristan, + uma: Uma, + umbra: Umbra, + wahid: Wahid, +} diff --git a/packages/react-components/src/linedrawings/lucy.mjs b/packages/react-components/src/linedrawings/lucy.mjs new file mode 100644 index 00000000000..389adeb29ce --- /dev/null +++ b/packages/react-components/src/linedrawings/lucy.mjs @@ -0,0 +1,80 @@ +import React from 'react' +import { LineDrawingWrapper, regular } from './shared.mjs' + +const strokeScale = 0.6 + +export const Lucy = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const LucyFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + +) diff --git a/packages/react-components/src/linedrawings/lumina.mjs b/packages/react-components/src/linedrawings/lumina.mjs new file mode 100644 index 00000000000..7548e00029a --- /dev/null +++ b/packages/react-components/src/linedrawings/lumina.mjs @@ -0,0 +1,161 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Lumina = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const LuminaFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const LuminaBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/lumira.mjs b/packages/react-components/src/linedrawings/lumira.mjs new file mode 100644 index 00000000000..0f8555dabf7 --- /dev/null +++ b/packages/react-components/src/linedrawings/lumira.mjs @@ -0,0 +1,179 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Lumira = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const LumiraFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const LumiraBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/lunetius.mjs b/packages/react-components/src/linedrawings/lunetius.mjs new file mode 100644 index 00000000000..c0aa3562c78 --- /dev/null +++ b/packages/react-components/src/linedrawings/lunetius.mjs @@ -0,0 +1,58 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.6 + +export const Lunetius = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the front + */ +export const LunetiusFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/noble.mjs b/packages/react-components/src/linedrawings/noble.mjs new file mode 100644 index 00000000000..38e9427779c --- /dev/null +++ b/packages/react-components/src/linedrawings/noble.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Noble = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const NobleFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const NobleBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the front + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/shared.mjs b/packages/react-components/src/linedrawings/shared.mjs new file mode 100644 index 00000000000..6db43f1a571 --- /dev/null +++ b/packages/react-components/src/linedrawings/shared.mjs @@ -0,0 +1,51 @@ +import React from 'react' + +/* + * A React component to wrap SVG linedrawings for FreeSewing designs + * + * @param design {string} - The (lowercase) name of a FreeSewing design + * @param className {string} - CSS classes to set on the svg tag + * + * @return LineDrawing as JSX + */ +export const LineDrawingWrapper = ({ + className = 'w-64', // CSS classes to apply + viewBox = '0 0 100 100', // SVG viewBox + stroke = 1, // Stroke to use + children = [], // The actual linedrawing + style = { maxHeight: 'inherit' }, +}) => ( + + {children} + +) + +/* + * Regular stroke-width helper to ensure consistency across linedrawings + */ +export const regular = (stroke = 1) => ({ strokeWidth: stroke }) + +/* + * Thin stroke-width helper to ensure consistency across linedrawings + */ +export const thin = (stroke = 1) => ({ strokeWidth: stroke / 2 }) + +/* + * Very thin stroke-width helper to ensure consistency across linedrawings + */ +export const veryThin = (stroke = 1) => ({ strokeWidth: stroke / 3 }) + +/* + * Dashed stroke-dasharray helper to ensure consistency across linedrawings + */ +export const dashed = (stroke = 1) => ({ strokeDasharray: `${stroke * 1.2},${stroke * 0.8}` }) diff --git a/packages/react-components/src/linedrawings/simon.mjs b/packages/react-components/src/linedrawings/simon.mjs new file mode 100644 index 00000000000..1899d395367 --- /dev/null +++ b/packages/react-components/src/linedrawings/simon.mjs @@ -0,0 +1,140 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.35 + +export const Simon = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const SimonFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const SimonBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * Always use an id for defs that is unique to the design because if we have + * multiple linedrawings on the page, they share the same namespace and thus + * IDs will collide + */ +const defs = ( + + + + + + + + + +) + +/* + * SVG elements for the back + */ +const Front = ({ stroke }) => ( + <> + {defs} + + + + + + + + + + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + + + + +) diff --git a/packages/react-components/src/linedrawings/teagan.mjs b/packages/react-components/src/linedrawings/teagan.mjs new file mode 100644 index 00000000000..98ee99cac58 --- /dev/null +++ b/packages/react-components/src/linedrawings/teagan.mjs @@ -0,0 +1,99 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Teagan = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const TeaganFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const TeaganBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/linedrawings/tristan.mjs b/packages/react-components/src/linedrawings/tristan.mjs new file mode 100644 index 00000000000..cabc6e4952f --- /dev/null +++ b/packages/react-components/src/linedrawings/tristan.mjs @@ -0,0 +1,89 @@ +import React from 'react' +import { LineDrawingWrapper, regular } from './shared.mjs' + +const strokeScale = 0.5 + +export const Tristan = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const TristanFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const TristanBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/uma.mjs b/packages/react-components/src/linedrawings/uma.mjs new file mode 100644 index 00000000000..d685c64ad8d --- /dev/null +++ b/packages/react-components/src/linedrawings/uma.mjs @@ -0,0 +1,89 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Uma = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const UmaFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const UmaBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/umbra.mjs b/packages/react-components/src/linedrawings/umbra.mjs new file mode 100644 index 00000000000..601f7d95208 --- /dev/null +++ b/packages/react-components/src/linedrawings/umbra.mjs @@ -0,0 +1,170 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.5 + +export const Umbra = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +/* + * React component for the front + */ +export const UmbraFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * React component for the back + */ +export const UmbraBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * SVG elements for the front + */ +export const Front = ({ stroke }) => ( + <> + + + +) + +/* + * SVG elements for the back + */ +const Back = ({ stroke }) => ( + <> + + + +) diff --git a/packages/react-components/src/linedrawings/wahid.mjs b/packages/react-components/src/linedrawings/wahid.mjs new file mode 100644 index 00000000000..c8db87d0d5f --- /dev/null +++ b/packages/react-components/src/linedrawings/wahid.mjs @@ -0,0 +1,117 @@ +import React from 'react' +import { LineDrawingWrapper, thin, dashed } from './shared.mjs' + +const strokeScale = 0.4 + +export const Wahid = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + + ) +} + +export const WahidFront = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +export const WahidBack = ({ + className = 'w-64', // CSS classes to apply + stroke = 1, // Stroke width to use +}) => { + // Normalize stroke across designs + stroke = stroke * strokeScale + + return ( + + + + ) +} + +/* + * Always use an id for defs that is unique to the design because if we have + * multiple linedrawings on the page, they share the same namespace and thus + * IDs will collide + */ +const defs = ( + + + + + + + + + +) + +/* + * React component for the front + */ +export const Front = ({ stroke }) => ( + <> + {defs} + + + + + + + + + + +) + +/* + * React component for the back + */ +const Back = ({ stroke }) => ( + <> + + + + +) diff --git a/packages/react-components/src/pattern-xray/path.mjs b/packages/react-components/src/pattern-xray/path.mjs index ae514a42d96..69193310fab 100644 --- a/packages/react-components/src/pattern-xray/path.mjs +++ b/packages/react-components/src/pattern-xray/path.mjs @@ -1,4 +1,5 @@ // __SDEFILE__ - This file is a dependency for the stand-alone environment +import React from 'react' // Components import { Path } from '../pattern/path.mjs' import { getProps } from '../pattern/utils.mjs' diff --git a/packages/react-components/src/pattern-xray/point.mjs b/packages/react-components/src/pattern-xray/point.mjs index a16aa52fd45..4d92370c99f 100644 --- a/packages/react-components/src/pattern-xray/point.mjs +++ b/packages/react-components/src/pattern-xray/point.mjs @@ -1,4 +1,5 @@ // __SDEFILE__ - This file is a dependency for the stand-alone environment +import React from 'react' // Components import { Point } from '../pattern/point.mjs' import { withinPartBounds } from '../pattern/utils.mjs' diff --git a/packages/react-components/src/popout.mjs b/packages/react-components/src/popout.mjs new file mode 100644 index 00000000000..7417579befb --- /dev/null +++ b/packages/react-components/src/popout.mjs @@ -0,0 +1,7 @@ +import React from 'react' +import { mergeProps } from './utils.mjs' +import { Popout as SwizzledPopout } from './editor/swizzle/components/popout.mjs' +import { CloseIcon } from './editor/swizzle/components/icons.mjs' +import { t } from '#methods' + +export const Popout = (props) => diff --git a/packages/react-components/src/utils.mjs b/packages/react-components/src/utils.mjs new file mode 100644 index 00000000000..0f06f2953ce --- /dev/null +++ b/packages/react-components/src/utils.mjs @@ -0,0 +1,37 @@ +/* + * Helper method to save us having to type typeof checks all the time + * + * @param {mixed} obj - The value to check + * @return {bool} result - True of obj is of type object + */ +export function isObject (obj) { + return (typeof obj === 'object' && !Array.isArray(obj)) +} + +/* + * Helper method to inject props into a component made for Swizzling + * + * @param {object} props - The props to merge + * @param {object} components - Any swizzled components to add + * @param {object} methods - Any swizzled methods to add + * @return {object} props - The merged props object + */ +export function mergeProps (props, components=false, methods=false) { + const Swizzled = isObject(props.Swizzled) + ? props.Swizzled + : { components: {}, methods: {} } + + if (components) { + if (isObject(Swizzled.components)) Swizzled.components = { ...components, ...Swizzled.components } + else Swizzled.components = components + } + + if (methods) { + if (isObject(Swizzled.methods)) Swizzled.methods = { ...methods, ...Swizzled.methods } + else Swizzled.methods = methods + } + + return { ...props, Swizzled } +} + + diff --git a/plugins/plugin-annotations/i18n/index.mjs b/plugins/plugin-annotations/i18n/index.mjs index 36aac928b67..3cb4ad5492b 100644 --- a/plugins/plugin-annotations/i18n/index.mjs +++ b/plugins/plugin-annotations/i18n/index.mjs @@ -1,8 +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' } +import en from './en.json' with { type: 'json' } +import de from './de.json' with { type: 'json' } +import es from './es.json' with { type: 'json' } +import fr from './fr.json' with { type: 'json' } +import nl from './nl.json' with { type: 'json' } +import uk from './uk.json' with { type: 'json' } export const i18n = { en, de, es, fr, nl, uk } diff --git a/plugins/plugin-annotations/src/logo.mjs b/plugins/plugin-annotations/src/logo.mjs index 0f1aaf5d580..76881e91ced 100644 --- a/plugins/plugin-annotations/src/logo.mjs +++ b/plugins/plugin-annotations/src/logo.mjs @@ -7,6 +7,6 @@ export const logoDefs = [ def: (scale) => ``, + }) translate(-23 -36)">