smiles-js 2.0.3 → 2.1.0

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.
@@ -2190,3 +2190,179 @@ export const v21 = v19.attach(2, v20);
2190
2190
  export const v22 = Ring({ atoms: 'C', size: 3, ringNumber: 3 });
2191
2191
  export const v23 = Molecule([v3, v18, v21, v22]);"
2192
2192
  `;
2193
+
2194
+ exports[`Cholesterol Integration Test parses cholesterol 1`] = `
2195
+ {
2196
+ "components": [
2197
+ {
2198
+ "atoms": [
2199
+ "C",
2200
+ "[C@H]",
2201
+ ],
2202
+ "attachments": {
2203
+ "2": [
2204
+ {
2205
+ "atoms": [
2206
+ "C",
2207
+ "C",
2208
+ "C",
2209
+ "C",
2210
+ "C",
2211
+ ],
2212
+ "attachments": {
2213
+ "4": [
2214
+ {
2215
+ "atoms": [
2216
+ "C",
2217
+ ],
2218
+ "attachments": {},
2219
+ "bonds": [
2220
+ null,
2221
+ ],
2222
+ "type": "linear",
2223
+ },
2224
+ ],
2225
+ },
2226
+ "bonds": [
2227
+ null,
2228
+ null,
2229
+ null,
2230
+ null,
2231
+ null,
2232
+ ],
2233
+ "type": "linear",
2234
+ },
2235
+ ],
2236
+ },
2237
+ "bonds": [
2238
+ null,
2239
+ ],
2240
+ "type": "linear",
2241
+ },
2242
+ {
2243
+ "rings": [
2244
+ {
2245
+ "atoms": "C",
2246
+ "attachments": {},
2247
+ "bonds": [
2248
+ null,
2249
+ null,
2250
+ null,
2251
+ null,
2252
+ null,
2253
+ ],
2254
+ "offset": 0,
2255
+ "ringNumber": 1,
2256
+ "size": 5,
2257
+ "substitutions": {
2258
+ "1": "[C@H]",
2259
+ "4": "[C@@H]",
2260
+ "5": "[C@@]",
2261
+ },
2262
+ "type": "ring",
2263
+ },
2264
+ {
2265
+ "atoms": "[C@H]",
2266
+ "attachments": {},
2267
+ "bonds": [
2268
+ null,
2269
+ null,
2270
+ null,
2271
+ null,
2272
+ null,
2273
+ null,
2274
+ ],
2275
+ "offset": 3,
2276
+ "ringNumber": 2,
2277
+ "size": 6,
2278
+ "substitutions": {
2279
+ "1": "[C@@H]",
2280
+ "2": "[C@@]",
2281
+ "3": "C",
2282
+ "4": "C",
2283
+ },
2284
+ "type": "ring",
2285
+ },
2286
+ {
2287
+ "atoms": "C",
2288
+ "attachments": {},
2289
+ "bonds": [
2290
+ null,
2291
+ null,
2292
+ null,
2293
+ "=",
2294
+ null,
2295
+ null,
2296
+ ],
2297
+ "offset": 0,
2298
+ "ringNumber": 3,
2299
+ "size": 6,
2300
+ "substitutions": {
2301
+ "1": "[C@H]",
2302
+ "2": "[C@H]",
2303
+ "6": "[C@@]",
2304
+ },
2305
+ "type": "ring",
2306
+ },
2307
+ {
2308
+ "atoms": "C",
2309
+ "attachments": {},
2310
+ "bonds": [
2311
+ null,
2312
+ null,
2313
+ null,
2314
+ null,
2315
+ null,
2316
+ null,
2317
+ ],
2318
+ "offset": 0,
2319
+ "ringNumber": 4,
2320
+ "size": 6,
2321
+ "substitutions": {
2322
+ "2": "[C@@]",
2323
+ "5": "[C@@H]",
2324
+ },
2325
+ "type": "ring",
2326
+ },
2327
+ ],
2328
+ "type": "fused_ring",
2329
+ },
2330
+ {
2331
+ "atoms": [
2332
+ "C",
2333
+ ],
2334
+ "attachments": {},
2335
+ "bonds": [],
2336
+ "type": "linear",
2337
+ },
2338
+ ],
2339
+ "type": "molecule",
2340
+ }
2341
+ `;
2342
+
2343
+ exports[`Cholesterol Integration Test generates valid code via toCode() 1`] = `
2344
+ "export const v1 = Linear(['C', '[C@H]']);
2345
+ export const v2 = Linear(['C', 'C', 'C', 'C', 'C']);
2346
+ export const v3 = Linear(['C']);
2347
+ export const v4 = v2.attach(4, v3);
2348
+ export const v5 = v1.attach(2, v4);
2349
+ export const v6 = Ring({ atoms: 'C', size: 5 });
2350
+ export const v7 = v6.substitute(1, '[C@H]');
2351
+ export const v8 = v7.substitute(4, '[C@@H]');
2352
+ export const v9 = v8.substitute(5, '[C@@]');
2353
+ export const v10 = Ring({ atoms: '[C@H]', size: 6, ringNumber: 2, offset: 3, branchDepths: [0, 0, 1, 1, 1, 1] });
2354
+ export const v11 = v10.substitute(1, '[C@@H]');
2355
+ export const v12 = v11.substitute(2, '[C@@]');
2356
+ export const v13 = v12.substitute(3, 'C');
2357
+ export const v14 = v13.substitute(4, 'C');
2358
+ export const v15 = Ring({ atoms: 'C', size: 6, ringNumber: 3, bonds: [null, null, null, '=', null, null] });
2359
+ export const v16 = v15.substitute(1, '[C@H]');
2360
+ export const v17 = v16.substitute(2, '[C@H]');
2361
+ export const v18 = v17.substitute(6, '[C@@]');
2362
+ export const v19 = Ring({ atoms: 'C', size: 6, ringNumber: 4, branchDepths: [1, 1, 2, 2, 2, 3], leadingBond: '=' });
2363
+ export const v20 = v19.substitute(2, '[C@@]');
2364
+ export const v21 = v20.substitute(5, '[C@@H]');
2365
+ export const v22 = FusedRing({ metadata: { rings: [{ ring: v9, start: 8, end: 12, atoms: [{ position: 8, depth: 0, value: '[C@H]', rings: [1, 1] }, { position: 9, depth: 0, value: 'C', rings: [1] }, { position: 10, depth: 0, value: 'C', rings: [1] }, { position: 11, depth: 0, value: '[C@@H]', rings: [2, 1, 2] }, { position: 12, depth: 0, value: '[C@@]', rings: [1, 2] }] }, { ring: v14, start: 11, end: 16, atoms: [{ position: 11, depth: 0, value: '[C@@H]', rings: [2, 1, 2] }, { position: 12, depth: 0, value: '[C@@]', rings: [1, 2] }, { position: 13, depth: 1, value: 'C', rings: [2], branchId: 20 }, { position: 14, depth: 1, value: 'C', rings: [2], branchId: 20 }, { position: 15, depth: 1, value: '[C@H]', rings: [3, 2, 3], branchId: 20 }, { position: 16, depth: 1, value: '[C@H]', rings: [2, 3], branchId: 20 }] }, { ring: v18, start: 15, end: 20, atoms: [{ position: 15, depth: 1, value: '[C@H]', rings: [3, 2, 3], branchId: 20 }, { position: 16, depth: 1, value: '[C@H]', rings: [2, 3], branchId: 20 }, { position: 17, depth: 1, value: 'C', rings: [3], branchId: 20 }, { position: 18, depth: 1, value: 'C', rings: [3], branchId: 20 }, { position: 19, depth: 1, value: 'C', bond: '=', rings: [4, 3, 4], branchId: 20 }, { position: 20, depth: 1, value: '[C@@]', rings: [3, 4], branchId: 20 }] }, { ring: v21, start: 19, end: 24, atoms: [{ position: 19, depth: 1, value: 'C', bond: '=', rings: [4, 3, 4], branchId: 20 }, { position: 20, depth: 1, value: '[C@@]', rings: [3, 4], branchId: 20 }, { position: 21, depth: 2, value: 'C', rings: [4], branchId: 34 }, { position: 22, depth: 2, value: 'C', rings: [4], branchId: 34 }, { position: 23, depth: 2, value: '[C@@H]', rings: [4], branchId: 34 }, { position: 24, depth: 3, value: 'C', rings: [4], branchId: 38 }] }], atoms: [{ position: 25, depth: 2, value: 'O', branchId: 34 }, { position: 26, depth: 1, value: 'C', branchId: 20 }] } });
2366
+ export const v23 = Linear(['C']);
2367
+ export const v24 = Molecule([v5, v22, v23]);"
2368
+ `;
@@ -308,7 +308,7 @@ export const v7 = v6.substitute(5, 'O');
308
308
  export const v8 = Linear(['C']);
309
309
  export const v9 = v7.attach(4, v8, { sibling: true });
310
310
  export const v10 = Ring({ atoms: 'C', size: 6, ringNumber: 3, offset: 4, bonds: [null, '=', null, null, null, null], branchDepths: [1, 1, 1, 2, 2, 2] });
311
- export const v11 = FusedRing({ metadata: { rings: [{ ring: v5, start: 5, end: 18, atoms: [{ position: 5, depth: 0, value: 'C', rings: [1, 1] }, { position: 6, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 7, depth: 0, value: 'C', rings: [1] }, { position: 8, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1] }, { position: 9, depth: 1, value: 'C', rings: [3, 3, 2, 1] }, { position: 10, depth: 1, value: 'C', rings: [3, 1] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [3, 1] }, { position: 12, depth: 2, value: 'C', rings: [3, 1] }, { position: 13, depth: 2, value: 'C', rings: [3, 1] }, { position: 14, depth: 2, value: 'C', rings: [3, 2, 1] }, { position: 15, depth: 2, value: 'C', rings: [2, 1] }, { position: 16, depth: 3, value: 'O', rings: [2, 1] }, { position: 17, depth: 3, value: 'C', rings: [2, 1] }, { position: 18, depth: 3, value: 'C', bond: '=', rings: [1] }] }, { ring: v9, start: 8, end: 17, atoms: [{ position: 8, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1] }, { position: 9, depth: 1, value: 'C', rings: [3, 3, 2, 1] }, { position: 14, depth: 2, value: 'C', rings: [3, 2, 1] }, { position: 15, depth: 2, value: 'C', rings: [2, 1] }, { position: 16, depth: 3, value: 'O', rings: [2, 1] }, { position: 17, depth: 3, value: 'C', rings: [2, 1] }] }, { ring: v10, start: 9, end: 14, atoms: [{ position: 9, depth: 1, value: 'C', rings: [3, 3, 2, 1] }, { position: 10, depth: 1, value: 'C', rings: [3, 1] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [3, 1] }, { position: 12, depth: 2, value: 'C', rings: [3, 1] }, { position: 13, depth: 2, value: 'C', rings: [3, 1] }, { position: 14, depth: 2, value: 'C', rings: [3, 2, 1] }] }], atoms: [{ position: 20, depth: 2, value: 'C' }, { position: 21, depth: 1, value: 'C' }] } });
311
+ export const v11 = FusedRing({ metadata: { rings: [{ ring: v5, start: 5, end: 18, atoms: [{ position: 5, depth: 0, value: 'C', rings: [1, 1] }, { position: 6, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 7, depth: 0, value: 'C', rings: [1] }, { position: 8, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1], branchId: 10 }, { position: 9, depth: 1, value: 'C', rings: [3, 3, 2, 1], branchId: 10 }, { position: 10, depth: 1, value: 'C', rings: [3, 1], branchId: 10 }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [3, 1], branchId: 10 }, { position: 12, depth: 2, value: 'C', rings: [3, 1], branchId: 19 }, { position: 13, depth: 2, value: 'C', rings: [3, 1], branchId: 19 }, { position: 14, depth: 2, value: 'C', rings: [3, 2, 1], branchId: 19 }, { position: 15, depth: 2, value: 'C', rings: [2, 1], branchId: 19 }, { position: 16, depth: 3, value: 'O', rings: [2, 1], branchId: 25 }, { position: 17, depth: 3, value: 'C', rings: [2, 1], branchId: 25 }, { position: 18, depth: 3, value: 'C', bond: '=', rings: [1], branchId: 25 }] }, { ring: v9, start: 8, end: 17, atoms: [{ position: 8, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1], branchId: 10 }, { position: 9, depth: 1, value: 'C', rings: [3, 3, 2, 1], branchId: 10 }, { position: 14, depth: 2, value: 'C', rings: [3, 2, 1], branchId: 19 }, { position: 15, depth: 2, value: 'C', rings: [2, 1], branchId: 19 }, { position: 16, depth: 3, value: 'O', rings: [2, 1], branchId: 25 }, { position: 17, depth: 3, value: 'C', rings: [2, 1], branchId: 25 }] }, { ring: v10, start: 9, end: 14, atoms: [{ position: 9, depth: 1, value: 'C', rings: [3, 3, 2, 1], branchId: 10 }, { position: 10, depth: 1, value: 'C', rings: [3, 1], branchId: 10 }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [3, 1], branchId: 10 }, { position: 12, depth: 2, value: 'C', rings: [3, 1], branchId: 19 }, { position: 13, depth: 2, value: 'C', rings: [3, 1], branchId: 19 }, { position: 14, depth: 2, value: 'C', rings: [3, 2, 1], branchId: 19 }] }], atoms: [{ position: 20, depth: 2, value: 'C', branchId: 19 }, { position: 21, depth: 1, value: 'C', branchId: 10 }] } });
312
312
  export const v12 = Linear(['O']);
313
313
  export const v13 = Molecule([v1, v11, v12]);"
314
314
  `;
