jspsych-tangram 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19637,8 +19637,7 @@ var TangramConstructPlugin = (function (jspsych) {
19637
19637
  }
19638
19638
  const sectorTangramMap = this.controller.state.cfg.sectors.map((s) => ({
19639
19639
  sectorId: s.id,
19640
- tangramId: s.id
19641
- // In our system, sector ID == tangram ID
19640
+ tangramId: s.tangramId
19642
19641
  }));
19643
19642
  const blueprintOrder = {
19644
19643
  primitives: this.controller.state.primitives.map((bp) => bp.id),
@@ -20143,11 +20142,11 @@ var TangramConstructPlugin = (function (jspsych) {
20143
20142
  return pts;
20144
20143
  }
20145
20144
  const FIRST_EDGES_UNITS = {
20146
- small_triangle: [P(0, 0), P(0.5, 0.5)],
20147
- parallelogram: [P(0, 0), P(0.5, 0)],
20148
- large_triangle: [P(0, 0), P(0.5, -0.5)],
20149
- med_triangle: [P(0, 0), P(0.5, 0)],
20150
- square: [P(0, 0), P(0.5, 0)]
20145
+ "smalltriangle": [P(0, 0), P(0.5, 0.5)],
20146
+ "parallelogram": [P(0, 0), P(0.5, 0)],
20147
+ "largetriangle": [P(0, 0), P(0.5, -0.5)],
20148
+ "medtriangle": [P(0, 0), P(0.5, 0)],
20149
+ "square": [P(0, 0), P(0.5, 0)]
20151
20150
  };
20152
20151
  const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
20153
20152
  const specs = [
@@ -20159,8 +20158,8 @@ var TangramConstructPlugin = (function (jspsych) {
20159
20158
  color: "#f43f5e"
20160
20159
  },
20161
20160
  {
20162
- id: "prim:small",
20163
- kind: "small_triangle",
20161
+ id: "prim:smalltriangle",
20162
+ kind: "smalltriangle",
20164
20163
  sideLens: [HALFDIAGONAL, HALFDIAGONAL, HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT],
20165
20164
  angles: [180, 45, 180, 90, 180, 45],
20166
20165
  color: "#f59e0b"
@@ -20173,15 +20172,15 @@ var TangramConstructPlugin = (function (jspsych) {
20173
20172
  color: "#10b981"
20174
20173
  },
20175
20174
  {
20176
- id: "prim:med",
20177
- kind: "med_triangle",
20175
+ id: "prim:medtriangle",
20176
+ kind: "medtriangle",
20178
20177
  sideLens: [HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL],
20179
20178
  angles: [180, 180, 180, 45, 180, 90, 180, 45],
20180
20179
  color: "#3b82f6"
20181
20180
  },
20182
20181
  {
20183
- id: "prim:large",
20184
- kind: "large_triangle",
20182
+ id: "prim:largetriangle",
20183
+ kind: "largetriangle",
20185
20184
  sideLens: [
20186
20185
  HALFDIAGONAL,
20187
20186
  HALFDIAGONAL,
@@ -20251,48 +20250,103 @@ var TangramConstructPlugin = (function (jspsych) {
20251
20250
  }
20252
20251
 
20253
20252
  function startConstructionTrial(display_element, params, _jsPsych) {
20254
- const sectors = params.tangrams.map((tangramSpec) => ({
20255
- id: tangramSpec.id,
20256
- silhouette: {
20257
- id: tangramSpec.id,
20258
- mask: tangramSpec.silhouette.mask.map(
20259
- (polygonArray) => polygonArray.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }))
20260
- // Convert to SVG coords (flip Y)
20261
- ),
20262
- requiredCount: tangramSpec.silhouette.requiredCount
20263
- }
20264
- }));
20253
+ const CANON = /* @__PURE__ */ new Set([
20254
+ "square",
20255
+ "smalltriangle",
20256
+ "parallelogram",
20257
+ "medtriangle",
20258
+ "largetriangle"
20259
+ ]);
20260
+ console.log("[ConstructionApp] Starting tangram conversion...");
20261
+ console.log("[ConstructionApp] Received tangrams:", params.tangrams);
20262
+ console.log("[ConstructionApp] Number of tangrams:", params.tangrams.length);
20263
+ const sectors = params.tangrams.map((tangramSpec, index) => {
20264
+ console.log(`
20265
+ [ConstructionApp] Processing tangram ${index}:`, tangramSpec);
20266
+ console.log(`[ConstructionApp] tangramID: ${tangramSpec.tangramID}`);
20267
+ console.log(`[ConstructionApp] setLabel: ${tangramSpec.setLabel}`);
20268
+ console.log(`[ConstructionApp] solutionTans count: ${tangramSpec.solutionTans?.length}`);
20269
+ console.log(`[ConstructionApp] solutionTans:`, tangramSpec.solutionTans);
20270
+ const filteredTans = tangramSpec.solutionTans.filter((tan) => {
20271
+ const tanName = tan.name ?? tan.kind;
20272
+ const isCanonical = CANON.has(tanName);
20273
+ console.log(`[ConstructionApp] Tan "${tanName}": canonical=${isCanonical}, vertices count=${tan.vertices?.length}`);
20274
+ return isCanonical;
20275
+ });
20276
+ console.log(`[ConstructionApp] Filtered to ${filteredTans.length} canonical pieces`);
20277
+ const mask = filteredTans.map((tan, tanIndex) => {
20278
+ const tanName = tan.name ?? tan.kind;
20279
+ const polygon = tan.vertices.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }));
20280
+ console.log(`[ConstructionApp] Polygon ${tanIndex} (${tanName}): ${tan.vertices.length} vertices -> ${polygon.length} points`);
20281
+ console.log(`[ConstructionApp] First vertex: [${tan.vertices[0]?.[0]}, ${tan.vertices[0]?.[1]}] -> {x: ${polygon[0]?.x}, y: ${polygon[0]?.y}}`);
20282
+ return polygon;
20283
+ });
20284
+ const sectorId = `sector${index}`;
20285
+ console.log(`[ConstructionApp] Assigned sector ID: ${sectorId}`);
20286
+ console.log(`[ConstructionApp] Final mask has ${mask.length} polygons`);
20287
+ const sector = {
20288
+ id: sectorId,
20289
+ tangramId: tangramSpec.tangramID,
20290
+ silhouette: {
20291
+ id: sectorId,
20292
+ mask
20293
+ }
20294
+ };
20295
+ console.log(`[ConstructionApp] Created sector:`, sector);
20296
+ return sector;
20297
+ });
20298
+ console.log("\n[ConstructionApp] Final sectors array:", sectors);
20299
+ console.log(`[ConstructionApp] Total sectors created: ${sectors.length}`);
20300
+ console.log("\n[ConstructionApp] Processing quickstash macros...");
20301
+ console.log("[ConstructionApp] quickstash_macros:", params.quickstash_macros);
20302
+ console.log("[ConstructionApp] quickstash_macros count:", params.quickstash_macros?.length ?? 0);
20265
20303
  let quickstash = [];
20266
20304
  if (params.quickstash_macros && params.quickstash_macros.length > 0) {
20267
20305
  const firstMacro = params.quickstash_macros[0];
20306
+ console.log("[ConstructionApp] First macro:", firstMacro);
20268
20307
  if (firstMacro && "parts" in firstMacro && firstMacro.parts && firstMacro.parts[0] && "anchorOffset" in firstMacro.parts[0]) {
20308
+ console.log("[ConstructionApp] Detected anchor-based composites, converting to pixels...");
20269
20309
  const primsByKind = /* @__PURE__ */ new Map();
20270
20310
  PRIMITIVE_BLUEPRINTS.forEach((p) => primsByKind.set(p.kind, p));
20271
20311
  quickstash = params.quickstash_macros.map(
20272
20312
  (anchorComposite) => convertAnchorCompositeToPixels(anchorComposite, primsByKind, CONFIG.layout.grid.stepPx)
20273
20313
  // Use current CONFIG grid step
20274
20314
  );
20315
+ console.log("[ConstructionApp] Converted to pixel-based blueprints:", quickstash);
20275
20316
  } else {
20317
+ console.log("[ConstructionApp] Already pixel-based blueprints");
20276
20318
  quickstash = params.quickstash_macros;
20277
20319
  }
20320
+ } else {
20321
+ console.log("[ConstructionApp] No quickstash macros provided");
20278
20322
  }
20323
+ const gameBoardProps = {
20324
+ sectors,
20325
+ quickstash,
20326
+ primitives: PRIMITIVE_BLUEPRINTS,
20327
+ layout: params.layout || "semicircle",
20328
+ target: params.target || "silhouette",
20329
+ input: params.input || "drag",
20330
+ timeLimitMs: params.time_limit_ms || 0,
20331
+ maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
20332
+ mode: "construction",
20333
+ // Explicit construction mode
20334
+ ...params.onInteraction && { onInteraction: params.onInteraction },
20335
+ ...params.onTrialEnd && { onTrialEnd: params.onTrialEnd }
20336
+ };
20337
+ console.log("\n[ConstructionApp] Final GameBoard props:");
20338
+ console.log("[ConstructionApp] sectors count:", gameBoardProps.sectors.length);
20339
+ console.log("[ConstructionApp] quickstash count:", gameBoardProps.quickstash.length);
20340
+ console.log("[ConstructionApp] primitives count:", gameBoardProps.primitives.length);
20341
+ console.log("[ConstructionApp] layout:", gameBoardProps.layout);
20342
+ console.log("[ConstructionApp] target:", gameBoardProps.target);
20343
+ console.log("[ConstructionApp] input:", gameBoardProps.input);
20344
+ console.log("[ConstructionApp] timeLimitMs:", gameBoardProps.timeLimitMs);
20345
+ console.log("[ConstructionApp] mode:", gameBoardProps.mode);
20346
+ console.log("[ConstructionApp] Full props:", gameBoardProps);
20279
20347
  const root = clientExports.createRoot(display_element);
20280
- root.render(
20281
- React.createElement(GameBoard, {
20282
- sectors,
20283
- quickstash,
20284
- primitives: PRIMITIVE_BLUEPRINTS,
20285
- layout: params.layout || "semicircle",
20286
- target: params.target || "silhouette",
20287
- input: params.input || "drag",
20288
- timeLimitMs: params.time_limit_ms || 0,
20289
- maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
20290
- mode: "construction",
20291
- // Explicit construction mode
20292
- ...params.onInteraction && { onInteraction: params.onInteraction },
20293
- ...params.onTrialEnd && { onTrialEnd: params.onTrialEnd }
20294
- })
20295
- );
20348
+ root.render(React.createElement(GameBoard, gameBoardProps));
20349
+ console.log("[ConstructionApp] GameBoard rendered successfully");
20296
20350
  return { root, display_element, jsPsych: _jsPsych };
20297
20351
  }
20298
20352