Repository: FHIR/sushi
Pull request #78 (2020-01-08 18:42:26)

Fix reference value on instance
This addresses https://standardhealthrecord.atlassian.net/browse/CIMPL-193.

This adds support for fixing a reference using the following syntax:
```
* subject = Reference(thingToReference) "optional display string"
```
If this is done on a profile, it will set the `patternReference` attribute on `subject` to:
```
"patternReference": {
  "reference": "thingToReference",
  "display": "optional display string"
}
```
Usually though, this will be done on an instance, not on a profile. On an instance, the above line will result in:
```
"subject": {
  "reference": "thingToReference"
  "display": "optional display string"
}
```
being added to the instance.

ngfreiter: Ok @cmoesel, the new commit should fix it so that a reference is resolved into the instance it is referring to, if that instance exists.
ngfreiter: Ok @cmoesel this time for real the latest commit should address your comments. I think the `equals` is working as we want now, and no more mutating rules.

Patch:
diff --git a/antlr/src/main/antlr/FSH.g4 b/antlr/src/main/antlr/FSH.g4
index 6067132..fa1ba2a 100644
--- a/antlr/src/main/antlr/FSH.g4
+++ b/antlr/src/main/antlr/FSH.g4
@@ -61,15 +61,16 @@ paths:              COMMA_DELIMITED_SEQUENCES;
 caretPath:          CARET_SEQUENCE;
 flag:               KW_MOD | KW_MS | KW_SU;
 strength:           KW_EXAMPLE | KW_PREFERRED | KW_EXTENSIBLE | KW_REQUIRED;
-value:              STRING | MULTILINE_STRING | NUMBER | DATETIME | TIME | code | quantity | ratio | bool ;
+value:              STRING | MULTILINE_STRING | NUMBER | DATETIME | TIME | reference | code | quantity | ratio | bool ;
 item:               SEQUENCE CARD flag*;
 code:               CODE STRING?;
 concept:            code STRING?;
 quantity:           NUMBER UNIT;
 ratio:              ratioPart COLON ratioPart;
+reference:          REFERENCE STRING?;
 ratioPart:          NUMBER | quantity;
 bool:               KW_TRUE | KW_FALSE;
-targetType:         SEQUENCE | REFERENCE;
+targetType:         SEQUENCE | reference;
 
 // KEYWORDS
 KW_ALIAS:           'Alias' WS* ':';