@@ -651,7 +651,7 @@ export const v15 = v13.attach(4, v14, { sibling: true });
651
651
  export const v16 = Ring({ atoms: 'C', size: 6, ringNumber: 3, offset: 4 });
652
652
  export const v17 = Linear(['O'], ['=']);
653
653
  export const v18 = v16.attach(3, v17);
654
- export const v19 = FusedRing({ metadata: { rings: [{ ring: v11, start: 9, end: 23, atoms: [{ position: 9, depth: 0, value: 'C', rings: [1, 1] }, { position: 10, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 11, depth: 0, value: 'C', rings: [1] }, { position: 12, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1] }, { position: 13, depth: 1, value: 'C', rings: [3, 3, 2, 1] }, { position: 14, depth: 1, value: 'C', rings: [3, 1] }, { position: 15, depth: 1, value: 'C', rings: [3, 1] }, { position: 17, depth: 1, value: 'C', rings: [3, 1] }, { position: 18, depth: 1, value: 'C', rings: [3, 1] }, { position: 19, depth: 1, value: 'C', rings: [3, 2, 1] }, { position: 20, depth: 1, value: 'C', rings: [2, 1] }, { position: 21, depth: 2, value: 'O', rings: [2, 1] }, { position: 22, depth: 2, value: 'C', rings: [2, 1] }, { position: 23, depth: 2, value: 'C', bond: '=', rings: [1] }] }, { ring: v15, start: 12, end: 22, atoms: [{ position: 12, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1] }, { position: 13, depth: 1, value: 'C', rings: [3, 3, 2, 1] }, { position: 19, depth: 1, value: 'C', rings: [3, 2, 1] }, { position: 20, depth: 1, value: 'C', rings: [2, 1] }, { position: 21, depth: 2, value: 'O', rings: [2, 1] }, { position: 22, depth: 2, value: 'C', rings: [2, 1] }] }, { ring: v18, start: 13, end: 19, atoms: [{ position: 13, depth: 1, value: 'C', rings: [3, 3, 2, 1] }, { position: 14, depth: 1, value: 'C', rings: [3, 1] }, { position: 15, depth: 1, value: 'C', rings: [3, 1] }, { position: 17, depth: 1, value: 'C', rings: [3, 1] }, { position: 18, depth: 1, value: 'C', rings: [3, 1] }, { position: 19, depth: 1, value: 'C', rings: [3, 2, 1] }] }], atoms: [{ position: 25, depth: 1, value: 'C' }] } });
654
+ export const v19 = FusedRing({ metadata: { rings: [{ ring: v11, start: 9, end: 23, atoms: [{ position: 9, depth: 0, value: 'C', rings: [1, 1] }, { position: 10, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 11, depth: 0, value: 'C', rings: [1] }, { position: 12, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1], branchId: 18 }, { position: 13, depth: 1, value: 'C', rings: [3, 3, 2, 1], branchId: 18 }, { position: 14, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 15, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 17, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 18, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 19, depth: 1, value: 'C', rings: [3, 2, 1], branchId: 18 }, { position: 20, depth: 1, value: 'C', rings: [2, 1], branchId: 18 }, { position: 21, depth: 2, value: 'O', rings: [2, 1], branchId: 35 }, { position: 22, depth: 2, value: 'C', rings: [2, 1], branchId: 35 }, { position: 23, depth: 2, value: 'C', bond: '=', rings: [1], branchId: 35 }] }, { ring: v15, start: 12, end: 22, atoms: [{ position: 12, depth: 1, value: 'C', bond: '=', rings: [2, 2, 1], branchId: 18 }, { position: 13, depth: 1, value: 'C', rings: [3, 3, 2, 1], branchId: 18 }, { position: 19, depth: 1, value: 'C', rings: [3, 2, 1], branchId: 18 }, { position: 20, depth: 1, value: 'C', rings: [2, 1], branchId: 18 }, { position: 21, depth: 2, value: 'O', rings: [2, 1], branchId: 35 }, { position: 22, depth: 2, value: 'C', rings: [2, 1], branchId: 35 }] }, { ring: v18, start: 13, end: 19, atoms: [{ position: 13, depth: 1, value: 'C', rings: [3, 3, 2, 1], branchId: 18 }, { position: 14, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 15, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 17, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 18, depth: 1, value: 'C', rings: [3, 1], branchId: 18 }, { position: 19, depth: 1, value: 'C', rings: [3, 2, 1], branchId: 18 }] }], atoms: [{ position: 25, depth: 1, value: 'C', branchId: 18 }] } });
655
655
  export const v20 = Linear(['O']);
