commit fff7c0e5a6d66d0d718dcf43476108c5798bb01d
parent 86820a2aa18c3039a80113013f43a638e7c2758d
Author: Michael Camilleri <[email protected]>
Date: Thu, 7 May 2026 19:26:47 +0900
Add initial 10 bundled puzzles
Diffstat:
15 files changed, 1081 insertions(+), 4 deletions(-)
diff --git a/Crossmate.xcodeproj/project.pbxproj b/Crossmate.xcodeproj/project.pbxproj
@@ -88,6 +88,7 @@
E91FB8101E1927CA567DE825 /* PuzzleSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AFD37B03A1C2E23E5766E6 /* PuzzleSource.swift */; };
ECC1A5C3623F50B67185CFFB /* RecordSerializerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E4DEAF9F7887CBB46A99E8E /* RecordSerializerTests.swift */; };
F2BE3AA7211847AD0CCF1202 /* MoveBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8E26067849A63758DDEA4 /* MoveBuffer.swift */; };
+ F34EDFD45E2F5006807DDAC7 /* PuzzleCatalogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8560440C548752EE93E0ED9 /* PuzzleCatalogTests.swift */; };
F46733AB3C72749A4A992667 /* SyncState+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A49C3C31F49A85764B84A15 /* SyncState+Helpers.swift */; };
F77177F48728ECEACD3B28B3 /* KeyboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D28E8CBB1AFFD801E87D4E3 /* KeyboardView.swift */; };
F8DDA34AC1A6B6499C5D222E /* PlayerPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46148CF0F4D719692F81A6EC /* PlayerPreferences.swift */; };
@@ -168,6 +169,7 @@
B23A692318044351247606DF /* SuccessPanel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessPanel.swift; sourceTree = "<group>"; };
B369788E0FEA0DCE1B125816 /* PUZToXDConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PUZToXDConverter.swift; sourceTree = "<group>"; };
B689A7138429641E61E9E558 /* Crossmate.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Crossmate.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ B8560440C548752EE93E0ED9 /* PuzzleCatalogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PuzzleCatalogTests.swift; sourceTree = "<group>"; };
B9031A1574C21866940F6A2C /* XD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XD.swift; sourceTree = "<group>"; };
BA67C509B467132D1B7510A4 /* Puzzles */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Puzzles; sourceTree = SOURCE_ROOT; };
BAC1B64755AE15CF45350DBB /* MoveBufferTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveBufferTests.swift; sourceTree = "<group>"; };
@@ -246,6 +248,7 @@
1813630FA05C194AFF43855C /* PlayerRosterTests.swift */,
ACD511B95227C7D57F32A2AC /* PresencePublisherTests.swift */,
FDE193CAB325C991952D7CE5 /* PUZToXDConverterTests.swift */,
+ B8560440C548752EE93E0ED9 /* PuzzleCatalogTests.swift */,
C90E94A01FEA77A5C9A2BC94 /* PuzzleNotificationTextTests.swift */,
7E4DEAF9F7887CBB46A99E8E /* RecordSerializerTests.swift */,
2899F77BEA1575B835D6EC3D /* SnapshotServiceTests.swift */,
@@ -502,6 +505,7 @@
014134FB81566B5D41168260 /* PerGameZoneTests.swift in Sources */,
04062BCD473ED244159B1066 /* PlayerRosterTests.swift in Sources */,
090039C84FAE212D5B0EA03F /* PresencePublisherTests.swift in Sources */,
+ F34EDFD45E2F5006807DDAC7 /* PuzzleCatalogTests.swift in Sources */,
7FCD3F582B5ADC235E1F88A0 /* PuzzleNotificationTextTests.swift in Sources */,
ECC1A5C3623F50B67185CFFB /* RecordSerializerTests.swift in Sources */,
BE57957589423497338EBD37 /* ShareRoutingTests.swift in Sources */,
diff --git a/Crossmate/Models/PuzzleCatalog.swift b/Crossmate/Models/PuzzleCatalog.swift
@@ -18,10 +18,16 @@ struct PuzzleCatalog {
}
private static func puzzles(in subdirectory: String) -> [Entry] {
- guard let urls = Bundle.main.urls(forResourcesWithExtension: "xd", subdirectory: subdirectory) else {
+ guard let directoryURL = Bundle.main.resourceURL?
+ .appendingPathComponent(subdirectory, isDirectory: true) else {
return []
}
+ let urls = (try? FileManager.default.contentsOfDirectory(at: directoryURL, includingPropertiesForKeys: nil)) ?? []
+
return urls.compactMap { url in
+ guard url.pathExtension == "xd" else {
+ return nil
+ }
let name = url.deletingPathExtension().lastPathComponent
guard let source = try? String(contentsOf: url, encoding: .utf8),
let xd = try? XD.parse(source) else {
@@ -29,6 +35,6 @@ struct PuzzleCatalog {
}
return Entry(id: name, title: xd.title ?? name, source: source)
}
- .sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == .orderedAscending }
+ .sorted { $0.id.localizedStandardCompare($1.id) == .orderedAscending }
}
}
diff --git a/Crossmate/Persistence/GameStore.swift b/Crossmate/Persistence/GameStore.swift
@@ -544,7 +544,8 @@ final class GameStore {
}
private func seedFromSample() throws -> (GameEntity, Puzzle) {
- guard let url = Bundle.main.url(forResource: "sample", withExtension: "xd") else {
+ guard let url = Bundle.main.resourceURL?
+ .appendingPathComponent("Puzzles/Debug/sample.xd") else {
throw LoadError.sampleResourceMissing
}
let source = try String(contentsOf: url, encoding: .utf8)
diff --git a/Crossmate/Views/ImportedBrowseView.swift b/Crossmate/Views/ImportedBrowseView.swift
@@ -104,7 +104,7 @@ private struct DriveItemRow: View {
onOpen(item)
} label: {
HStack {
- Label(item.name, systemImage: "doc.text")
+ Label(item.url.lastPathComponent, systemImage: "doc.text")
.foregroundStyle(.primary)
Spacer()
if !item.isDownloaded {
diff --git a/Puzzles/Bundled/Crossmate-0001.xd b/Puzzles/Bundled/Crossmate-0001.xd
@@ -0,0 +1,102 @@
+Title: Crossmake #1
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 05/15/2013
+
+
+OPTS#ISAAC#THOR
+SOAP#ROLLO#REDO
+HOMEREPAIR#ARID
+ARENA###CONFESS
+###SIDEBENEFIT#
+AIREDALE#ARI###
+DOER#RANK#TCELL
+INN#INTEARS#RIO
+TATAR#HASH#DIES
+###VEE#TEENIEST
+#SPANISHMAIN###
+DEAREST###LEAPT
+ANTI#NEWSLETTER
+ROTC#ERIKA#TOTE
+ERIE#RETAG#EPEE
+
+
+A1. Chooses, with "for" ~ OPTS
+A5. Newton with a famous apple story ~ ISAAC
+A10. Hammer-wielding Avenger ~ THOR
+A14. Sudsy bar ~ SOAP
+A15. Caramel candy brand ~ ROLLO
+A16. Second attempt ~ REDO
+A17. Weekend project involving tools and paint, maybe ~ HOMEREPAIR
+A19. Desertlike ~ ARID
+A20. Stadium setting ~ ARENA
+A21. Come clean ~ CONFESS
+A23. Extra perk ~ SIDEBENEFIT
+A27. Wiry-coated terrier ~ AIREDALE
+A30. "Entourage" agent Gold ~ ARI
+A31. Action-oriented sort ~ DOER
+A32. Position in a hierarchy ~ RANK
+A34. Immune-system lymphocyte ~ TCELL
+A38. Roadside lodging ~ INN
+A39. Crying ~ INTEARS
+A41. City with Copacabana Beach ~ RIO
+A42. Member of a Turkic-speaking people ~ TATAR
+A44. Breakfast order with corned beef, perhaps ~ HASH
+A45. Stops living ~ DIES
+A46. Letter after u ~ VEE
+A48. Most like a young adolescent ~ TEENIEST
+A50. Old pirate waters of the Caribbean ~ SPANISHMAIN
+A53. Most beloved ~ DEAREST
+A54. Jumped ~ LEAPT
+A58. Opposed to ~ ANTI
+A59. Email update from a club or school ~ NEWSLETTER
+A63. Campus officer-training program ~ ROTC
+A64. Actress Christensen of "Parenthood" ~ ERIKA
+A65. Carryall bag ~ TOTE
+A66. Great Lake bordering Ohio ~ ERIE
+A67. Put a new label on ~ RETAG
+A68. Fencing sword ~ EPEE
+
+D1. Workplace-safety agcy. ~ OSHA
+D2. Low on funds ~ POOR
+D3. Domesticate ~ TAME
+D4. "The Faerie Queene" poet Edmund ~ SPENSER
+D5. Anger ~ IRE
+D6. Token concession ~ SOP
+D7. ___ carte ~ ALA
+D8. Girl who follows a rabbit in a classic story ~ ALICE
+D9. Beer often served with lime ~ CORONA
+D10. Rush-hour headache ~ TRAFFIC
+D11. Start of a roll-call response ~ HEREI
+D12. Writer of lyric poems ~ ODIST
+D13. Fishing poles ~ RODS
+D18. Surprise police action ~ RAID
+D22. "Drat!" ~ NERTS
+D24. Mild oath ~ DARN
+D25. Israeli resort on the Gulf of Aqaba ~ ELATH
+D26. Under ~ BENEATH
+D27. Mine entrance ~ ADIT
+D28. Scottish island with an ancient abbey ~ IONA
+D29. Tenant's monthly payment ~ RENT
+D33. Casey who counted down the hits ~ KASEM
+D35. Canal city of Pennsylvania ~ ERIE
+D36. Untruths ~ LIES
+D37. Unable to find the way ~ LOST
+D39. Adler of Sherlock Holmes stories ~ IRENE
+D40. Flightless bird of South America ~ RHEA
+D43. Greed ~ AVARICE
+D45. Small eating area off a kitchen ~ DINETTE
+D47. Former Disney chief Michael ~ EISNER
+D49. River through Cairo ~ NILE
+D50. Mister, in Madrid ~ SENOR
+D51. Singer LaBelle ~ PATTI
+D52. Cubic meter ~ STERE
+D53. Challenge to take a risk ~ DARE
+D55. On top of ~ ATOP
+D56. Townshend of the Who ~ PETE
+D57. Maple or pine ~ TREE
+D60. Clever humor ~ WIT
+D61. Jamaican music genre ~ SKA
+D62. Fall behind ~ LAG
diff --git a/Puzzles/Bundled/Crossmate-0002.xd b/Puzzles/Bundled/Crossmate-0002.xd
@@ -0,0 +1,104 @@
+Title: Crossmake #2
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 07/27/2010
+
+
+ADES#TSAR#SEEMS
+LINT#ANNO#AERIE
+MANOAMANO#FLARE
+ONEIL#PASTA####
+SNACKS##TORONTO
+TED#ALBA#TINEAR
+###SLOANE##ERNE
+#UPRIGHTPIANOS#
+GRIT##SEENTO###
+SALAAM#SECT#BOA
+ALLSTAR##HIKERS
+####TROTS#RAGES
+RADII#WHITEROSE
+ICALL#EERO#ANTS
+GENOA#ROSE#TEES
+
+
+A1. Fruity summer coolers ~ ADES
+A5. Old Russian ruler ~ TSAR
+A9. Gives the impression ~ SEEMS
+A14. Dryer-screen buildup ~ LINT
+A15. Year, in a Latin phrase ~ ANNO
+A16. Eagle's lofty home ~ AERIE
+A17. Face-to-face, in a duel ~ MANOAMANO
+A19. Emergency road signal ~ FLARE
+A20. Writer Eugene or basketball great Shaquille ~ ONEIL
+A21. Penne or linguine ~ PASTA
+A23. Between-meal bites ~ SNACKS
+A25. Canada's largest city ~ TORONTO
+A30. "Lasso" of Apple TV+ ~ TED
+A31. Jessica of "Fantastic Four" ~ ALBA
+A34. Like a dog's cropped ears, sometimes ~ TINEAR
+A35. "Ferris Bueller" girlfriend ~ SLOANE
+A37. Sea eagle ~ ERNE
+A38. Instruments in many school music rooms ~ UPRIGHTPIANOS
+A42. Perseverance ~ GRIT
+A43. Witnessed by ~ SEENTO
+A44. Peaceful greeting ~ SALAAM
+A47. Small religious group ~ SECT
+A48. Feathered neckwear ~ BOA
+A51. Top player in a league ~ ALLSTAR
+A53. Trail followers ~ HIKERS
+A55. Moves at an easy horse gait ~ TROTS
+A58. Throws a fit ~ RAGES
+A59. Lines from a circle's center ~ RADII
+A63. Anti-Nazi student group in 1940s Munich ~ WHITEROSE
+A65. Umpire's shout before a ball or strike ~ ICALL
+A66. Architect Saarinen ~ EERO
+A67. Picnic invaders ~ ANTS
+A68. Italian port city ~ GENOA
+A69. Got up ~ ROSE
+A70. Golf-course pegs ~ TEES
+
+D1. Just about ~ ALMOST
+D2. Actress Wiest ~ DIANNE
+D3. Group of nine ~ ENNEAD
+D4. Unmoved by hardship ~ STOIC
+D5. Scottish cap ~ TAM
+D6. Break suddenly ~ SNAP
+D7. "Frozen" sister ~ ANNA
+D8. Henhouse perch ~ ROOST
+D9. Wildlife-watching trip ~ SAFARI
+D10. Long, slippery fish ~ EEL
+D11. Historical period ~ ERA
+D12. Former Russian space station ~ MIR
+D13. Understand ~ SEE
+D18. Strong base in chemistry ~ ALKALI
+D22. Little kid ~ TOT
+D24. Trudge through difficulty ~ SLOG
+D26. Binary score in a shutout, perhaps ~ ONENO
+D27. Emperor who fiddled, supposedly ~ NERO
+D28. Gets some sun ~ TANS
+D29. Mined mineral ~ ORE
+D32. Humbug preceders ~ BAHS
+D33. Poker payments before the deal ~ ANTES
+D35. Spanish "Misses": Abbr. ~ SRTAS
+D36. Fencing blade ~ EPEE
+D38. Mountain range near Siberia ~ URAL
+D39. Tablet, maybe ~ PILL
+D40. Small amount of progress ~ INCH
+D41. Clothing ~ ATTIRE
+D42. Federal property-management agcy. ~ GSA
+D45. Hun leader nicknamed "the Scourge of God" ~ ATTILA
+D46. Spoil the surface of ~ MAR
+D48. "Go away!" ~ BEGONE
+D49. Opera title role for a tenor ~ ORESTE
+D50. Evaluate ~ ASSESS
+D52. Crew team member ~ ROWER
+D54. Gold purity unit ~ KARAT
+D56. Painter van Doesburg ~ THEO
+D57. Polite address to gentlemen ~ SIRS
+D59. Oil-platform setup ~ RIG
+D60. Tennis serve nobody touches ~ ACE
+D61. Rather of the evening news ~ DAN
+D62. U.N. labor agency ~ ILO
+D64. Shoe tip? ~ TOE
diff --git a/Puzzles/Bundled/Crossmate-0003.xd b/Puzzles/Bundled/Crossmate-0003.xd
@@ -0,0 +1,102 @@
+Title: Crossmake #3
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 12/21/2011
+
+
+ASPS#REAM#BEAST
+SCOT#OSLO#ERNIE
+LENA#NEEDLENOSE
+ANGIO##NEATEN##
+NEERDOWELL##UKE
+TIE#DNA#TARHEEL
+###ABUTS##EAVES
+ANDMASTEROFNONE
+REOIL##WINED###
+NEEDLES#PER#SAS
+ODS##REVERENTLY
+##TIRANA##EARLS
+PHILOSOPHY#POET
+EAMES#ROBE#EDGE
+ALEXA#ARON#SEEM
+
+
+A1. Cobras' relatives ~ ASPS
+A5. Paper quantity ~ REAM
+A9. Monster ~ BEAST
+A14. Glasgow native ~ SCOT
+A15. Capital of Norway ~ OSLO
+A16. Bert's roommate ~ ERNIE
+A17. Dunham of "Girls" ~ LENA
+A18. Pliers with tapered jaws ~ NEEDLENOSE
+A20. Blood-vessel prefix ~ ANGIO
+A22. Make tidier ~ NEATEN
+A23. Lazy, unreliable sort ~ NEERDOWELL
+A26. Small four-stringed instrument, briefly ~ UKE
+A29. Deadlock ~ TIE
+A30. Heredity molecule ~ DNA
+A31. North Carolina student or athlete ~ TARHEEL
+A34. Border on ~ ABUTS
+A36. Roof overhangs ~ EAVES
+A37. Phrase after "Jack of all trades" ~ ANDMASTEROFNONE
+A42. Lubricate again ~ REOIL
+A43. Took out for drinks, say ~ WINED
+A44. Sewing-kit items ~ NEEDLES
+A47. For each ~ PER
+A48. Scandinavian airline ~ SAS
+A51. Excessive amounts, for short ~ ODS
+A52. With deep respect ~ REVERENTLY
+A55. Capital of Albania ~ TIRANA
+A58. British nobles ~ EARLS
+A59. Major concerned with big questions ~ PHILOSOPHY
+A63. Writer of verse ~ POET
+A64. Midcentury designer Charles ~ EAMES
+A65. Judge's garment ~ ROBE
+A66. Advantage ~ EDGE
+A67. Amazon voice assistant ~ ALEXA
+A68. Elvis's middle name ~ ARON
+A69. Appear to be ~ SEEM
+
+D1. At an angle ~ ASLANT
+D2. Play opener ~ SCENEI
+D3. Soft silk fabric ~ PONGEE
+D4. Step in a flight ~ STAIR
+D5. Howard of "Happy Days" ~ RON
+D6. Direction opposite WNW ~ ESE
+D7. One of two in naphthalene ~ ALENE
+D8. Ford that followed the Model S ~ MODELT
+D9. Root vegetable in borscht ~ BEET
+D10. Sea eagle ~ ERNE
+D11. New Year's Day, in Mexico ~ ANONUEVO
+D12. Female sibling, informally ~ SIS
+D13. Driving-range peg ~ TEE
+D19. Repeated syllables in a tune ~ LALA
+D21. Eccentric person ~ ODDBALL
+D24. Burden ~ ONUS
+D25. Unit named for a Scottish inventor ~ WATT
+D27. Sharp-minded ~ KEEN
+D28. Otherwise ~ ELSE
+D32. Striped official ~ REFEREE
+D33. Poker holding ~ HAND
+D34. Surrounded by ~ AMID
+D35. Use a needle and thread ~ SEW
+D37. Florentine river ~ ARNO
+D38. Require ~ NEED
+D39. Serves a prison sentence ~ DOESTIME
+D40. Ready to pick ~ RIPE
+D41. Standout, in slang ~ ONER
+D45. Historical periods ~ ERAS
+D46. Married woman, in Spanish ~ SENORA
+D48. Walked with long steps ~ STRODE
+D49. Claim without proof ~ ALLEGE
+D50. Organized set of parts ~ SYSTEM
+D53. Mist or steam ~ VAPOR
+D54. Backs of necks ~ NAPES
+D56. Holly genus ~ ILEX
+D57. Parks of civil-rights history ~ ROSA
+D59. Tiny vegetable in a pod ~ PEA
+D60. Computer in "2001" ~ HAL
+D61. "Succession" network ~ HBO
+D62. Japanese currency ~ YEN
diff --git a/Puzzles/Bundled/Crossmate-0004.xd b/Puzzles/Bundled/Crossmate-0004.xd
@@ -0,0 +1,104 @@
+Title: Crossmake #4
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 03/24/2010
+
+
+AVESTA#OSHA#OTT
+BAZAAR#SHAM#SEE
+ENISLE#MART#ATE
+ENOS#SNAPDRAGON
+TAPER#ONE#AMENS
+##IDIOT##SKI###
+USN#AMIDST#CLUE
+SIZELIMITATIONS
+NCAA#TENORS#SOP
+###TAS##LEAST##
+NANAS#ACE#RECTI
+ANOTHERONE#LAID
+OWL#TROT#ALLURE
+MAT#OMIT#REESES
+IRE#NADA#NOREST
+
+
+A1. Zoroastrian sacred text ~ AVESTA
+A7. Workplace safety org. ~ OSHA
+A11. Mel of baseball ~ OTT
+A14. Middle Eastern marketplace ~ BAZAAR
+A15. Pretend; counterfeit ~ SHAM
+A16. Understand ~ SEE
+A17. Strand, as on an island ~ ENISLE
+A18. Place to shop ~ MART
+A19. Had dinner, say ~ ATE
+A20. Slaughter of baseball ~ ENOS
+A21. Colorful garden flower with a dragon-like name ~ SNAPDRAGON
+A24. Narrow gradually ~ TAPER
+A26. Single unit ~ ONE
+A27. Congregational assents ~ AMENS
+A28. Foolish person ~ IDIOT
+A30. Hit the slopes ~ SKI
+A31. Navy, for short ~ USN
+A33. In the middle of ~ AMIDST
+A36. Solver's hint ~ CLUE
+A40. Restrictions on upload size, maybe ~ SIZELIMITATIONS
+A43. March Madness org. ~ NCAA
+A44. High male voices ~ TENORS
+A45. Token concession ~ SOP
+A46. Thanks, casually ~ TAS
+A48. Smallest in amount ~ LEAST
+A50. Grandmothers, informally ~ NANAS
+A53. Tennis serve no one touches ~ ACE
+A55. Abdominal muscles, formally ~ RECTI
+A58. "Not that one either" ~ ANOTHERONE
+A61. Put down, as carpet ~ LAID
+A62. Night hooter ~ OWL
+A63. Easy horse gait ~ TROT
+A64. Attractive quality ~ ALLURE
+A66. Gymnast's landing pad ~ MAT
+A67. Leave out ~ OMIT
+A68. Peanut-butter candy brand ~ REESES
+A69. Anger ~ IRE
+A70. Nothing, in Spanish ~ NADA
+A71. Condition after an all-nighter ~ NOREST
+
+D1. Root vegetable, with article ~ ABEET
+D2. Wheel of Fortune letter-turner White ~ VANNA
+D3. Opera singer Pinza ~ EZIOPINZA
+D4. Talked back to ~ SASSED
+D5. Actor's agent, informally ~ TAL
+D6. Greek war god ~ ARES
+D7. Founder of the Ottoman dynasty ~ OSMAN
+D8. Form ~ SHAPE
+D9. Difficult ~ HARD
+D10. Rail travel brand ~ AMTRAK
+D11. Native American people of the Plains ~ OSAGE
+D12. Grand ___ National Park ~ TETON
+D13. High schoolers, often ~ TEENS
+D22. "I have to run!" ~ NOTIME
+D23. Friends, in Italian ~ AMICI
+D25. Former Iranian currency ~ RIAL
+D29. Leaves out ~ OMITS
+D30. Look fixedly ~ STARE
+D31. Navy, for short ~ USN
+D32. Thus, in quoted text ~ SIC
+D34. Loud racket ~ DIN
+D35. Taken without permission ~ STOLEN
+D37. Hopeless effort ~ LOSTCAUSE
+D38. Card game with a Reverse card ~ UNO
+D39. Mind-reading ability, briefly ~ ESP
+D41. Dine in a restaurant ~ EATAT
+D42. Old Russian ruler ~ TSAR
+D47. Kutcher of "That '70s Show" ~ ASHTON
+D49. Vendor ~ SELLER
+D50. Osaka of tennis ~ NAOMI
+D51. Sadat of Egypt ~ ANWAR
+D52. Actor Nick ~ NOLTE
+D53. Plant such as a calla lily ~ AROID
+D54. Terra ___ ~ COTTA
+D56. Car parts that need rotating ~ TIRES
+D57. "The ___ of March" ~ IDEST
+D59. Bombeck who wrote humor columns ~ ERMA
+D60. Bring in, as income ~ EARN
+D65. Zodiac lion ~ LEO
diff --git a/Puzzles/Bundled/Crossmate-0005.xd b/Puzzles/Bundled/Crossmate-0005.xd
@@ -0,0 +1,104 @@
+Title: Crossmake #5
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 12/06/2011
+
+
+VASSAR#ATE#ACED
+EUCHRE#ION#TORE
+STARED#LONGHORN
+TONICS#STEAL###
+###NATE##ABELES
+TASK#ONRED#TORT
+OPT#INEED#GENRE
+REY#DESSERT#DAR
+EMMAS#CAMEO#ONE
+RAIN#SOYAS#UNDO
+ONESEC##SIGN###
+###WEARE#SELECT
+ETHELRED#TEEPEE
+TEAR#ANG#ESSENE
+SASS#BEE#RESETS
+
+
+A1. Seven Sisters college in Poughkeepsie ~ VASSAR
+A7. Had lunch, say ~ ATE
+A10. Nailed the test ~ ACED
+A14. Trick-taking card game ~ EUCHRE
+A15. Charged particle ~ ION
+A16. Ripped ~ TORE
+A17. Looked intently ~ STARED
+A18. Texas cattle breed ~ LONGHORN
+A20. Mixer drinks ~ TONICS
+A21. Basketball takeaway ~ STEAL
+A22. Archibald of basketball ~ NATE
+A24. Israeli writer Aharon ___ ~ ABELES
+A28. Chore ~ TASK
+A31. Backing a roulette color, perhaps ~ ONRED
+A34. Civil wrong ~ TORT
+A35. Choose ~ OPT
+A36. "Help me out here!" ~ INEED
+A37. Mystery or romance, e.g. ~ GENRE
+A38. Daisy Ridley's "Star Wars" role ~ REY
+A39. Sweet course ~ DESSERT
+A41. Daughters of the American Revolution, briefly ~ DAR
+A42. Watson and Stone ~ EMMAS
+A44. Brief appearance in a movie ~ CAMEO
+A45. Single ~ ONE
+A46. Forecast word ~ RAIN
+A47. Soybean products ~ SOYAS
+A48. Reverse ~ UNDO
+A49. "Hold on a moment" ~ ONESEC
+A51. Omen ~ SIGN
+A53. "___ family" ~ WEARE
+A56. Pick out ~ SELECT
+A60. Medieval English king called "the Unready" ~ ETHELRED
+A63. Conical tent ~ TEEPEE
+A64. Rip ~ TEAR
+A65. Trig function, for short ~ ANG
+A66. Ancient Jewish ascetic ~ ESSENE
+A67. Back talk ~ SASS
+A68. Spelling contest ~ BEE
+A69. Starts over ~ RESETS
+
+D1. Sleeveless garment ~ VEST
+D2. Car, informally ~ AUTO
+D3. Check with a reader, as a barcode ~ SCAN
+D4. Get smaller ~ SHRINK
+D5. Betel palm genus ~ ARECA
+D6. Minecraft wiring material ~ REDSTONE
+D7. Is under the weather ~ AILS
+D8. Blow a horn ~ TOOT
+D9. Group of nine ~ ENNEAD
+D10. Sports competitor ~ ATHLETE
+D11. Company executive, briefly ~ COO
+D12. Make a mistake ~ ERR
+D13. Cozy room ~ DEN
+D19. Chatter ~ GAB
+D23. Romanian composer George ~ ENESCO
+D25. Capital on the Thames ~ LONDON
+D26. Small chore outside the house ~ ERRAND
+D27. Two-speaker sound system ~ STEREO
+D28. Bullfighter ~ TORERO
+D29. Primitive human, informally ~ APEMAN
+D30. Thwart ~ STYMIE
+D32. State again ~ RESAY
+D33. Swellings from fluid buildup ~ EDEMAS
+D36. Proofs of identity, briefly ~ IDS
+D37. Classic Pontiac muscle car ~ GTO
+D40. One who opposes ~ RESISTER
+D43. Puzzle solutions ~ ANSWERS
+D47. Egyptian beetle amulet ~ SCARAB
+D48. Except if ~ UNLESS
+D50. Long, slippery fish ~ EEL
+D52. Honking flock ~ GEESE
+D54. Artist Magritte ~ RENE
+D55. Advantage ~ EDGE
+D57. Fencing sword ~ EPEE
+D58. Penny ~ CENT
+D59. Golf-course pegs ~ TEES
+D60. Little green visitors, briefly ~ ETS
+D61. Afternoon drink ~ TEA
+D62. Possesses ~ HAS
diff --git a/Puzzles/Bundled/Crossmate-0006.xd b/Puzzles/Bundled/Crossmate-0006.xd
@@ -0,0 +1,104 @@
+Title: Crossmake #6
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 11/07/2011
+
+
+ERIC##DEMS#IRMA
+GOSH#ARMEE#LIES
+GALA#POUNDSIGNS
+ONESTEP##ANA###
+###TED#DSTUDENT
+#SEEN#CELEB#LEO
+BANNS#ONES#MART
+ALLEE#STU#NAIVE
+RAID#EMIT#ERNES
+IDS#IRISH#PIES#
+CATARACT#TAN###
+###RAS##MOLESTS
+SINEQUANON#SAIL
+EROS#RLESS#ULNA
+EERO#EATS##BEET
+
+
+A1. Idle of Monty Python ~ ERIC
+A5. Some blue-state politicians, briefly ~ DEMS
+A9. 2017 hurricane name ~ IRMA
+A13. "Gee whiz!" ~ GOSH
+A14. French army ~ ARMEE
+A15. Untruths ~ LIES
+A16. Fund-raising event ~ GALA
+A17. Symbols also called hashtags ~ POUNDSIGNS
+A19. "___ at a time" ~ ONESTEP
+A21. Santa ___, California ~ ANA
+A22. "Lasso" of Apple TV+ ~ TED
+A23. One earning barely passing grades ~ DSTUDENT
+A28. Spotted ~ SEEN
+A30. Tabloid subject, for short ~ CELEB
+A31. Zodiac lion ~ LEO
+A32. Marriage announcements in church ~ BANNS
+A33. Single bills ~ ONES
+A34. Shop ~ MART
+A35. Tree-lined walk ~ ALLEE
+A36. Disco ___ of "The Simpsons" ~ STU
+A37. Unsophisticated ~ NAIVE
+A38. Police surprise ~ RAID
+A39. Give off ~ EMIT
+A40. Sea eagles ~ ERNES
+A41. Wallet cards, briefly ~ IDS
+A42. From Dublin, say ~ IRISH
+A43. Bakery buys ~ PIES
+A44. Eye-clouding condition ~ CATARACT
+A46. Beachgoer's goal ~ TAN
+A47. Org. with chapters at universities ~ RAS
+A48. Harasses sexually ~ MOLESTS
+A52. Essential condition ~ SINEQUANON
+A57. Canvas catcher ~ SAIL
+A58. Greek god of love ~ EROS
+A59. Like some merchandise after markdowns ~ RLESS
+A60. Forearm bone ~ ULNA
+A61. Architect Saarinen ~ EERO
+A62. Has dinner ~ EATS
+A63. Borscht vegetable ~ BEET
+
+D1. Frozen waffle brand ~ EGGO
+D2. Reddish-brown horse ~ ROAN
+D3. Small landmass in water ~ ISLE
+D4. Reprimanded ~ CHASTENED
+D5. Let fall ~ DROP
+D6. Flightless Australian bird ~ EMU
+D7. Gentlemen ~ MEN
+D8. Calms with medication ~ SEDATES
+D9. Epic poem about Troy ~ ILIAD
+D10. Oil-drilling setup ~ RIG
+D11. Guys ~ MEN
+D12. Donkey ~ ASS
+D14. Imitated ~ APED
+D18. Cold shoulder ~ SNUB
+D20. On edge ~ TENSE
+D23. Tooth doctor ~ DENTIST
+D24. Detective ~ SLEUTH
+D25. Benes of "Seinfeld" ~ ELAINE
+D26. Courage, informally ~ NERVES
+D27. Carries ~ TOTES
+D28. Tea brand in a red package ~ SALADA
+D29. Sign up ~ ENLIST
+D30. Relating to the universe ~ COSMIC
+D32. Like barium, chemically ~ BARIC
+D34. Underwater naval vessel ~ MARINESUB
+D37. Kathmandu's country ~ NEPAL
+D39. Removal by rubbing out ~ ERASURE
+D42. Baghdad's country ~ IRAQ
+D45. "You ___ right!" ~ ARESO
+D46. Large quantities ~ TONS
+D48. Green growth on damp rocks ~ MOSS
+D49. Discount event ~ SALE
+D50. Fork prong ~ TINE
+D51. Blind strip ~ SLAT
+D52. Understand ~ SEE
+D53. Anger ~ IRE
+D54. "Neither" partner ~ NOR
+D55. ___ carte ~ ALA
+D56. Fisherman's need ~ NET
diff --git a/Puzzles/Bundled/Crossmate-0007.xd b/Puzzles/Bundled/Crossmate-0007.xd
@@ -0,0 +1,104 @@
+Title: Crossmake #7
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 11/29/2016
+
+
+ASOF#ATRA#SPRAT
+ROAR#LEOS#TAEBO
+RATE#LASTSUPPER
+AMESS#SARA#ARES
+SINCERE#OLD#ETO
+###APE#ANTICS##
+UPS#ANDSO#SHELF
+SATURDAYMATINEE
+NYASA#MEYER#TIE
+##FATCAT#OAT###
+ARF#EIS#INCISOR
+MICA#TKOS#TRACE
+PLUSWEEKLY#ALTA
+LETHE#ERIE#DOER
+ESSES#NAPS#ENTS
+
+
+A1. Starting on, in date lines ~ ASOF
+A5. Gillette razor brand ~ ATRA
+A9. Small herring ~ SPRAT
+A14. Lion's sound ~ ROAR
+A15. Zodiac lions ~ LEOS
+A16. Billy Blanks workout ~ TAEBO
+A17. Evaluate ~ RATE
+A18. Leonardo da Vinci mural ~ LASTSUPPER
+A20. "What ___!" ~ AMESS
+A22. Bareilles of pop music ~ SARA
+A23. Greek war god ~ ARES
+A24. Genuine ~ SINCERE
+A26. Aged ~ OLD
+A28. WWII Pacific theater initials ~ ETO
+A29. Gorilla or gibbon ~ APE
+A30. Silly behavior ~ ANTICS
+A32. Delivery company, briefly ~ UPS
+A35. "Furthermore..." ~ ANDSO
+A37. Bookcase level ~ SHELF
+A40. Weekend afternoon movie showing ~ SATURDAYMATINEE
+A43. Lake also called Malawi ~ NYASA
+A44. "Twilight" author Stephenie ~ MEYER
+A45. Draw ~ TIE
+A46. Wealthy power broker ~ FATCAT
+A48. Breakfast grain ~ OAT
+A50. Dog's bark ~ ARF
+A52. German ice creams ~ EIS
+A53. Cutting tooth ~ INCISOR
+A57. Flaky mineral ~ MICA
+A59. Referee's stoppages, briefly ~ TKOS
+A61. Hint of evidence ~ TRACE
+A62. Additional edition every seven days ~ PLUSWEEKLY
+A65. Utah ski area ~ ALTA
+A66. River of forgetfulness ~ LETHE
+A67. Great Lake bordering Ohio ~ ERIE
+A68. Person who takes action ~ DOER
+A69. Hissing letters ~ ESSES
+A70. Short sleeps ~ NAPS
+A71. Tree creatures in Tolkien ~ ENTS
+
+D1. Tapestry wall hangings ~ ARRAS
+D2. "___ right?" ~ SOAMI
+D3. Made with a cereal grain ~ OATEN
+D4. Grapefruit soda brand ~ FRESCA
+D5. Every bit ~ ALL
+D6. Rib playfully ~ TEASE
+D7. Parks of civil-rights history ~ ROSA
+D8. Study of stars and planets ~ ASTRONOMY
+D9. Disco ___ of "The Simpsons" ~ STU
+D10. Dad ~ PAPA
+D11. Stand for ~ REPRESENT
+D12. Root vegetable, with article ~ ABEET
+D13. Body trunk ~ TORSO
+D19. Seasoning from the sea ~ SALT
+D21. Set apart ~ SEPARATE
+D25. Tear violently ~ REND
+D27. Divert attention ~ DISTRACT
+D30. Up to now ~ ASYET
+D31. Greek letter after phi ~ CHI
+D32. Navy, for short ~ USN
+D33. Wages ~ PAY
+D34. Reductions in personnel ~ STAFFCUTS
+D36. Decorated with inlaid metal ~ DAMASKEEN
+D38. Hawaiian garland ~ LEI
+D39. Charge for service ~ FEE
+D41. Country with 50 states, briefly ~ USA
+D42. Long span of time ~ AEON
+D47. Quote as evidence ~ CITE
+D49. Angry speech ~ TIRADE
+D50. More than enough ~ AMPLE
+D51. Annoys ~ RILES
+D53. Long Island town ~ ISLIP
+D54. Hairdresser's workplace ~ SALON
+D55. Group of eight ~ OCTET
+D56. Raises, as children ~ REARS
+D58. Tennis great Arthur ~ ASHE
+D60. Gumbo vegetable ~ OKRA
+D63. Anderson of film ~ WES
+D64. Affirmative vote ~ YES
diff --git a/Puzzles/Bundled/Crossmate-0008.xd b/Puzzles/Bundled/Crossmate-0008.xd
@@ -0,0 +1,102 @@
+Title: Crossmake #8
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 10/23/2012
+
+
+ASPS#BLAB#TEMPT
+BLIP#RAIL#ISOLA
+BANANACREAMPIES
+ANTRA##YELP#RAT
+STARLET#PLACATE
+###ODEON#ONO###
+WEEWILLIEWINKIE
+IKE###EEL###IDI
+TELLSITLIKEITIS
+###ETO#SAENS###
+AGITATE#SNOOKER
+TEN#SALE##CLOVE
+WEKISSINASHADOW
+ANELE#TIRE#TAKE
+RADON#EDIT#EKED
+
+
+A1. Cobras' kin ~ ASPS
+A5. Reveal a secret ~ BLAB
+A9. Entice ~ TEMPT
+A14. Tiny radar-screen mark ~ BLIP
+A15. Train track ~ RAIL
+A16. Island, in Italian ~ ISOLA
+A17. Desserts with yellow fruit and whipped topping ~ BANANACREAMPIES
+A20. Cavities in bones ~ ANTRA
+A21. Restaurant-review app ~ YELP
+A22. Informer ~ RAT
+A23. Up-and-coming actress ~ STARLET
+A26. Pacify ~ PLACATE
+A28. Old movie theater name ~ ODEON
+A30. Yoko of art and music ~ ONO
+A31. Nursery-rhyme boy who runs through town ~ WEEWILLIEWINKIE
+A38. Eisenhower nickname ~ IKE
+A39. Sushi fish ~ EEL
+A40. Amin of Uganda ~ IDI
+A41. Speaks bluntly ~ TELLSITLIKEITIS
+A48. WWII Pacific theater initials ~ ETO
+A49. Saint-___, French composer ~ SAENS
+A50. Stir up ~ AGITATE
+A54. Cue sport played on a large table ~ SNOOKER
+A58. Number after nine ~ TEN
+A59. Store discount event ~ SALE
+A61. Aromatic spice bud ~ CLOVE
+A62. "The King and I" song ~ WEKISSINASHADOW
+A66. Anoint, in old usage ~ ANELE
+A67. Wheel covering ~ TIRE
+A68. Capture on film ~ TAKE
+A69. Radioactive gas ~ RADON
+A70. Revise text ~ EDIT
+A71. Managed with difficulty, with "out" ~ EKED
+
+D1. Palestinian leader Mahmoud ~ ABBAS
+D2. Lean at an angle ~ SLANT
+D3. One of Columbus's ships ~ PINTA
+D4. Small brown songbird ~ SPARROW
+D5. Lingerie item ~ BRA
+D6. Resin once used in records ~ LAC
+D7. Light and breezy ~ AIRY
+D8. Censor's sound ~ BLEEP
+D9. Kettledrums ~ TIMPANI
+D10. Mind-reading ability, briefly ~ ESP
+D11. Rose of "Schitt's Creek" ~ MOIRA
+D12. Fold in fabric ~ PLEAT
+D13. Sense sampled by a chef ~ TASTE
+D18. Silent-film star Nita ~ NALDI
+D19. Permit ~ ALLOW
+D24. Long, slippery fish ~ EEL
+D25. Available for rent, on a sign ~ TOLET
+D27. Swindle ~ CON
+D29. Physicist Bohr ~ NIELS
+D31. Clever humor ~ WIT
+D32. Scrape by ~ EKE
+D33. Moray, e.g. ~ EEL
+D34. Howe of hockey ~ ELIAS
+D35. Set of parts ~ KIT
+D36. Amin of Uganda ~ IDI
+D37. German ice creams ~ EIS
+D42. Permit ~ LET
+D43. 1948 presidential hopeful Harold ~ STASSEN
+D44. Tiny amounts ~ IOTAS
+D45. Barbie's companion ~ KEN
+D46. Biblical patriarch who "walked with God" ~ ENOCH
+D47. Set apart ~ ISOLATE
+D50. In conflict ~ ATWAR
+D51. Davis of "Thelma & Louise" ~ GEENA
+D52. Signed, as a contract ~ INKED
+D53. Best of the best ~ ELITE
+D55. Camera brand ~ KODAK
+D56. Bring to mind ~ EVOKE
+D57. Marry again ~ REWED
+D60. Oklahoma city ~ ENID
+D63. U.N. labor agency ~ ILO
+D64. "Entourage" agent Gold ~ ARI
+D65. Put in place ~ SET
diff --git a/Puzzles/Bundled/Crossmate-0009.xd b/Puzzles/Bundled/Crossmate-0009.xd
@@ -0,0 +1,102 @@
+Title: Crossmake #9
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 07/12/2012
+
+
+SAFE#CARE#AFLAC
+AXLE#OPED#TIARA
+TEARDROPS#TENET
+##TOOTLE#DILATE
+AHA#SELLSOLDIER
+VAN#AGO#CRAG###
+ENGAGE#TAM#OCHO
+ROLFE#SUN#BALER
+TIER#INN#MELONS
+###IONA#TOY#CIO
+RATKANGAROO#KEN
+UBOATS#MINNOW##
+DUNNE#LETSDRIVE
+ESKER#OBOE#ASEA
+REARS#WANT#LEER
+
+
+A1. Out of danger ~ SAFE
+A5. Concern ~ CARE
+A9. Insurer with a duck mascot ~ AFLAC
+A14. Wheel rod ~ AXLE
+A15. Newspaper opinion piece ~ OPED
+A16. Princess's headwear ~ TIARA
+A17. Signs of sorrow ~ TEARDROPS
+A19. Doctrine ~ TENET
+A20. Move along leisurely ~ TOOTLE
+A21. Widen, as pupils ~ DILATE
+A22. "Now I get it!" ~ AHA
+A24. Betray a comrade in arms ~ SELLSOLDIER
+A26. Moving vehicle ~ VAN
+A27. In the past ~ AGO
+A28. Rocky outcrop ~ CRAG
+A29. Take part ~ ENGAGE
+A31. Scottish cap ~ TAM
+A32. Eight, in Spanish ~ OCHO
+A36. John of Jamestown history ~ ROLFE
+A37. Star at the center of our solar system ~ SUN
+A38. Hay-bundling machine ~ BALER
+A39. Level in a hierarchy ~ TIER
+A40. Roadside lodging ~ INN
+A41. Cantaloupes and honeydews ~ MELONS
+A42. Scottish island with an ancient abbey ~ IONA
+A44. Child's plaything ~ TOY
+A45. Tech exec, briefly ~ CIO
+A46. Small desert marsupial ~ RATKANGAROO
+A50. Barbie's companion ~ KEN
+A51. German submarines ~ UBOATS
+A52. Small fish often used as bait ~ MINNOW
+A54. Writer Dominick ~ DUNNE
+A55. "Hit the road!" ~ LETSDRIVE
+A58. Winding glacial ridge ~ ESKER
+A59. Double-reed woodwind ~ OBOE
+A60. On the ocean ~ ASEA
+A61. Raises, as children ~ REARS
+A62. Desire ~ WANT
+A63. Sly look ~ LEER
+
+D1. Was seated ~ SAT
+D2. Chopping tool ~ AXE
+D3. 180-degree angle ~ FLATANGLE
+D4. Architect Saarinen ~ EERO
+D5. Funeral procession ~ CORTEGE
+D6. Greek god associated with the sun ~ APOLLO
+D7. Drive back ~ REPEL
+D8. Magazine staffers, briefly ~ EDS
+D9. Hun leader nicknamed "the Scourge of God" ~ ATTILA
+D10. Three-point football score ~ FIELDGOAL
+D11. Hawaiian porch ~ LANAI
+D12. Sharp mountain ridge ~ ARETE
+D13. Provide food for an event ~ CATER
+D18. Prescribed amount ~ DOSAGE
+D21. Campus residence, briefly ~ DORM
+D22. Ward off ~ AVERT
+D23. Vietnam's capital ~ HANOI
+D25. Look over quickly ~ SCAN
+D30. South African of Dutch descent ~ AFRIKANER
+D31. Large wine cask ~ TUN
+D33. In the direction hands move on a clock ~ CLOCKWISE
+D34. Figure skater Sonja ~ HENIE
+D35. Welles of film ~ ORSON
+D37. Catch unexpectedly ~ SNAG
+D38. Past ~ BEYOND
+D40. Lodgings for travelers ~ INNS
+D41. Lunar disappearance below the horizon ~ MOONSET
+D43. Western films, informally ~ OATERS
+D44. Neptune's largest moon ~ TRITON
+D46. Less polite ~ RUDER
+D47. Mistreat ~ ABUSE
+D48. Toy truck brand ~ TONKA
+D49. Single-celled organism, variant spelling ~ AMEBA
+D53. Spoken ~ ORAL
+D55. Not high ~ LOW
+D56. Letter after u ~ VEE
+D57. Hearing organ ~ EAR
diff --git a/Puzzles/Bundled/Crossmate-0010.xd b/Puzzles/Bundled/Crossmate-0010.xd
@@ -0,0 +1,104 @@
+Title: Crossmake #10
+Author: Crossmake
+Publisher: Crossmake
+Date: 2026-04-29
+Copyright: Generated
+Source Grid: 03/27/2012
+
+
+AGASP#STARE#ARC
+SORTA#ERNIE#GEL
+PANAMACANALCITY
+#TOTEM#SOL#ARID
+###SLUSHY#FTLEE
+MAC#ANT#SPAN###
+ACLU#DEB#ARABLE
+SHAKESPEAREPLAY
+TENURE#END#SURE
+###LAND#EOS#RAD
+ANTES#YAWNED###
+SEAL#AND#MERIT#
+HAREBRAINEDIDEA
+ETO#AIMEE#ELLAS
+SOT#ADOUT#RLESS
+
+
+A1. Open-mouthed with surprise ~ AGASP
+A6. Look fixedly ~ STARE
+A11. Part of a circle ~ ARC
+A14. Somewhat, informally ~ SORTA
+A15. Bert's roommate ~ ERNIE
+A16. Set, as hair ~ GEL
+A17. Colón, where a famous waterway begins ~ PANAMACANALCITY
+A20. Clan emblem ~ TOTEM
+A21. Musical note after fa ~ SOL
+A22. Desertlike ~ ARID
+A23. Partly melted ~ SLUSHY
+A25. Virginia military post, for short ~ FTLEE
+A26. Apple computer, casually ~ MAC
+A29. Picnic invader ~ ANT
+A30. Stretch of time ~ SPAN
+A32. Civil-liberties org. ~ ACLU
+A34. Young woman making a formal society entrance ~ DEB
+A36. Fit for farming ~ ARABLE
+A40. "Hamlet" or "Macbeth" ~ SHAKESPEAREPLAY
+A43. Job security for a professor ~ TENURE
+A44. Finish ~ END
+A45. Certain ~ SURE
+A46. Touch down ~ LAND
+A48. Greek dawn goddess ~ EOS
+A50. Cool, in old slang ~ RAD
+A51. Poker payments before the deal ~ ANTES
+A54. Showed boredom or fatigue ~ YAWNED
+A57. Animal on a Navy emblem ~ SEAL
+A58. Plus ~ AND
+A59. Deserve ~ MERIT
+A62. Wildly impractical notion ~ HAREBRAINEDIDEA
+A66. WWII Pacific theater initials ~ ETO
+A67. Singer Mann ~ AIMEE
+A68. Fitzgerald and Raines ~ ELLAS
+A69. Drunkard ~ SOT
+A70. Stir, with "make" ~ ADOUT
+A71. Like some marked-down merchandise ~ RLESS
+
+D1. Small venomous snake ~ ASP
+D2. Barnyard bleater ~ GOAT
+D3. River through Florence ~ ARNO
+D4. Sports figures ~ STATS
+D5. Anderson of "Baywatch" ~ PAMELA
+D6. Minuscule time unit, for short ~ SEC
+D7. Garbage ~ TRASH
+D8. Irritates ~ ANNOYS
+D9. Former Iranian currency ~ RIAL
+D10. Long, slippery fish ~ EEL
+D11. "Just ___" ~ AGIRL
+D12. Knot again ~ RETIE
+D13. Bonnie's partner ~ CLYDE
+D18. Explorer Roald ~ AMUNDSEN
+D19. Short sleeps ~ CATNAPS
+D24. Stair part ~ STEP
+D25. Bus ticket price ~ FARE
+D26. Sail support ~ MAST
+D27. Dull pain ~ ACHE
+D28. Scottish family group ~ CLAN
+D31. "Excuse me" ~ PARDONME
+D33. Small four-stringed instrument ~ UKULELE
+D35. Spelling contest ~ BEE
+D37. Smear ~ BLUR
+D38. Croft of video games ~ LARA
+D39. Looked at closely ~ EYED
+D41. Historical periods ~ ERAS
+D42. Once more ~ ANEW
+D47. Energetic person ~ DYNAMO
+D49. Lawn-planting tool ~ SEEDER
+D51. Fireplace remains ~ ASHES
+D52. "Cool!" ~ NEATO
+D53. Fortune-telling deck ~ TAROT
+D55. French farewell ~ ADIEU
+D56. Practice exercise ~ DRILL
+D58. Desertlike ~ ARID
+D60. Not active ~ IDLE
+D61. Steeps, as leaves ~ TEAS
+D63. Sheep's sound ~ BAA
+D64. Fisherman's need ~ NET
+D65. Donkey ~ ASS
diff --git a/Tests/Unit/PuzzleCatalogTests.swift b/Tests/Unit/PuzzleCatalogTests.swift
@@ -0,0 +1,34 @@
+import Testing
+
+@testable import Crossmate
+
+@Suite("PuzzleCatalog")
+struct PuzzleCatalogTests {
+ @Test("Bundled puzzle resources are discoverable")
+ func bundledPuzzleResourcesAreDiscoverable() {
+ let puzzles = PuzzleCatalog.bundledPuzzles()
+
+ #expect(puzzles.count == 10)
+ #expect(puzzles.map(\.title).contains("Crossmake #1"))
+ #expect(puzzles.map(\.title).contains("Crossmake #10"))
+ #expect(puzzles.map(\.id) == [
+ "Crossmate-0001",
+ "Crossmate-0002",
+ "Crossmate-0003",
+ "Crossmate-0004",
+ "Crossmate-0005",
+ "Crossmate-0006",
+ "Crossmate-0007",
+ "Crossmate-0008",
+ "Crossmate-0009",
+ "Crossmate-0010"
+ ])
+ }
+
+ @Test("Debug puzzle resources are discoverable")
+ func debugPuzzleResourcesAreDiscoverable() {
+ let puzzles = PuzzleCatalog.debugPuzzles()
+
+ #expect(puzzles.count == 3)
+ }
+}