diff --git a/src/export/InstanceExporter.ts b/src/export/InstanceExporter.ts
index b13b865..cc4fcb2 100644
--- a/src/export/InstanceExporter.ts
+++ b/src/export/InstanceExporter.ts
@@ -9,7 +9,7 @@ import {
 import { Instance } from '../fshtypes';
 import { FHIRDefinitions } from '../fhirdefs';
 import { logger } from '../utils/FSHLogger';
-import { setPropertyOnInstance } from '../fhirtypes/common';
+import { setPropertyOnInstance, replaceReferences } from '../fhirtypes/common';
 import { InstanceOfNotDefinedError } from '../errors/InstanceOfNotDefinedError';
 
 export class InstanceExporter {
@@ -26,6 +26,7 @@ export class InstanceExporter {
   ): InstanceDefinition {
     // All rules will be FixValueRule
     fshInstanceDef.rules.forEach(rule => {
+      rule = replaceReferences(rule, this.tank, this.resolve);
       const { fixedValue, pathParts } = instanceOfStructureDefinition.validateValueAtPath(
         rule.path,
         rule.fixedValue,
diff --git a/src/export/StructureDefinitionExporter.ts b/src/export/StructureDefinitionExporter.ts
index aab9771..25c96de 100644
--- a/src/export/StructureDefinitionExporter.ts
+++ b/src/export/StructureDefinitionExporter.ts
@@ -14,6 +14,7 @@ import {
 } from '../fshtypes/rules';
 import { logger } from '../utils/FSHLogger';
 import cloneDeep from 'lodash/cloneDeep';
+import { replaceReferences } from '../fhirtypes/common';
 
 /**
  * The StructureDefinitionExporter is the class for exporting Profiles and Extensions.
@@ -75,7 +76,8 @@ export class StructureDefinitionExporter {
           if (rule instanceof CardRule) {
             element.constrainCardinality(rule.min, rule.max);
           } else if (rule instanceof FixedValueRule) {
-            element.fixValue(rule.fixedValue);
+            const replacedRule = replaceReferences(rule, this.tank, this.resolve);
+            element.fixValue(replacedRule.fixedValue);
           } else if (rule instanceof FlagRule) {
             element.applyFlags(rule.mustSupport, rule.summary, rule.modifier);
           } else if (rule instanceof OnlyRule) {
diff --git a/src/fhirtypes/ElementDefinition.ts b/src/fhirtypes/ElementDefinition.ts
index b0a37b4..10155db 100644
--- a/src/fhirtypes/ElementDefinition.ts
+++ b/src/fhirtypes/ElementDefinition.ts
@@ -1,7 +1,7 @@
 import { isEmpty, isEqual, cloneDeep, isBoolean } from 'lodash';
 import { StructureDefinition } from './StructureDefinition';
-import { CodeableConcept, Coding, Quantity, Ratio } from './dataTypes';
-import { FshCode, FshRatio, FshQuantity } from '../fshtypes';
+import { CodeableConcept, Coding, Quantity, Ratio, Reference } from './dataTypes';
+import { FshCode, FshRatio, FshQuantity, FshReference } from '../fshtypes';
 import { FixedValueType } from '../fshtypes/rules';
 import {
   BindingStrengthError,
@@ -147,6 +147,7 @@ export class ElementDefinition {
   patternCoding: Coding;
   patternQuantity: Quantity;
   patternRatio: Ratio;
+  patternReference: Reference;
   example: ElementDefinitionExample[];
   // minValue[x] can be many different field names (e.g., minValueDate, minValueQuantity, etc.),
   // so we can't easily use a getter/setter.  It will be just an unspecified property.  For now.
@@ -805,6 +806,8 @@ export class ElementDefinition {
       this.fixFshQuantity(value);
     } else if (value instanceof FshRatio) {
       this.fixFshRatio(value);
+    } else if (value instanceof FshReference) {
+      this.fixFshReference(value);
     }
   }
 
@@ -1083,6 +1086,45 @@ export class ElementDefinition {
     }
   }
 
+  /**
+   * Fixes a Reference to this element.
+   * @see {@link fixValue}
+   * @param {FshReference} value - the Reference value to fix
+   * @throws {NoSingleTypeError} when the ElementDefinition does not have a single type
+   * @throws {ValueAlreadyFixedError} when the value is already fixed to a different value
+   * @throws {TypeNotFoundError} when the value does not match the type of the ElementDefinition
+   */
+  fixFshReference(value: FshReference): void {
+    if (!this.hasSingleType()) {
+      throw new NoSingleTypeError('Reference');
+    }
+    const type = this.type[0].code;
+    if (type === 'Reference') {
+      if (this.patternReference) {
+        const found = this.patternReference;
+        const foundFshReference = new FshReference(found.reference, found.display);
+        // Check if the new quantity matches the current
+        if (!value.equals(foundFshReference, true)) {
+          throw new ValueAlreadyFixedError(
+            value.toString(),
+            'Reference',
+            foundFshReference.toString()
+          );
+        }
+        // The original display was not set, allow it to be set if references are otherwise equal
+        if (foundFshReference.display == null) {
+          this.patternReference.display = value.display;
+        }
+        // If they do match, there is nothing to do, so return
+        return;
+      }
+      this.patternReference = { reference: value.reference };
+      if (value.display) this.patternReference.display = value.display;
+    } else {
+      throw new MismatchedTypeError('Reference', value.toString(), type);
+    }
+  }
+
   /**
    * Fixes a code to this element using the appropriate methodology based on the element type.
    * - CodeableConcept: patternCodeableConcept using code and system properties
diff --git a/src/fhirtypes/common.ts b/src/fhirtypes/common.ts
index f32437c..c609e0c 100644
--- a/src/fhirtypes/common.ts
+++ b/src/fhirtypes/common.ts
@@ -1,4 +1,8 @@
 import { ResolveFn, StructureDefinition, PathPart, ElementDefinition, InstanceDefinition } from '.';
+import { FixedValueRule } from '../fshtypes/rules';
+import { FshReference } from '../fshtypes';
+import { FSHTank } from '../import';
+import cloneDeep = require('lodash/cloneDeep');
 
 /**
  * This function sets an instance property of an SD or ED if possible
@@ -83,3 +87,32 @@ export function getArrayIndex(pathPart: PathPart): number {
   }
   return arrayIndex >= 0 ? arrayIndex : null;
 }
+
+/**
+ * Replaces references to instances by the correct path to that instance
+ * @param {FixedValueRule} rule - The rule to replace references on
+ * @param {FSHTank} tank - The tank holding the instances
+ * @param {ResolveFn} resolve - A function that can resolve to Structure Definitions
+ * @returns {FixedValueRule} a clone of the rule if replacing is done, otherwise the original rule
+ */
+export function replaceReferences(
+  rule: FixedValueRule,
+  tank: FSHTank,
+  resolve: ResolveFn
+): FixedValueRule {
+  let clone: FixedValueRule;
+  if (rule.fixedValue instanceof FshReference) {
+    const instance = tank.findInstance(rule.fixedValue.reference);
+    const instanceSD = resolve(instance?.instanceOf);
+    // If we can't find a matching instance, just leave the reference as is
+    if (instance && instanceSD) {
+      // If the instance has a rule setting id, that overrides instance.id
+      const idRule = instance.rules.find(r => r.path === 'id');
+      const id = idRule?.fixedValue ?? instance.id;
+      clone = cloneDeep(rule);
+      const fv = clone.fixedValue as FshReference;
+      fv.reference = `${instanceSD.type}/${id}`;
+    }
+  }
+  return clone ?? rule;
+}
diff --git a/src/fshtypes/FshReference.ts b/src/fshtypes/FshReference.ts
new file mode 100644
index 0000000..b05c7db
--- /dev/null
+++ b/src/fshtypes/FshReference.ts
@@ -0,0 +1,18 @@
+import { FshEntity } from './FshEntity';
+
+export class FshReference extends FshEntity {
+  constructor(public reference: string, public display?: string) {
+    super();
+  }
+
+  toString() {
+    return `Reference(${this.reference})${this.display ? ` "${this.display}"` : ''}`;
+  }
+
+  equals(other: FshReference, ignoreOtherDisplay = false) {
+    return (
+      this.reference === other.reference &&
+      (this.display == other.display || (ignoreOtherDisplay && other.display == null))
+    );
+  }
+}
diff --git a/src/fshtypes/index.ts b/src/fshtypes/index.ts
index 85ee60b..d1c2922 100644
--- a/src/fshtypes/index.ts
+++ b/src/fshtypes/index.ts
@@ -6,6 +6,7 @@ export * from './FshCode';
 export * from './FshEntity';
 export * from './FshQuantity';
 export * from './FshRatio';
+export * from './FshReference';
 export * from './Instance';
 export * from './Profile';
 export * from './ValueSet';
diff --git a/src/fshtypes/rules/FixedValueRule.ts b/src/fshtypes/rules/FixedValueRule.ts
index ae0e9aa..32b7c75 100644
--- a/src/fshtypes/rules/FixedValueRule.ts
+++ b/src/fshtypes/rules/FixedValueRule.ts
@@ -1,7 +1,14 @@
 import { Rule } from './Rule';
-import { FshCode, FshQuantity, FshRatio } from '../index';
+import { FshCode, FshQuantity, FshRatio, FshReference } from '../index';
 
-export type FixedValueType = boolean | number | string | FshCode | FshQuantity | FshRatio;
+export type FixedValueType =
+  | boolean
+  | number
+  | string
+  | FshCode
+  | FshQuantity
+  | FshRatio
+  | FshReference;
 
 export class FixedValueRule extends Rule {
   fixedValue: FixedValueType;
diff --git a/src/import/FSHImporter.ts b/src/import/FSHImporter.ts
index ab24c02..664eee3 100644
--- a/src/import/FSHImporter.ts
+++ b/src/import/FSHImporter.ts
@@ -11,6 +11,7 @@ import {
   FshCode,
   FshQuantity,
   FshRatio,
+  FshReference,
   TextLocation,
   Instance,
   ValueSet,
@@ -523,6 +524,10 @@ export class FSHImporter extends FSHVisitor {
       return ctx.TIME().getText();
     }
 
+    if (ctx.reference()) {
+      return this.visitReference(ctx.reference());
+    }
+
     if (ctx.code()) {
       return this.visitCode(ctx.code());
     }
@@ -598,6 +603,22 @@ export class FSHImporter extends FSHVisitor {
     return this.visitQuantity(ctx.quantity());
   }
 
+  visitReference(ctx: pc.ReferenceContext): FshReference {
+    const ref = new FshReference(
+      this.aliasAwareValue(this.parseReference(ctx.REFERENCE().getText())[0])
+    )
+      .withLocation(this.extractStartStop(ctx))
+      .withFile(this.currentFile);
+    if (ctx.STRING()) {
+      ref.display = this.extractString(ctx.STRING());
+    }
+    return ref;
+  }
+
+  private parseReference(reference: string): string[] {
+    return reference.slice(reference.indexOf('(') + 1, reference.length - 1).split(/\s*\|\s*/);
+  }
+
   visitBool(ctx: pc.BoolContext): boolean {
     return ctx.KW_TRUE() != null;
   }
@@ -607,9 +628,13 @@ export class FSHImporter extends FSHVisitor {
       .withLocation(this.extractStartStop(ctx))
       .withFile(this.currentFile);
     ctx.targetType().forEach(t => {
-      if (t.REFERENCE()) {
-        const text = t.REFERENCE().getText();
-        const references = text.slice(text.indexOf('(') + 1, text.length - 1).split(/\s*\|\s*/);
+      if (t.reference()) {
+        const references = this.parseReference(
+          t
+            .reference()
+            .REFERENCE()
+            .getText()
+        );
         references.forEach(r =>
           onlyRule.types.push({ type: this.aliasAwareValue(r), isReference: true })
         );
diff --git a/src/import/FSHTank.ts b/src/import/FSHTank.ts
index 1291934..00e6e90 100644
--- a/src/import/FSHTank.ts
+++ b/src/import/FSHTank.ts
@@ -1,5 +1,5 @@
 import { FSHDocument } from './FSHDocument';
-import { Profile, Extension } from '../fshtypes';
+import { Profile, Extension, Instance } from '../fshtypes';
 import flatMap from 'lodash/flatMap';
 import { Config } from '../fshtypes/Config';
 
@@ -26,6 +26,14 @@ export class FSHTank {
     return flatMap(this.docs, doc => Array.from(doc.extensions.values()));
   }
 
+  /**
+   * Gets all instances in the tank
+   * @returns {Instance[]}
+   */
+  public getAllInstances(): Instance[] {
+    return flatMap(this.docs, doc => Array.from(doc.instances.values()));
+  }
+
   /**
    * Gets all structure definitions (profiles and extensions) in the tank
    * @returns {(Profile | Extension)[]}
@@ -62,6 +70,15 @@ export class FSHTank {
     );
   }
 
+  /**
+   * Finds the instance in the tank by name or id, if it exists
+   * @param {string} key - The name or id of the instance we're looking for
+   * @returns {[Instance, string]}
+   */
+  public findInstance(key: string): Instance | undefined {
+    return this.getAllInstances().find(p => p.name === key || p.id === key);
+  }
+
   /**
    * Finds the alias in the tank, if it exists
    * @param {string} name - The name of the alias we're looking for
diff --git a/src/import/generated/FSH.interp b/src/import/generated/FSH.interp
index 4fc5515..5cc8638 100644
--- a/src/import/generated/FSH.interp
+++ b/src/import/generated/FSH.interp
@@ -171,10 +171,11 @@ code
 concept
 quantity
 ratio
+reference
 ratioPart
 bool
 targetType
 
 
 atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 59, 460, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 3, 2, 7, 2, 114, 10, 2, 12, 2, 14, 2, 117, 11, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 126, 10, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 6, 5, 136, 10, 5, 13, 5, 14, 5, 137, 3, 5, 7, 5, 141, 10, 5, 12, 5, 14, 5, 144, 11, 5, 3, 6, 3, 6, 3, 6, 7, 6, 149, 10, 6, 12, 6, 14, 6, 152, 11, 6, 3, 6, 7, 6, 155, 10, 6, 12, 6, 14, 6, 158, 11, 6, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 164, 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 174, 10, 8, 3, 9, 3, 9, 3, 9, 7, 9, 179, 10, 9, 12, 9, 14, 9, 182, 11, 9, 3, 9, 7, 9, 185, 10, 9, 12, 9, 14, 9, 188, 11, 9, 3, 10, 3, 10, 5, 10, 192, 10, 10, 3, 11, 3, 11, 3, 11, 6, 11, 197, 10, 11, 13, 11, 14, 11, 198, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 205, 10, 12, 3, 13, 3, 13, 3, 13, 7, 13, 210, 10, 13, 12, 13, 14, 13, 213, 11, 13, 3, 13, 7, 13, 216, 10, 13, 12, 13, 14, 13, 219, 11, 13, 3, 14, 3, 14, 3, 14, 5, 14, 224, 10, 14, 3, 15, 3, 15, 3, 15, 7, 15, 229, 10, 15, 12, 15, 14, 15, 232, 11, 15, 3, 15, 7, 15, 235, 10, 15, 12, 15, 14, 15, 238, 11, 15, 3, 16, 3, 16, 3, 16, 5, 16, 243, 10, 16, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 7, 25, 273, 10, 25, 12, 25, 14, 25, 276, 11, 25, 3, 26, 3, 26, 3, 26, 5, 26, 281, 10, 26, 3, 26, 6, 26, 284, 10, 26, 13, 26, 14, 26, 285, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 5, 27, 293, 10, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 7, 29, 306, 10, 29, 12, 29, 14, 29, 309, 11, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 7, 30, 317, 10, 30, 12, 30, 14, 30, 320, 11, 30, 3, 31, 3, 31, 5, 31, 324, 10, 31, 3, 31, 3, 31, 3, 31, 3, 31, 7, 31, 330, 10, 31, 12, 31, 14, 31, 333, 11, 31, 3, 32, 3, 32, 5, 32, 337, 10, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 345, 10, 33, 3, 33, 3, 33, 5, 33, 349, 10, 33, 3, 34, 3, 34, 5, 34, 353, 10, 34, 3, 34, 3, 34, 5, 34, 357, 10, 34, 3, 35, 3, 35, 3, 35, 3, 35, 5, 35, 363, 10, 35, 3, 36, 3, 36, 3, 36, 3, 36, 5, 36, 369, 10, 36, 3, 36, 3, 36, 3, 36, 5, 36, 374, 10, 36, 5, 36, 376, 10, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 7, 39, 387, 10, 39, 12, 39, 14, 39, 390, 11, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 5, 40, 397, 10, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 5, 42, 406, 10, 42, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 427, 10, 48, 3, 49, 3, 49, 3, 49, 7, 49, 432, 10, 49, 12, 49, 14, 49, 435, 11, 49, 3, 50, 3, 50, 5, 50, 439, 10, 50, 3, 51, 3, 51, 5, 51, 443, 10, 51, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 5, 54, 454, 10, 54, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 2, 2, 57, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 2, 9, 3, 2, 42, 43, 3, 2, 55, 56, 4, 2, 38, 38, 56, 56, 3, 2, 18, 20, 3, 2, 22, 25, 3, 2, 31, 32, 4, 2, 51, 51, 56, 56, 2, 475, 2, 115, 3, 2, 2, 2, 4, 125, 3, 2, 2, 2, 6, 127, 3, 2, 2, 2, 8, 132, 3, 2, 2, 2, 10, 145, 3, 2, 2, 2, 12, 163, 3, 2, 2, 2, 14, 173, 3, 2, 2, 2, 16, 175, 3, 2, 2, 2, 18, 191, 3, 2, 2, 2, 20, 193, 3, 2, 2, 2, 22, 204, 3, 2, 2, 2, 24, 206, 3, 2, 2, 2, 26, 223, 3, 2, 2, 2, 28, 225, 3, 2, 2, 2, 30, 242, 3, 2, 2, 2, 32, 244, 3, 2, 2, 2, 34, 247, 3, 2, 2, 2, 36, 250, 3, 2, 2, 2, 38, 253, 3, 2, 2, 2, 40, 256, 3, 2, 2, 2, 42, 259, 3, 2, 2, 2, 44, 262, 3, 2, 2, 2, 46, 265, 3, 2, 2, 2, 48, 268, 3, 2, 2, 2, 50, 277, 3, 2, 2, 2, 52, 287, 3, 2, 2, 2, 54, 294, 3, 2, 2, 2, 56, 299, 3, 2, 2, 2, 58, 310, 3, 2, 2, 2, 60, 321, 3, 2, 2, 2, 62, 334, 3, 2, 2, 2, 64, 342, 3, 2, 2, 2, 66, 356, 3, 2, 2, 2, 68, 358, 3, 2, 2, 2, 70, 364, 3, 2, 2, 2, 72, 377, 3, 2, 2, 2, 74, 380, 3, 2, 2, 2, 76, 388, 3, 2, 2, 2, 78, 393, 3, 2, 2, 2, 80, 398, 3, 2, 2, 2, 82, 405, 3, 2, 2, 2, 84, 407, 3, 2, 2, 2, 86, 409, 3, 2, 2, 2, 88, 411, 3, 2, 2, 2, 90, 413, 3, 2, 2, 2, 92, 415, 3, 2, 2, 2, 94, 426, 3, 2, 2, 2, 96, 428, 3, 2, 2, 2, 98, 436, 3, 2, 2, 2, 100, 440, 3, 2, 2, 2, 102, 444, 3, 2, 2, 2, 104, 447, 3, 2, 2, 2, 106, 453, 3, 2, 2, 2, 108, 455, 3, 2, 2, 2, 110, 457, 3, 2, 2, 2, 112, 114, 5, 4, 3, 2, 113, 112, 3, 2, 2, 2, 114, 117, 3, 2, 2, 2, 115, 113, 3, 2, 2, 2, 115, 116, 3, 2, 2, 2, 116, 3, 3, 2, 2, 2, 117, 115, 3, 2, 2, 2, 118, 126, 5, 6, 4, 2, 119, 126, 5, 8, 5, 2, 120, 126, 5, 10, 6, 2, 121, 126, 5, 20, 11, 2, 122, 126, 5, 16, 9, 2, 123, 126, 5, 24, 13, 2, 124, 126, 5, 28, 15, 2, 125, 118, 3, 2, 2, 2, 125, 119, 3, 2, 2, 2, 125, 120, 3, 2, 2, 2, 125, 121, 3, 2, 2, 2, 125, 122, 3, 2, 2, 2, 125, 123, 3, 2, 2, 2, 125, 124, 3, 2, 2, 2, 126, 5, 3, 2, 2, 2, 127, 128, 7, 3, 2, 2, 128, 129, 7, 56, 2, 2, 129, 130, 7, 38, 2, 2, 130, 131, 7, 56, 2, 2, 131, 7, 3, 2, 2, 2, 132, 133, 7, 4, 2, 2, 133, 135, 7, 56, 2, 2, 134, 136, 5, 12, 7, 2, 135, 134, 3, 2, 2, 2, 136, 137, 3, 2, 2, 2, 137, 135, 3, 2, 2, 2, 137, 138, 3, 2, 2, 2, 138, 142, 3, 2, 2, 2, 139, 141, 5, 14, 8, 2, 140, 139, 3, 2, 2, 2, 141, 144, 3, 2, 2, 2, 142, 140, 3, 2, 2, 2, 142, 143, 3, 2, 2, 2, 143, 9, 3, 2, 2, 2, 144, 142, 3, 2, 2, 2, 145, 146, 7, 5, 2, 2, 146, 150, 7, 56, 2, 2, 147, 149, 5, 12, 7, 2, 148, 147, 3, 2, 2, 2, 149, 152, 3, 2, 2, 2, 150, 148, 3, 2, 2, 2, 150, 151, 3, 2, 2, 2, 151, 156, 3, 2, 2, 2, 152, 150, 3, 2, 2, 2, 153, 155, 5, 14, 8, 2, 154, 153, 3, 2, 2, 2, 155, 158, 3, 2, 2, 2, 156, 154, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, 157, 11, 3, 2, 2, 2, 158, 156, 3, 2, 2, 2, 159, 164, 5, 32, 17, 2, 160, 164, 5, 34, 18, 2, 161, 164, 5, 36, 19, 2, 162, 164, 5, 38, 20, 2, 163, 159, 3, 2, 2, 2, 163, 160, 3, 2, 2, 2, 163, 161, 3, 2, 2, 2, 163, 162, 3, 2, 2, 2, 164, 13, 3, 2, 2, 2, 165, 174, 5, 48, 25, 2, 166, 174, 5, 50, 26, 2, 167, 174, 5, 52, 27, 2, 168, 174, 5, 54, 28, 2, 169, 174, 5, 56, 29, 2, 170, 174, 5, 58, 30, 2, 171, 174, 5, 60, 31, 2, 172, 174, 5, 62, 32, 2, 173, 165, 3, 2, 2, 2, 173, 166, 3, 2, 2, 2, 173, 167, 3, 2, 2, 2, 173, 168, 3, 2, 2, 2, 173, 169, 3, 2, 2, 2, 173, 170, 3, 2, 2, 2, 173, 171, 3, 2, 2, 2, 173, 172, 3, 2, 2, 2, 174, 15, 3, 2, 2, 2, 175, 176, 7, 6, 2, 2, 176, 180, 7, 56, 2, 2, 177, 179, 5, 18, 10, 2, 178, 177, 3, 2, 2, 2, 179, 182, 3, 2, 2, 2, 180, 178, 3, 2, 2, 2, 180, 181, 3, 2, 2, 2, 181, 186, 3, 2, 2, 2, 182, 180, 3, 2, 2, 2, 183, 185, 5, 54, 28, 2, 184, 183, 3, 2, 2, 2, 185, 188, 3, 2, 2, 2, 186, 184, 3, 2, 2, 2, 186, 187, 3, 2, 2, 2, 187, 17, 3, 2, 2, 2, 188, 186, 3, 2, 2, 2, 189, 192, 5, 46, 24, 2, 190, 192, 5, 36, 19, 2, 191, 189, 3, 2, 2, 2, 191, 190, 3, 2, 2, 2, 192, 19, 3, 2, 2, 2, 193, 194, 7, 8, 2, 2, 194, 196, 7, 56, 2, 2, 195, 197, 5, 22, 12, 2, 196, 195, 3, 2, 2, 2, 197, 198, 3, 2, 2, 2, 198, 196, 3, 2, 2, 2, 198, 199, 3, 2, 2, 2, 199, 21, 3, 2, 2, 2, 200, 205, 5, 38, 20, 2, 201, 205, 5, 40, 21, 2, 202, 205, 5, 42, 22, 2, 203, 205, 5, 44, 23, 2, 204, 200, 3, 2, 2, 2, 204, 201, 3, 2, 2, 2, 204, 202, 3, 2, 2, 2, 204, 203, 3, 2, 2, 2, 205, 23, 3, 2, 2, 2, 206, 207, 7, 9, 2, 2, 207, 211, 7, 56, 2, 2, 208, 210, 5, 26, 14, 2, 209, 208, 3, 2, 2, 2, 210, 213, 3, 2, 2, 2, 211, 209, 3, 2, 2, 2, 211, 212, 3, 2, 2, 2, 212, 217, 3, 2, 2, 2, 213, 211, 3, 2, 2, 2, 214, 216, 5, 64, 33, 2, 215, 214, 3, 2, 2, 2, 216, 219, 3, 2, 2, 2, 217, 215, 3, 2, 2, 2, 217, 218, 3, 2, 2, 2, 218, 25, 3, 2, 2, 2, 219, 217, 3, 2, 2, 2, 220, 224, 5, 34, 18, 2, 221, 224, 5, 36, 19, 2, 222, 224, 5, 38, 20, 2, 223, 220, 3, 2, 2, 2, 223, 221, 3, 2, 2, 2, 223, 222, 3, 2, 2, 2, 224, 27, 3, 2, 2, 2, 225, 226, 7, 10, 2, 2, 226, 230, 7, 56, 2, 2, 227, 229, 5, 30, 16, 2, 228, 227, 3, 2, 2, 2, 229, 232, 3, 2, 2, 2, 230, 228, 3, 2, 2, 2, 230, 231, 3, 2, 2, 2, 231, 236, 3, 2, 2, 2, 232, 230, 3, 2, 2, 2, 233, 235, 5, 100, 51, 2, 234, 233, 3, 2, 2, 2, 235, 238, 3, 2, 2, 2, 236, 234, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 29, 3, 2, 2, 2, 238, 236, 3, 2, 2, 2, 239, 243, 5, 34, 18, 2, 240, 243, 5, 36, 19, 2, 241, 243, 5, 38, 20, 2, 242, 239, 3, 2, 2, 2, 242, 240, 3, 2, 2, 2, 242, 241, 3, 2, 2, 2, 243, 31, 3, 2, 2, 2, 244, 245, 7, 11, 2, 2, 245, 246, 7, 56, 2, 2, 246, 33, 3, 2, 2, 2, 247, 248, 7, 12, 2, 2, 248, 249, 7, 56, 2, 2, 249, 35, 3, 2, 2, 2, 250, 251, 7, 13, 2, 2, 251, 252, 7, 42, 2, 2, 252, 37, 3, 2, 2, 2, 253, 254, 7, 14, 2, 2, 254, 255, 9, 2, 2, 2, 255, 39, 3, 2, 2, 2, 256, 257, 7, 15, 2, 2, 257, 258, 7, 42, 2, 2, 258, 41, 3, 2, 2, 2, 259, 260, 7, 16, 2, 2, 260, 261, 7, 42, 2, 2, 261, 43, 3, 2, 2, 2, 262, 263, 7, 17, 2, 2, 263, 264, 7, 46, 2, 2, 264, 45, 3, 2, 2, 2, 265, 266, 7, 7, 2, 2, 266, 267, 7, 56, 2, 2, 267, 47, 3, 2, 2, 2, 268, 269, 7, 39, 2, 2, 269, 270, 5, 84, 43, 2, 270, 274, 7, 50, 2, 2, 271, 273, 5, 90, 46, 2, 272, 271, 3, 2, 2, 2, 273, 276, 3, 2, 2, 2, 274, 272, 3, 2, 2, 2, 274, 275, 3, 2, 2, 2, 275, 49, 3, 2, 2, 2, 276, 274, 3, 2, 2, 2, 277, 280, 7, 39, 2, 2, 278, 281, 5, 84, 43, 2, 279, 281, 5, 86, 44, 2, 280, 278, 3, 2, 2, 2, 280, 279, 3, 2, 2, 2, 281, 283, 3, 2, 2, 2, 282, 284, 5, 90, 46, 2, 283, 282, 3, 2, 2, 2, 284, 285, 3, 2, 2, 2, 285, 283, 3, 2, 2, 2, 285, 286, 3, 2, 2, 2, 286, 51, 3, 2, 2, 2, 287, 288, 7, 39, 2, 2, 288, 289, 5, 84, 43, 2, 289, 290, 7, 21, 2, 2, 290, 292, 7, 56, 2, 2, 291, 293, 5, 92, 47, 2, 292, 291, 3, 2, 2, 2, 292, 293, 3, 2, 2, 2, 293, 53, 3, 2, 2, 2, 294, 295, 7, 39, 2, 2, 295, 296, 5, 84, 43, 2, 296, 297, 7, 38, 2, 2, 297, 298, 5, 94, 48, 2, 298, 55, 3, 2, 2, 2, 299, 300, 7, 39, 2, 2, 300, 301, 5, 84, 43, 2, 301, 302, 7, 26, 2, 2, 302, 307, 5, 96, 49, 2, 303, 304, 7, 27, 2, 2, 304, 306, 5, 96, 49, 2, 305, 303, 3, 2, 2, 2, 306, 309, 3, 2, 2, 2, 307, 305, 3, 2, 2, 2, 307, 308, 3, 2, 2, 2, 308, 57, 3, 2, 2, 2, 309, 307, 3, 2, 2, 2, 310, 311, 7, 39, 2, 2, 311, 312, 5, 84, 43, 2, 312, 313, 7, 28, 2, 2, 313, 318, 5, 110, 56, 2, 314, 315, 7, 29, 2, 2, 315, 317, 5, 110, 56, 2, 316, 314, 3, 2, 2, 2, 317, 320, 3, 2, 2, 2, 318, 316, 3, 2, 2, 2, 318, 319, 3, 2, 2, 2, 319, 59, 3, 2, 2, 2, 320, 318, 3, 2, 2, 2, 321, 323, 7, 39, 2, 2, 322, 324, 5, 84, 43, 2, 323, 322, 3, 2, 2, 2, 323, 324, 3, 2, 2, 2, 324, 325, 3, 2, 2, 2, 325, 326, 7, 30, 2, 2, 326, 331, 7, 56, 2, 2, 327, 328, 7, 27, 2, 2, 328, 330, 7, 56, 2, 2, 329, 327, 3, 2, 2, 2, 330, 333, 3, 2, 2, 2, 331, 329, 3, 2, 2, 2, 331, 332, 3, 2, 2, 2, 332, 61, 3, 2, 2, 2, 333, 331, 3, 2, 2, 2, 334, 336, 7, 39, 2, 2, 335, 337, 5, 84, 43, 2, 336, 335, 3, 2, 2, 2, 336, 337, 3, 2, 2, 2, 337, 338, 3, 2, 2, 2, 338, 339, 5, 88, 45, 2, 339, 340, 7, 38, 2, 2, 340, 341, 5, 94, 48, 2, 341, 63, 3, 2, 2, 2, 342, 344, 7, 39, 2, 2, 343, 345, 7, 33, 2, 2, 344, 343, 3, 2, 2, 2, 344, 345, 3, 2, 2, 2, 345, 348, 3, 2, 2, 2, 346, 349, 5, 66, 34, 2, 347, 349, 5, 68, 35, 2, 348, 346, 3, 2, 2, 2, 348, 347, 3, 2, 2, 2, 349, 65, 3, 2, 2, 2, 350, 352, 5, 98, 50, 2, 351, 353, 5, 70, 36, 2, 352, 351, 3, 2, 2, 2, 352, 353, 3, 2, 2, 2, 353, 357, 3, 2, 2, 2, 354, 355, 7, 54, 2, 2, 355, 357, 5, 70, 36, 2, 356, 350, 3, 2, 2, 2, 356, 354, 3, 2, 2, 2, 357, 67, 3, 2, 2, 2, 358, 359, 7, 34, 2, 2, 359, 362, 5, 70, 36, 2, 360, 361, 7, 35, 2, 2, 361, 363, 5, 76, 39, 2, 362, 360, 3, 2, 2, 2, 362, 363, 3, 2, 2, 2, 363, 69, 3, 2, 2, 2, 364, 375, 7, 21, 2, 2, 365, 368, 5, 72, 37, 2, 366, 367, 7, 27, 2, 2, 367, 369, 5, 74, 38, 2, 368, 366, 3, 2, 2, 2, 368, 369, 3, 2, 2, 2, 369, 376, 3, 2, 2, 2, 370, 373, 5, 74, 38, 2, 371, 372, 7, 27, 2, 2, 372, 374, 5, 72, 37, 2, 373, 371, 3, 2, 2, 2, 373, 374, 3, 2, 2, 2, 374, 376, 3, 2, 2, 2, 375, 365, 3, 2, 2, 2, 375, 370, 3, 2, 2, 2, 376, 71, 3, 2, 2, 2, 377, 378, 7, 37, 2, 2, 378, 379, 7, 56, 2, 2, 379, 73, 3, 2, 2, 2, 380, 381, 7, 36, 2, 2, 381, 382, 9, 3, 2, 2, 382, 75, 3, 2, 2, 2, 383, 384, 5, 78, 40, 2, 384, 385, 7, 27, 2, 2, 385, 387, 3, 2, 2, 2, 386, 383, 3, 2, 2, 2, 387, 390, 3, 2, 2, 2, 388, 386, 3, 2, 2, 2, 388, 389, 3, 2, 2, 2, 389, 391, 3, 2, 2, 2, 390, 388, 3, 2, 2, 2, 391, 392, 5, 78, 40, 2, 392, 77, 3, 2, 2, 2, 393, 394, 7, 56, 2, 2, 394, 396, 5, 80, 41, 2, 395, 397, 5, 82, 42, 2, 396, 395, 3, 2, 2, 2, 396, 397, 3, 2, 2, 2, 397, 79, 3, 2, 2, 2, 398, 399, 9, 4, 2, 2, 399, 81, 3, 2, 2, 2, 400, 406, 5, 98, 50, 2, 401, 406, 7, 31, 2, 2, 402, 406, 7, 32, 2, 2, 403, 406, 7, 53, 2, 2, 404, 406, 7, 42, 2, 2, 405, 400, 3, 2, 2, 2, 405, 401, 3, 2, 2, 2, 405, 402, 3, 2, 2, 2, 405, 403, 3, 2, 2, 2, 405, 404, 3, 2, 2, 2, 406, 83, 3, 2, 2, 2, 407, 408, 7, 56, 2, 2, 408, 85, 3, 2, 2, 2, 409, 410, 7, 55, 2, 2, 410, 87, 3, 2, 2, 2, 411, 412, 7, 52, 2, 2, 412, 89, 3, 2, 2, 2, 413, 414, 9, 5, 2, 2, 414, 91, 3, 2, 2, 2, 415, 416, 9, 6, 2, 2, 416, 93, 3, 2, 2, 2, 417, 427, 7, 42, 2, 2, 418, 427, 7, 43, 2, 2, 419, 427, 7, 44, 2, 2, 420, 427, 7, 48, 2, 2, 421, 427, 7, 49, 2, 2, 422, 427, 5, 98, 50, 2, 423, 427, 5, 102, 52, 2, 424, 427, 5, 104, 53, 2, 425, 427, 5, 108, 55, 2, 426, 417, 3, 2, 2, 2, 426, 418, 3, 2, 2, 2, 426, 419, 3, 2, 2, 2, 426, 420, 3, 2, 2, 2, 426, 421, 3, 2, 2, 2, 426, 422, 3, 2, 2, 2, 426, 423, 3, 2, 2, 2, 426, 424, 3, 2, 2, 2, 426, 425, 3, 2, 2, 2, 427, 95, 3, 2, 2, 2, 428, 429, 7, 56, 2, 2, 429, 433, 7, 50, 2, 2, 430, 432, 5, 90, 46, 2, 431, 430, 3, 2, 2, 2, 432, 435, 3, 2, 2, 2, 433, 431, 3, 2, 2, 2, 433, 434, 3, 2, 2, 2, 434, 97, 3, 2, 2, 2, 435, 433, 3, 2, 2, 2, 436, 438, 7, 46, 2, 2, 437, 439, 7, 42, 2, 2, 438, 437, 3, 2, 2, 2, 438, 439, 3, 2, 2, 2, 439, 99, 3, 2, 2, 2, 440, 442, 5, 98, 50, 2, 441, 443, 7, 42, 2, 2, 442, 441, 3, 2, 2, 2, 442, 443, 3, 2, 2, 2, 443, 101, 3, 2, 2, 2, 444, 445, 7, 44, 2, 2, 445, 446, 7, 45, 2, 2, 446, 103, 3, 2, 2, 2, 447, 448, 5, 106, 54, 2, 448, 449, 7, 40, 2, 2, 449, 450, 5, 106, 54, 2, 450, 105, 3, 2, 2, 2, 451, 454, 7, 44, 2, 2, 452, 454, 5, 102, 52, 2, 453, 451, 3, 2, 2, 2, 453, 452, 3, 2, 2, 2, 454, 107, 3, 2, 2, 2, 455, 456, 9, 7, 2, 2, 456, 109, 3, 2, 2, 2, 457, 458, 9, 8, 2, 2, 458, 111, 3, 2, 2, 2, 46, 115, 125, 137, 142, 150, 156, 163, 173, 180, 186, 191, 198, 204, 211, 217, 223, 230, 236, 242, 274, 280, 285, 292, 307, 318, 323, 331, 336, 344, 348, 352, 356, 362, 368, 373, 375, 388, 396, 405, 426, 433, 438, 442, 453]
\ No newline at end of file
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 59, 469, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 3, 2, 7, 2, 116, 10, 2, 12, 2, 14, 2, 119, 11, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 128, 10, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 6, 5, 138, 10, 5, 13, 5, 14, 5, 139, 3, 5, 7, 5, 143, 10, 5, 12, 5, 14, 5, 146, 11, 5, 3, 6, 3, 6, 3, 6, 7, 6, 151, 10, 6, 12, 6, 14, 6, 154, 11, 6, 3, 6, 7, 6, 157, 10, 6, 12, 6, 14, 6, 160, 11, 6, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 166, 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 176, 10, 8, 3, 9, 3, 9, 3, 9, 7, 9, 181, 10, 9, 12, 9, 14, 9, 184, 11, 9, 3, 9, 7, 9, 187, 10, 9, 12, 9, 14, 9, 190, 11, 9, 3, 10, 3, 10, 5, 10, 194, 10, 10, 3, 11, 3, 11, 3, 11, 6, 11, 199, 10, 11, 13, 11, 14, 11, 200, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 207, 10, 12, 3, 13, 3, 13, 3, 13, 7, 13, 212, 10, 13, 12, 13, 14, 13, 215, 11, 13, 3, 13, 7, 13, 218, 10, 13, 12, 13, 14, 13, 221, 11, 13, 3, 14, 3, 14, 3, 14, 5, 14, 226, 10, 14, 3, 15, 3, 15, 3, 15, 7, 15, 231, 10, 15, 12, 15, 14, 15, 234, 11, 15, 3, 15, 7, 15, 237, 10, 15, 12, 15, 14, 15, 240, 11, 15, 3, 16, 3, 16, 3, 16, 5, 16, 245, 10, 16, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 7, 25, 275, 10, 25, 12, 25, 14, 25, 278, 11, 25, 3, 26, 3, 26, 3, 26, 5, 26, 283, 10, 26, 3, 26, 6, 26, 286, 10, 26, 13, 26, 14, 26, 287, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 5, 27, 295, 10, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 7, 29, 308, 10, 29, 12, 29, 14, 29, 311, 11, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 7, 30, 319, 10, 30, 12, 30, 14, 30, 322, 11, 30, 3, 31, 3, 31, 5, 31, 326, 10, 31, 3, 31, 3, 31, 3, 31, 3, 31, 7, 31, 332, 10, 31, 12, 31, 14, 31, 335, 11, 31, 3, 32, 3, 32, 5, 32, 339, 10, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 347, 10, 33, 3, 33, 3, 33, 5, 33, 351, 10, 33, 3, 34, 3, 34, 5, 34, 355, 10, 34, 3, 34, 3, 34, 5, 34, 359, 10, 34, 3, 35, 3, 35, 3, 35, 3, 35, 5, 35, 365, 10, 35, 3, 36, 3, 36, 3, 36, 3, 36, 5, 36, 371, 10, 36, 3, 36, 3, 36, 3, 36, 5, 36, 376, 10, 36, 5, 36, 378, 10, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 7, 39, 389, 10, 39, 12, 39, 14, 39, 392, 11, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 5, 40, 399, 10, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 5, 42, 408, 10, 42, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 430, 10, 48, 3, 49, 3, 49, 3, 49, 7, 49, 435, 10, 49, 12, 49, 14, 49, 438, 11, 49, 3, 50, 3, 50, 5, 50, 442, 10, 50, 3, 51, 3, 51, 5, 51, 446, 10, 51, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 5, 54, 457, 10, 54, 3, 55, 3, 55, 5, 55, 461, 10, 55, 3, 56, 3, 56, 3, 57, 3, 57, 5, 57, 467, 10, 57, 3, 57, 2, 2, 58, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 2, 8, 3, 2, 42, 43, 3, 2, 55, 56, 4, 2, 38, 38, 56, 56, 3, 2, 18, 20, 3, 2, 22, 25, 3, 2, 31, 32, 2, 486, 2, 117, 3, 2, 2, 2, 4, 127, 3, 2, 2, 2, 6, 129, 3, 2, 2, 2, 8, 134, 3, 2, 2, 2, 10, 147, 3, 2, 2, 2, 12, 165, 3, 2, 2, 2, 14, 175, 3, 2, 2, 2, 16, 177, 3, 2, 2, 2, 18, 193, 3, 2, 2, 2, 20, 195, 3, 2, 2, 2, 22, 206, 3, 2, 2, 2, 24, 208, 3, 2, 2, 2, 26, 225, 3, 2, 2, 2, 28, 227, 3, 2, 2, 2, 30, 244, 3, 2, 2, 2, 32, 246, 3, 2, 2, 2, 34, 249, 3, 2, 2, 2, 36, 252, 3, 2, 2, 2, 38, 255, 3, 2, 2, 2, 40, 258, 3, 2, 2, 2, 42, 261, 3, 2, 2, 2, 44, 264, 3, 2, 2, 2, 46, 267, 3, 2, 2, 2, 48, 270, 3, 2, 2, 2, 50, 279, 3, 2, 2, 2, 52, 289, 3, 2, 2, 2, 54, 296, 3, 2, 2, 2, 56, 301, 3, 2, 2, 2, 58, 312, 3, 2, 2, 2, 60, 323, 3, 2, 2, 2, 62, 336, 3, 2, 2, 2, 64, 344, 3, 2, 2, 2, 66, 358, 3, 2, 2, 2, 68, 360, 3, 2, 2, 2, 70, 366, 3, 2, 2, 2, 72, 379, 3, 2, 2, 2, 74, 382, 3, 2, 2, 2, 76, 390, 3, 2, 2, 2, 78, 395, 3, 2, 2, 2, 80, 400, 3, 2, 2, 2, 82, 407, 3, 2, 2, 2, 84, 409, 3, 2, 2, 2, 86, 411, 3, 2, 2, 2, 88, 413, 3, 2, 2, 2, 90, 415, 3, 2, 2, 2, 92, 417, 3, 2, 2, 2, 94, 429, 3, 2, 2, 2, 96, 431, 3, 2, 2, 2, 98, 439, 3, 2, 2, 2, 100, 443, 3, 2, 2, 2, 102, 447, 3, 2, 2, 2, 104, 450, 3, 2, 2, 2, 106, 454, 3, 2, 2, 2, 108, 460, 3, 2, 2, 2, 110, 462, 3, 2, 2, 2, 112, 466, 3, 2, 2, 2, 114, 116, 5, 4, 3, 2, 115, 114, 3, 2, 2, 2, 116, 119, 3, 2, 2, 2, 117, 115, 3, 2, 2, 2, 117, 118, 3, 2, 2, 2, 118, 3, 3, 2, 2, 2, 119, 117, 3, 2, 2, 2, 120, 128, 5, 6, 4, 2, 121, 128, 5, 8, 5, 2, 122, 128, 5, 10, 6, 2, 123, 128, 5, 20, 11, 2, 124, 128, 5, 16, 9, 2, 125, 128, 5, 24, 13, 2, 126, 128, 5, 28, 15, 2, 127, 120, 3, 2, 2, 2, 127, 121, 3, 2, 2, 2, 127, 122, 3, 2, 2, 2, 127, 123, 3, 2, 2, 2, 127, 124, 3, 2, 2, 2, 127, 125, 3, 2, 2, 2, 127, 126, 3, 2, 2, 2, 128, 5, 3, 2, 2, 2, 129, 130, 7, 3, 2, 2, 130, 131, 7, 56, 2, 2, 131, 132, 7, 38, 2, 2, 132, 133, 7, 56, 2, 2, 133, 7, 3, 2, 2, 2, 134, 135, 7, 4, 2, 2, 135, 137, 7, 56, 2, 2, 136, 138, 5, 12, 7, 2, 137, 136, 3, 2, 2, 2, 138, 139, 3, 2, 2, 2, 139, 137, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 144, 3, 2, 2, 2, 141, 143, 5, 14, 8, 2, 142, 141, 3, 2, 2, 2, 143, 146, 3, 2, 2, 2, 144, 142, 3, 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 9, 3, 2, 2, 2, 146, 144, 3, 2, 2, 2, 147, 148, 7, 5, 2, 2, 148, 152, 7, 56, 2, 2, 149, 151, 5, 12, 7, 2, 150, 149, 3, 2, 2, 2, 151, 154, 3, 2, 2, 2, 152, 150, 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 153, 158, 3, 2, 2, 2, 154, 152, 3, 2, 2, 2, 155, 157, 5, 14, 8, 2, 156, 155, 3, 2, 2, 2, 157, 160, 3, 2, 2, 2, 158, 156, 3, 2, 2, 2, 158, 159, 3, 2, 2, 2, 159, 11, 3, 2, 2, 2, 160, 158, 3, 2, 2, 2, 161, 166, 5, 32, 17, 2, 162, 166, 5, 34, 18, 2, 163, 166, 5, 36, 19, 2, 164, 166, 5, 38, 20, 2, 165, 161, 3, 2, 2, 2, 165, 162, 3, 2, 2, 2, 165, 163, 3, 2, 2, 2, 165, 164, 3, 2, 2, 2, 166, 13, 3, 2, 2, 2, 167, 176, 5, 48, 25, 2, 168, 176, 5, 50, 26, 2, 169, 176, 5, 52, 27, 2, 170, 176, 5, 54, 28, 2, 171, 176, 5, 56, 29, 2, 172, 176, 5, 58, 30, 2, 173, 176, 5, 60, 31, 2, 174, 176, 5, 62, 32, 2, 175, 167, 3, 2, 2, 2, 175, 168, 3, 2, 2, 2, 175, 169, 3, 2, 2, 2, 175, 170, 3, 2, 2, 2, 175, 171, 3, 2, 2, 2, 175, 172, 3, 2, 2, 2, 175, 173, 3, 2, 2, 2, 175, 174, 3, 2, 2, 2, 176, 15, 3, 2, 2, 2, 177, 178, 7, 6, 2, 2, 178, 182, 7, 56, 2, 2, 179, 181, 5, 18, 10, 2, 180, 179, 3, 2, 2, 2, 181, 184, 3, 2, 2, 2, 182, 180, 3, 2, 2, 2, 182, 183, 3, 2, 2, 2, 183, 188, 3, 2, 2, 2, 184, 182, 3, 2, 2, 2, 185, 187, 5, 54, 28, 2, 186, 185, 3, 2, 2, 2, 187, 190, 3, 2, 2, 2, 188, 186, 3, 2, 2, 2, 188, 189, 3, 2, 2, 2, 189, 17, 3, 2, 2, 2, 190, 188, 3, 2, 2, 2, 191, 194, 5, 46, 24, 2, 192, 194, 5, 36, 19, 2, 193, 191, 3, 2, 2, 2, 193, 192, 3, 2, 2, 2, 194, 19, 3, 2, 2, 2, 195, 196, 7, 8, 2, 2, 196, 198, 7, 56, 2, 2, 197, 199, 5, 22, 12, 2, 198, 197, 3, 2, 2, 2, 199, 200, 3, 2, 2, 2, 200, 198, 3, 2, 2, 2, 200, 201, 3, 2, 2, 2, 201, 21, 3, 2, 2, 2, 202, 207, 5, 38, 20, 2, 203, 207, 5, 40, 21, 2, 204, 207, 5, 42, 22, 2, 205, 207, 5, 44, 23, 2, 206, 202, 3, 2, 2, 2, 206, 203, 3, 2, 2, 2, 206, 204, 3, 2, 2, 2, 206, 205, 3, 2, 2, 2, 207, 23, 3, 2, 2, 2, 208, 209, 7, 9, 2, 2, 209, 213, 7, 56, 2, 2, 210, 212, 5, 26, 14, 2, 211, 210, 3, 2, 2, 2, 212, 215, 3, 2, 2, 2, 213, 211, 3, 2, 2, 2, 213, 214, 3, 2, 2, 2, 214, 219, 3, 2, 2, 2, 215, 213, 3, 2, 2, 2, 216, 218, 5, 64, 33, 2, 217, 216, 3, 2, 2, 2, 218, 221, 3, 2, 2, 2, 219, 217, 3, 2, 2, 2, 219, 220, 3, 2, 2, 2, 220, 25, 3, 2, 2, 2, 221, 219, 3, 2, 2, 2, 222, 226, 5, 34, 18, 2, 223, 226, 5, 36, 19, 2, 224, 226, 5, 38, 20, 2, 225, 222, 3, 2, 2, 2, 225, 223, 3, 2, 2, 2, 225, 224, 3, 2, 2, 2, 226, 27, 3, 2, 2, 2, 227, 228, 7, 10, 2, 2, 228, 232, 7, 56, 2, 2, 229, 231, 5, 30, 16, 2, 230, 229, 3, 2, 2, 2, 231, 234, 3, 2, 2, 2, 232, 230, 3, 2, 2, 2, 232, 233, 3, 2, 2, 2, 233, 238, 3, 2, 2, 2, 234, 232, 3, 2, 2, 2, 235, 237, 5, 100, 51, 2, 236, 235, 3, 2, 2, 2, 237, 240, 3, 2, 2, 2, 238, 236, 3, 2, 2, 2, 238, 239, 3, 2, 2, 2, 239, 29, 3, 2, 2, 2, 240, 238, 3, 2, 2, 2, 241, 245, 5, 34, 18, 2, 242, 245, 5, 36, 19, 2, 243, 245, 5, 38, 20, 2, 244, 241, 3, 2, 2, 2, 244, 242, 3, 2, 2, 2, 244, 243, 3, 2, 2, 2, 245, 31, 3, 2, 2, 2, 246, 247, 7, 11, 2, 2, 247, 248, 7, 56, 2, 2, 248, 33, 3, 2, 2, 2, 249, 250, 7, 12, 2, 2, 250, 251, 7, 56, 2, 2, 251, 35, 3, 2, 2, 2, 252, 253, 7, 13, 2, 2, 253, 254, 7, 42, 2, 2, 254, 37, 3, 2, 2, 2, 255, 256, 7, 14, 2, 2, 256, 257, 9, 2, 2, 2, 257, 39, 3, 2, 2, 2, 258, 259, 7, 15, 2, 2, 259, 260, 7, 42, 2, 2, 260, 41, 3, 2, 2, 2, 261, 262, 7, 16, 2, 2, 262, 263, 7, 42, 2, 2, 263, 43, 3, 2, 2, 2, 264, 265, 7, 17, 2, 2, 265, 266, 7, 46, 2, 2, 266, 45, 3, 2, 2, 2, 267, 268, 7, 7, 2, 2, 268, 269, 7, 56, 2, 2, 269, 47, 3, 2, 2, 2, 270, 271, 7, 39, 2, 2, 271, 272, 5, 84, 43, 2, 272, 276, 7, 50, 2, 2, 273, 275, 5, 90, 46, 2, 274, 273, 3, 2, 2, 2, 275, 278, 3, 2, 2, 2, 276, 274, 3, 2, 2, 2, 276, 277, 3, 2, 2, 2, 277, 49, 3, 2, 2, 2, 278, 276, 3, 2, 2, 2, 279, 282, 7, 39, 2, 2, 280, 283, 5, 84, 43, 2, 281, 283, 5, 86, 44, 2, 282, 280, 3, 2, 2, 2, 282, 281, 3, 2, 2, 2, 283, 285, 3, 2, 2, 2, 284, 286, 5, 90, 46, 2, 285, 284, 3, 2, 2, 2, 286, 287, 3, 2, 2, 2, 287, 285, 3, 2, 2, 2, 287, 288, 3, 2, 2, 2, 288, 51, 3, 2, 2, 2, 289, 290, 7, 39, 2, 2, 290, 291, 5, 84, 43, 2, 291, 292, 7, 21, 2, 2, 292, 294, 7, 56, 2, 2, 293, 295, 5, 92, 47, 2, 294, 293, 3, 2, 2, 2, 294, 295, 3, 2, 2, 2, 295, 53, 3, 2, 2, 2, 296, 297, 7, 39, 2, 2, 297, 298, 5, 84, 43, 2, 298, 299, 7, 38, 2, 2, 299, 300, 5, 94, 48, 2, 300, 55, 3, 2, 2, 2, 301, 302, 7, 39, 2, 2, 302, 303, 5, 84, 43, 2, 303, 304, 7, 26, 2, 2, 304, 309, 5, 96, 49, 2, 305, 306, 7, 27, 2, 2, 306, 308, 5, 96, 49, 2, 307, 305, 3, 2, 2, 2, 308, 311, 3, 2, 2, 2, 309, 307, 3, 2, 2, 2, 309, 310, 3, 2, 2, 2, 310, 57, 3, 2, 2, 2, 311, 309, 3, 2, 2, 2, 312, 313, 7, 39, 2, 2, 313, 314, 5, 84, 43, 2, 314, 315, 7, 28, 2, 2, 315, 320, 5, 112, 57, 2, 316, 317, 7, 29, 2, 2, 317, 319, 5, 112, 57, 2, 318, 316, 3, 2, 2, 2, 319, 322, 3, 2, 2, 2, 320, 318, 3, 2, 2, 2, 320, 321, 3, 2, 2, 2, 321, 59, 3, 2, 2, 2, 322, 320, 3, 2, 2, 2, 323, 325, 7, 39, 2, 2, 324, 326, 5, 84, 43, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 327, 3, 2, 2, 2, 327, 328, 7, 30, 2, 2, 328, 333, 7, 56, 2, 2, 329, 330, 7, 27, 2, 2, 330, 332, 7, 56, 2, 2, 331, 329, 3, 2, 2, 2, 332, 335, 3, 2, 2, 2, 333, 331, 3, 2, 2, 2, 333, 334, 3, 2, 2, 2, 334, 61, 3, 2, 2, 2, 335, 333, 3, 2, 2, 2, 336, 338, 7, 39, 2, 2, 337, 339, 5, 84, 43, 2, 338, 337, 3, 2, 2, 2, 338, 339, 3, 2, 2, 2, 339, 340, 3, 2, 2, 2, 340, 341, 5, 88, 45, 2, 341, 342, 7, 38, 2, 2, 342, 343, 5, 94, 48, 2, 343, 63, 3, 2, 2, 2, 344, 346, 7, 39, 2, 2, 345, 347, 7, 33, 2, 2, 346, 345, 3, 2, 2, 2, 346, 347, 3, 2, 2, 2, 347, 350, 3, 2, 2, 2, 348, 351, 5, 66, 34, 2, 349, 351, 5, 68, 35, 2, 350, 348, 3, 2, 2, 2, 350, 349, 3, 2, 2, 2, 351, 65, 3, 2, 2, 2, 352, 354, 5, 98, 50, 2, 353, 355, 5, 70, 36, 2, 354, 353, 3, 2, 2, 2, 354, 355, 3, 2, 2, 2, 355, 359, 3, 2, 2, 2, 356, 357, 7, 54, 2, 2, 357, 359, 5, 70, 36, 2, 358, 352, 3, 2, 2, 2, 358, 356, 3, 2, 2, 2, 359, 67, 3, 2, 2, 2, 360, 361, 7, 34, 2, 2, 361, 364, 5, 70, 36, 2, 362, 363, 7, 35, 2, 2, 363, 365, 5, 76, 39, 2, 364, 362, 3, 2, 2, 2, 364, 365, 3, 2, 2, 2, 365, 69, 3, 2, 2, 2, 366, 377, 7, 21, 2, 2, 367, 370, 5, 72, 37, 2, 368, 369, 7, 27, 2, 2, 369, 371, 5, 74, 38, 2, 370, 368, 3, 2, 2, 2, 370, 371, 3, 2, 2, 2, 371, 378, 3, 2, 2, 2, 372, 375, 5, 74, 38, 2, 373, 374, 7, 27, 2, 2, 374, 376, 5, 72, 37, 2, 375, 373, 3, 2, 2, 2, 375, 376, 3, 2, 2, 2, 376, 378, 3, 2, 2, 2, 377, 367, 3, 2, 2, 2, 377, 372, 3, 2, 2, 2, 378, 71, 3, 2, 2, 2, 379, 380, 7, 37, 2, 2, 380, 381, 7, 56, 2, 2, 381, 73, 3, 2, 2, 2, 382, 383, 7, 36, 2, 2, 383, 384, 9, 3, 2, 2, 384, 75, 3, 2, 2, 2, 385, 386, 5, 78, 40, 2, 386, 387, 7, 27, 2, 2, 387, 389, 3, 2, 2, 2, 388, 385, 3, 2, 2, 2, 389, 392, 3, 2, 2, 2, 390, 388, 3, 2, 2, 2, 390, 391, 3, 2, 2, 2, 391, 393, 3, 2, 2, 2, 392, 390, 3, 2, 2, 2, 393, 394, 5, 78, 40, 2, 394, 77, 3, 2, 2, 2, 395, 396, 7, 56, 2, 2, 396, 398, 5, 80, 41, 2, 397, 399, 5, 82, 42, 2, 398, 397, 3, 2, 2, 2, 398, 399, 3, 2, 2, 2, 399, 79, 3, 2, 2, 2, 400, 401, 9, 4, 2, 2, 401, 81, 3, 2, 2, 2, 402, 408, 5, 98, 50, 2, 403, 408, 7, 31, 2, 2, 404, 408, 7, 32, 2, 2, 405, 408, 7, 53, 2, 2, 406, 408, 7, 42, 2, 2, 407, 402, 3, 2, 2, 2, 407, 403, 3, 2, 2, 2, 407, 404, 3, 2, 2, 2, 407, 405, 3, 2, 2, 2, 407, 406, 3, 2, 2, 2, 408, 83, 3, 2, 2, 2, 409, 410, 7, 56, 2, 2, 410, 85, 3, 2, 2, 2, 411, 412, 7, 55, 2, 2, 412, 87, 3, 2, 2, 2, 413, 414, 7, 52, 2, 2, 414, 89, 3, 2, 2, 2, 415, 416, 9, 5, 2, 2, 416, 91, 3, 2, 2, 2, 417, 418, 9, 6, 2, 2, 418, 93, 3, 2, 2, 2, 419, 430, 7, 42, 2, 2, 420, 430, 7, 43, 2, 2, 421, 430, 7, 44, 2, 2, 422, 430, 7, 48, 2, 2, 423, 430, 7, 49, 2, 2, 424, 430, 5, 106, 54, 2, 425, 430, 5, 98, 50, 2, 426, 430, 5, 102, 52, 2, 427, 430, 5, 104, 53, 2, 428, 430, 5, 110, 56, 2, 429, 419, 3, 2, 2, 2, 429, 420, 3, 2, 2, 2, 429, 421, 3, 2, 2, 2, 429, 422, 3, 2, 2, 2, 429, 423, 3, 2, 2, 2, 429, 424, 3, 2, 2, 2, 429, 425, 3, 2, 2, 2, 429, 426, 3, 2, 2, 2, 429, 427, 3, 2, 2, 2, 429, 428, 3, 2, 2, 2, 430, 95, 3, 2, 2, 2, 431, 432, 7, 56, 2, 2, 432, 436, 7, 50, 2, 2, 433, 435, 5, 90, 46, 2, 434, 433, 3, 2, 2, 2, 435, 438, 3, 2, 2, 2, 436, 434, 3, 2, 2, 2, 436, 437, 3, 2, 2, 2, 437, 97, 3, 2, 2, 2, 438, 436, 3, 2, 2, 2, 439, 441, 7, 46, 2, 2, 440, 442, 7, 42, 2, 2, 441, 440, 3, 2, 2, 2, 441, 442, 3, 2, 2, 2, 442, 99, 3, 2, 2, 2, 443, 445, 5, 98, 50, 2, 444, 446, 7, 42, 2, 2, 445, 444, 3, 2, 2, 2, 445, 446, 3, 2, 2, 2, 446, 101, 3, 2, 2, 2, 447, 448, 7, 44, 2, 2, 448, 449, 7, 45, 2, 2, 449, 103, 3, 2, 2, 2, 450, 451, 5, 108, 55, 2, 451, 452, 7, 40, 2, 2, 452, 453, 5, 108, 55, 2, 453, 105, 3, 2, 2, 2, 454, 456, 7, 51, 2, 2, 455, 457, 7, 42, 2, 2, 456, 455, 3, 2, 2, 2, 456, 457, 3, 2, 2, 2, 457, 107, 3, 2, 2, 2, 458, 461, 7, 44, 2, 2, 459, 461, 5, 102, 52, 2, 460, 458, 3, 2, 2, 2, 460, 459, 3, 2, 2, 2, 461, 109, 3, 2, 2, 2, 462, 463, 9, 7, 2, 2, 463, 111, 3, 2, 2, 2, 464, 467, 7, 56, 2, 2, 465, 467, 5, 106, 54, 2, 466, 464, 3, 2, 2, 2, 466, 465, 3, 2, 2, 2, 467, 113, 3, 2, 2, 2, 48, 117, 127, 139, 144, 152, 158, 165, 175, 182, 188, 193, 200, 206, 213, 219, 225, 232, 238, 244, 276, 282, 287, 294, 309, 320, 325, 333, 338, 346, 350, 354, 358, 364, 370, 375, 377, 390, 398, 407, 429, 436, 441, 445, 456, 460, 466]
\ No newline at end of file
diff --git a/src/import/generated/FSHListener.js b/src/import/generated/FSHListener.js
index bd457cb..01ad413 100644
--- a/src/import/generated/FSHListener.js
+++ b/src/import/generated/FSHListener.js
@@ -479,6 +479,15 @@ FSHListener.prototype.exitRatio = function(ctx) {
 };
 
 
+// Enter a parse tree produced by FSHParser#reference.
+FSHListener.prototype.enterReference = function(ctx) {
+};
+
+// Exit a parse tree produced by FSHParser#reference.
+FSHListener.prototype.exitReference = function(ctx) {
+};
+
+
 // Enter a parse tree produced by FSHParser#ratioPart.
 FSHListener.prototype.enterRatioPart = function(ctx) {
 };
diff --git a/src/import/generated/FSHParser.js b/src/import/generated/FSHParser.js
index b7cb6bc..90b1ae3 100644
--- a/src/import/generated/FSHParser.js
+++ b/src/import/generated/FSHParser.js
@@ -8,7 +8,7 @@ var grammarFileName = "FSH.g4";
 
 
 var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964",
-    "\u0003;\u01cc\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004\u0004\t",
+    "\u0003;\u01d5\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004\u0004\t",
     "\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t\u0007\u0004",
     "\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004\f\t\f\u0004",
     "\r\t\r\u0004\u000e\t\u000e\u0004\u000f\t\u000f\u0004\u0010\t\u0010\u0004",
@@ -19,286 +19,294 @@ var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964",
     "\u001f\t\u001f\u0004 \t \u0004!\t!\u0004\"\t\"\u0004#\t#\u0004$\t$\u0004",
     "%\t%\u0004&\t&\u0004\'\t\'\u0004(\t(\u0004)\t)\u0004*\t*\u0004+\t+\u0004",
     ",\t,\u0004-\t-\u0004.\t.\u0004/\t/\u00040\t0\u00041\t1\u00042\t2\u0004",
-    "3\t3\u00044\t4\u00045\t5\u00046\t6\u00047\t7\u00048\t8\u0003\u0002\u0007",
-    "\u0002r\n\u0002\f\u0002\u000e\u0002u\u000b\u0002\u0003\u0003\u0003\u0003",
-    "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0005\u0003",
-    "~\n\u0003\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004",
-    "\u0003\u0005\u0003\u0005\u0003\u0005\u0006\u0005\u0088\n\u0005\r\u0005",
-    "\u000e\u0005\u0089\u0003\u0005\u0007\u0005\u008d\n\u0005\f\u0005\u000e",
-    "\u0005\u0090\u000b\u0005\u0003\u0006\u0003\u0006\u0003\u0006\u0007\u0006",
-    "\u0095\n\u0006\f\u0006\u000e\u0006\u0098\u000b\u0006\u0003\u0006\u0007",
-    "\u0006\u009b\n\u0006\f\u0006\u000e\u0006\u009e\u000b\u0006\u0003\u0007",
-    "\u0003\u0007\u0003\u0007\u0003\u0007\u0005\u0007\u00a4\n\u0007\u0003",
-    "\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0005\b\u00ae",
-    "\n\b\u0003\t\u0003\t\u0003\t\u0007\t\u00b3\n\t\f\t\u000e\t\u00b6\u000b",
-    "\t\u0003\t\u0007\t\u00b9\n\t\f\t\u000e\t\u00bc\u000b\t\u0003\n\u0003",
-    "\n\u0005\n\u00c0\n\n\u0003\u000b\u0003\u000b\u0003\u000b\u0006\u000b",
-    "\u00c5\n\u000b\r\u000b\u000e\u000b\u00c6\u0003\f\u0003\f\u0003\f\u0003",
-    "\f\u0005\f\u00cd\n\f\u0003\r\u0003\r\u0003\r\u0007\r\u00d2\n\r\f\r\u000e",
-    "\r\u00d5\u000b\r\u0003\r\u0007\r\u00d8\n\r\f\r\u000e\r\u00db\u000b\r",
-    "\u0003\u000e\u0003\u000e\u0003\u000e\u0005\u000e\u00e0\n\u000e\u0003",
-    "\u000f\u0003\u000f\u0003\u000f\u0007\u000f\u00e5\n\u000f\f\u000f\u000e",
-    "\u000f\u00e8\u000b\u000f\u0003\u000f\u0007\u000f\u00eb\n\u000f\f\u000f",
-    "\u000e\u000f\u00ee\u000b\u000f\u0003\u0010\u0003\u0010\u0003\u0010\u0005",
-    "\u0010\u00f3\n\u0010\u0003\u0011\u0003\u0011\u0003\u0011\u0003\u0012",
-    "\u0003\u0012\u0003\u0012\u0003\u0013\u0003\u0013\u0003\u0013\u0003\u0014",
-    "\u0003\u0014\u0003\u0014\u0003\u0015\u0003\u0015\u0003\u0015\u0003\u0016",
-    "\u0003\u0016\u0003\u0016\u0003\u0017\u0003\u0017\u0003\u0017\u0003\u0018",
-    "\u0003\u0018\u0003\u0018\u0003\u0019\u0003\u0019\u0003\u0019\u0003\u0019",
-    "\u0007\u0019\u0111\n\u0019\f\u0019\u000e\u0019\u0114\u000b\u0019\u0003",
-    "\u001a\u0003\u001a\u0003\u001a\u0005\u001a\u0119\n\u001a\u0003\u001a",
-    "\u0006\u001a\u011c\n\u001a\r\u001a\u000e\u001a\u011d\u0003\u001b\u0003",
-    "\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0005\u001b\u0125\n\u001b",
-    "\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001d",
-    "\u0003\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0007\u001d",
-    "\u0132\n\u001d\f\u001d\u000e\u001d\u0135\u000b\u001d\u0003\u001e\u0003",
-    "\u001e\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001e\u0007\u001e\u013d",
-    "\n\u001e\f\u001e\u000e\u001e\u0140\u000b\u001e\u0003\u001f\u0003\u001f",
-    "\u0005\u001f\u0144\n\u001f\u0003\u001f\u0003\u001f\u0003\u001f\u0003",
-    "\u001f\u0007\u001f\u014a\n\u001f\f\u001f\u000e\u001f\u014d\u000b\u001f",
-    "\u0003 \u0003 \u0005 \u0151\n \u0003 \u0003 \u0003 \u0003 \u0003!\u0003",
-    "!\u0005!\u0159\n!\u0003!\u0003!\u0005!\u015d\n!\u0003\"\u0003\"\u0005",
-    "\"\u0161\n\"\u0003\"\u0003\"\u0005\"\u0165\n\"\u0003#\u0003#\u0003#",
-    "\u0003#\u0005#\u016b\n#\u0003$\u0003$\u0003$\u0003$\u0005$\u0171\n$",
-    "\u0003$\u0003$\u0003$\u0005$\u0176\n$\u0005$\u0178\n$\u0003%\u0003%",
-    "\u0003%\u0003&\u0003&\u0003&\u0003\'\u0003\'\u0003\'\u0007\'\u0183\n",
-    "\'\f\'\u000e\'\u0186\u000b\'\u0003\'\u0003\'\u0003(\u0003(\u0003(\u0005",
-    "(\u018d\n(\u0003)\u0003)\u0003*\u0003*\u0003*\u0003*\u0003*\u0005*\u0196",
-    "\n*\u0003+\u0003+\u0003,\u0003,\u0003-\u0003-\u0003.\u0003.\u0003/\u0003",
-    "/\u00030\u00030\u00030\u00030\u00030\u00030\u00030\u00030\u00030\u0005",
-    "0\u01ab\n0\u00031\u00031\u00031\u00071\u01b0\n1\f1\u000e1\u01b3\u000b",
-    "1\u00032\u00032\u00052\u01b7\n2\u00033\u00033\u00053\u01bb\n3\u0003",
-    "4\u00034\u00034\u00035\u00035\u00035\u00035\u00036\u00036\u00056\u01c6",
-    "\n6\u00037\u00037\u00038\u00038\u00038\u0002\u00029\u0002\u0004\u0006",
-    "\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*",
-    ",.02468:<>@BDFHJLNPRTVXZ\\^`bdfhjln\u0002\t\u0003\u0002*+\u0003\u0002",
-    "78\u0004\u0002&&88\u0003\u0002\u0012\u0014\u0003\u0002\u0016\u0019\u0003",
-    "\u0002\u001f \u0004\u00023388\u0002\u01db\u0002s\u0003\u0002\u0002\u0002",
-    "\u0004}\u0003\u0002\u0002\u0002\u0006\u007f\u0003\u0002\u0002\u0002",
-    "\b\u0084\u0003\u0002\u0002\u0002\n\u0091\u0003\u0002\u0002\u0002\f\u00a3",
-    "\u0003\u0002\u0002\u0002\u000e\u00ad\u0003\u0002\u0002\u0002\u0010\u00af",
-    "\u0003\u0002\u0002\u0002\u0012\u00bf\u0003\u0002\u0002\u0002\u0014\u00c1",
-    "\u0003\u0002\u0002\u0002\u0016\u00cc\u0003\u0002\u0002\u0002\u0018\u00ce",
-    "\u0003\u0002\u0002\u0002\u001a\u00df\u0003\u0002\u0002\u0002\u001c\u00e1",
-    "\u0003\u0002\u0002\u0002\u001e\u00f2\u0003\u0002\u0002\u0002 \u00f4",
-    "\u0003\u0002\u0002\u0002\"\u00f7\u0003\u0002\u0002\u0002$\u00fa\u0003",
-    "\u0002\u0002\u0002&\u00fd\u0003\u0002\u0002\u0002(\u0100\u0003\u0002",
-    "\u0002\u0002*\u0103\u0003\u0002\u0002\u0002,\u0106\u0003\u0002\u0002",
-    "\u0002.\u0109\u0003\u0002\u0002\u00020\u010c\u0003\u0002\u0002\u0002",
-    "2\u0115\u0003\u0002\u0002\u00024\u011f\u0003\u0002\u0002\u00026\u0126",
-    "\u0003\u0002\u0002\u00028\u012b\u0003\u0002\u0002\u0002:\u0136\u0003",
-    "\u0002\u0002\u0002<\u0141\u0003\u0002\u0002\u0002>\u014e\u0003\u0002",
-    "\u0002\u0002@\u0156\u0003\u0002\u0002\u0002B\u0164\u0003\u0002\u0002",
-    "\u0002D\u0166\u0003\u0002\u0002\u0002F\u016c\u0003\u0002\u0002\u0002",
-    "H\u0179\u0003\u0002\u0002\u0002J\u017c\u0003\u0002\u0002\u0002L\u0184",
-    "\u0003\u0002\u0002\u0002N\u0189\u0003\u0002\u0002\u0002P\u018e\u0003",
-    "\u0002\u0002\u0002R\u0195\u0003\u0002\u0002\u0002T\u0197\u0003\u0002",
-    "\u0002\u0002V\u0199\u0003\u0002\u0002\u0002X\u019b\u0003\u0002\u0002",
-    "\u0002Z\u019d\u0003\u0002\u0002\u0002\\\u019f\u0003\u0002\u0002\u0002",
-    "^\u01aa\u0003\u0002\u0002\u0002`\u01ac\u0003\u0002\u0002\u0002b\u01b4",
-    "\u0003\u0002\u0002\u0002d\u01b8\u0003\u0002\u0002\u0002f\u01bc\u0003",
-    "\u0002\u0002\u0002h\u01bf\u0003\u0002\u0002\u0002j\u01c5\u0003\u0002",
-    "\u0002\u0002l\u01c7\u0003\u0002\u0002\u0002n\u01c9\u0003\u0002\u0002",
-    "\u0002pr\u0005\u0004\u0003\u0002qp\u0003\u0002\u0002\u0002ru\u0003\u0002",
-    "\u0002\u0002sq\u0003\u0002\u0002\u0002st\u0003\u0002\u0002\u0002t\u0003",
-    "\u0003\u0002\u0002\u0002us\u0003\u0002\u0002\u0002v~\u0005\u0006\u0004",
-    "\u0002w~\u0005\b\u0005\u0002x~\u0005\n\u0006\u0002y~\u0005\u0014\u000b",
-    "\u0002z~\u0005\u0010\t\u0002{~\u0005\u0018\r\u0002|~\u0005\u001c\u000f",
-    "\u0002}v\u0003\u0002\u0002\u0002}w\u0003\u0002\u0002\u0002}x\u0003\u0002",
-    "\u0002\u0002}y\u0003\u0002\u0002\u0002}z\u0003\u0002\u0002\u0002}{\u0003",
-    "\u0002\u0002\u0002}|\u0003\u0002\u0002\u0002~\u0005\u0003\u0002\u0002",
-    "\u0002\u007f\u0080\u0007\u0003\u0002\u0002\u0080\u0081\u00078\u0002",
-    "\u0002\u0081\u0082\u0007&\u0002\u0002\u0082\u0083\u00078\u0002\u0002",
-    "\u0083\u0007\u0003\u0002\u0002\u0002\u0084\u0085\u0007\u0004\u0002\u0002",
-    "\u0085\u0087\u00078\u0002\u0002\u0086\u0088\u0005\f\u0007\u0002\u0087",
-    "\u0086\u0003\u0002\u0002\u0002\u0088\u0089\u0003\u0002\u0002\u0002\u0089",
-    "\u0087\u0003\u0002\u0002\u0002\u0089\u008a\u0003\u0002\u0002\u0002\u008a",
-    "\u008e\u0003\u0002\u0002\u0002\u008b\u008d\u0005\u000e\b\u0002\u008c",
-    "\u008b\u0003\u0002\u0002\u0002\u008d\u0090\u0003\u0002\u0002\u0002\u008e",
-    "\u008c\u0003\u0002\u0002\u0002\u008e\u008f\u0003\u0002\u0002\u0002\u008f",
-    "\t\u0003\u0002\u0002\u0002\u0090\u008e\u0003\u0002\u0002\u0002\u0091",
-    "\u0092\u0007\u0005\u0002\u0002\u0092\u0096\u00078\u0002\u0002\u0093",
-    "\u0095\u0005\f\u0007\u0002\u0094\u0093\u0003\u0002\u0002\u0002\u0095",
-    "\u0098\u0003\u0002\u0002\u0002\u0096\u0094\u0003\u0002\u0002\u0002\u0096",
-    "\u0097\u0003\u0002\u0002\u0002\u0097\u009c\u0003\u0002\u0002\u0002\u0098",
-    "\u0096\u0003\u0002\u0002\u0002\u0099\u009b\u0005\u000e\b\u0002\u009a",
-    "\u0099\u0003\u0002\u0002\u0002\u009b\u009e\u0003\u0002\u0002\u0002\u009c",
-    "\u009a\u0003\u0002\u0002\u0002\u009c\u009d\u0003\u0002\u0002\u0002\u009d",
-    "\u000b\u0003\u0002\u0002\u0002\u009e\u009c\u0003\u0002\u0002\u0002\u009f",
-    "\u00a4\u0005 \u0011\u0002\u00a0\u00a4\u0005\"\u0012\u0002\u00a1\u00a4",
-    "\u0005$\u0013\u0002\u00a2\u00a4\u0005&\u0014\u0002\u00a3\u009f\u0003",
-    "\u0002\u0002\u0002\u00a3\u00a0\u0003\u0002\u0002\u0002\u00a3\u00a1\u0003",
-    "\u0002\u0002\u0002\u00a3\u00a2\u0003\u0002\u0002\u0002\u00a4\r\u0003",
-    "\u0002\u0002\u0002\u00a5\u00ae\u00050\u0019\u0002\u00a6\u00ae\u0005",
-    "2\u001a\u0002\u00a7\u00ae\u00054\u001b\u0002\u00a8\u00ae\u00056\u001c",
-    "\u0002\u00a9\u00ae\u00058\u001d\u0002\u00aa\u00ae\u0005:\u001e\u0002",
-    "\u00ab\u00ae\u0005<\u001f\u0002\u00ac\u00ae\u0005> \u0002\u00ad\u00a5",
-    "\u0003\u0002\u0002\u0002\u00ad\u00a6\u0003\u0002\u0002\u0002\u00ad\u00a7",
-    "\u0003\u0002\u0002\u0002\u00ad\u00a8\u0003\u0002\u0002\u0002\u00ad\u00a9",
-    "\u0003\u0002\u0002\u0002\u00ad\u00aa\u0003\u0002\u0002\u0002\u00ad\u00ab",
-    "\u0003\u0002\u0002\u0002\u00ad\u00ac\u0003\u0002\u0002\u0002\u00ae\u000f",
-    "\u0003\u0002\u0002\u0002\u00af\u00b0\u0007\u0006\u0002\u0002\u00b0\u00b4",
-    "\u00078\u0002\u0002\u00b1\u00b3\u0005\u0012\n\u0002\u00b2\u00b1\u0003",
-    "\u0002\u0002\u0002\u00b3\u00b6\u0003\u0002\u0002\u0002\u00b4\u00b2\u0003",
-    "\u0002\u0002\u0002\u00b4\u00b5\u0003\u0002\u0002\u0002\u00b5\u00ba\u0003",
-    "\u0002\u0002\u0002\u00b6\u00b4\u0003\u0002\u0002\u0002\u00b7\u00b9\u0005",
-    "6\u001c\u0002\u00b8\u00b7\u0003\u0002\u0002\u0002\u00b9\u00bc\u0003",
-    "\u0002\u0002\u0002\u00ba\u00b8\u0003\u0002\u0002\u0002\u00ba\u00bb\u0003",
-    "\u0002\u0002\u0002\u00bb\u0011\u0003\u0002\u0002\u0002\u00bc\u00ba\u0003",
-    "\u0002\u0002\u0002\u00bd\u00c0\u0005.\u0018\u0002\u00be\u00c0\u0005",
-    "$\u0013\u0002\u00bf\u00bd\u0003\u0002\u0002\u0002\u00bf\u00be\u0003",
-    "\u0002\u0002\u0002\u00c0\u0013\u0003\u0002\u0002\u0002\u00c1\u00c2\u0007",
-    "\b\u0002\u0002\u00c2\u00c4\u00078\u0002\u0002\u00c3\u00c5\u0005\u0016",
-    "\f\u0002\u00c4\u00c3\u0003\u0002\u0002\u0002\u00c5\u00c6\u0003\u0002",
-    "\u0002\u0002\u00c6\u00c4\u0003\u0002\u0002\u0002\u00c6\u00c7\u0003\u0002",
-    "\u0002\u0002\u00c7\u0015\u0003\u0002\u0002\u0002\u00c8\u00cd\u0005&",
-    "\u0014\u0002\u00c9\u00cd\u0005(\u0015\u0002\u00ca\u00cd\u0005*\u0016",
-    "\u0002\u00cb\u00cd\u0005,\u0017\u0002\u00cc\u00c8\u0003\u0002\u0002",
-    "\u0002\u00cc\u00c9\u0003\u0002\u0002\u0002\u00cc\u00ca\u0003\u0002\u0002",
-    "\u0002\u00cc\u00cb\u0003\u0002\u0002\u0002\u00cd\u0017\u0003\u0002\u0002",
-    "\u0002\u00ce\u00cf\u0007\t\u0002\u0002\u00cf\u00d3\u00078\u0002\u0002",
-    "\u00d0\u00d2\u0005\u001a\u000e\u0002\u00d1\u00d0\u0003\u0002\u0002\u0002",
-    "\u00d2\u00d5\u0003\u0002\u0002\u0002\u00d3\u00d1\u0003\u0002\u0002\u0002",
-    "\u00d3\u00d4\u0003\u0002\u0002\u0002\u00d4\u00d9\u0003\u0002\u0002\u0002",
-    "\u00d5\u00d3\u0003\u0002\u0002\u0002\u00d6\u00d8\u0005@!\u0002\u00d7",
-    "\u00d6\u0003\u0002\u0002\u0002\u00d8\u00db\u0003\u0002\u0002\u0002\u00d9",
-    "\u00d7\u0003\u0002\u0002\u0002\u00d9\u00da\u0003\u0002\u0002\u0002\u00da",
-    "\u0019\u0003\u0002\u0002\u0002\u00db\u00d9\u0003\u0002\u0002\u0002\u00dc",
-    "\u00e0\u0005\"\u0012\u0002\u00dd\u00e0\u0005$\u0013\u0002\u00de\u00e0",
-    "\u0005&\u0014\u0002\u00df\u00dc\u0003\u0002\u0002\u0002\u00df\u00dd",
-    "\u0003\u0002\u0002\u0002\u00df\u00de\u0003\u0002\u0002\u0002\u00e0\u001b",
-    "\u0003\u0002\u0002\u0002\u00e1\u00e2\u0007\n\u0002\u0002\u00e2\u00e6",
-    "\u00078\u0002\u0002\u00e3\u00e5\u0005\u001e\u0010\u0002\u00e4\u00e3",
-    "\u0003\u0002\u0002\u0002\u00e5\u00e8\u0003\u0002\u0002\u0002\u00e6\u00e4",
-    "\u0003\u0002\u0002\u0002\u00e6\u00e7\u0003\u0002\u0002\u0002\u00e7\u00ec",
-    "\u0003\u0002\u0002\u0002\u00e8\u00e6\u0003\u0002\u0002\u0002\u00e9\u00eb",
-    "\u0005d3\u0002\u00ea\u00e9\u0003\u0002\u0002\u0002\u00eb\u00ee\u0003",
-    "\u0002\u0002\u0002\u00ec\u00ea\u0003\u0002\u0002\u0002\u00ec\u00ed\u0003",
-    "\u0002\u0002\u0002\u00ed\u001d\u0003\u0002\u0002\u0002\u00ee\u00ec\u0003",
-    "\u0002\u0002\u0002\u00ef\u00f3\u0005\"\u0012\u0002\u00f0\u00f3\u0005",
-    "$\u0013\u0002\u00f1\u00f3\u0005&\u0014\u0002\u00f2\u00ef\u0003\u0002",
-    "\u0002\u0002\u00f2\u00f0\u0003\u0002\u0002\u0002\u00f2\u00f1\u0003\u0002",
-    "\u0002\u0002\u00f3\u001f\u0003\u0002\u0002\u0002\u00f4\u00f5\u0007\u000b",
-    "\u0002\u0002\u00f5\u00f6\u00078\u0002\u0002\u00f6!\u0003\u0002\u0002",
-    "\u0002\u00f7\u00f8\u0007\f\u0002\u0002\u00f8\u00f9\u00078\u0002\u0002",
-    "\u00f9#\u0003\u0002\u0002\u0002\u00fa\u00fb\u0007\r\u0002\u0002\u00fb",
-    "\u00fc\u0007*\u0002\u0002\u00fc%\u0003\u0002\u0002\u0002\u00fd\u00fe",
-    "\u0007\u000e\u0002\u0002\u00fe\u00ff\t\u0002\u0002\u0002\u00ff\'\u0003",
-    "\u0002\u0002\u0002\u0100\u0101\u0007\u000f\u0002\u0002\u0101\u0102\u0007",
-    "*\u0002\u0002\u0102)\u0003\u0002\u0002\u0002\u0103\u0104\u0007\u0010",
-    "\u0002\u0002\u0104\u0105\u0007*\u0002\u0002\u0105+\u0003\u0002\u0002",
-    "\u0002\u0106\u0107\u0007\u0011\u0002\u0002\u0107\u0108\u0007.\u0002",
-    "\u0002\u0108-\u0003\u0002\u0002\u0002\u0109\u010a\u0007\u0007\u0002",
-    "\u0002\u010a\u010b\u00078\u0002\u0002\u010b/\u0003\u0002\u0002\u0002",
-    "\u010c\u010d\u0007\'\u0002\u0002\u010d\u010e\u0005T+\u0002\u010e\u0112",
-    "\u00072\u0002\u0002\u010f\u0111\u0005Z.\u0002\u0110\u010f\u0003\u0002",
-    "\u0002\u0002\u0111\u0114\u0003\u0002\u0002\u0002\u0112\u0110\u0003\u0002",
-    "\u0002\u0002\u0112\u0113\u0003\u0002\u0002\u0002\u01131\u0003\u0002",
-    "\u0002\u0002\u0114\u0112\u0003\u0002\u0002\u0002\u0115\u0118\u0007\'",
-    "\u0002\u0002\u0116\u0119\u0005T+\u0002\u0117\u0119\u0005V,\u0002\u0118",
-    "\u0116\u0003\u0002\u0002\u0002\u0118\u0117\u0003\u0002\u0002\u0002\u0119",
-    "\u011b\u0003\u0002\u0002\u0002\u011a\u011c\u0005Z.\u0002\u011b\u011a",
-    "\u0003\u0002\u0002\u0002\u011c\u011d\u0003\u0002\u0002\u0002\u011d\u011b",
-    "\u0003\u0002\u0002\u0002\u011d\u011e\u0003\u0002\u0002\u0002\u011e3",
-    "\u0003\u0002\u0002\u0002\u011f\u0120\u0007\'\u0002\u0002\u0120\u0121",
-    "\u0005T+\u0002\u0121\u0122\u0007\u0015\u0002\u0002\u0122\u0124\u0007",
-    "8\u0002\u0002\u0123\u0125\u0005\\/\u0002\u0124\u0123\u0003\u0002\u0002",
-    "\u0002\u0124\u0125\u0003\u0002\u0002\u0002\u01255\u0003\u0002\u0002",
-    "\u0002\u0126\u0127\u0007\'\u0002\u0002\u0127\u0128\u0005T+\u0002\u0128",
-    "\u0129\u0007&\u0002\u0002\u0129\u012a\u0005^0\u0002\u012a7\u0003\u0002",
-    "\u0002\u0002\u012b\u012c\u0007\'\u0002\u0002\u012c\u012d\u0005T+\u0002",
-    "\u012d\u012e\u0007\u001a\u0002\u0002\u012e\u0133\u0005`1\u0002\u012f",
-    "\u0130\u0007\u001b\u0002\u0002\u0130\u0132\u0005`1\u0002\u0131\u012f",
-    "\u0003\u0002\u0002\u0002\u0132\u0135\u0003\u0002\u0002\u0002\u0133\u0131",
-    "\u0003\u0002\u0002\u0002\u0133\u0134\u0003\u0002\u0002\u0002\u01349",
-    "\u0003\u0002\u0002\u0002\u0135\u0133\u0003\u0002\u0002\u0002\u0136\u0137",
-    "\u0007\'\u0002\u0002\u0137\u0138\u0005T+\u0002\u0138\u0139\u0007\u001c",
-    "\u0002\u0002\u0139\u013e\u0005n8\u0002\u013a\u013b\u0007\u001d\u0002",
-    "\u0002\u013b\u013d\u0005n8\u0002\u013c\u013a\u0003\u0002\u0002\u0002",
-    "\u013d\u0140\u0003\u0002\u0002\u0002\u013e\u013c\u0003\u0002\u0002\u0002",
-    "\u013e\u013f\u0003\u0002\u0002\u0002\u013f;\u0003\u0002\u0002\u0002",
-    "\u0140\u013e\u0003\u0002\u0002\u0002\u0141\u0143\u0007\'\u0002\u0002",
-    "\u0142\u0144\u0005T+\u0002\u0143\u0142\u0003\u0002\u0002\u0002\u0143",
-    "\u0144\u0003\u0002\u0002\u0002\u0144\u0145\u0003\u0002\u0002\u0002\u0145",
-    "\u0146\u0007\u001e\u0002\u0002\u0146\u014b\u00078\u0002\u0002\u0147",
-    "\u0148\u0007\u001b\u0002\u0002\u0148\u014a\u00078\u0002\u0002\u0149",
-    "\u0147\u0003\u0002\u0002\u0002\u014a\u014d\u0003\u0002\u0002\u0002\u014b",
-    "\u0149\u0003\u0002\u0002\u0002\u014b\u014c\u0003\u0002\u0002\u0002\u014c",
-    "=\u0003\u0002\u0002\u0002\u014d\u014b\u0003\u0002\u0002\u0002\u014e",
-    "\u0150\u0007\'\u0002\u0002\u014f\u0151\u0005T+\u0002\u0150\u014f\u0003",
-    "\u0002\u0002\u0002\u0150\u0151\u0003\u0002\u0002\u0002\u0151\u0152\u0003",
-    "\u0002\u0002\u0002\u0152\u0153\u0005X-\u0002\u0153\u0154\u0007&\u0002",
-    "\u0002\u0154\u0155\u0005^0\u0002\u0155?\u0003\u0002\u0002\u0002\u0156",
-    "\u0158\u0007\'\u0002\u0002\u0157\u0159\u0007!\u0002\u0002\u0158\u0157",
-    "\u0003\u0002\u0002\u0002\u0158\u0159\u0003\u0002\u0002\u0002\u0159\u015c",
-    "\u0003\u0002\u0002\u0002\u015a\u015d\u0005B\"\u0002\u015b\u015d\u0005",
-    "D#\u0002\u015c\u015a\u0003\u0002\u0002\u0002\u015c\u015b\u0003\u0002",
-    "\u0002\u0002\u015dA\u0003\u0002\u0002\u0002\u015e\u0160\u0005b2\u0002",
-    "\u015f\u0161\u0005F$\u0002\u0160\u015f\u0003\u0002\u0002\u0002\u0160",
-    "\u0161\u0003\u0002\u0002\u0002\u0161\u0165\u0003\u0002\u0002\u0002\u0162",
-    "\u0163\u00076\u0002\u0002\u0163\u0165\u0005F$\u0002\u0164\u015e\u0003",
-    "\u0002\u0002\u0002\u0164\u0162\u0003\u0002\u0002\u0002\u0165C\u0003",
-    "\u0002\u0002\u0002\u0166\u0167\u0007\"\u0002\u0002\u0167\u016a\u0005",
-    "F$\u0002\u0168\u0169\u0007#\u0002\u0002\u0169\u016b\u0005L\'\u0002\u016a",
-    "\u0168\u0003\u0002\u0002\u0002\u016a\u016b\u0003\u0002\u0002\u0002\u016b",
-    "E\u0003\u0002\u0002\u0002\u016c\u0177\u0007\u0015\u0002\u0002\u016d",
-    "\u0170\u0005H%\u0002\u016e\u016f\u0007\u001b\u0002\u0002\u016f\u0171",
-    "\u0005J&\u0002\u0170\u016e\u0003\u0002\u0002\u0002\u0170\u0171\u0003",
-    "\u0002\u0002\u0002\u0171\u0178\u0003\u0002\u0002\u0002\u0172\u0175\u0005",
-    "J&\u0002\u0173\u0174\u0007\u001b\u0002\u0002\u0174\u0176\u0005H%\u0002",
-    "\u0175\u0173\u0003\u0002\u0002\u0002\u0175\u0176\u0003\u0002\u0002\u0002",
-    "\u0176\u0178\u0003\u0002\u0002\u0002\u0177\u016d\u0003\u0002\u0002\u0002",
-    "\u0177\u0172\u0003\u0002\u0002\u0002\u0178G\u0003\u0002\u0002\u0002",
-    "\u0179\u017a\u0007%\u0002\u0002\u017a\u017b\u00078\u0002\u0002\u017b",
-    "I\u0003\u0002\u0002\u0002\u017c\u017d\u0007$\u0002\u0002\u017d\u017e",
-    "\t\u0003\u0002\u0002\u017eK\u0003\u0002\u0002\u0002\u017f\u0180\u0005",
-    "N(\u0002\u0180\u0181\u0007\u001b\u0002\u0002\u0181\u0183\u0003\u0002",
-    "\u0002\u0002\u0182\u017f\u0003\u0002\u0002\u0002\u0183\u0186\u0003\u0002",
-    "\u0002\u0002\u0184\u0182\u0003\u0002\u0002\u0002\u0184\u0185\u0003\u0002",
-    "\u0002\u0002\u0185\u0187\u0003\u0002\u0002\u0002\u0186\u0184\u0003\u0002",
-    "\u0002\u0002\u0187\u0188\u0005N(\u0002\u0188M\u0003\u0002\u0002\u0002",
-    "\u0189\u018a\u00078\u0002\u0002\u018a\u018c\u0005P)\u0002\u018b\u018d",
-    "\u0005R*\u0002\u018c\u018b\u0003\u0002\u0002\u0002\u018c\u018d\u0003",
-    "\u0002\u0002\u0002\u018dO\u0003\u0002\u0002\u0002\u018e\u018f\t\u0004",
-    "\u0002\u0002\u018fQ\u0003\u0002\u0002\u0002\u0190\u0196\u0005b2\u0002",
-    "\u0191\u0196\u0007\u001f\u0002\u0002\u0192\u0196\u0007 \u0002\u0002",
-    "\u0193\u0196\u00075\u0002\u0002\u0194\u0196\u0007*\u0002\u0002\u0195",
-    "\u0190\u0003\u0002\u0002\u0002\u0195\u0191\u0003\u0002\u0002\u0002\u0195",
-    "\u0192\u0003\u0002\u0002\u0002\u0195\u0193\u0003\u0002\u0002\u0002\u0195",
-    "\u0194\u0003\u0002\u0002\u0002\u0196S\u0003\u0002\u0002\u0002\u0197",
-    "\u0198\u00078\u0002\u0002\u0198U\u0003\u0002\u0002\u0002\u0199\u019a",
-    "\u00077\u0002\u0002\u019aW\u0003\u0002\u0002\u0002\u019b\u019c\u0007",
-    "4\u0002\u0002\u019cY\u0003\u0002\u0002\u0002\u019d\u019e\t\u0005\u0002",
-    "\u0002\u019e[\u0003\u0002\u0002\u0002\u019f\u01a0\t\u0006\u0002\u0002",
-    "\u01a0]\u0003\u0002\u0002\u0002\u01a1\u01ab\u0007*\u0002\u0002\u01a2",
-    "\u01ab\u0007+\u0002\u0002\u01a3\u01ab\u0007,\u0002\u0002\u01a4\u01ab",
-    "\u00070\u0002\u0002\u01a5\u01ab\u00071\u0002\u0002\u01a6\u01ab\u0005",
-    "b2\u0002\u01a7\u01ab\u0005f4\u0002\u01a8\u01ab\u0005h5\u0002\u01a9\u01ab",
-    "\u0005l7\u0002\u01aa\u01a1\u0003\u0002\u0002\u0002\u01aa\u01a2\u0003",
-    "\u0002\u0002\u0002\u01aa\u01a3\u0003\u0002\u0002\u0002\u01aa\u01a4\u0003",
-    "\u0002\u0002\u0002\u01aa\u01a5\u0003\u0002\u0002\u0002\u01aa\u01a6\u0003",
-    "\u0002\u0002\u0002\u01aa\u01a7\u0003\u0002\u0002\u0002\u01aa\u01a8\u0003",
-    "\u0002\u0002\u0002\u01aa\u01a9\u0003\u0002\u0002\u0002\u01ab_\u0003",
-    "\u0002\u0002\u0002\u01ac\u01ad\u00078\u0002\u0002\u01ad\u01b1\u0007",
-    "2\u0002\u0002\u01ae\u01b0\u0005Z.\u0002\u01af\u01ae\u0003\u0002\u0002",
-    "\u0002\u01b0\u01b3\u0003\u0002\u0002\u0002\u01b1\u01af\u0003\u0002\u0002",
-    "\u0002\u01b1\u01b2\u0003\u0002\u0002\u0002\u01b2a\u0003\u0002\u0002",
-    "\u0002\u01b3\u01b1\u0003\u0002\u0002\u0002\u01b4\u01b6\u0007.\u0002",
-    "\u0002\u01b5\u01b7\u0007*\u0002\u0002\u01b6\u01b5\u0003\u0002\u0002",
-    "\u0002\u01b6\u01b7\u0003\u0002\u0002\u0002\u01b7c\u0003\u0002\u0002",
-    "\u0002\u01b8\u01ba\u0005b2\u0002\u01b9\u01bb\u0007*\u0002\u0002\u01ba",
-    "\u01b9\u0003\u0002\u0002\u0002\u01ba\u01bb\u0003\u0002\u0002\u0002\u01bb",
-    "e\u0003\u0002\u0002\u0002\u01bc\u01bd\u0007,\u0002\u0002\u01bd\u01be",
-    "\u0007-\u0002\u0002\u01beg\u0003\u0002\u0002\u0002\u01bf\u01c0\u0005",
-    "j6\u0002\u01c0\u01c1\u0007(\u0002\u0002\u01c1\u01c2\u0005j6\u0002\u01c2",
-    "i\u0003\u0002\u0002\u0002\u01c3\u01c6\u0007,\u0002\u0002\u01c4\u01c6",
-    "\u0005f4\u0002\u01c5\u01c3\u0003\u0002\u0002\u0002\u01c5\u01c4\u0003",
-    "\u0002\u0002\u0002\u01c6k\u0003\u0002\u0002\u0002\u01c7\u01c8\t\u0007",
-    "\u0002\u0002\u01c8m\u0003\u0002\u0002\u0002\u01c9\u01ca\t\b\u0002\u0002",
-    "\u01cao\u0003\u0002\u0002\u0002.s}\u0089\u008e\u0096\u009c\u00a3\u00ad",
-    "\u00b4\u00ba\u00bf\u00c6\u00cc\u00d3\u00d9\u00df\u00e6\u00ec\u00f2\u0112",
-    "\u0118\u011d\u0124\u0133\u013e\u0143\u014b\u0150\u0158\u015c\u0160\u0164",
-    "\u016a\u0170\u0175\u0177\u0184\u018c\u0195\u01aa\u01b1\u01b6\u01ba\u01c5"].join("");
+    "3\t3\u00044\t4\u00045\t5\u00046\t6\u00047\t7\u00048\t8\u00049\t9\u0003",
+    "\u0002\u0007\u0002t\n\u0002\f\u0002\u000e\u0002w\u000b\u0002\u0003\u0003",
+    "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003",
+    "\u0005\u0003\u0080\n\u0003\u0003\u0004\u0003\u0004\u0003\u0004\u0003",
+    "\u0004\u0003\u0004\u0003\u0005\u0003\u0005\u0003\u0005\u0006\u0005\u008a",
+    "\n\u0005\r\u0005\u000e\u0005\u008b\u0003\u0005\u0007\u0005\u008f\n\u0005",
+    "\f\u0005\u000e\u0005\u0092\u000b\u0005\u0003\u0006\u0003\u0006\u0003",
+    "\u0006\u0007\u0006\u0097\n\u0006\f\u0006\u000e\u0006\u009a\u000b\u0006",
+    "\u0003\u0006\u0007\u0006\u009d\n\u0006\f\u0006\u000e\u0006\u00a0\u000b",
+    "\u0006\u0003\u0007\u0003\u0007\u0003\u0007\u0003\u0007\u0005\u0007\u00a6",
+    "\n\u0007\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003",
+    "\b\u0005\b\u00b0\n\b\u0003\t\u0003\t\u0003\t\u0007\t\u00b5\n\t\f\t\u000e",
+    "\t\u00b8\u000b\t\u0003\t\u0007\t\u00bb\n\t\f\t\u000e\t\u00be\u000b\t",
+    "\u0003\n\u0003\n\u0005\n\u00c2\n\n\u0003\u000b\u0003\u000b\u0003\u000b",
+    "\u0006\u000b\u00c7\n\u000b\r\u000b\u000e\u000b\u00c8\u0003\f\u0003\f",
+    "\u0003\f\u0003\f\u0005\f\u00cf\n\f\u0003\r\u0003\r\u0003\r\u0007\r\u00d4",
+    "\n\r\f\r\u000e\r\u00d7\u000b\r\u0003\r\u0007\r\u00da\n\r\f\r\u000e\r",
+    "\u00dd\u000b\r\u0003\u000e\u0003\u000e\u0003\u000e\u0005\u000e\u00e2",
+    "\n\u000e\u0003\u000f\u0003\u000f\u0003\u000f\u0007\u000f\u00e7\n\u000f",
+    "\f\u000f\u000e\u000f\u00ea\u000b\u000f\u0003\u000f\u0007\u000f\u00ed",
+    "\n\u000f\f\u000f\u000e\u000f\u00f0\u000b\u000f\u0003\u0010\u0003\u0010",
+    "\u0003\u0010\u0005\u0010\u00f5\n\u0010\u0003\u0011\u0003\u0011\u0003",
+    "\u0011\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0013\u0003\u0013\u0003",
+    "\u0013\u0003\u0014\u0003\u0014\u0003\u0014\u0003\u0015\u0003\u0015\u0003",
+    "\u0015\u0003\u0016\u0003\u0016\u0003\u0016\u0003\u0017\u0003\u0017\u0003",
+    "\u0017\u0003\u0018\u0003\u0018\u0003\u0018\u0003\u0019\u0003\u0019\u0003",
+    "\u0019\u0003\u0019\u0007\u0019\u0113\n\u0019\f\u0019\u000e\u0019\u0116",
+    "\u000b\u0019\u0003\u001a\u0003\u001a\u0003\u001a\u0005\u001a\u011b\n",
+    "\u001a\u0003\u001a\u0006\u001a\u011e\n\u001a\r\u001a\u000e\u001a\u011f",
+    "\u0003\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0005\u001b",
+    "\u0127\n\u001b\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003",
+    "\u001c\u0003\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0003",
+    "\u001d\u0007\u001d\u0134\n\u001d\f\u001d\u000e\u001d\u0137\u000b\u001d",
+    "\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001e",
+    "\u0007\u001e\u013f\n\u001e\f\u001e\u000e\u001e\u0142\u000b\u001e\u0003",
+    "\u001f\u0003\u001f\u0005\u001f\u0146\n\u001f\u0003\u001f\u0003\u001f",
+    "\u0003\u001f\u0003\u001f\u0007\u001f\u014c\n\u001f\f\u001f\u000e\u001f",
+    "\u014f\u000b\u001f\u0003 \u0003 \u0005 \u0153\n \u0003 \u0003 \u0003",
+    " \u0003 \u0003!\u0003!\u0005!\u015b\n!\u0003!\u0003!\u0005!\u015f\n",
+    "!\u0003\"\u0003\"\u0005\"\u0163\n\"\u0003\"\u0003\"\u0005\"\u0167\n",
+    "\"\u0003#\u0003#\u0003#\u0003#\u0005#\u016d\n#\u0003$\u0003$\u0003$",
+    "\u0003$\u0005$\u0173\n$\u0003$\u0003$\u0003$\u0005$\u0178\n$\u0005$",
+    "\u017a\n$\u0003%\u0003%\u0003%\u0003&\u0003&\u0003&\u0003\'\u0003\'",
+    "\u0003\'\u0007\'\u0185\n\'\f\'\u000e\'\u0188\u000b\'\u0003\'\u0003\'",
+    "\u0003(\u0003(\u0003(\u0005(\u018f\n(\u0003)\u0003)\u0003*\u0003*\u0003",
+    "*\u0003*\u0003*\u0005*\u0198\n*\u0003+\u0003+\u0003,\u0003,\u0003-\u0003",
+    "-\u0003.\u0003.\u0003/\u0003/\u00030\u00030\u00030\u00030\u00030\u0003",
+    "0\u00030\u00030\u00030\u00030\u00050\u01ae\n0\u00031\u00031\u00031\u0007",
+    "1\u01b3\n1\f1\u000e1\u01b6\u000b1\u00032\u00032\u00052\u01ba\n2\u0003",
+    "3\u00033\u00053\u01be\n3\u00034\u00034\u00034\u00035\u00035\u00035\u0003",
+    "5\u00036\u00036\u00056\u01c9\n6\u00037\u00037\u00057\u01cd\n7\u0003",
+    "8\u00038\u00039\u00039\u00059\u01d3\n9\u00039\u0002\u0002:\u0002\u0004",
+    "\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e ",
+    "\"$&(*,.02468:<>@BDFHJLNPRTVXZ\\^`bdfhjlnp\u0002\b\u0003\u0002*+\u0003",
+    "\u000278\u0004\u0002&&88\u0003\u0002\u0012\u0014\u0003\u0002\u0016\u0019",
+    "\u0003\u0002\u001f \u0002\u01e6\u0002u\u0003\u0002\u0002\u0002\u0004",
+    "\u007f\u0003\u0002\u0002\u0002\u0006\u0081\u0003\u0002\u0002\u0002\b",
+    "\u0086\u0003\u0002\u0002\u0002\n\u0093\u0003\u0002\u0002\u0002\f\u00a5",
+    "\u0003\u0002\u0002\u0002\u000e\u00af\u0003\u0002\u0002\u0002\u0010\u00b1",
+    "\u0003\u0002\u0002\u0002\u0012\u00c1\u0003\u0002\u0002\u0002\u0014\u00c3",
+    "\u0003\u0002\u0002\u0002\u0016\u00ce\u0003\u0002\u0002\u0002\u0018\u00d0",
+    "\u0003\u0002\u0002\u0002\u001a\u00e1\u0003\u0002\u0002\u0002\u001c\u00e3",
+    "\u0003\u0002\u0002\u0002\u001e\u00f4\u0003\u0002\u0002\u0002 \u00f6",
+    "\u0003\u0002\u0002\u0002\"\u00f9\u0003\u0002\u0002\u0002$\u00fc\u0003",
+    "\u0002\u0002\u0002&\u00ff\u0003\u0002\u0002\u0002(\u0102\u0003\u0002",
+    "\u0002\u0002*\u0105\u0003\u0002\u0002\u0002,\u0108\u0003\u0002\u0002",
+    "\u0002.\u010b\u0003\u0002\u0002\u00020\u010e\u0003\u0002\u0002\u0002",
+    "2\u0117\u0003\u0002\u0002\u00024\u0121\u0003\u0002\u0002\u00026\u0128",
+    "\u0003\u0002\u0002\u00028\u012d\u0003\u0002\u0002\u0002:\u0138\u0003",
+    "\u0002\u0002\u0002<\u0143\u0003\u0002\u0002\u0002>\u0150\u0003\u0002",
+    "\u0002\u0002@\u0158\u0003\u0002\u0002\u0002B\u0166\u0003\u0002\u0002",
+    "\u0002D\u0168\u0003\u0002\u0002\u0002F\u016e\u0003\u0002\u0002\u0002",
+    "H\u017b\u0003\u0002\u0002\u0002J\u017e\u0003\u0002\u0002\u0002L\u0186",
+    "\u0003\u0002\u0002\u0002N\u018b\u0003\u0002\u0002\u0002P\u0190\u0003",
+    "\u0002\u0002\u0002R\u0197\u0003\u0002\u0002\u0002T\u0199\u0003\u0002",
+    "\u0002\u0002V\u019b\u0003\u0002\u0002\u0002X\u019d\u0003\u0002\u0002",
+    "\u0002Z\u019f\u0003\u0002\u0002\u0002\\\u01a1\u0003\u0002\u0002\u0002",
+    "^\u01ad\u0003\u0002\u0002\u0002`\u01af\u0003\u0002\u0002\u0002b\u01b7",
+    "\u0003\u0002\u0002\u0002d\u01bb\u0003\u0002\u0002\u0002f\u01bf\u0003",
+    "\u0002\u0002\u0002h\u01c2\u0003\u0002\u0002\u0002j\u01c6\u0003\u0002",
+    "\u0002\u0002l\u01cc\u0003\u0002\u0002\u0002n\u01ce\u0003\u0002\u0002",
+    "\u0002p\u01d2\u0003\u0002\u0002\u0002rt\u0005\u0004\u0003\u0002sr\u0003",
+    "\u0002\u0002\u0002tw\u0003\u0002\u0002\u0002us\u0003\u0002\u0002\u0002",
+    "uv\u0003\u0002\u0002\u0002v\u0003\u0003\u0002\u0002\u0002wu\u0003\u0002",
+    "\u0002\u0002x\u0080\u0005\u0006\u0004\u0002y\u0080\u0005\b\u0005\u0002",
+    "z\u0080\u0005\n\u0006\u0002{\u0080\u0005\u0014\u000b\u0002|\u0080\u0005",
+    "\u0010\t\u0002}\u0080\u0005\u0018\r\u0002~\u0080\u0005\u001c\u000f\u0002",
+    "\u007fx\u0003\u0002\u0002\u0002\u007fy\u0003\u0002\u0002\u0002\u007f",
+    "z\u0003\u0002\u0002\u0002\u007f{\u0003\u0002\u0002\u0002\u007f|\u0003",
+    "\u0002\u0002\u0002\u007f}\u0003\u0002\u0002\u0002\u007f~\u0003\u0002",
+    "\u0002\u0002\u0080\u0005\u0003\u0002\u0002\u0002\u0081\u0082\u0007\u0003",
+    "\u0002\u0002\u0082\u0083\u00078\u0002\u0002\u0083\u0084\u0007&\u0002",
+    "\u0002\u0084\u0085\u00078\u0002\u0002\u0085\u0007\u0003\u0002\u0002",
+    "\u0002\u0086\u0087\u0007\u0004\u0002\u0002\u0087\u0089\u00078\u0002",
+    "\u0002\u0088\u008a\u0005\f\u0007\u0002\u0089\u0088\u0003\u0002\u0002",
+    "\u0002\u008a\u008b\u0003\u0002\u0002\u0002\u008b\u0089\u0003\u0002\u0002",
+    "\u0002\u008b\u008c\u0003\u0002\u0002\u0002\u008c\u0090\u0003\u0002\u0002",
+    "\u0002\u008d\u008f\u0005\u000e\b\u0002\u008e\u008d\u0003\u0002\u0002",
+    "\u0002\u008f\u0092\u0003\u0002\u0002\u0002\u0090\u008e\u0003\u0002\u0002",
+    "\u0002\u0090\u0091\u0003\u0002\u0002\u0002\u0091\t\u0003\u0002\u0002",
+    "\u0002\u0092\u0090\u0003\u0002\u0002\u0002\u0093\u0094\u0007\u0005\u0002",
+    "\u0002\u0094\u0098\u00078\u0002\u0002\u0095\u0097\u0005\f\u0007\u0002",
+    "\u0096\u0095\u0003\u0002\u0002\u0002\u0097\u009a\u0003\u0002\u0002\u0002",
+    "\u0098\u0096\u0003\u0002\u0002\u0002\u0098\u0099\u0003\u0002\u0002\u0002",
+    "\u0099\u009e\u0003\u0002\u0002\u0002\u009a\u0098\u0003\u0002\u0002\u0002",
+    "\u009b\u009d\u0005\u000e\b\u0002\u009c\u009b\u0003\u0002\u0002\u0002",
+    "\u009d\u00a0\u0003\u0002\u0002\u0002\u009e\u009c\u0003\u0002\u0002\u0002",
+    "\u009e\u009f\u0003\u0002\u0002\u0002\u009f\u000b\u0003\u0002\u0002\u0002",
+    "\u00a0\u009e\u0003\u0002\u0002\u0002\u00a1\u00a6\u0005 \u0011\u0002",
+    "\u00a2\u00a6\u0005\"\u0012\u0002\u00a3\u00a6\u0005$\u0013\u0002\u00a4",
+    "\u00a6\u0005&\u0014\u0002\u00a5\u00a1\u0003\u0002\u0002\u0002\u00a5",
+    "\u00a2\u0003\u0002\u0002\u0002\u00a5\u00a3\u0003\u0002\u0002\u0002\u00a5",
+    "\u00a4\u0003\u0002\u0002\u0002\u00a6\r\u0003\u0002\u0002\u0002\u00a7",
+    "\u00b0\u00050\u0019\u0002\u00a8\u00b0\u00052\u001a\u0002\u00a9\u00b0",
+    "\u00054\u001b\u0002\u00aa\u00b0\u00056\u001c\u0002\u00ab\u00b0\u0005",
+    "8\u001d\u0002\u00ac\u00b0\u0005:\u001e\u0002\u00ad\u00b0\u0005<\u001f",
+    "\u0002\u00ae\u00b0\u0005> \u0002\u00af\u00a7\u0003\u0002\u0002\u0002",
+    "\u00af\u00a8\u0003\u0002\u0002\u0002\u00af\u00a9\u0003\u0002\u0002\u0002",
+    "\u00af\u00aa\u0003\u0002\u0002\u0002\u00af\u00ab\u0003\u0002\u0002\u0002",
+    "\u00af\u00ac\u0003\u0002\u0002\u0002\u00af\u00ad\u0003\u0002\u0002\u0002",
+    "\u00af\u00ae\u0003\u0002\u0002\u0002\u00b0\u000f\u0003\u0002\u0002\u0002",
+    "\u00b1\u00b2\u0007\u0006\u0002\u0002\u00b2\u00b6\u00078\u0002\u0002",
+    "\u00b3\u00b5\u0005\u0012\n\u0002\u00b4\u00b3\u0003\u0002\u0002\u0002",
+    "\u00b5\u00b8\u0003\u0002\u0002\u0002\u00b6\u00b4\u0003\u0002\u0002\u0002",
+    "\u00b6\u00b7\u0003\u0002\u0002\u0002\u00b7\u00bc\u0003\u0002\u0002\u0002",
+    "\u00b8\u00b6\u0003\u0002\u0002\u0002\u00b9\u00bb\u00056\u001c\u0002",
+    "\u00ba\u00b9\u0003\u0002\u0002\u0002\u00bb\u00be\u0003\u0002\u0002\u0002",
+    "\u00bc\u00ba\u0003\u0002\u0002\u0002\u00bc\u00bd\u0003\u0002\u0002\u0002",
+    "\u00bd\u0011\u0003\u0002\u0002\u0002\u00be\u00bc\u0003\u0002\u0002\u0002",
+    "\u00bf\u00c2\u0005.\u0018\u0002\u00c0\u00c2\u0005$\u0013\u0002\u00c1",
+    "\u00bf\u0003\u0002\u0002\u0002\u00c1\u00c0\u0003\u0002\u0002\u0002\u00c2",
+    "\u0013\u0003\u0002\u0002\u0002\u00c3\u00c4\u0007\b\u0002\u0002\u00c4",
+    "\u00c6\u00078\u0002\u0002\u00c5\u00c7\u0005\u0016\f\u0002\u00c6\u00c5",
+    "\u0003\u0002\u0002\u0002\u00c7\u00c8\u0003\u0002\u0002\u0002\u00c8\u00c6",
+    "\u0003\u0002\u0002\u0002\u00c8\u00c9\u0003\u0002\u0002\u0002\u00c9\u0015",
+    "\u0003\u0002\u0002\u0002\u00ca\u00cf\u0005&\u0014\u0002\u00cb\u00cf",
+    "\u0005(\u0015\u0002\u00cc\u00cf\u0005*\u0016\u0002\u00cd\u00cf\u0005",
+    ",\u0017\u0002\u00ce\u00ca\u0003\u0002\u0002\u0002\u00ce\u00cb\u0003",
+    "\u0002\u0002\u0002\u00ce\u00cc\u0003\u0002\u0002\u0002\u00ce\u00cd\u0003",
+    "\u0002\u0002\u0002\u00cf\u0017\u0003\u0002\u0002\u0002\u00d0\u00d1\u0007",
+    "\t\u0002\u0002\u00d1\u00d5\u00078\u0002\u0002\u00d2\u00d4\u0005\u001a",
+    "\u000e\u0002\u00d3\u00d2\u0003\u0002\u0002\u0002\u00d4\u00d7\u0003\u0002",
+    "\u0002\u0002\u00d5\u00d3\u0003\u0002\u0002\u0002\u00d5\u00d6\u0003\u0002",
+    "\u0002\u0002\u00d6\u00db\u0003\u0002\u0002\u0002\u00d7\u00d5\u0003\u0002",
+    "\u0002\u0002\u00d8\u00da\u0005@!\u0002\u00d9\u00d8\u0003\u0002\u0002",
+    "\u0002\u00da\u00dd\u0003\u0002\u0002\u0002\u00db\u00d9\u0003\u0002\u0002",
+    "\u0002\u00db\u00dc\u0003\u0002\u0002\u0002\u00dc\u0019\u0003\u0002\u0002",
+    "\u0002\u00dd\u00db\u0003\u0002\u0002\u0002\u00de\u00e2\u0005\"\u0012",
+    "\u0002\u00df\u00e2\u0005$\u0013\u0002\u00e0\u00e2\u0005&\u0014\u0002",
+    "\u00e1\u00de\u0003\u0002\u0002\u0002\u00e1\u00df\u0003\u0002\u0002\u0002",
+    "\u00e1\u00e0\u0003\u0002\u0002\u0002\u00e2\u001b\u0003\u0002\u0002\u0002",
+    "\u00e3\u00e4\u0007\n\u0002\u0002\u00e4\u00e8\u00078\u0002\u0002\u00e5",
+    "\u00e7\u0005\u001e\u0010\u0002\u00e6\u00e5\u0003\u0002\u0002\u0002\u00e7",
+    "\u00ea\u0003\u0002\u0002\u0002\u00e8\u00e6\u0003\u0002\u0002\u0002\u00e8",
+    "\u00e9\u0003\u0002\u0002\u0002\u00e9\u00ee\u0003\u0002\u0002\u0002\u00ea",
+    "\u00e8\u0003\u0002\u0002\u0002\u00eb\u00ed\u0005d3\u0002\u00ec\u00eb",
+    "\u0003\u0002\u0002\u0002\u00ed\u00f0\u0003\u0002\u0002\u0002\u00ee\u00ec",
+    "\u0003\u0002\u0002\u0002\u00ee\u00ef\u0003\u0002\u0002\u0002\u00ef\u001d",
+    "\u0003\u0002\u0002\u0002\u00f0\u00ee\u0003\u0002\u0002\u0002\u00f1\u00f5",
+    "\u0005\"\u0012\u0002\u00f2\u00f5\u0005$\u0013\u0002\u00f3\u00f5\u0005",
+    "&\u0014\u0002\u00f4\u00f1\u0003\u0002\u0002\u0002\u00f4\u00f2\u0003",
+    "\u0002\u0002\u0002\u00f4\u00f3\u0003\u0002\u0002\u0002\u00f5\u001f\u0003",
+    "\u0002\u0002\u0002\u00f6\u00f7\u0007\u000b\u0002\u0002\u00f7\u00f8\u0007",
+    "8\u0002\u0002\u00f8!\u0003\u0002\u0002\u0002\u00f9\u00fa\u0007\f\u0002",
+    "\u0002\u00fa\u00fb\u00078\u0002\u0002\u00fb#\u0003\u0002\u0002\u0002",
+    "\u00fc\u00fd\u0007\r\u0002\u0002\u00fd\u00fe\u0007*\u0002\u0002\u00fe",
+    "%\u0003\u0002\u0002\u0002\u00ff\u0100\u0007\u000e\u0002\u0002\u0100",
+    "\u0101\t\u0002\u0002\u0002\u0101\'\u0003\u0002\u0002\u0002\u0102\u0103",
+    "\u0007\u000f\u0002\u0002\u0103\u0104\u0007*\u0002\u0002\u0104)\u0003",
+    "\u0002\u0002\u0002\u0105\u0106\u0007\u0010\u0002\u0002\u0106\u0107\u0007",
+    "*\u0002\u0002\u0107+\u0003\u0002\u0002\u0002\u0108\u0109\u0007\u0011",
+    "\u0002\u0002\u0109\u010a\u0007.\u0002\u0002\u010a-\u0003\u0002\u0002",
+    "\u0002\u010b\u010c\u0007\u0007\u0002\u0002\u010c\u010d\u00078\u0002",
+    "\u0002\u010d/\u0003\u0002\u0002\u0002\u010e\u010f\u0007\'\u0002\u0002",
+    "\u010f\u0110\u0005T+\u0002\u0110\u0114\u00072\u0002\u0002\u0111\u0113",
+    "\u0005Z.\u0002\u0112\u0111\u0003\u0002\u0002\u0002\u0113\u0116\u0003",
+    "\u0002\u0002\u0002\u0114\u0112\u0003\u0002\u0002\u0002\u0114\u0115\u0003",
+    "\u0002\u0002\u0002\u01151\u0003\u0002\u0002\u0002\u0116\u0114\u0003",
+    "\u0002\u0002\u0002\u0117\u011a\u0007\'\u0002\u0002\u0118\u011b\u0005",
+    "T+\u0002\u0119\u011b\u0005V,\u0002\u011a\u0118\u0003\u0002\u0002\u0002",
+    "\u011a\u0119\u0003\u0002\u0002\u0002\u011b\u011d\u0003\u0002\u0002\u0002",
+    "\u011c\u011e\u0005Z.\u0002\u011d\u011c\u0003\u0002\u0002\u0002\u011e",
+    "\u011f\u0003\u0002\u0002\u0002\u011f\u011d\u0003\u0002\u0002\u0002\u011f",
+    "\u0120\u0003\u0002\u0002\u0002\u01203\u0003\u0002\u0002\u0002\u0121",
+    "\u0122\u0007\'\u0002\u0002\u0122\u0123\u0005T+\u0002\u0123\u0124\u0007",
+    "\u0015\u0002\u0002\u0124\u0126\u00078\u0002\u0002\u0125\u0127\u0005",
+    "\\/\u0002\u0126\u0125\u0003\u0002\u0002\u0002\u0126\u0127\u0003\u0002",
+    "\u0002\u0002\u01275\u0003\u0002\u0002\u0002\u0128\u0129\u0007\'\u0002",
+    "\u0002\u0129\u012a\u0005T+\u0002\u012a\u012b\u0007&\u0002\u0002\u012b",
+    "\u012c\u0005^0\u0002\u012c7\u0003\u0002\u0002\u0002\u012d\u012e\u0007",
+    "\'\u0002\u0002\u012e\u012f\u0005T+\u0002\u012f\u0130\u0007\u001a\u0002",
+    "\u0002\u0130\u0135\u0005`1\u0002\u0131\u0132\u0007\u001b\u0002\u0002",
+    "\u0132\u0134\u0005`1\u0002\u0133\u0131\u0003\u0002\u0002\u0002\u0134",
+    "\u0137\u0003\u0002\u0002\u0002\u0135\u0133\u0003\u0002\u0002\u0002\u0135",
+    "\u0136\u0003\u0002\u0002\u0002\u01369\u0003\u0002\u0002\u0002\u0137",
+    "\u0135\u0003\u0002\u0002\u0002\u0138\u0139\u0007\'\u0002\u0002\u0139",
+    "\u013a\u0005T+\u0002\u013a\u013b\u0007\u001c\u0002\u0002\u013b\u0140",
+    "\u0005p9\u0002\u013c\u013d\u0007\u001d\u0002\u0002\u013d\u013f\u0005",
+    "p9\u0002\u013e\u013c\u0003\u0002\u0002\u0002\u013f\u0142\u0003\u0002",
+    "\u0002\u0002\u0140\u013e\u0003\u0002\u0002\u0002\u0140\u0141\u0003\u0002",
+    "\u0002\u0002\u0141;\u0003\u0002\u0002\u0002\u0142\u0140\u0003\u0002",
+    "\u0002\u0002\u0143\u0145\u0007\'\u0002\u0002\u0144\u0146\u0005T+\u0002",
+    "\u0145\u0144\u0003\u0002\u0002\u0002\u0145\u0146\u0003\u0002\u0002\u0002",
+    "\u0146\u0147\u0003\u0002\u0002\u0002\u0147\u0148\u0007\u001e\u0002\u0002",
+    "\u0148\u014d\u00078\u0002\u0002\u0149\u014a\u0007\u001b\u0002\u0002",
+    "\u014a\u014c\u00078\u0002\u0002\u014b\u0149\u0003\u0002\u0002\u0002",
+    "\u014c\u014f\u0003\u0002\u0002\u0002\u014d\u014b\u0003\u0002\u0002\u0002",
+    "\u014d\u014e\u0003\u0002\u0002\u0002\u014e=\u0003\u0002\u0002\u0002",
+    "\u014f\u014d\u0003\u0002\u0002\u0002\u0150\u0152\u0007\'\u0002\u0002",
+    "\u0151\u0153\u0005T+\u0002\u0152\u0151\u0003\u0002\u0002\u0002\u0152",
+    "\u0153\u0003\u0002\u0002\u0002\u0153\u0154\u0003\u0002\u0002\u0002\u0154",
+    "\u0155\u0005X-\u0002\u0155\u0156\u0007&\u0002\u0002\u0156\u0157\u0005",
+    "^0\u0002\u0157?\u0003\u0002\u0002\u0002\u0158\u015a\u0007\'\u0002\u0002",
+    "\u0159\u015b\u0007!\u0002\u0002\u015a\u0159\u0003\u0002\u0002\u0002",
+    "\u015a\u015b\u0003\u0002\u0002\u0002\u015b\u015e\u0003\u0002\u0002\u0002",
+    "\u015c\u015f\u0005B\"\u0002\u015d\u015f\u0005D#\u0002\u015e\u015c\u0003",
+    "\u0002\u0002\u0002\u015e\u015d\u0003\u0002\u0002\u0002\u015fA\u0003",
+    "\u0002\u0002\u0002\u0160\u0162\u0005b2\u0002\u0161\u0163\u0005F$\u0002",
+    "\u0162\u0161\u0003\u0002\u0002\u0002\u0162\u0163\u0003\u0002\u0002\u0002",
+    "\u0163\u0167\u0003\u0002\u0002\u0002\u0164\u0165\u00076\u0002\u0002",
+    "\u0165\u0167\u0005F$\u0002\u0166\u0160\u0003\u0002\u0002\u0002\u0166",
+    "\u0164\u0003\u0002\u0002\u0002\u0167C\u0003\u0002\u0002\u0002\u0168",
+    "\u0169\u0007\"\u0002\u0002\u0169\u016c\u0005F$\u0002\u016a\u016b\u0007",
+    "#\u0002\u0002\u016b\u016d\u0005L\'\u0002\u016c\u016a\u0003\u0002\u0002",
+    "\u0002\u016c\u016d\u0003\u0002\u0002\u0002\u016dE\u0003\u0002\u0002",
+    "\u0002\u016e\u0179\u0007\u0015\u0002\u0002\u016f\u0172\u0005H%\u0002",
+    "\u0170\u0171\u0007\u001b\u0002\u0002\u0171\u0173\u0005J&\u0002\u0172",
+    "\u0170\u0003\u0002\u0002\u0002\u0172\u0173\u0003\u0002\u0002\u0002\u0173",
+    "\u017a\u0003\u0002\u0002\u0002\u0174\u0177\u0005J&\u0002\u0175\u0176",
+    "\u0007\u001b\u0002\u0002\u0176\u0178\u0005H%\u0002\u0177\u0175\u0003",
+    "\u0002\u0002\u0002\u0177\u0178\u0003\u0002\u0002\u0002\u0178\u017a\u0003",
+    "\u0002\u0002\u0002\u0179\u016f\u0003\u0002\u0002\u0002\u0179\u0174\u0003",
+    "\u0002\u0002\u0002\u017aG\u0003\u0002\u0002\u0002\u017b\u017c\u0007",
+    "%\u0002\u0002\u017c\u017d\u00078\u0002\u0002\u017dI\u0003\u0002\u0002",
+    "\u0002\u017e\u017f\u0007$\u0002\u0002\u017f\u0180\t\u0003\u0002\u0002",
+    "\u0180K\u0003\u0002\u0002\u0002\u0181\u0182\u0005N(\u0002\u0182\u0183",
+    "\u0007\u001b\u0002\u0002\u0183\u0185\u0003\u0002\u0002\u0002\u0184\u0181",
+    "\u0003\u0002\u0002\u0002\u0185\u0188\u0003\u0002\u0002\u0002\u0186\u0184",
+    "\u0003\u0002\u0002\u0002\u0186\u0187\u0003\u0002\u0002\u0002\u0187\u0189",
+    "\u0003\u0002\u0002\u0002\u0188\u0186\u0003\u0002\u0002\u0002\u0189\u018a",
+    "\u0005N(\u0002\u018aM\u0003\u0002\u0002\u0002\u018b\u018c\u00078\u0002",
+    "\u0002\u018c\u018e\u0005P)\u0002\u018d\u018f\u0005R*\u0002\u018e\u018d",
+    "\u0003\u0002\u0002\u0002\u018e\u018f\u0003\u0002\u0002\u0002\u018fO",
+    "\u0003\u0002\u0002\u0002\u0190\u0191\t\u0004\u0002\u0002\u0191Q\u0003",
+    "\u0002\u0002\u0002\u0192\u0198\u0005b2\u0002\u0193\u0198\u0007\u001f",
+    "\u0002\u0002\u0194\u0198\u0007 \u0002\u0002\u0195\u0198\u00075\u0002",
+    "\u0002\u0196\u0198\u0007*\u0002\u0002\u0197\u0192\u0003\u0002\u0002",
+    "\u0002\u0197\u0193\u0003\u0002\u0002\u0002\u0197\u0194\u0003\u0002\u0002",
+    "\u0002\u0197\u0195\u0003\u0002\u0002\u0002\u0197\u0196\u0003\u0002\u0002",
+    "\u0002\u0198S\u0003\u0002\u0002\u0002\u0199\u019a\u00078\u0002\u0002",
+    "\u019aU\u0003\u0002\u0002\u0002\u019b\u019c\u00077\u0002\u0002\u019c",
+    "W\u0003\u0002\u0002\u0002\u019d\u019e\u00074\u0002\u0002\u019eY\u0003",
+    "\u0002\u0002\u0002\u019f\u01a0\t\u0005\u0002\u0002\u01a0[\u0003\u0002",
+    "\u0002\u0002\u01a1\u01a2\t\u0006\u0002\u0002\u01a2]\u0003\u0002\u0002",
+    "\u0002\u01a3\u01ae\u0007*\u0002\u0002\u01a4\u01ae\u0007+\u0002\u0002",
+    "\u01a5\u01ae\u0007,\u0002\u0002\u01a6\u01ae\u00070\u0002\u0002\u01a7",
+    "\u01ae\u00071\u0002\u0002\u01a8\u01ae\u0005j6\u0002\u01a9\u01ae\u0005",
+    "b2\u0002\u01aa\u01ae\u0005f4\u0002\u01ab\u01ae\u0005h5\u0002\u01ac\u01ae",
+    "\u0005n8\u0002\u01ad\u01a3\u0003\u0002\u0002\u0002\u01ad\u01a4\u0003",
+    "\u0002\u0002\u0002\u01ad\u01a5\u0003\u0002\u0002\u0002\u01ad\u01a6\u0003",
+    "\u0002\u0002\u0002\u01ad\u01a7\u0003\u0002\u0002\u0002\u01ad\u01a8\u0003",
+    "\u0002\u0002\u0002\u01ad\u01a9\u0003\u0002\u0002\u0002\u01ad\u01aa\u0003",
+    "\u0002\u0002\u0002\u01ad\u01ab\u0003\u0002\u0002\u0002\u01ad\u01ac\u0003",
+    "\u0002\u0002\u0002\u01ae_\u0003\u0002\u0002\u0002\u01af\u01b0\u0007",
+    "8\u0002\u0002\u01b0\u01b4\u00072\u0002\u0002\u01b1\u01b3\u0005Z.\u0002",
+    "\u01b2\u01b1\u0003\u0002\u0002\u0002\u01b3\u01b6\u0003\u0002\u0002\u0002",
+    "\u01b4\u01b2\u0003\u0002\u0002\u0002\u01b4\u01b5\u0003\u0002\u0002\u0002",
+    "\u01b5a\u0003\u0002\u0002\u0002\u01b6\u01b4\u0003\u0002\u0002\u0002",
+    "\u01b7\u01b9\u0007.\u0002\u0002\u01b8\u01ba\u0007*\u0002\u0002\u01b9",
+    "\u01b8\u0003\u0002\u0002\u0002\u01b9\u01ba\u0003\u0002\u0002\u0002\u01ba",
+    "c\u0003\u0002\u0002\u0002\u01bb\u01bd\u0005b2\u0002\u01bc\u01be\u0007",
+    "*\u0002\u0002\u01bd\u01bc\u0003\u0002\u0002\u0002\u01bd\u01be\u0003",
+    "\u0002\u0002\u0002\u01bee\u0003\u0002\u0002\u0002\u01bf\u01c0\u0007",
+    ",\u0002\u0002\u01c0\u01c1\u0007-\u0002\u0002\u01c1g\u0003\u0002\u0002",
+    "\u0002\u01c2\u01c3\u0005l7\u0002\u01c3\u01c4\u0007(\u0002\u0002\u01c4",
+    "\u01c5\u0005l7\u0002\u01c5i\u0003\u0002\u0002\u0002\u01c6\u01c8\u0007",
+    "3\u0002\u0002\u01c7\u01c9\u0007*\u0002\u0002\u01c8\u01c7\u0003\u0002",
+    "\u0002\u0002\u01c8\u01c9\u0003\u0002\u0002\u0002\u01c9k\u0003\u0002",
+    "\u0002\u0002\u01ca\u01cd\u0007,\u0002\u0002\u01cb\u01cd\u0005f4\u0002",
+    "\u01cc\u01ca\u0003\u0002\u0002\u0002\u01cc\u01cb\u0003\u0002\u0002\u0002",
+    "\u01cdm\u0003\u0002\u0002\u0002\u01ce\u01cf\t\u0007\u0002\u0002\u01cf",
+    "o\u0003\u0002\u0002\u0002\u01d0\u01d3\u00078\u0002\u0002\u01d1\u01d3",
+    "\u0005j6\u0002\u01d2\u01d0\u0003\u0002\u0002\u0002\u01d2\u01d1\u0003",
+    "\u0002\u0002\u0002\u01d3q\u0003\u0002\u0002\u00020u\u007f\u008b\u0090",
+    "\u0098\u009e\u00a5\u00af\u00b6\u00bc\u00c1\u00c8\u00ce\u00d5\u00db\u00e1",
+    "\u00e8\u00ee\u00f4\u0114\u011a\u011f\u0126\u0135\u0140\u0145\u014d\u0152",
+    "\u015a\u015e\u0162\u0166\u016c\u0172\u0177\u0179\u0186\u018e\u0197\u01ad",
+    "\u01b4\u01b9\u01bd\u01c8\u01cc\u01d2"].join("");
 
 
 var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN);
@@ -339,8 +347,8 @@ var ruleNames =  [ "doc", "entity", "alias", "profile", "extension", "sdMetadata
                    "vsFromSystem", "vsFromValueset", "vsFilterList", "vsFilterDefinition", 
                    "vsFilterOperator", "vsFilterValue", "path", "paths", 
                    "caretPath", "flag", "strength", "value", "item", "code", 
-                   "concept", "quantity", "ratio", "ratioPart", "bool", 
-                   "targetType" ];
+                   "concept", "quantity", "ratio", "reference", "ratioPart", 
+                   "bool", "targetType" ];
 
 function FSHParser (input) {
 	antlr4.Parser.call(this, input);
@@ -471,9 +479,10 @@ FSHParser.RULE_code = 48;
 FSHParser.RULE_concept = 49;
 FSHParser.RULE_quantity = 50;
 FSHParser.RULE_ratio = 51;
-FSHParser.RULE_ratioPart = 52;
-FSHParser.RULE_bool = 53;
-FSHParser.RULE_targetType = 54;
+FSHParser.RULE_reference = 52;
+FSHParser.RULE_ratioPart = 53;
+FSHParser.RULE_bool = 54;
+FSHParser.RULE_targetType = 55;
 
 
 function DocContext(parser, parent, invokingState) {
@@ -535,13 +544,13 @@ FSHParser.prototype.doc = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 113;
+        this.state = 115;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_ALIAS) | (1 << FSHParser.KW_PROFILE) | (1 << FSHParser.KW_EXTENSION) | (1 << FSHParser.KW_INSTANCE) | (1 << FSHParser.KW_INVARIANT) | (1 << FSHParser.KW_VALUESET) | (1 << FSHParser.KW_CODESYSTEM))) !== 0)) {
-            this.state = 110;
+            this.state = 112;
             this.entity();
-            this.state = 115;
+            this.state = 117;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -634,42 +643,42 @@ FSHParser.prototype.entity = function() {
     var localctx = new EntityContext(this, this._ctx, this.state);
     this.enterRule(localctx, 2, FSHParser.RULE_entity);
     try {
-        this.state = 123;
+        this.state = 125;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_ALIAS:
             this.enterOuterAlt(localctx, 1);
-            this.state = 116;
+            this.state = 118;
             this.alias();
             break;
         case FSHParser.KW_PROFILE:
             this.enterOuterAlt(localctx, 2);
-            this.state = 117;
+            this.state = 119;
             this.profile();
             break;
         case FSHParser.KW_EXTENSION:
             this.enterOuterAlt(localctx, 3);
-            this.state = 118;
+            this.state = 120;
             this.extension();
             break;
         case FSHParser.KW_INVARIANT:
             this.enterOuterAlt(localctx, 4);
-            this.state = 119;
+            this.state = 121;
             this.invariant();
             break;
         case FSHParser.KW_INSTANCE:
             this.enterOuterAlt(localctx, 5);
-            this.state = 120;
+            this.state = 122;
             this.instance();
             break;
         case FSHParser.KW_VALUESET:
             this.enterOuterAlt(localctx, 6);
-            this.state = 121;
+            this.state = 123;
             this.valueSet();
             break;
         case FSHParser.KW_CODESYSTEM:
             this.enterOuterAlt(localctx, 7);
-            this.state = 122;
+            this.state = 124;
             this.codeSystem();
             break;
         default:
@@ -757,13 +766,13 @@ FSHParser.prototype.alias = function() {
     this.enterRule(localctx, 4, FSHParser.RULE_alias);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 125;
+        this.state = 127;
         this.match(FSHParser.KW_ALIAS);
-        this.state = 126;
+        this.state = 128;
         this.match(FSHParser.SEQUENCE);
-        this.state = 127;
+        this.state = 129;
         this.match(FSHParser.EQUAL);
-        this.state = 128;
+        this.state = 130;
         this.match(FSHParser.SEQUENCE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -858,27 +867,27 @@ FSHParser.prototype.profile = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 130;
+        this.state = 132;
         this.match(FSHParser.KW_PROFILE);
-        this.state = 131;
+        this.state = 133;
         this.match(FSHParser.SEQUENCE);
-        this.state = 133; 
+        this.state = 135; 
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         do {
-            this.state = 132;
+            this.state = 134;
             this.sdMetadata();
-            this.state = 135; 
+            this.state = 137; 
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         } while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_PARENT) | (1 << FSHParser.KW_ID) | (1 << FSHParser.KW_TITLE) | (1 << FSHParser.KW_DESCRIPTION))) !== 0));
-        this.state = 140;
+        this.state = 142;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.STAR) {
-            this.state = 137;
+            this.state = 139;
             this.sdRule();
-            this.state = 142;
+            this.state = 144;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -975,27 +984,27 @@ FSHParser.prototype.extension = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 143;
+        this.state = 145;
         this.match(FSHParser.KW_EXTENSION);
-        this.state = 144;
+        this.state = 146;
         this.match(FSHParser.SEQUENCE);
-        this.state = 148;
+        this.state = 150;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_PARENT) | (1 << FSHParser.KW_ID) | (1 << FSHParser.KW_TITLE) | (1 << FSHParser.KW_DESCRIPTION))) !== 0)) {
-            this.state = 145;
+            this.state = 147;
             this.sdMetadata();
-            this.state = 150;
+            this.state = 152;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
-        this.state = 154;
+        this.state = 156;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.STAR) {
-            this.state = 151;
+            this.state = 153;
             this.sdRule();
-            this.state = 156;
+            this.state = 158;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -1076,27 +1085,27 @@ FSHParser.prototype.sdMetadata = function() {
     var localctx = new SdMetadataContext(this, this._ctx, this.state);
     this.enterRule(localctx, 10, FSHParser.RULE_sdMetadata);
     try {
-        this.state = 161;
+        this.state = 163;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_PARENT:
             this.enterOuterAlt(localctx, 1);
-            this.state = 157;
+            this.state = 159;
             this.parent();
             break;
         case FSHParser.KW_ID:
             this.enterOuterAlt(localctx, 2);
-            this.state = 158;
+            this.state = 160;
             this.id();
             break;
         case FSHParser.KW_TITLE:
             this.enterOuterAlt(localctx, 3);
-            this.state = 159;
+            this.state = 161;
             this.title();
             break;
         case FSHParser.KW_DESCRIPTION:
             this.enterOuterAlt(localctx, 4);
-            this.state = 160;
+            this.state = 162;
             this.description();
             break;
         default:
@@ -1195,55 +1204,55 @@ FSHParser.prototype.sdRule = function() {
     var localctx = new SdRuleContext(this, this._ctx, this.state);
     this.enterRule(localctx, 12, FSHParser.RULE_sdRule);
     try {
-        this.state = 171;
+        this.state = 173;
         this._errHandler.sync(this);
         var la_ = this._interp.adaptivePredict(this._input,7,this._ctx);
         switch(la_) {
         case 1:
             this.enterOuterAlt(localctx, 1);
-            this.state = 163;
+            this.state = 165;
             this.cardRule();
             break;
 
         case 2:
             this.enterOuterAlt(localctx, 2);
-            this.state = 164;
+            this.state = 166;
             this.flagRule();
             break;
 
         case 3:
             this.enterOuterAlt(localctx, 3);
-            this.state = 165;
+            this.state = 167;
             this.valueSetRule();
             break;
 
         case 4:
             this.enterOuterAlt(localctx, 4);
-            this.state = 166;
+            this.state = 168;
             this.fixedValueRule();
             break;
 
         case 5:
             this.enterOuterAlt(localctx, 5);
-            this.state = 167;
+            this.state = 169;
             this.containsRule();
             break;
 
         case 6:
             this.enterOuterAlt(localctx, 6);
-            this.state = 168;
+            this.state = 170;
             this.onlyRule();
             break;
 
         case 7:
             this.enterOuterAlt(localctx, 7);
-            this.state = 169;
+            this.state = 171;
             this.obeysRule();
             break;
 
         case 8:
             this.enterOuterAlt(localctx, 8);
-            this.state = 170;
+            this.state = 172;
             this.caretValueRule();
             break;
 
@@ -1341,27 +1350,27 @@ FSHParser.prototype.instance = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 173;
+        this.state = 175;
         this.match(FSHParser.KW_INSTANCE);
-        this.state = 174;
+        this.state = 176;
         this.match(FSHParser.SEQUENCE);
-        this.state = 178;
+        this.state = 180;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_INSTANCEOF || _la===FSHParser.KW_TITLE) {
-            this.state = 175;
+            this.state = 177;
             this.instanceMetadata();
-            this.state = 180;
+            this.state = 182;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
-        this.state = 184;
+        this.state = 186;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.STAR) {
-            this.state = 181;
+            this.state = 183;
             this.fixedValueRule();
-            this.state = 186;
+            this.state = 188;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -1434,17 +1443,17 @@ FSHParser.prototype.instanceMetadata = function() {
     var localctx = new InstanceMetadataContext(this, this._ctx, this.state);
     this.enterRule(localctx, 16, FSHParser.RULE_instanceMetadata);
     try {
-        this.state = 189;
+        this.state = 191;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_INSTANCEOF:
             this.enterOuterAlt(localctx, 1);
-            this.state = 187;
+            this.state = 189;
             this.instanceOf();
             break;
         case FSHParser.KW_TITLE:
             this.enterOuterAlt(localctx, 2);
-            this.state = 188;
+            this.state = 190;
             this.title();
             break;
         default:
@@ -1532,17 +1541,17 @@ FSHParser.prototype.invariant = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 191;
+        this.state = 193;
         this.match(FSHParser.KW_INVARIANT);
-        this.state = 192;
+        this.state = 194;
         this.match(FSHParser.SEQUENCE);
-        this.state = 194; 
+        this.state = 196; 
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         do {
-            this.state = 193;
+            this.state = 195;
             this.invariantMetadata();
-            this.state = 196; 
+            this.state = 198; 
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         } while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_DESCRIPTION) | (1 << FSHParser.KW_EXPRESSION) | (1 << FSHParser.KW_XPATH) | (1 << FSHParser.KW_SEVERITY))) !== 0));
@@ -1623,27 +1632,27 @@ FSHParser.prototype.invariantMetadata = function() {
     var localctx = new InvariantMetadataContext(this, this._ctx, this.state);
     this.enterRule(localctx, 20, FSHParser.RULE_invariantMetadata);
     try {
-        this.state = 202;
+        this.state = 204;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_DESCRIPTION:
             this.enterOuterAlt(localctx, 1);
-            this.state = 198;
+            this.state = 200;
             this.description();
             break;
         case FSHParser.KW_EXPRESSION:
             this.enterOuterAlt(localctx, 2);
-            this.state = 199;
+            this.state = 201;
             this.expression();
             break;
         case FSHParser.KW_XPATH:
             this.enterOuterAlt(localctx, 3);
-            this.state = 200;
+            this.state = 202;
             this.xpath();
             break;
         case FSHParser.KW_SEVERITY:
             this.enterOuterAlt(localctx, 4);
-            this.state = 201;
+            this.state = 203;
             this.severity();
             break;
         default:
@@ -1742,27 +1751,27 @@ FSHParser.prototype.valueSet = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 204;
+        this.state = 206;
         this.match(FSHParser.KW_VALUESET);
-        this.state = 205;
+        this.state = 207;
         this.match(FSHParser.SEQUENCE);
-        this.state = 209;
+        this.state = 211;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_ID) | (1 << FSHParser.KW_TITLE) | (1 << FSHParser.KW_DESCRIPTION))) !== 0)) {
-            this.state = 206;
+            this.state = 208;
             this.vsMetadata();
-            this.state = 211;
+            this.state = 213;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
-        this.state = 215;
+        this.state = 217;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.STAR) {
-            this.state = 212;
+            this.state = 214;
             this.vsComponent();
-            this.state = 217;
+            this.state = 219;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -1839,22 +1848,22 @@ FSHParser.prototype.vsMetadata = function() {
     var localctx = new VsMetadataContext(this, this._ctx, this.state);
     this.enterRule(localctx, 24, FSHParser.RULE_vsMetadata);
     try {
-        this.state = 221;
+        this.state = 223;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_ID:
             this.enterOuterAlt(localctx, 1);
-            this.state = 218;
+            this.state = 220;
             this.id();
             break;
         case FSHParser.KW_TITLE:
             this.enterOuterAlt(localctx, 2);
-            this.state = 219;
+            this.state = 221;
             this.title();
             break;
         case FSHParser.KW_DESCRIPTION:
             this.enterOuterAlt(localctx, 3);
-            this.state = 220;
+            this.state = 222;
             this.description();
             break;
         default:
@@ -1953,27 +1962,27 @@ FSHParser.prototype.codeSystem = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 223;
+        this.state = 225;
         this.match(FSHParser.KW_CODESYSTEM);
-        this.state = 224;
+        this.state = 226;
         this.match(FSHParser.SEQUENCE);
-        this.state = 228;
+        this.state = 230;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_ID) | (1 << FSHParser.KW_TITLE) | (1 << FSHParser.KW_DESCRIPTION))) !== 0)) {
-            this.state = 225;
+            this.state = 227;
             this.csMetadata();
-            this.state = 230;
+            this.state = 232;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
-        this.state = 234;
+        this.state = 236;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.CODE) {
-            this.state = 231;
+            this.state = 233;
             this.concept();
-            this.state = 236;
+            this.state = 238;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -2050,22 +2059,22 @@ FSHParser.prototype.csMetadata = function() {
     var localctx = new CsMetadataContext(this, this._ctx, this.state);
     this.enterRule(localctx, 28, FSHParser.RULE_csMetadata);
     try {
-        this.state = 240;
+        this.state = 242;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_ID:
             this.enterOuterAlt(localctx, 1);
-            this.state = 237;
+            this.state = 239;
             this.id();
             break;
         case FSHParser.KW_TITLE:
             this.enterOuterAlt(localctx, 2);
-            this.state = 238;
+            this.state = 240;
             this.title();
             break;
         case FSHParser.KW_DESCRIPTION:
             this.enterOuterAlt(localctx, 3);
-            this.state = 239;
+            this.state = 241;
             this.description();
             break;
         default:
@@ -2141,9 +2150,9 @@ FSHParser.prototype.parent = function() {
     this.enterRule(localctx, 30, FSHParser.RULE_parent);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 242;
+        this.state = 244;
         this.match(FSHParser.KW_PARENT);
-        this.state = 243;
+        this.state = 245;
         this.match(FSHParser.SEQUENCE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -2215,9 +2224,9 @@ FSHParser.prototype.id = function() {
     this.enterRule(localctx, 32, FSHParser.RULE_id);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 245;
+        this.state = 247;
         this.match(FSHParser.KW_ID);
-        this.state = 246;
+        this.state = 248;
         this.match(FSHParser.SEQUENCE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -2289,9 +2298,9 @@ FSHParser.prototype.title = function() {
     this.enterRule(localctx, 34, FSHParser.RULE_title);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 248;
+        this.state = 250;
         this.match(FSHParser.KW_TITLE);
-        this.state = 249;
+        this.state = 251;
         this.match(FSHParser.STRING);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -2368,9 +2377,9 @@ FSHParser.prototype.description = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 251;
+        this.state = 253;
         this.match(FSHParser.KW_DESCRIPTION);
-        this.state = 252;
+        this.state = 254;
         _la = this._input.LA(1);
         if(!(_la===FSHParser.STRING || _la===FSHParser.MULTILINE_STRING)) {
         this._errHandler.recoverInline(this);
@@ -2449,9 +2458,9 @@ FSHParser.prototype.expression = function() {
     this.enterRule(localctx, 38, FSHParser.RULE_expression);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 254;
+        this.state = 256;
         this.match(FSHParser.KW_EXPRESSION);
-        this.state = 255;
+        this.state = 257;
         this.match(FSHParser.STRING);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -2523,9 +2532,9 @@ FSHParser.prototype.xpath = function() {
     this.enterRule(localctx, 40, FSHParser.RULE_xpath);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 257;
+        this.state = 259;
         this.match(FSHParser.KW_XPATH);
-        this.state = 258;
+        this.state = 260;
         this.match(FSHParser.STRING);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -2597,9 +2606,9 @@ FSHParser.prototype.severity = function() {
     this.enterRule(localctx, 42, FSHParser.RULE_severity);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 260;
+        this.state = 262;
         this.match(FSHParser.KW_SEVERITY);
-        this.state = 261;
+        this.state = 263;
         this.match(FSHParser.CODE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -2671,9 +2680,9 @@ FSHParser.prototype.instanceOf = function() {
     this.enterRule(localctx, 44, FSHParser.RULE_instanceOf);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 263;
+        this.state = 265;
         this.match(FSHParser.KW_INSTANCEOF);
-        this.state = 264;
+        this.state = 266;
         this.match(FSHParser.SEQUENCE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -2761,19 +2770,19 @@ FSHParser.prototype.cardRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 266;
+        this.state = 268;
         this.match(FSHParser.STAR);
-        this.state = 267;
+        this.state = 269;
         this.path();
-        this.state = 268;
+        this.state = 270;
         this.match(FSHParser.CARD);
-        this.state = 272;
+        this.state = 274;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_MOD) | (1 << FSHParser.KW_MS) | (1 << FSHParser.KW_SU))) !== 0)) {
-            this.state = 269;
+            this.state = 271;
             this.flag();
-            this.state = 274;
+            this.state = 276;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -2863,29 +2872,29 @@ FSHParser.prototype.flagRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 275;
+        this.state = 277;
         this.match(FSHParser.STAR);
-        this.state = 278;
+        this.state = 280;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.SEQUENCE:
-            this.state = 276;
+            this.state = 278;
             this.path();
             break;
         case FSHParser.COMMA_DELIMITED_SEQUENCES:
-            this.state = 277;
+            this.state = 279;
             this.paths();
             break;
         default:
             throw new antlr4.error.NoViableAltException(this);
         }
-        this.state = 281; 
+        this.state = 283; 
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         do {
-            this.state = 280;
+            this.state = 282;
             this.flag();
-            this.state = 283; 
+            this.state = 285; 
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         } while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_MOD) | (1 << FSHParser.KW_MS) | (1 << FSHParser.KW_SU))) !== 0));
@@ -2972,19 +2981,19 @@ FSHParser.prototype.valueSetRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 285;
+        this.state = 287;
         this.match(FSHParser.STAR);
-        this.state = 286;
+        this.state = 288;
         this.path();
-        this.state = 287;
+        this.state = 289;
         this.match(FSHParser.KW_FROM);
-        this.state = 288;
-        this.match(FSHParser.SEQUENCE);
         this.state = 290;
+        this.match(FSHParser.SEQUENCE);
+        this.state = 292;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_EXAMPLE) | (1 << FSHParser.KW_PREFERRED) | (1 << FSHParser.KW_EXTENSIBLE) | (1 << FSHParser.KW_REQUIRED))) !== 0)) {
-            this.state = 289;
+            this.state = 291;
             this.strength();
         }
 
@@ -3066,13 +3075,13 @@ FSHParser.prototype.fixedValueRule = function() {
     this.enterRule(localctx, 52, FSHParser.RULE_fixedValueRule);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 292;
+        this.state = 294;
         this.match(FSHParser.STAR);
-        this.state = 293;
+        this.state = 295;
         this.path();
-        this.state = 294;
+        this.state = 296;
         this.match(FSHParser.EQUAL);
-        this.state = 295;
+        this.state = 297;
         this.value();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -3172,23 +3181,23 @@ FSHParser.prototype.containsRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 297;
+        this.state = 299;
         this.match(FSHParser.STAR);
-        this.state = 298;
+        this.state = 300;
         this.path();
-        this.state = 299;
+        this.state = 301;
         this.match(FSHParser.KW_CONTAINS);
-        this.state = 300;
+        this.state = 302;
         this.item();
-        this.state = 305;
+        this.state = 307;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_AND) {
-            this.state = 301;
+            this.state = 303;
             this.match(FSHParser.KW_AND);
-            this.state = 302;
+            this.state = 304;
             this.item();
-            this.state = 307;
+            this.state = 309;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -3290,23 +3299,23 @@ FSHParser.prototype.onlyRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 308;
+        this.state = 310;
         this.match(FSHParser.STAR);
-        this.state = 309;
+        this.state = 311;
         this.path();
-        this.state = 310;
+        this.state = 312;
         this.match(FSHParser.KW_ONLY);
-        this.state = 311;
+        this.state = 313;
         this.targetType();
-        this.state = 316;
+        this.state = 318;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_OR) {
-            this.state = 312;
+            this.state = 314;
             this.match(FSHParser.KW_OR);
-            this.state = 313;
+            this.state = 315;
             this.targetType();
-            this.state = 318;
+            this.state = 320;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -3409,29 +3418,29 @@ FSHParser.prototype.obeysRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 319;
-        this.match(FSHParser.STAR);
         this.state = 321;
+        this.match(FSHParser.STAR);
+        this.state = 323;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.SEQUENCE) {
-            this.state = 320;
+            this.state = 322;
             this.path();
         }
 
-        this.state = 323;
+        this.state = 325;
         this.match(FSHParser.KW_OBEYS);
-        this.state = 324;
+        this.state = 326;
         this.match(FSHParser.SEQUENCE);
-        this.state = 329;
+        this.state = 331;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_AND) {
-            this.state = 325;
+            this.state = 327;
             this.match(FSHParser.KW_AND);
-            this.state = 326;
+            this.state = 328;
             this.match(FSHParser.SEQUENCE);
-            this.state = 331;
+            this.state = 333;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -3518,21 +3527,21 @@ FSHParser.prototype.caretValueRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 332;
-        this.match(FSHParser.STAR);
         this.state = 334;
+        this.match(FSHParser.STAR);
+        this.state = 336;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.SEQUENCE) {
-            this.state = 333;
+            this.state = 335;
             this.path();
         }
 
-        this.state = 336;
+        this.state = 338;
         this.caretPath();
-        this.state = 337;
+        this.state = 339;
         this.match(FSHParser.EQUAL);
-        this.state = 338;
+        this.state = 340;
         this.value();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -3613,26 +3622,26 @@ FSHParser.prototype.vsComponent = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 340;
-        this.match(FSHParser.STAR);
         this.state = 342;
+        this.match(FSHParser.STAR);
+        this.state = 344;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.KW_EXCLUDE) {
-            this.state = 341;
+            this.state = 343;
             this.match(FSHParser.KW_EXCLUDE);
         }
 
-        this.state = 346;
+        this.state = 348;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.CODE:
         case FSHParser.COMMA_DELIMITED_CODES:
-            this.state = 344;
+            this.state = 346;
             this.vsConceptComponent();
             break;
         case FSHParser.KW_CODES:
-            this.state = 345;
+            this.state = 347;
             this.vsFilterComponent();
             break;
         default:
@@ -3712,27 +3721,27 @@ FSHParser.prototype.vsConceptComponent = function() {
     this.enterRule(localctx, 64, FSHParser.RULE_vsConceptComponent);
     var _la = 0; // Token type
     try {
-        this.state = 354;
+        this.state = 356;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.CODE:
             this.enterOuterAlt(localctx, 1);
-            this.state = 348;
-            this.code();
             this.state = 350;
+            this.code();
+            this.state = 352;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
             if(_la===FSHParser.KW_FROM) {
-                this.state = 349;
+                this.state = 351;
                 this.vsComponentFrom();
             }
 
             break;
         case FSHParser.COMMA_DELIMITED_CODES:
             this.enterOuterAlt(localctx, 2);
-            this.state = 352;
+            this.state = 354;
             this.match(FSHParser.COMMA_DELIMITED_CODES);
-            this.state = 353;
+            this.state = 355;
             this.vsComponentFrom();
             break;
         default:
@@ -3817,17 +3826,17 @@ FSHParser.prototype.vsFilterComponent = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 356;
+        this.state = 358;
         this.match(FSHParser.KW_CODES);
-        this.state = 357;
+        this.state = 359;
         this.vsComponentFrom();
-        this.state = 360;
+        this.state = 362;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.KW_WHERE) {
-            this.state = 358;
+            this.state = 360;
             this.match(FSHParser.KW_WHERE);
-            this.state = 359;
+            this.state = 361;
             this.vsFilterList();
         }
 
@@ -3910,35 +3919,35 @@ FSHParser.prototype.vsComponentFrom = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 362;
+        this.state = 364;
         this.match(FSHParser.KW_FROM);
-        this.state = 373;
+        this.state = 375;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_SYSTEM:
-            this.state = 363;
+            this.state = 365;
             this.vsFromSystem();
-            this.state = 366;
+            this.state = 368;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
             if(_la===FSHParser.KW_AND) {
-                this.state = 364;
+                this.state = 366;
                 this.match(FSHParser.KW_AND);
-                this.state = 365;
+                this.state = 367;
                 this.vsFromValueset();
             }
 
             break;
         case FSHParser.KW_VSREFERENCE:
-            this.state = 368;
+            this.state = 370;
             this.vsFromValueset();
-            this.state = 371;
+            this.state = 373;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
             if(_la===FSHParser.KW_AND) {
-                this.state = 369;
+                this.state = 371;
                 this.match(FSHParser.KW_AND);
-                this.state = 370;
+                this.state = 372;
                 this.vsFromSystem();
             }
 
@@ -4016,9 +4025,9 @@ FSHParser.prototype.vsFromSystem = function() {
     this.enterRule(localctx, 70, FSHParser.RULE_vsFromSystem);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 375;
+        this.state = 377;
         this.match(FSHParser.KW_SYSTEM);
-        this.state = 376;
+        this.state = 378;
         this.match(FSHParser.SEQUENCE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4095,9 +4104,9 @@ FSHParser.prototype.vsFromValueset = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 378;
+        this.state = 380;
         this.match(FSHParser.KW_VSREFERENCE);
-        this.state = 379;
+        this.state = 381;
         _la = this._input.LA(1);
         if(!(_la===FSHParser.COMMA_DELIMITED_SEQUENCES || _la===FSHParser.SEQUENCE)) {
         this._errHandler.recoverInline(this);
@@ -4191,22 +4200,22 @@ FSHParser.prototype.vsFilterList = function() {
     this.enterRule(localctx, 74, FSHParser.RULE_vsFilterList);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 386;
+        this.state = 388;
         this._errHandler.sync(this);
         var _alt = this._interp.adaptivePredict(this._input,36,this._ctx)
         while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) {
             if(_alt===1) {
-                this.state = 381;
+                this.state = 383;
                 this.vsFilterDefinition();
-                this.state = 382;
+                this.state = 384;
                 this.match(FSHParser.KW_AND); 
             }
-            this.state = 388;
+            this.state = 390;
             this._errHandler.sync(this);
             _alt = this._interp.adaptivePredict(this._input,36,this._ctx);
         }
 
-        this.state = 389;
+        this.state = 391;
         this.vsFilterDefinition();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4283,15 +4292,15 @@ FSHParser.prototype.vsFilterDefinition = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 391;
+        this.state = 393;
         this.match(FSHParser.SEQUENCE);
-        this.state = 392;
-        this.vsFilterOperator();
         this.state = 394;
+        this.vsFilterOperator();
+        this.state = 396;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(((((_la - 29)) & ~0x1f) == 0 && ((1 << (_la - 29)) & ((1 << (FSHParser.KW_TRUE - 29)) | (1 << (FSHParser.KW_FALSE - 29)) | (1 << (FSHParser.STRING - 29)) | (1 << (FSHParser.CODE - 29)) | (1 << (FSHParser.REGEX - 29)))) !== 0)) {
-            this.state = 393;
+            this.state = 395;
             this.vsFilterValue();
         }
 
@@ -4366,7 +4375,7 @@ FSHParser.prototype.vsFilterOperator = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 396;
+        this.state = 398;
         _la = this._input.LA(1);
         if(!(_la===FSHParser.EQUAL || _la===FSHParser.SEQUENCE)) {
         this._errHandler.recoverInline(this);
@@ -4456,32 +4465,32 @@ FSHParser.prototype.vsFilterValue = function() {
     var localctx = new VsFilterValueContext(this, this._ctx, this.state);
     this.enterRule(localctx, 80, FSHParser.RULE_vsFilterValue);
     try {
-        this.state = 403;
+        this.state = 405;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.CODE:
             this.enterOuterAlt(localctx, 1);
-            this.state = 398;
+            this.state = 400;
             this.code();
             break;
         case FSHParser.KW_TRUE:
             this.enterOuterAlt(localctx, 2);
-            this.state = 399;
+            this.state = 401;
             this.match(FSHParser.KW_TRUE);
             break;
         case FSHParser.KW_FALSE:
             this.enterOuterAlt(localctx, 3);
-            this.state = 400;
+            this.state = 402;
             this.match(FSHParser.KW_FALSE);
             break;
         case FSHParser.REGEX:
             this.enterOuterAlt(localctx, 4);
-            this.state = 401;
+            this.state = 403;
             this.match(FSHParser.REGEX);
             break;
         case FSHParser.STRING:
             this.enterOuterAlt(localctx, 5);
-            this.state = 402;
+            this.state = 404;
             this.match(FSHParser.STRING);
             break;
         default:
@@ -4553,7 +4562,7 @@ FSHParser.prototype.path = function() {
     this.enterRule(localctx, 82, FSHParser.RULE_path);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 405;
+        this.state = 407;
         this.match(FSHParser.SEQUENCE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4621,7 +4630,7 @@ FSHParser.prototype.paths = function() {
     this.enterRule(localctx, 84, FSHParser.RULE_paths);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 407;
+        this.state = 409;
         this.match(FSHParser.COMMA_DELIMITED_SEQUENCES);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4689,7 +4698,7 @@ FSHParser.prototype.caretPath = function() {
     this.enterRule(localctx, 86, FSHParser.RULE_caretPath);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 409;
+        this.state = 411;
         this.match(FSHParser.CARET_SEQUENCE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4766,7 +4775,7 @@ FSHParser.prototype.flag = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 411;
+        this.state = 413;
         _la = this._input.LA(1);
         if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_MOD) | (1 << FSHParser.KW_MS) | (1 << FSHParser.KW_SU))) !== 0))) {
         this._errHandler.recoverInline(this);
@@ -4854,7 +4863,7 @@ FSHParser.prototype.strength = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 413;
+        this.state = 415;
         _la = this._input.LA(1);
         if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_EXAMPLE) | (1 << FSHParser.KW_PREFERRED) | (1 << FSHParser.KW_EXTENSIBLE) | (1 << FSHParser.KW_REQUIRED))) !== 0))) {
         this._errHandler.recoverInline(this);
@@ -4914,6 +4923,10 @@ ValueContext.prototype.TIME = function() {
     return this.getToken(FSHParser.TIME, 0);
 };
 
+ValueContext.prototype.reference = function() {
+    return this.getTypedRuleContext(ReferenceContext,0);
+};
+
 ValueContext.prototype.code = function() {
     return this.getTypedRuleContext(CodeContext,0);
 };
@@ -4960,61 +4973,67 @@ FSHParser.prototype.value = function() {
     var localctx = new ValueContext(this, this._ctx, this.state);
     this.enterRule(localctx, 92, FSHParser.RULE_value);
     try {
-        this.state = 424;
+        this.state = 427;
         this._errHandler.sync(this);
         var la_ = this._interp.adaptivePredict(this._input,39,this._ctx);
         switch(la_) {
         case 1:
             this.enterOuterAlt(localctx, 1);
-            this.state = 415;
+            this.state = 417;
             this.match(FSHParser.STRING);
             break;
 
         case 2:
             this.enterOuterAlt(localctx, 2);
-            this.state = 416;
+            this.state = 418;
             this.match(FSHParser.MULTILINE_STRING);
             break;
 
         case 3:
             this.enterOuterAlt(localctx, 3);
-            this.state = 417;
+            this.state = 419;
             this.match(FSHParser.NUMBER);
             break;
 
         case 4:
             this.enterOuterAlt(localctx, 4);
-            this.state = 418;
+            this.state = 420;
             this.match(FSHParser.DATETIME);
             break;
 
         case 5:
             this.enterOuterAlt(localctx, 5);
-            this.state = 419;
+            this.state = 421;
             this.match(FSHParser.TIME);
             break;
 
         case 6:
             this.enterOuterAlt(localctx, 6);
-            this.state = 420;
-            this.code();
+            this.state = 422;
+            this.reference();
             break;
 
         case 7:
             this.enterOuterAlt(localctx, 7);
-            this.state = 421;
-            this.quantity();
+            this.state = 423;
+            this.code();
             break;
 
         case 8:
             this.enterOuterAlt(localctx, 8);
-            this.state = 422;
-            this.ratio();
+            this.state = 424;
+            this.quantity();
             break;
 
         case 9:
             this.enterOuterAlt(localctx, 9);
-            this.state = 423;
+            this.state = 425;
+            this.ratio();
+            break;
+
+        case 10:
+            this.enterOuterAlt(localctx, 10);
+            this.state = 426;
             this.bool();
             break;
 
@@ -5101,17 +5120,17 @@ FSHParser.prototype.item = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 426;
+        this.state = 429;
         this.match(FSHParser.SEQUENCE);
-        this.state = 427;
+        this.state = 430;
         this.match(FSHParser.CARD);
-        this.state = 431;
+        this.state = 434;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_MOD) | (1 << FSHParser.KW_MS) | (1 << FSHParser.KW_SU))) !== 0)) {
-            this.state = 428;
+            this.state = 431;
             this.flag();
-            this.state = 433;
+            this.state = 436;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -5185,13 +5204,13 @@ FSHParser.prototype.code = function() {
     this.enterRule(localctx, 96, FSHParser.RULE_code);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 434;
+        this.state = 437;
         this.match(FSHParser.CODE);
-        this.state = 436;
+        this.state = 439;
         this._errHandler.sync(this);
         var la_ = this._interp.adaptivePredict(this._input,41,this._ctx);
         if(la_===1) {
-            this.state = 435;
+            this.state = 438;
             this.match(FSHParser.STRING);
 
         }
@@ -5266,13 +5285,13 @@ FSHParser.prototype.concept = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 438;
+        this.state = 441;
         this.code();
-        this.state = 440;
+        this.state = 443;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.STRING) {
-            this.state = 439;
+            this.state = 442;
             this.match(FSHParser.STRING);
         }
 
@@ -5346,9 +5365,9 @@ FSHParser.prototype.quantity = function() {
     this.enterRule(localctx, 100, FSHParser.RULE_quantity);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 442;
+        this.state = 445;
         this.match(FSHParser.NUMBER);
-        this.state = 443;
+        this.state = 446;
         this.match(FSHParser.UNIT);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -5427,11 +5446,11 @@ FSHParser.prototype.ratio = function() {
     this.enterRule(localctx, 102, FSHParser.RULE_ratio);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 445;
+        this.state = 448;
         this.ratioPart();
-        this.state = 446;
+        this.state = 449;
         this.match(FSHParser.COLON);
-        this.state = 447;
+        this.state = 450;
         this.ratioPart();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -5448,6 +5467,87 @@ FSHParser.prototype.ratio = function() {
 };
 
 
+function ReferenceContext(parser, parent, invokingState) {
+	if(parent===undefined) {
+	    parent = null;
+	}
+	if(invokingState===undefined || invokingState===null) {
+		invokingState = -1;
+	}
+	antlr4.ParserRuleContext.call(this, parent, invokingState);
+    this.parser = parser;
+    this.ruleIndex = FSHParser.RULE_reference;
+    return this;
+}
+
+ReferenceContext.prototype = Object.create(antlr4.ParserRuleContext.prototype);
+ReferenceContext.prototype.constructor = ReferenceContext;
+
+ReferenceContext.prototype.REFERENCE = function() {
+    return this.getToken(FSHParser.REFERENCE, 0);
+};
+
+ReferenceContext.prototype.STRING = function() {
+    return this.getToken(FSHParser.STRING, 0);
+};
+
+ReferenceContext.prototype.enterRule = function(listener) {
+    if(listener instanceof FSHListener ) {
+        listener.enterReference(this);
+	}
+};
+
+ReferenceContext.prototype.exitRule = function(listener) {
+    if(listener instanceof FSHListener ) {
+        listener.exitReference(this);
+	}
+};
+
+ReferenceContext.prototype.accept = function(visitor) {
+    if ( visitor instanceof FSHVisitor ) {
+        return visitor.visitReference(this);
+    } else {
+        return visitor.visitChildren(this);
+    }
+};
+
+
+
+
+FSHParser.ReferenceContext = ReferenceContext;
+
+FSHParser.prototype.reference = function() {
+
+    var localctx = new ReferenceContext(this, this._ctx, this.state);
+    this.enterRule(localctx, 104, FSHParser.RULE_reference);
+    var _la = 0; // Token type
+    try {
+        this.enterOuterAlt(localctx, 1);
+        this.state = 452;
+        this.match(FSHParser.REFERENCE);
+        this.state = 454;
+        this._errHandler.sync(this);
+        _la = this._input.LA(1);
+        if(_la===FSHParser.STRING) {
+            this.state = 453;
+            this.match(FSHParser.STRING);
+        }
+
+    } catch (re) {
+    	if(re instanceof antlr4.error.RecognitionException) {
+	        localctx.exception = re;
+	        this._errHandler.reportError(this, re);
+	        this._errHandler.recover(this, re);
+	    } else {
+	    	throw re;
+	    }
+    } finally {
+        this.exitRule();
+    }
+    return localctx;
+};
+
+
 function RatioPartContext(parser, parent, invokingState) {
 	if(parent===undefined) {
 	    parent = null;
@@ -5500,21 +5600,21 @@ FSHParser.RatioPartContext = RatioPartContext;
 FSHParser.prototype.ratioPart = function() {
 
     var localctx = new RatioPartContext(this, this._ctx, this.state);
-    this.enterRule(localctx, 104, FSHParser.RULE_ratioPart);
+    this.enterRule(localctx, 106, FSHParser.RULE_ratioPart);
     try {
-        this.state = 451;
+        this.state = 458;
         this._errHandler.sync(this);
-        var la_ = this._interp.adaptivePredict(this._input,43,this._ctx);
+        var la_ = this._interp.adaptivePredict(this._input,44,this._ctx);
         switch(la_) {
         case 1:
             this.enterOuterAlt(localctx, 1);
-            this.state = 449;
+            this.state = 456;
             this.match(FSHParser.NUMBER);
             break;
 
         case 2:
             this.enterOuterAlt(localctx, 2);
-            this.state = 450;
+            this.state = 457;
             this.quantity();
             break;
 
@@ -5586,11 +5686,11 @@ FSHParser.BoolContext = BoolContext;
 FSHParser.prototype.bool = function() {
 
     var localctx = new BoolContext(this, this._ctx, this.state);
-    this.enterRule(localctx, 106, FSHParser.RULE_bool);
+    this.enterRule(localctx, 108, FSHParser.RULE_bool);
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 453;
+        this.state = 460;
         _la = this._input.LA(1);
         if(!(_la===FSHParser.KW_TRUE || _la===FSHParser.KW_FALSE)) {
         this._errHandler.recoverInline(this);
@@ -5634,8 +5734,8 @@ TargetTypeContext.prototype.SEQUENCE = function() {
     return this.getToken(FSHParser.SEQUENCE, 0);
 };
 
-TargetTypeContext.prototype.REFERENCE = function() {
-    return this.getToken(FSHParser.REFERENCE, 0);
+TargetTypeContext.prototype.reference = function() {
+    return this.getTypedRuleContext(ReferenceContext,0);
 };
 
 TargetTypeContext.prototype.enterRule = function(listener) {
@@ -5666,18 +5766,23 @@ FSHParser.TargetTypeContext = TargetTypeContext;
 FSHParser.prototype.targetType = function() {
 
     var localctx = new TargetTypeContext(this, this._ctx, this.state);
-    this.enterRule(localctx, 108, FSHParser.RULE_targetType);
-    var _la = 0; // Token type
+    this.enterRule(localctx, 110, FSHParser.RULE_targetType);
     try {
-        this.enterOuterAlt(localctx, 1);
-        this.state = 455;
-        _la = this._input.LA(1);
-        if(!(_la===FSHParser.REFERENCE || _la===FSHParser.SEQUENCE)) {
-        this._errHandler.recoverInline(this);
-        }
-        else {
-        	this._errHandler.reportMatch(this);
-            this.consume();
+        this.state = 464;
+        this._errHandler.sync(this);
+        switch(this._input.LA(1)) {
+        case FSHParser.SEQUENCE:
+            this.enterOuterAlt(localctx, 1);
+            this.state = 462;
+            this.match(FSHParser.SEQUENCE);
+            break;
+        case FSHParser.REFERENCE:
+            this.enterOuterAlt(localctx, 2);
+            this.state = 463;
+            this.reference();
+            break;
+        default:
+            throw new antlr4.error.NoViableAltException(this);
         }
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
diff --git a/src/import/generated/FSHVisitor.js b/src/import/generated/FSHVisitor.js
index cde5121..abbcc6b 100644
--- a/src/import/generated/FSHVisitor.js
+++ b/src/import/generated/FSHVisitor.js
@@ -324,6 +324,12 @@ FSHVisitor.prototype.visitRatio = function(ctx) {
 };
 
 
+// Visit a parse tree produced by FSHParser#reference.
+FSHVisitor.prototype.visitReference = function(ctx) {
+  return this.visitChildren(ctx);
+};
+
+
 // Visit a parse tree produced by FSHParser#ratioPart.
 FSHVisitor.prototype.visitRatioPart = function(ctx) {
   return this.visitChildren(ctx);
diff --git a/src/import/parserContexts.ts b/src/import/parserContexts.ts
index 0d999fb..239af14 100644
--- a/src/import/parserContexts.ts
+++ b/src/import/parserContexts.ts
@@ -158,6 +158,7 @@ export interface ValueContext extends ParserRuleContext {
   NUMBER(): ParserRuleContext;
   DATETIME(): ParserRuleContext;
   TIME(): ParserRuleContext;
+  reference(): ReferenceContext;
   code(): CodeContext;
   quantity(): QuantityContext;
   ratio(): RatioContext;
@@ -187,6 +188,10 @@ export interface RatioPartContext extends ParserRuleContext {
   NUMBER(): ParserRuleContext;
   quantity(): QuantityContext;
 }
+export interface ReferenceContext extends ParserRuleContext {
+  REFERENCE(): ParserRuleContext;
+  STRING(): ParserRuleContext;
+}
 
 export interface BoolContext extends ParserRuleContext {
   KW_TRUE(): ParserRuleContext;
@@ -211,7 +216,7 @@ export interface OnlyRuleContext extends ParserRuleContext {
 
 export interface TargetTypeContext extends ParserRuleContext {
   SEQUENCE(): ParserRuleContext;
-  REFERENCE(): ParserRuleContext;
+  reference(): ReferenceContext;
 }
 
 export interface CaretValueRuleContext extends ParserRuleContext {


Test patch:
diff --git a/test/export/InstanceExporter.test.ts b/test/export/InstanceExporter.test.ts
index 3b822ea..3d644e0 100644
--- a/test/export/InstanceExporter.test.ts
+++ b/test/export/InstanceExporter.test.ts
@@ -2,7 +2,7 @@ import { InstanceExporter, StructureDefinitionExporter } from '../../src/export'
 import { FSHTank, FSHDocument } from '../../src/import';
 import { FHIRDefinitions, loadFromPath } from '../../src/fhirdefs';
 import { ResolveFn } from '../../src/fhirtypes';
-import { Instance, Profile, FshCode } from '../../src/fshtypes';
+import { Instance, Profile, FshCode, FshReference } from '../../src/fshtypes';
 import { FixedValueRule } from '../../src/fshtypes/rules';
 import { loggerSpy } from '../testhelpers/loggerSpy';
 import { getResolver } from '../testhelpers/getResolver';
@@ -304,5 +304,34 @@ describe('InstanceExporter', () => {
       expect(exported.address[0]._line[1].extension.length).toBe(1);
       expect(exported.address[0]._line[1].extension[0].url).toBe('bar');
     });
+
+    // Fixing References
+    it('should fix a reference while resolving the Instance being referred to', () => {
+      const orgInstance = new Instance('TestOrganization');
+      orgInstance.instanceOf = 'Organization';
+      const fixedIdRule = new FixedValueRule('id');
+      fixedIdRule.fixedValue = 'org-id';
+      orgInstance.rules.push(fixedIdRule);
+      const fixedRefRule = new FixedValueRule('managingOrganization');
+      fixedRefRule.fixedValue = new FshReference('TestOrganization');
+      instance.rules.push(fixedRefRule);
+      doc.instances.set(instance.name, instance);
+      doc.instances.set(orgInstance.name, orgInstance);
+      const exported = exporter.exportInstance(instance);
+      expect(exported.managingOrganization).toEqual({
+        reference: 'Organization/org-id'
+      });
+    });
+
+    it('should fix a reference without replacing if the referred Instance does not exist', () => {
+      const fixedRefRule = new FixedValueRule('managingOrganization');
+      fixedRefRule.fixedValue = new FshReference('http://example.com');
+      instance.rules.push(fixedRefRule);
+      doc.instances.set(instance.name, instance);
+      const exported = exporter.exportInstance(instance);
+      expect(exported.managingOrganization).toEqual({
+        reference: 'http://example.com'
+      });
+    });
   });
 });
diff --git a/test/export/StructureDefinitionExporter.test.ts b/test/export/StructureDefinitionExporter.test.ts
index 25828eb..9d5730b 100644
--- a/test/export/StructureDefinitionExporter.test.ts
+++ b/test/export/StructureDefinitionExporter.test.ts
@@ -1,7 +1,7 @@
 import { StructureDefinitionExporter } from '../../src/export';
 import { FSHTank, FSHDocument } from '../../src/import';
 import { FHIRDefinitions, loadFromPath } from '../../src/fhirdefs';
-import { Profile, Extension, FshCode } from '../../src/fshtypes';
+import { Profile, Extension, FshCode, FshReference, Instance } from '../../src/fshtypes';
 import {
   CardRule,
   FlagRule,
@@ -661,6 +661,29 @@ describe('StructureDefinitionExporter', () => {
     });
   });
 
+  it('should apply a Reference FixedValueRule and replace the Reference', () => {
+    const profile = new Profile('Foo');
+    profile.parent = 'Observation';
+
+    const instance = new Instance('Bar');
+    instance.id = 'bar-id';
+    instance.instanceOf = 'Patient';
+    doc.instances.set(instance.name, instance);
+
+    const rule = new FixedValueRule('subject');
+    rule.fixedValue = new FshReference('Bar');
+    profile.rules.push(rule);
+
+    exporter.exportStructDef(profile);
+    const sd = exporter.profileDefs[0];
+
+    const fixedSubject = sd.findElement('Observation.subject');
+
+    expect(fixedSubject.patternReference).toEqual({
+      reference: 'Patient/bar-id'
+    });
+  });
+
   it('should not apply an incorrect FixedValueRule', () => {
     const profile = new Profile('Foo');
     profile.parent = 'Observation';
diff --git a/test/fhirtypes/ElementDefinition.fixFshReference.test.ts b/test/fhirtypes/ElementDefinition.fixFshReference.test.ts
new file mode 100644
index 0000000..efb99a0
--- /dev/null
+++ b/test/fhirtypes/ElementDefinition.fixFshReference.test.ts
@@ -0,0 +1,123 @@
+import { loadFromPath } from '../../src/fhirdefs/load';
+import { FHIRDefinitions } from '../../src/fhirdefs/FHIRDefinitions';
+import { StructureDefinition } from '../../src/fhirtypes/StructureDefinition';
+import { FshReference } from '../../src/fshtypes';
+import { getResolver } from '../testhelpers/getResolver';
+import { ResolveFn } from '../../src/fhirtypes';
+import path from 'path';
+
+describe('ElementDefinition', () => {
+  let defs: FHIRDefinitions;
+  let observation: StructureDefinition;
+  let fshReference1: FshReference;
+  let fshReference2: FshReference;
+  let resolve: ResolveFn;
+
+  beforeAll(() => {
+    defs = new FHIRDefinitions();
+    loadFromPath(
+      path.join(__dirname, '..', 'testhelpers', 'testdefs', 'package'),
+      'testPackage',
+      defs
+    );
+    resolve = getResolver(defs);
+  });
+  beforeEach(() => {
+    observation = resolve('Observation');
+    fshReference1 = new FshReference('foo', 'bar');
+    fshReference2 = new FshReference('otherFoo', 'otherBar');
+  });
+
+  describe('#fixFshReference', () => {
+    it('should fix a FshReference to a Reference', () => {
+      const subject = observation.elements.find(e => e.id === 'Observation.subject');
+      subject.fixFshReference(fshReference1);
+      expect(subject.patternReference).toEqual({
+        reference: 'foo',
+        display: 'bar'
+      });
+    });
+
+    it('should fix a FshReference to a Reference allowing a more specific display', () => {
+      const subject = observation.elements.find(e => e.id === 'Observation.subject');
+      subject.fixFshReference(new FshReference('foo'));
+      expect(subject.patternReference).toEqual({
+        reference: 'foo'
+      });
+      subject.fixFshReference(new FshReference('foo', 'bar'));
+      expect(subject.patternReference).toEqual({
+        reference: 'foo',
+        display: 'bar'
+      });
+    });
+
+    it('should throw NoSingleTypeError when element has multiple types', () => {
+      const valueX = observation.elements.find(e => e.id === 'Observation.value[x]');
+      expect(() => {
+        valueX.fixFshReference(fshReference1);
+      }).toThrow(
+        'Cannot fix Reference value on this element since this element does not have a single type'
+      );
+    });
+
+    it('should throw ValueAlreadyFixedError when the value is fixed to a different value', () => {
+      const subject = observation.elements.find(e => e.id === 'Observation.subject');
+      subject.fixFshReference(fshReference1);
+      // should be able to fix a Reference twice in the same way without issue
+      subject.fixFshReference(fshReference1);
+      expect(subject.patternReference).toEqual({
+        reference: 'foo',
+        display: 'bar'
+      });
+      // different value
+      expect(() => {
+        subject.fixFshReference(fshReference2);
+      }).toThrow(
+        'Cannot fix Reference(otherFoo) "otherBar" to this element; a different Reference is already fixed: Reference(foo) "bar"'
+      );
+    });
+
+    it('should throw ValueAlreadyFixedError when the value is fixed to a different value and a display is added', () => {
+      const subject = observation.elements.find(e => e.id === 'Observation.subject');
+      subject.fixFshReference(new FshReference('foo'));
+      expect(subject.patternReference).toEqual({
+        reference: 'foo'
+      });
+      expect(() => subject.fixFshReference(new FshReference('bar', 'bar'))).toThrow(
+        'Cannot fix Reference(bar) "bar" to this element; a different Reference is already fixed: Reference(foo)'
+      );
+    });
+
+    it('should throw ValueAlreadyFixedError when the value is fixed to a different value, no display', () => {
+      const subject = observation.elements.find(e => e.id === 'Observation.subject');
+      subject.fixFshReference(new FshReference('foo'));
+      // should be able to fix a Reference twice in the same way without issue
+      subject.fixFshReference(new FshReference('foo'));
+      expect(subject.patternReference).toEqual({
+        reference: 'foo'
+      });
+      // different value
+      expect(() => {
+        subject.fixFshReference(new FshReference('bar'));
+      }).toThrow(
+        'Cannot fix Reference(bar) to this element; a different Reference is already fixed: Reference(foo).'
+      );
+    });
+
+    it('should throw MismatchedTypeError when the value is fixed to a non-Reference', () => {
+      const status = observation.elements.find(e => e.id === 'Observation.status');
+      // with units
+      expect(() => {
+        status.fixFshReference(fshReference1);
+      }).toThrow(
+        'Cannot fix Reference value: Reference(foo) "bar". Value does not match element type: code'
+      );
+      // without units
+      expect(() => {
+        status.fixFshReference(new FshReference('foo'));
+      }).toThrow(
+        'Cannot fix Reference value: Reference(foo). Value does not match element type: code'
+      );
+    });
+  });
+});
diff --git a/test/fhirtypes/ElementDefinition.fixValue.test.ts b/test/fhirtypes/ElementDefinition.fixValue.test.ts
index d7ac6c6..24f052c 100644
--- a/test/fhirtypes/ElementDefinition.fixValue.test.ts
+++ b/test/fhirtypes/ElementDefinition.fixValue.test.ts
@@ -2,7 +2,7 @@ import { loadFromPath } from '../../src/fhirdefs/load';
 import { FHIRDefinitions } from '../../src/fhirdefs/FHIRDefinitions';
 import { StructureDefinition } from '../../src/fhirtypes/StructureDefinition';
 import { FshCode } from '../../src/fshtypes/FshCode';
-import { FshQuantity, FshRatio } from '../../src/fshtypes';
+import { FshQuantity, FshRatio, FshReference } from '../../src/fshtypes';
 import { getResolver } from '../testhelpers/getResolver';
 import { ResolveFn } from '../../src/fhirtypes';
 import path from 'path';
@@ -92,5 +92,14 @@ describe('ElementDefinition', () => {
         }
       });
     });
+
+    it('should fix a FshReference', () => {
+      const subject = medicationRequest.elements.find(e => e.id === 'MedicationRequest.subject');
+      subject.fixValue(new FshReference('foo', 'bar'));
+      expect(subject.patternReference).toEqual({
+        reference: 'foo',
+        display: 'bar'
+      });
+    });
   });
 });
diff --git a/test/import/FSHImporter.Profile.test.ts b/test/import/FSHImporter.Profile.test.ts
index 58d3c1e..021ea17 100644
--- a/test/import/FSHImporter.Profile.test.ts
+++ b/test/import/FSHImporter.Profile.test.ts
@@ -7,7 +7,7 @@ import {
   assertContainsRule,
   assertCaretValueRule
 } from '../testhelpers/asserts';
-import { FshCode, FshQuantity, FshRatio } from '../../src/fshtypes';
+import { FshCode, FshQuantity, FshRatio, FshReference } from '../../src/fshtypes';
 import { loggerSpy } from '../testhelpers/loggerSpy';
 import { importSingleText } from '../testhelpers/importSingleText';
 
@@ -650,6 +650,64 @@ describe('FSHImporter', () => {
           .withFile('');
         assertFixedValueRule(profile.rules[0], 'valueRatio', expectedRatio);
       });
+
+      it('should parse fixed value Reference rule', () => {
+        const input = `
+
+        Profile: ObservationProfile
+        Parent: Observation
+        * basedOn = Reference(fooProfile)
+        `;
+
+        const result = importSingleText(input);
+        const profile = result.profiles.get('ObservationProfile');
+        expect(profile.rules).toHaveLength(1);
+
+        const expectedReference = new FshReference('fooProfile')
+          .withLocation([5, 21, 5, 41])
+          .withFile('');
+        assertFixedValueRule(profile.rules[0], 'basedOn', expectedReference);
+      });
+
+      it('should parse fixed value Reference rules while allowing and translating aliases', () => {
+        const input = `
+        Alias: FOO = http://hl7.org/fhir/StructureDefinition/Foo
+
+        Profile: ObservationProfile
+        Parent: Observation
+        * basedOn = Reference(FOO) "bar"
+        `;
+
+        const result = importSingleText(input);
+        const profile = result.profiles.get('ObservationProfile');
+        expect(profile.rules).toHaveLength(1);
+
+        const expectedReference = new FshReference(
+          'http://hl7.org/fhir/StructureDefinition/Foo',
+          'bar'
+        )
+          .withLocation([6, 21, 6, 40])
+          .withFile('');
+        assertFixedValueRule(profile.rules[0], 'basedOn', expectedReference);
+      });
+
+      it('should parse fixed value Reference rule with a display string', () => {
+        const input = `
+
+        Profile: ObservationProfile
+        Parent: Observation
+        * basedOn = Reference(fooProfile) "bar"
+        `;
+
+        const result = importSingleText(input);
+        const profile = result.profiles.get('ObservationProfile');
+        expect(profile.rules).toHaveLength(1);
+
+        const expectedReference = new FshReference('fooProfile', 'bar')
+          .withLocation([5, 21, 5, 47])
+          .withFile('');
+        assertFixedValueRule(profile.rules[0], 'basedOn', expectedReference);
+      });
     });
 
     describe('#onlyRule', () => {