656
656
  export const v21 = Molecule([v5, v19, v20]);"
657
657
  `;
@@ -535,7 +535,7 @@ export const v4 = v3.substitute(5, 'N');
535
535
  export const v5 = Linear(['O'], ['=']);
536
536
  export const v6 = v4.attach(4, v5);
537
537
  export const v7 = Ring({ atoms: 'C', size: 5, ringNumber: 2, offset: 2, branchDepths: [0, 1, 1, 1, 1] });
538
- export const v8 = FusedRing({ metadata: { rings: [{ ring: v6, start: 4, end: 13, atoms: [{ position: 4, depth: 0, value: 'C', rings: [1, 1] }, { position: 5, depth: 0, value: 'N', bond: '=', rings: [1] }, { position: 6, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 11, depth: 0, value: 'C', rings: [1] }, { position: 13, depth: 0, value: 'N', rings: [1] }] }, { ring: v7, start: 6, end: 10, atoms: [{ position: 6, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 7, depth: 1, value: 'C', rings: [2] }, { position: 8, depth: 1, value: 'C', rings: [2] }, { position: 9, depth: 1, value: 'C', rings: [2] }, { position: 10, depth: 1, value: 'C', rings: [2] }] }] } });
538
+ export const v8 = FusedRing({ metadata: { rings: [{ ring: v6, start: 4, end: 13, atoms: [{ position: 4, depth: 0, value: 'C', rings: [1, 1] }, { position: 5, depth: 0, value: 'N', bond: '=', rings: [1] }, { position: 6, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 11, depth: 0, value: 'C', rings: [1] }, { position: 13, depth: 0, value: 'N', rings: [1] }] }, { ring: v7, start: 6, end: 10, atoms: [{ position: 6, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 7, depth: 1, value: 'C', rings: [2], branchId: 10 }, { position: 8, depth: 1, value: 'C', rings: [2], branchId: 10 }, { position: 9, depth: 1, value: 'C', rings: [2], branchId: 10 }, { position: 10, depth: 1, value: 'C', rings: [2], branchId: 10 }] }] } });
539
539
  export const v9 = Linear(['C']);
540
540
  export const v10 = Ring({ atoms: 'C', size: 6, ringNumber: 3, bonds: ['=', null, '=', null, '=', null], branchDepths: [0, 0, 0, 0, 1, 1] });
541
541
  export const v11 = Ring({ atoms: 'C', size: 6, ringNumber: 4, bonds: ['=', null, '=', null, '=', null] });
@@ -288,7 +288,7 @@ exports[`Naproxen Integration Test generates valid code via toCode() 1`] = `
288
288
  "export const v1 = Linear(['C', 'O']);
289
289
  export const v2 = Ring({ atoms: 'c', size: 6, branchDepths: [0, 0, 0, 0, 1, 1] });
290
290
  export const v3 = Ring({ atoms: 'c', size: 6, ringNumber: 2, offset: 3, branchDepths: [0, 0, 0, 1, 1, 1] });
291
- export const v4 = FusedRing({ metadata: { rings: [{ ring: v2, start: 2, end: 11, atoms: [{ position: 2, depth: 0, value: 'c', rings: [1, 1] }, { position: 3, depth: 0, value: 'c', rings: [1] }, { position: 4, depth: 0, value: 'c', rings: [1] }, { position: 5, depth: 0, value: 'c', rings: [2, 2, 1] }, { position: 10, depth: 1, value: 'c', rings: [2, 1] }, { position: 11, depth: 1, value: 'c', rings: [1] }] }, { ring: v3, start: 5, end: 10, atoms: [{ position: 5, depth: 0, value: 'c', rings: [2, 2, 1] }, { position: 6, depth: 0, value: 'c', rings: [2] }, { position: 7, depth: 0, value: 'c', rings: [2] }, { position: 8, depth: 1, value: 'c', rings: [2] }, { position: 9, depth: 1, value: 'c', rings: [2] }, { position: 10, depth: 1, value: 'c', rings: [2, 1] }] }] } });
291
+ export const v4 = FusedRing({ metadata: { rings: [{ ring: v2, start: 2, end: 11, atoms: [{ position: 2, depth: 0, value: 'c', rings: [1, 1] }, { position: 3, depth: 0, value: 'c', rings: [1] }, { position: 4, depth: 0, value: 'c', rings: [1] }, { position: 5, depth: 0, value: 'c', rings: [2, 2, 1] }, { position: 10, depth: 1, value: 'c', rings: [2, 1], branchId: 10 }, { position: 11, depth: 1, value: 'c', rings: [1], branchId: 10 }] }, { ring: v3, start: 5, end: 10, atoms: [{ position: 5, depth: 0, value: 'c', rings: [2, 2, 1] }, { position: 6, depth: 0, value: 'c', rings: [2] }, { position: 7, depth: 0, value: 'c', rings: [2] }, { position: 8, depth: 1, value: 'c', rings: [2], branchId: 10 }, { position: 9, depth: 1, value: 'c', rings: [2], branchId: 10 }, { position: 10, depth: 1, value: 'c', rings: [2, 1], branchId: 10 }] }] } });
292
292
  export const v5 = Linear(['C', 'C', 'O']);
293
293
  export const v6 = Linear(['C']);
294
294
  export const v7 = v5.attach(1, v6);
@@ -365,7 +365,7 @@ export const v6 = v5.substitute(5, 'O');
365
365
  export const v7 = Linear(['C', 'C']);
366
366
  export const v8 = v6.attach(6, v7);
367
367
  export const v9 = Linear(['O'], ['=']);
368
- export const v10 = FusedRing({ metadata: { rings: [{ ring: v2, start: 2, end: 7, atoms: [{ position: 2, depth: 0, value: 'C', rings: [1, 1] }, { position: 3, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 1, 2] }, { position: 5, depth: 0, value: 'C', bond: '=', rings: [1, 2] }, { position: 6, depth: 1, value: 'C', rings: [1] }, { position: 7, depth: 1, value: 'C', bond: '=', rings: [1] }] }, { ring: v4, start: 4, end: 14, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 1, 2] }, { position: 5, depth: 0, value: 'C', bond: '=', rings: [1, 2] }, { position: 12, depth: 0, value: 'N', rings: [2] }, { position: 13, depth: 0, value: 'C', rings: [3, 2, 3] }, { position: 14, depth: 0, value: 'C', bond: '=', rings: [2, 3] }] }, { ring: v8, start: 13, end: 18, atoms: [{ position: 13, depth: 0, value: 'C', rings: [3, 2, 3] }, { position: 14, depth: 0, value: 'C', bond: '=', rings: [2, 3] }, { position: 15, depth: 0, value: 'C', rings: [3] }, { position: 16, depth: 0, value: 'C', rings: [3] }, { position: 17, depth: 0, value: 'O', rings: [3] }, { position: 18, depth: 0, value: 'C', rings: [3] }] }], atoms: [{ position: 8, depth: 1, value: 'C' }, { position: 9, depth: 1, value: 'C', attachments: [v9] }, { position: 11, depth: 1, value: 'O' }] } });
368
+ export const v10 = FusedRing({ metadata: { rings: [{ ring: v2, start: 2, end: 7, atoms: [{ position: 2, depth: 0, value: 'C', rings: [1, 1] }, { position: 3, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 1, 2] }, { position: 5, depth: 0, value: 'C', bond: '=', rings: [1, 2] }, { position: 6, depth: 1, value: 'C', rings: [1], branchId: 10 }, { position: 7, depth: 1, value: 'C', bond: '=', rings: [1], branchId: 10 }] }, { ring: v4, start: 4, end: 14, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 1, 2] }, { position: 5, depth: 0, value: 'C', bond: '=', rings: [1, 2] }, { position: 12, depth: 0, value: 'N', rings: [2] }, { position: 13, depth: 0, value: 'C', rings: [3, 2, 3] }, { position: 14, depth: 0, value: 'C', bond: '=', rings: [2, 3] }] }, { ring: v8, start: 13, end: 18, atoms: [{ position: 13, depth: 0, value: 'C', rings: [3, 2, 3] }, { position: 14, depth: 0, value: 'C', bond: '=', rings: [2, 3] }, { position: 15, depth: 0, value: 'C', rings: [3] }, { position: 16, depth: 0, value: 'C', rings: [3] }, { position: 17, depth: 0, value: 'O', rings: [3] }, { position: 18, depth: 0, value: 'C', rings: [3] }] }], atoms: [{ position: 8, depth: 1, value: 'C', branchId: 10 }, { position: 9, depth: 1, value: 'C', branchId: 10, attachments: [v9] }, { position: 11, depth: 1, value: 'O', branchId: 10 }] } });
369
369
  export const v11 = Linear(['C', 'C']);
370
370
  export const v12 = Molecule([v1, v10, v11]);"
371
371
  `;
@@ -822,7 +822,7 @@ exports[`Nabumetone Integration Test generates valid code via toCode() 1`] = `
822
822
  "export const v1 = Linear(['C', 'O']);
823
823
  export const v2 = Ring({ atoms: 'C', size: 6, bonds: ['=', null, '=', null, '=', null], branchDepths: [0, 0, 0, 1, 1, 1] });
824
824
  export const v3 = Ring({ atoms: 'C', size: 6, ringNumber: 2, offset: 2, bonds: ['=', null, null, null, '=', null], branchDepths: [0, 0, 0, 1, 1, 1] });
825
- export const v4 = FusedRing({ metadata: { rings: [{ ring: v2, start: 2, end: 11, atoms: [{ position: 2, depth: 0, value: 'C', rings: [1, 1] }, { position: 3, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 9, depth: 1, value: 'C', bond: '=', rings: [2, 1] }, { position: 10, depth: 1, value: 'C', rings: [1] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [1] }] }, { ring: v3, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 5, depth: 0, value: 'C', bond: '=', rings: [2] }, { position: 6, depth: 0, value: 'C', rings: [2] }, { position: 7, depth: 1, value: 'C', rings: [2] }, { position: 8, depth: 1, value: 'C', rings: [2] }, { position: 9, depth: 1, value: 'C', bond: '=', rings: [2, 1] }] }] } });
825
+ export const v4 = FusedRing({ metadata: { rings: [{ ring: v2, start: 2, end: 11, atoms: [{ position: 2, depth: 0, value: 'C', rings: [1, 1] }, { position: 3, depth: 0, value: 'C', bond: '=', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 9, depth: 1, value: 'C', bond: '=', rings: [2, 1], branchId: 11 }, { position: 10, depth: 1, value: 'C', rings: [1], branchId: 11 }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [1], branchId: 11 }] }, { ring: v3, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 5, depth: 0, value: 'C', bond: '=', rings: [2] }, { position: 6, depth: 0, value: 'C', rings: [2] }, { position: 7, depth: 1, value: 'C', rings: [2], branchId: 11 }, { position: 8, depth: 1, value: 'C', rings: [2], branchId: 11 }, { position: 9, depth: 1, value: 'C', bond: '=', rings: [2, 1], branchId: 11 }] }] } });
826
826
  export const v5 = Linear(['C', 'C', 'C', 'C']);
827
827
  export const v6 = Linear(['O'], ['=']);
828
828
  export const v7 = v5.attach(3, v6);
@@ -134,7 +134,7 @@ export const v6 = v5.substitute(6, 'O');
134
134
  export const v7 = Ring({ atoms: 'C', size: 9, ringNumber: 4, offset: 4, bonds: [null, null, null, null, null, null, null, '=', null], branchDepths: [0, 0, 0, 0, 0, 0, 0, 1, 1] });
135
135
  export const v8 = v7.substitute(5, 'O');
136
136
  export const v9 = Ring({ atoms: 'C', size: 6, ringNumber: 5, bonds: ['=', null, '=', null, '=', null], branchDepths: [0, 0, 0, 1, 2, 2] });
137
- export const v10 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 6, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }] }, { ring: v4, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }] }, { ring: v6, start: 4, end: 16, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 15, depth: 0, value: 'O', rings: [3, 4] }, { position: 16, depth: 0, value: 'C', rings: [3, 4] }] }, { ring: v8, start: 5, end: 19, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 15, depth: 0, value: 'O', rings: [3, 4] }, { position: 16, depth: 0, value: 'C', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [4] }, { position: 18, depth: 1, value: 'C', rings: [4] }, { position: 19, depth: 1, value: 'C', bond: '=', rings: [4] }] }, { ring: v9, start: 8, end: 13, atoms: [{ position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }, { position: 10, depth: 0, value: 'C', rings: [5] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [5] }, { position: 12, depth: 2, value: 'C', rings: [5] }, { position: 13, depth: 2, value: 'C', bond: '=', rings: [5] }] }], atoms: [{ position: 14, depth: 1, value: 'O' }] } });
137
+ export const v10 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 6, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }] }, { ring: v4, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }] }, { ring: v6, start: 4, end: 16, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 15, depth: 0, value: 'O', rings: [3, 4] }, { position: 16, depth: 0, value: 'C', rings: [3, 4] }] }, { ring: v8, start: 5, end: 19, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 15, depth: 0, value: 'O', rings: [3, 4] }, { position: 16, depth: 0, value: 'C', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [4] }, { position: 18, depth: 1, value: 'C', rings: [4], branchId: 34 }, { position: 19, depth: 1, value: 'C', bond: '=', rings: [4], branchId: 34 }] }, { ring: v9, start: 8, end: 13, atoms: [{ position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }, { position: 10, depth: 0, value: 'C', rings: [5] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [5], branchId: 19 }, { position: 12, depth: 2, value: 'C', rings: [5], branchId: 22 }, { position: 13, depth: 2, value: 'C', bond: '=', rings: [5], branchId: 22 }] }], atoms: [{ position: 14, depth: 1, value: 'O', branchId: 19 }] } });
138
138
  export const v11 = Linear(['O']);
139
139
  export const v12 = Molecule([v1, v10, v11]);"
140
140
  `;
@@ -273,7 +273,7 @@ export const v6 = v5.substitute(6, 'O');
273
273
  export const v7 = Ring({ atoms: 'C', size: 9, ringNumber: 4, offset: 4, bonds: [null, null, null, null, null, null, null, '=', null], branchDepths: [0, 0, 0, 0, 0, 0, 0, 1, 1] });
274
274
  export const v8 = v7.substitute(5, 'O');
275
275
  export const v9 = Ring({ atoms: 'C', size: 6, ringNumber: 5, bonds: ['=', null, '=', null, '=', null], branchDepths: [0, 0, 0, 1, 2, 2] });
276
- export const v10 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 6, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }] }, { ring: v4, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }] }, { ring: v6, start: 4, end: 17, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }] }, { ring: v8, start: 5, end: 20, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }, { position: 18, depth: 0, value: 'C', rings: [4] }, { position: 19, depth: 1, value: 'C', rings: [4] }, { position: 20, depth: 1, value: 'C', bond: '=', rings: [4] }] }, { ring: v9, start: 8, end: 13, atoms: [{ position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }, { position: 10, depth: 0, value: 'C', rings: [5] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [5] }, { position: 12, depth: 2, value: 'C', rings: [5] }, { position: 13, depth: 2, value: 'C', bond: '=', rings: [5] }] }], atoms: [{ position: 14, depth: 1, value: 'O' }, { position: 15, depth: 1, value: 'C' }] } });
276
+ export const v10 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 6, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }] }, { ring: v4, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }] }, { ring: v6, start: 4, end: 17, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }] }, { ring: v8, start: 5, end: 20, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }, { position: 18, depth: 0, value: 'C', rings: [4] }, { position: 19, depth: 1, value: 'C', rings: [4], branchId: 35 }, { position: 20, depth: 1, value: 'C', bond: '=', rings: [4], branchId: 35 }] }, { ring: v9, start: 8, end: 13, atoms: [{ position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }, { position: 10, depth: 0, value: 'C', rings: [5] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [5], branchId: 19 }, { position: 12, depth: 2, value: 'C', rings: [5], branchId: 22 }, { position: 13, depth: 2, value: 'C', bond: '=', rings: [5], branchId: 22 }] }], atoms: [{ position: 14, depth: 1, value: 'O', branchId: 19 }, { position: 15, depth: 1, value: 'C', branchId: 19 }] } });
277
277
  export const v11 = Linear(['O']);
278
278
  export const v12 = Molecule([v1, v10, v11]);"
279
279
  `;
@@ -459,7 +459,7 @@ export const v11 = v10.substitute(11, 'O');
459
459
  export const v12 = Linear(['O'], ['=']);
460
460
  export const v13 = v11.attach(2, v12, { sibling: true });
461
461
  export const v14 = Ring({ atoms: 'C', size: 6, ringNumber: 5, bonds: ['=', null, '=', null, '=', null], branchDepths: [1, 1, 1, 2, 3, 3] });
462
- export const v15 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 11, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 2, 1, 3] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }, { position: 11, depth: 1, value: 'C', rings: [1, 3, 4] }] }, { ring: v6, start: 4, end: 10, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 2, 1, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 9, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }] }, { ring: v9, start: 4, end: 14, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 2, 1, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 9, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }, { position: 11, depth: 1, value: 'C', rings: [1, 3, 4] }, { position: 12, depth: 1, value: 'C', rings: [3, 4] }, { position: 13, depth: 1, value: 'C', rings: [5, 3, 5, 4] }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 5, 4] }] }, { ring: v13, start: 5, end: 21, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 9, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }, { position: 11, depth: 1, value: 'C', rings: [1, 3, 4] }, { position: 12, depth: 1, value: 'C', rings: [3, 4] }, { position: 13, depth: 1, value: 'C', rings: [5, 3, 5, 4] }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 5, 4] }, { position: 15, depth: 1, value: 'C', rings: [5, 4] }, { position: 21, depth: 1, value: 'O', rings: [4] }] }, { ring: v14, start: 13, end: 18, atoms: [{ position: 13, depth: 1, value: 'C', rings: [5, 3, 5, 4] }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 5, 4] }, { position: 15, depth: 1, value: 'C', rings: [5, 4] }, { position: 16, depth: 2, value: 'C', bond: '=', rings: [5] }, { position: 17, depth: 3, value: 'C', rings: [5] }, { position: 18, depth: 3, value: 'C', bond: '=', rings: [5] }] }], atoms: [{ position: 19, depth: 2, value: 'O' }, { position: 20, depth: 2, value: 'C' }] } });
462
+ export const v15 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 11, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 2, 1, 3] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }, { position: 11, depth: 1, value: 'C', rings: [1, 3, 4], branchId: 19 }] }, { ring: v6, start: 4, end: 10, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 2, 1, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 9, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }] }, { ring: v9, start: 4, end: 14, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 2, 1, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 9, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }, { position: 11, depth: 1, value: 'C', rings: [1, 3, 4], branchId: 19 }, { position: 12, depth: 1, value: 'C', rings: [3, 4], branchId: 19 }, { position: 13, depth: 1, value: 'C', rings: [5, 3, 5, 4], branchId: 19 }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 5, 4], branchId: 19 }] }, { ring: v13, start: 5, end: 21, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 9, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 10, depth: 0, value: 'C', rings: [2, 1, 3, 4] }, { position: 11, depth: 1, value: 'C', rings: [1, 3, 4], branchId: 19 }, { position: 12, depth: 1, value: 'C', rings: [3, 4], branchId: 19 }, { position: 13, depth: 1, value: 'C', rings: [5, 3, 5, 4], branchId: 19 }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 5, 4], branchId: 19 }, { position: 15, depth: 1, value: 'C', rings: [5, 4], branchId: 19 }, { position: 21, depth: 1, value: 'O', rings: [4], branchId: 19 }] }, { ring: v14, start: 13, end: 18, atoms: [{ position: 13, depth: 1, value: 'C', rings: [5, 3, 5, 4], branchId: 19 }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 5, 4], branchId: 19 }, { position: 15, depth: 1, value: 'C', rings: [5, 4], branchId: 19 }, { position: 16, depth: 2, value: 'C', bond: '=', rings: [5], branchId: 29 }, { position: 17, depth: 3, value: 'C', rings: [5], branchId: 32 }, { position: 18, depth: 3, value: 'C', bond: '=', rings: [5], branchId: 32 }] }], atoms: [{ position: 19, depth: 2, value: 'O', branchId: 29 }, { position: 20, depth: 2, value: 'C', branchId: 29 }] } });
463
463
  export const v16 = Linear(['O']);
464
464
  export const v17 = Molecule([v1, v15, v16]);"
465
465
  `;
@@ -605,7 +605,7 @@ export const v8 = v7.substitute(5, 'O');
605
605
  export const v9 = Linear(['O'], ['=']);
606
606
  export const v10 = v8.attach(7, v9);
607
607
  export const v11 = Ring({ atoms: 'C', size: 6, ringNumber: 5, bonds: ['=', null, '=', null, '=', null], branchDepths: [0, 0, 0, 1, 2, 2] });
608
- export const v12 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 6, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }] }, { ring: v4, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }] }, { ring: v6, start: 4, end: 17, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }] }, { ring: v10, start: 5, end: 21, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }, { position: 18, depth: 0, value: 'C', rings: [4] }, { position: 20, depth: 0, value: 'C', rings: [4] }, { position: 21, depth: 0, value: 'C', rings: [4] }] }, { ring: v11, start: 8, end: 13, atoms: [{ position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }, { position: 10, depth: 0, value: 'C', rings: [5] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [5] }, { position: 12, depth: 2, value: 'C', rings: [5] }, { position: 13, depth: 2, value: 'C', bond: '=', rings: [5] }] }], atoms: [{ position: 14, depth: 1, value: 'O' }, { position: 15, depth: 1, value: 'C' }] } });
608
+ export const v12 = FusedRing({ metadata: { rings: [{ ring: v3, start: 1, end: 6, atoms: [{ position: 1, depth: 0, value: 'N', rings: [1, 1] }, { position: 2, depth: 0, value: 'C', rings: [1] }, { position: 3, depth: 0, value: 'C', rings: [1] }, { position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }] }, { ring: v4, start: 4, end: 9, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }] }, { ring: v6, start: 4, end: 17, atoms: [{ position: 4, depth: 0, value: 'C', rings: [2, 3, 1, 2, 3] }, { position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }] }, { ring: v10, start: 5, end: 21, atoms: [{ position: 5, depth: 0, value: 'C', rings: [4, 1, 2, 3, 4] }, { position: 6, depth: 0, value: 'C', rings: [1, 2, 3, 4] }, { position: 7, depth: 0, value: 'C', rings: [2, 3, 4] }, { position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 16, depth: 0, value: 'O', rings: [3, 4] }, { position: 17, depth: 0, value: 'C', rings: [3, 4] }, { position: 18, depth: 0, value: 'C', rings: [4] }, { position: 20, depth: 0, value: 'C', rings: [4] }, { position: 21, depth: 0, value: 'C', rings: [4] }] }, { ring: v11, start: 8, end: 13, atoms: [{ position: 8, depth: 0, value: 'C', rings: [5, 2, 5, 3, 4] }, { position: 9, depth: 0, value: 'C', bond: '=', rings: [2, 5] }, { position: 10, depth: 0, value: 'C', rings: [5] }, { position: 11, depth: 1, value: 'C', bond: '=', rings: [5], branchId: 19 }, { position: 12, depth: 2, value: 'C', rings: [5], branchId: 22 }, { position: 13, depth: 2, value: 'C', bond: '=', rings: [5], branchId: 22 }] }], atoms: [{ position: 14, depth: 1, value: 'O', branchId: 19 }, { position: 15, depth: 1, value: 'C', branchId: 19 }] } });
609
609
  export const v13 = Molecule([v1, v12]);"
610
610
  `;
611
611
 
@@ -1757,7 +1757,7 @@ export const v18 = v16.attach(7, v17, { sibling: true });
1757
1757
  export const v19 = Ring({ atoms: 'C', size: 6, ringNumber: 4, bonds: ['=', null, null, '=', null, null] });
1758
1758
  export const v20 = Linear(['O'], ['=']);
1759
1759
  export const v21 = v19.attach(3, v20);
1760
- export const v22 = FusedRing({ metadata: { rings: [{ ring: v6, start: 1, end: 17, atoms: [{ position: 1, depth: 0, value: 'C', rings: [1, 2, 1, 2] }, { position: 2, depth: 0, value: 'C', rings: [1, 2] }, { position: 3, depth: 0, value: 'C', rings: [1, 2] }, { position: 5, depth: 0, value: 'C', rings: [3, 3, 1, 2] }, { position: 17, depth: 0, value: 'C', rings: [1, 2] }] }, { ring: v15, start: 1, end: 22, atoms: [{ position: 1, depth: 0, value: 'C', rings: [1, 2, 1, 2] }, { position: 2, depth: 0, value: 'C', rings: [1, 2] }, { position: 3, depth: 0, value: 'C', rings: [1, 2] }, { position: 5, depth: 0, value: 'C', rings: [3, 3, 1, 2] }, { position: 17, depth: 0, value: 'C', rings: [1, 2] }, { position: 19, depth: 0, value: 'C', rings: [2] }, { position: 21, depth: 0, value: 'C', rings: [2] }, { position: 22, depth: 0, value: 'C', rings: [2] }] }, { ring: v18, start: 5, end: 15, atoms: [{ position: 5, depth: 0, value: 'C', rings: [3, 3, 1, 2] }, { position: 6, depth: 0, value: 'C', rings: [3] }, { position: 7, depth: 1, value: 'C', rings: [3] }, { position: 8, depth: 1, value: 'C', rings: [3] }, { position: 9, depth: 1, value: 'C', rings: [4, 3, 4] }, { position: 10, depth: 1, value: 'C', bond: '=', rings: [3, 4] }, { position: 11, depth: 1, value: 'C', rings: [3, 4] }, { position: 13, depth: 1, value: 'C', rings: [3, 4] }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 4] }, { position: 15, depth: 1, value: 'C', rings: [3, 4] }] }, { ring: v21, start: 9, end: 15, atoms: [{ position: 9, depth: 1, value: 'C', rings: [4, 3, 4] }, { position: 10, depth: 1, value: 'C', bond: '=', rings: [3, 4] }, { position: 11, depth: 1, value: 'C', rings: [3, 4] }, { position: 13, depth: 1, value: 'C', rings: [3, 4] }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 4] }, { position: 15, depth: 1, value: 'C', rings: [3, 4] }] }], atoms: [{ position: 16, depth: 1, value: 'C' }] } });
1760
+ export const v22 = FusedRing({ metadata: { rings: [{ ring: v6, start: 1, end: 17, atoms: [{ position: 1, depth: 0, value: 'C', rings: [1, 2, 1, 2] }, { position: 2, depth: 0, value: 'C', rings: [1, 2] }, { position: 3, depth: 0, value: 'C', rings: [1, 2] }, { position: 5, depth: 0, value: 'C', rings: [3, 3, 1, 2] }, { position: 17, depth: 0, value: 'C', rings: [1, 2] }] }, { ring: v15, start: 1, end: 22, atoms: [{ position: 1, depth: 0, value: 'C', rings: [1, 2, 1, 2] }, { position: 2, depth: 0, value: 'C', rings: [1, 2] }, { position: 3, depth: 0, value: 'C', rings: [1, 2] }, { position: 5, depth: 0, value: 'C', rings: [3, 3, 1, 2] }, { position: 17, depth: 0, value: 'C', rings: [1, 2] }, { position: 19, depth: 0, value: 'C', rings: [2] }, { position: 21, depth: 0, value: 'C', rings: [2] }, { position: 22, depth: 0, value: 'C', rings: [2] }] }, { ring: v18, start: 5, end: 15, atoms: [{ position: 5, depth: 0, value: 'C', rings: [3, 3, 1, 2] }, { position: 6, depth: 0, value: 'C', rings: [3] }, { position: 7, depth: 1, value: 'C', rings: [3], branchId: 12 }, { position: 8, depth: 1, value: 'C', rings: [3], branchId: 12 }, { position: 9, depth: 1, value: 'C', rings: [4, 3, 4], branchId: 12 }, { position: 10, depth: 1, value: 'C', bond: '=', rings: [3, 4], branchId: 12 }, { position: 11, depth: 1, value: 'C', rings: [3, 4], branchId: 12 }, { position: 13, depth: 1, value: 'C', rings: [3, 4], branchId: 12 }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 4], branchId: 12 }, { position: 15, depth: 1, value: 'C', rings: [3, 4], branchId: 12 }] }, { ring: v21, start: 9, end: 15, atoms: [{ position: 9, depth: 1, value: 'C', rings: [4, 3, 4], branchId: 12 }, { position: 10, depth: 1, value: 'C', bond: '=', rings: [3, 4], branchId: 12 }, { position: 11, depth: 1, value: 'C', rings: [3, 4], branchId: 12 }, { position: 13, depth: 1, value: 'C', rings: [3, 4], branchId: 12 }, { position: 14, depth: 1, value: 'C', bond: '=', rings: [3, 4], branchId: 12 }, { position: 15, depth: 1, value: 'C', rings: [3, 4], branchId: 12 }] }], atoms: [{ position: 16, depth: 1, value: 'C', branchId: 12 }] } });
1761
1761
  export const v23 = Linear(['C', 'C', 'O']);
1762
1762
  export const v24 = Linear(['O'], ['=']);
1763
1763
  export const v25 = v23.attach(1, v24);
@@ -2027,7 +2027,7 @@ export const v21 = Linear(['O'], ['=']);
2027
2027
  export const v22 = v20.attach(3, v21);
2028
2028
  export const v23 = Linear(['C']);
2029
2029
  export const v24 = v22.attach(6, v23);
2030
- export const v25 = FusedRing({ metadata: { rings: [{ ring: v4, start: 3, end: 27, atoms: [{ position: 3, depth: 0, value: 'C', rings: [1, 1] }, { position: 4, depth: 0, value: 'O', rings: [1] }, { position: 5, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 26, depth: 0, value: 'C', rings: [2, 1] }, { position: 27, depth: 1, value: 'O', rings: [1] }] }, { ring: v7, start: 5, end: 26, atoms: [{ position: 5, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 6, depth: 0, value: 'C', rings: [2] }, { position: 7, depth: 0, value: 'C', rings: [3, 3, 2] }, { position: 24, depth: 0, value: 'C', rings: [3, 2] }, { position: 26, depth: 0, value: 'C', rings: [2, 1] }] }, { ring: v14, start: 7, end: 24, atoms: [{ position: 7, depth: 0, value: 'C', rings: [3, 3, 2] }, { position: 8, depth: 0, value: 'C', rings: [4, 4, 3] }, { position: 19, depth: 0, value: 'C', rings: [4, 3] }, { position: 21, depth: 0, value: 'C', rings: [3] }, { position: 23, depth: 0, value: 'C', rings: [3] }, { position: 24, depth: 0, value: 'C', rings: [3, 2] }] }, { ring: v19, start: 8, end: 19, atoms: [{ position: 8, depth: 0, value: 'C', rings: [4, 4, 3] }, { position: 9, depth: 0, value: 'C', rings: [4] }, { position: 10, depth: 0, value: 'C', rings: [4] }, { position: 11, depth: 0, value: 'C', rings: [5, 5, 4] }, { position: 17, depth: 0, value: 'C', rings: [5, 4] }, { position: 19, depth: 0, value: 'C', rings: [4, 3] }] }, { ring: v24, start: 11, end: 17, atoms: [{ position: 11, depth: 0, value: 'C', rings: [5, 5, 4] }, { position: 12, depth: 0, value: 'C', bond: '=', rings: [5] }, { position: 13, depth: 0, value: 'C', rings: [5] }, { position: 15, depth: 0, value: 'C', rings: [5] }, { position: 16, depth: 0, value: 'C', bond: '=', rings: [5] }, { position: 17, depth: 0, value: 'C', rings: [5, 4] }] }] } });
2030
+ export const v25 = FusedRing({ metadata: { rings: [{ ring: v4, start: 3, end: 27, atoms: [{ position: 3, depth: 0, value: 'C', rings: [1, 1] }, { position: 4, depth: 0, value: 'O', rings: [1] }, { position: 5, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 26, depth: 0, value: 'C', rings: [2, 1] }, { position: 27, depth: 1, value: 'O', rings: [1], branchId: 49 }] }, { ring: v7, start: 5, end: 26, atoms: [{ position: 5, depth: 0, value: 'C', rings: [2, 2, 1] }, { position: 6, depth: 0, value: 'C', rings: [2] }, { position: 7, depth: 0, value: 'C', rings: [3, 3, 2] }, { position: 24, depth: 0, value: 'C', rings: [3, 2] }, { position: 26, depth: 0, value: 'C', rings: [2, 1] }] }, { ring: v14, start: 7, end: 24, atoms: [{ position: 7, depth: 0, value: 'C', rings: [3, 3, 2] }, { position: 8, depth: 0, value: 'C', rings: [4, 4, 3] }, { position: 19, depth: 0, value: 'C', rings: [4, 3] }, { position: 21, depth: 0, value: 'C', rings: [3] }, { position: 23, depth: 0, value: 'C', rings: [3] }, { position: 24, depth: 0, value: 'C', rings: [3, 2] }] }, { ring: v19, start: 8, end: 19, atoms: [{ position: 8, depth: 0, value: 'C', rings: [4, 4, 3] }, { position: 9, depth: 0, value: 'C', rings: [4] }, { position: 10, depth: 0, value: 'C', rings: [4] }, { position: 11, depth: 0, value: 'C', rings: [5, 5, 4] }, { position: 17, depth: 0, value: 'C', rings: [5, 4] }, { position: 19, depth: 0, value: 'C', rings: [4, 3] }] }, { ring: v24, start: 11, end: 17, atoms: [{ position: 11, depth: 0, value: 'C', rings: [5, 5, 4] }, { position: 12, depth: 0, value: 'C', bond: '=', rings: [5] }, { position: 13, depth: 0, value: 'C', rings: [5] }, { position: 15, depth: 0, value: 'C', rings: [5] }, { position: 16, depth: 0, value: 'C', bond: '=', rings: [5] }, { position: 17, depth: 0, value: 'C', rings: [5, 4] }] }] } });
2031
2031
  export const v26 = Linear(['C', 'C', 'O']);
2032
2032
  export const v27 = Linear(['O'], ['=']);
2033
2033
  export const v28 = v26.attach(1, v27);
@@ -12,6 +12,7 @@ const EZETIMIBE_SMILES = 'C[C@H]1[C@@H](O)[C@H](O[C@H]1c2ccc(F)cc2)c3ccc(O)cc3C(
12
12
  const FENOFIBRATE_SMILES = 'CC(C)OC(=O)C(C)(C)Oc1ccc(cc1)C(=O)c2ccc(Cl)cc2';
13
13
  const GEMFIBROZIL_SMILES = 'CC1=CC(C)=CC=C1CCCC(C)(C)C(=O)O';
14
14
  const PITAVASTATIN_SMILES = 'CC(C)c1nc(nc(c1/C=C/[C@@H](O)C[C@@H](O)CC(=O)O)c2ccc(F)cc2)NC(=O)C3CC3';
15
+ const CHOLESTEROL_SMILES = 'C[C@H](CCCC(C)C)[C@H]1CC[C@@H]2[C@@]1(CC[C@H]3[C@H]2CC=C4[C@@]3(CC[C@@H](C4)O)C)C';
15
16
 
16
17
  describe('Atorvastatin Integration Test', () => {
17
18
  test('parses atorvastatin', () => {
@@ -412,3 +413,43 @@ describe('Pitavastatin Integration Test', () => {
412
413
  expect(reconstructed.smiles).toBe(PITAVASTATIN_SMILES);
413
414
  });
414
415
  });
416
+
417
+ describe('Cholesterol Integration Test', () => {
418
+ test('parses cholesterol', () => {
419
+ const ast = parse(CHOLESTEROL_SMILES);
420
+ const obj = ast.toObject();
421
+ expect(obj).toMatchSnapshot();
422
+ expect(ast.smiles).toBe(CHOLESTEROL_SMILES);
423
+ });
424
+
425
+ test('generates valid code via toCode()', () => {
426
+ const ast = parse(CHOLESTEROL_SMILES);
427
+ const code = ast.toCode('v');
428
+ expect(code).toMatchSnapshot();
429
+ });
430
+
431
+ test('generated code is valid JavaScript', () => {
432
+ const ast = parse(CHOLESTEROL_SMILES);
433
+ const code = ast.toCode('v');
434
+ const executableCode = stripExports(code);
435
+
436
+ let factory;
437
+ expect(() => {
438
+ factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
439
+ }).not.toThrow();
440
+ expect(typeof factory).toBe('function');
441
+ });
442
+
443
+ test('codegen round-trip: generated code produces valid SMILES', () => {
444
+ const ast = parse(CHOLESTEROL_SMILES);
445
+ const code = ast.toCode('v');
446
+ const executableCode = stripExports(code);
447
+
448
+ const varMatch = code.match(/export const (v\d+) = /g);
449
+ const lastVar = varMatch ? varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1] : 'v1';
450
+
451
+ const reconstructed = executeCode(executableCode, lastVar);
452
+
453
+ expect(reconstructed.smiles).toBe(CHOLESTEROL_SMILES);
454
+ });
455
+ });
@@ -0,0 +1,112 @@
1
+ import { describe, test, expect } from 'bun:test';
2
+ import { parse } from '../src/parser/index.js';
3
+ import { codegenRoundTrip } from './utils.js';
4
+
5
+ const CHOLESTEROL_SMILES = 'C[C@H](CCCC(C)C)[C@H]1CC[C@@H]2[C@@]1(CC[C@H]3[C@H]2CC=C4[C@@]3(CC[C@@H](C4)O)C)C';
6
+
7
+ describe('Cholesterol - Divide and Conquer', () => {
8
+ // Cholesterol SMILES:
9
+ // C[C@H](CCCC(C)C)[C@H]1CC[C@@H]2[C@@]1(CC[C@H]3[C@H]2CC=C4[C@@]3(CC[C@@H](C4)O)C)C
10
+ //
11
+ // The failure: ring 4 is being dropped
12
+ // Expected: ...CC=C4[C@@]3(CC[C@@H](C4)O)C)C
13
+ // Received: ...CC=C[C@@]3(CC[C@@H](C)O)C)C
14
+
15
+ // Level 1: Simple ring closures
16
+ test('simple ring', () => {
17
+ const s = 'C1CCCCC1';
18
+ expect(parse(s).smiles).toBe(s);
19
+ expect(codegenRoundTrip(s).smiles).toBe(s);
20
+ });
21
+
22
+ // Level 2: Two fused rings (decalin-like)
23
+ test('two fused rings', () => {
24
+ const s = 'C1CCC2CCCCC2C1';
25
+ expect(parse(s).smiles).toBe(s);
26
+ expect(codegenRoundTrip(s).smiles).toBe(s);
27
+ });
28
+
29
+ // Level 3: Ring closure inside a branch - the core pattern
30
+ test('ring closure in branch: C1CCC(C1)C', () => {
31
+ const s = 'C1CCC(C1)C';
32
+ expect(parse(s).smiles).toBe(s);
33
+ expect(codegenRoundTrip(s).smiles).toBe(s);
34
+ });
35
+
36
+ // Level 4: Two ring numbers, one closing in a branch
37
+ test('two rings, one closing in branch: C1CC2CCC(C2)C1', () => {
38
+ const s = 'C1CC2CCC(C2)C1';
39
+ expect(parse(s).smiles).toBe(s);
40
+ expect(codegenRoundTrip(s).smiles).toBe(s);
41
+ });
42
+
43
+ // Level 5: Ring opening and closing with different numbers in nested context
44
+ test('ring 4 opens and closes in branch: C4CCC(C4)', () => {
45
+ const s = 'C4CCC(C4)';
46
+ expect(parse(s).smiles).toBe(s);
47
+ expect(codegenRoundTrip(s).smiles).toBe(s);
48
+ });
49
+
50
+ // Level 6: The specific pattern from cholesterol - ring opens, then closes inside a parenthesized branch
51
+ test('ring open at atom, close inside branch argument: CC=C4C(CC(C4)O)', () => {
52
+ const s = 'CC=C4C(CC(C4)O)';
53
+ expect(parse(s).smiles).toBe(s);
54
+ expect(codegenRoundTrip(s).smiles).toBe(s);
55
+ });
56
+
57
+ // Level 7: Closer to cholesterol D-ring pattern
58
+ test('cholesterol D-ring pattern: CC=C4C(CCC(C4)O)C', () => {
59
+ const s = 'CC=C4C(CCC(C4)O)C';
60
+ expect(parse(s).smiles).toBe(s);
61
+ expect(codegenRoundTrip(s).smiles).toBe(s);
62
+ });
63
+
64
+ // Level 8: Add ring 3 fused with ring 4
65
+ test('fused rings 3+4: C3CC=C4C3(CCC(C4)O)C', () => {
66
+ const s = 'C3CC=C4C3(CCC(C4)O)C';
67
+ expect(parse(s).smiles).toBe(s);
68
+ expect(codegenRoundTrip(s).smiles).toBe(s);
69
+ });
70
+
71
+ // Level 9: The C/D ring system from cholesterol (without stereo)
72
+ test('C/D ring system: C2CC=C4C(CC2)(CCC(C4)O)C', () => {
73
+ const s = 'C2CC=C4C(CC2)(CCC(C4)O)C';
74
+ expect(parse(s).smiles).toBe(s);
75
+ expect(codegenRoundTrip(s).smiles).toBe(s);
76
+ });
77
+
78
+ // Level 10: Three fused rings (A/B/C ring without stereo)
79
+ test('three fused rings: C1CCC2C1CCC3CC=C4C3(CCC(C4)O)C', () => {
80
+ const s = 'C1CCC2C1CCC3C2CC=C4C3(CCC(C4)O)C';
81
+ expect(parse(s).smiles).toBe(s);
82
+ expect(codegenRoundTrip(s).smiles).toBe(s);
83
+ });
84
+
85
+ // Level 11: Isolate multiple branches on same atom with ring closures
86
+ test('two branches with ring closures: C1C(C1)(C2)CC2', () => {
87
+ const s = 'C1C(C1)(C2)CC2';
88
+ expect(parse(s).smiles).toBe(s);
89
+ expect(codegenRoundTrip(s).smiles).toBe(s);
90
+ });
91
+
92
+ // Level 12: Minimal failing pattern - ring closure in second branch
93
+ test('ring close in second branch: C4CC(C)(C4)', () => {
94
+ const s = 'C4CC(C)(C4)';
95
+ expect(parse(s).smiles).toBe(s);
96
+ expect(codegenRoundTrip(s).smiles).toBe(s);
97
+ });
98
+
99
+ // Level 13: Full cholesterol (no stereo) to isolate stereo vs ring issue
100
+ test('cholesterol without stereochemistry', () => {
101
+ const s = 'CC(CCCC(C)C)C1CCC2C1(CCC3C2CC=C4C3(CCC(C4)O)C)C';
102
+ expect(parse(s).smiles).toBe(s);
103
+ expect(codegenRoundTrip(s).smiles).toBe(s);
104
+ });
105
+
106
+ // Level 14: Full cholesterol with stereochemistry
107
+ test('full cholesterol', () => {
108
+ const s = CHOLESTEROL_SMILES;
109
+ expect(parse(s).smiles).toBe(s);
110
+ expect(codegenRoundTrip(s).smiles).toBe(s);
111
+ });
112
+ });