css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <header>
  <h1>Shadowrun&trade; Demo Sheet (JSON-powered)</h1>
</header>

<main>

  <div id="Core">
    <p>
      The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
    </p>
  </div>

  <div id="Magic">
    <p>
      The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
    </p>
  </div>

  <div id="Cyber">
    <p>
      The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
    </p>
  </div>

  <div id="VehicleDrone">
    <p>
      The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
    </p>
  </div>

  <div id="Notes">
    <p>
      The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
    </p>
  </div>
</main>

<footer>
  <ul>
    <li><a href="https://s.codepen.io/aardrian/pen/aLRwBV" target="_top">Static version</a> of this experiment.</li>
    <li><a href="https://jsonformatter.curiousconcept.com/">JSON Formatter &amp; Validator</a></li>
    <li><a href="https://www.danstools.com/javascript-minify/">JavaScript Minifier</a></li>
  </ul>
</footer>
            
          
!
            
              body {
  padding: .25em;
  margin: 0;
  font-family: "Open Sans", Arial, sans-serif;
  line-height: 1.4;
  background-color: #fff;
  color: #333;
  background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/2729/Shadowrun_bg.svg);
  background-repeat: no-repeat;
  background-position: 50% 10em;
  background-size: contain;
}

h1 {
  font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
  font-weight: bold;
  font-size: 200%;
  margin: 0;
  line-height: 1.0;
}

article {
  margin: 2em 0;
}

@media print {
  body, main {
    margin: 0;
    padding: 0;
  }
  article {
    page-break-inside: avoid;
  }
  footer {
    display: none;
  }
}

@media screen and (min-width: 68em), print and (min-width: 6in) {
  main > div {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-gap: 1em 2em;
  }
}

@media screen and (min-width: 80em), print and (min-width: 7in) {
  main > div {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
    grid-gap: 1em 2em;
  }
}

@media print and (min-width: 6in) {
  main > div {
    grid-gap: 0.25in 0.25in;
    margin: 0.25in 0;
  }
}

h2 {
  font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
  font-weight: bold;
  font-size: 150%;
  line-height: 1.0;
/*   padding: 0.2em 1.5em 0.2em 0.4em; */
/*   background: linear-gradient(
    -135deg,
    transparent 0,
    transparent 1.5em,
    #5a0a0d 1.5em,
    #5a0a0d 100%
  ); */
  margin: 0 0 0.5em 0;
  border-bottom: .1rem solid #5a0a0d;
  display: flex;
}

h2 span:first-child {
  padding: 0.2em 0 0.2em 0.4em;
  color: #fff;
  background-color: #5a0a0d;
}

h2 span:last-child {
  background: linear-gradient(
    -135deg,
    transparent 0,
    transparent calc(100% - 1em),
    #5a0a0d calc(100% - 1em),
    #5a0a0d 100%
  );
  flex-grow: 1;
}

@media print {
  body {
    font-size: 6pt;
    color: #000;
    background-color: #fff;
    margin: 0;
    padding: 0;
  }
}

@media all and (min-width: 30em) {
  body {
    padding: 1vw;
  }
  article {
    border-left: 0.1rem solid #5a0a0d;
  }
  article > *:not(h2) {
    margin-left: .5em;
    margin-right: .5em;
  }
  h2 {
    margin: 0 0 0.5em 0;
  }
}

@media print {
  h2 {
    background: transparent;
    color: #000;
    border-bottom: 0.1em solid #000;
  }
  h2 span:first-child {
    background-color: #999;
  }
  h2 span:last-child {
    background: linear-gradient(
      -135deg,
      transparent 0,
      transparent calc(100% - 1em),
      #999 calc(100% - 1em),
      #999 100%
    );
  }
  article {
    border-left: none;
    margin: 0;
  }
}

p > strong:first-child {
  font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
  font-weight: bold;
}

p.boxes {
  display: flex;
  flex-wrap: wrap;
}

p.boxes strong {
  flex-basis: 100%;
}

p.boxes span {
  flex: 0 0 auto;
  height: auto;
  padding: 0 .15em;
  margin: 0;
}

p.boxes span:nth-of-type(3n) {
  background-color: #eee;
  font-weight: bold;
}

dl {
  display: grid;
  grid-template-columns: auto auto auto auto auto auto;
/*  Disabled until anything other than WebKit supports it  */
/*   grid-template-columns: repeat(auto-fill, minmax(4em, 1fr)); */
  grid-gap: 0.1em 0;
}

/* All these media queries can go away when other browsers support the minmax bits below. */
@media all and (min-width: 28em) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto;
  }
  dt::after {
    content: ":";
  }
}

@media all and (min-width: 34em) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
  }
}

@media all and (min-width: 40em) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto
      auto auto;
  }
}

@media all and (min-width: 46em) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto
      auto auto auto auto;
  }
}

@media all and (min-width: 52em) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto
      auto auto auto auto auto auto;
  }
}

@media all and (min-width: 58em) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto
      auto auto auto auto auto auto auto auto;
  }
}

@media all and (min-width: 64em) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto
      auto auto auto auto auto auto auto auto auto auto;
  }
}

@media screen and (min-width: 68em), print and (min-width: 7in) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto
      auto auto auto auto;
  }
}

@media screen and (min-width: 70em), print and (min-width: 8in) {
  dl {
    grid-template-columns: auto auto auto auto auto auto auto auto auto auto
      auto auto auto auto auto auto;
  }
}

@supports (grid-template-columns: repeat(auto-fill, minmax(4em, 1fr) minmax(4em, 1fr))) {
  dl {
    grid-template-columns: repeat(auto-fill, minmax(3.75em, 1fr) minmax(3.75em, 1fr));
  }
}

dt {
  font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
  font-weight: bold;
}

dd {
  margin: 0;
  padding: 0 0.5em 0 0.25em;
}

table {
  border-collapse: collapse;
  width: calc(100% - 1em);
  max-width: 100%;
}

table caption {
  color: #f00;
  position: absolute;
  top: auto;
  overflow: hidden;
  clip: rect(1px 1px 1px 1px); /* IE 6/7 */
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px;
  height: 1px;
  white-space: nowrap;
}

th,
td {
  text-align: center;
  padding: 0.2em 0.4em;
  border-bottom: 0.02em solid #ccc;
}

th {
  font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
  font-weight: bold;
  vertical-align: bottom;
}

td {
  vertical-align: top;
}

th:first-child,
td:first-child {
  text-align: left;
}

ul {
  padding-left: 1em;
}

@media all and (min-width: 40em) {
  article div > ul {
    column-count: 2;
    column-gap: 2em;
  }
}

@media all and (min-width: 80em), print and (min-width: 9in) {
  article div > ul {
    column-count: 3;
    column-gap: 2em;
  }
}

/* Layout that must be customized for every set of blocks */

@media screen and (min-width: 68em), print and (min-width: 6in) {
  #Core {
    grid-template-areas:
      "C1  C3"
      "C2  C5"
      "C6  C9"
      "C7  C9"
      "C8  C9"
      "C10 C4"
      "C11 C4";
  }
  #Magic {
    grid-template-areas:
      "M1 M2";
  }
  #Cyber {
    grid-template-areas:
      "A1 A2";
  }
  #VehicleDrone {
    grid-template-areas:
      "V6 V4"
      "V3 V2"
      "V1 V1"
      "V5 V7";
  }
  #Notes {
    grid-template-areas:
      "N2 N1";
  }
}

@media screen and (min-width: 80em), print and (min-width: 7in) {
  #Core {
    grid-template-areas:
      "C1  C1  C1  C1  C1  C1  C3  C3  C3  C3  C3  C3"
      "C2  C2  C2  C2  C6  C6  C6  C6  C4  C4  C4  C4"
      "C2  C2  C2  C2  C6  C6  C6  C6  C4  C4  C4  C4"
      "C7  C7  C7  C7  C8  C8  C8  C8  C4  C4  C4  C4"
      "C11 C11 C11 C11 C11 C11 C11 C11 C4  C4  C4  C4"
      "C5  C5  C5  C5  C5  C10 C10 C10 C10 C10 C10 C10"
      "C9  C9  C9  C9  C9  C9  C9  C9  C9  C9  C9  C9";
  }
  #Magic {
    grid-template-areas:
      "M1 M1 M1 M1 M1 M1 M2 M2 M2 M2 M2 M2";
  }
  #Cyber {
    grid-template-areas:
      "A1 A1 A1 A1 A2 A2 A2 A2 A2 A2 A2 A2";
  }
  #VehicleDrone {
    grid-template-areas:
      "V1 V1 V1 V1 V1 V1 V4 V4 V4 V4 V4 V4"
      "V1 V1 V1 V1 V1 V1 V5 V5 V5 V5 V5 V5"
      "V1 V1 V1 V1 V1 V1 V6 V6 V6 V6 V6 V6"
      "V1 V1 V1 V1 V1 V1 V7 V7 V7 V7 V7 V7"
      "V2 V2 V2 V2 V2 V2 V3 V3 V3 V3 V3 V3";
  }
  #Notes {
    grid-template-areas:
      "N2 N2 N2 N2 N2 N2 N1 N1 N1 N1 N1 N1";
  }
}

#PersonalData {
  grid-area: C1;
}

#Attributes {
  grid-area: C2;
}

#ConditionMonitor {
  grid-area: C3;
}

#Skills {
  grid-area: C4;
}

#IDLifestyleCurrency {
  grid-area: C5;
}

#Armor {
  grid-area: C6;
}

#RangedWeapons {
  grid-area: C7;
}

#MeleeWeapons {
  grid-area: C8;
}

#Qualities {
  grid-area: C9;
}

#Contacts {
  grid-area: C10;
}

#Gear {
  grid-area: C11;
}

#Spells {
  grid-area: M1;
}

#AdeptPowers {
  grid-area: M2;
}

#Augmentation {
  grid-area: A1;
}

#ProteusPoseidonRCC {
  grid-area: A2;
}

#GMCBulldog {
  grid-area: V1;
}

#GMNissanDoberman {
  grid-area: V2;
}

#MCTNissanRotodrone {
  grid-area: V3;
}

#MCTFlyspy {
  grid-area: V4;
}

#HorizonNoizquito {
  grid-area: V5;
}

#SonyNightingale {
  grid-area: V6;
}

#MCTSevenSwims {
  grid-area: V7;
}

#RiggingPools {
  grid-area: N1;
}

#Background {
  grid-area: N2;
}

#Augmentation table th:nth-child(3), #Augmentation table td:nth-child(3), #Armor table th:nth-child(3), #Armor table td:nth-child(3), #Qualities table th:nth-child(2), #Qualities table td:nth-child(2), #AdeptPowers table th:nth-child(2), #AdeptPowers table td:nth-child(2), #Contacts table th:nth-child(2), #Contacts table td:nth-child(2), #Contacts table th:nth-child(5), #Contacts table td:nth-child(5), #Skills table th:nth-child(2), #Skills table td:nth-child(2) {
  text-align: left;
}

#Augmentation table th:nth-child(4), #Augmentation table td:nth-child(4) {
  text-align: right;
}

#ConditionMonitor th:nth-child(2), #ConditionMonitor th:nth-child(3), #ConditionMonitor th:nth-child(5), #ConditionMonitor th:nth-child(6), #ConditionMonitor th:nth-child(8), #ConditionMonitor th:nth-child(9), #ConditionMonitor th:nth-child(11), #ConditionMonitor th:nth-child(12) {
  color: transparent;
   font-size: 70%;
}

#ConditionMonitor td:nth-child(4), #ConditionMonitor td:nth-child(7), #ConditionMonitor td:nth-child(10), #ConditionMonitor td:nth-child(13) {
  background-color: #eee;
  font-weight: bold;
}

#PersonalData dl, #IDLifestyleCurrency dl {
  grid-template-columns: auto auto auto auto;
}

#Attributes dl {
  grid-template-columns: auto auto auto auto;
}
#Attributes dd:nth-child(-n+20) {
  font-size: 150%;
  align-self: end;
}
#Attributes dt:nth-child(-n+20) {
  align-self: end;
}
#Attributes *:nth-child(21), #Attributes *:nth-child(22), #Attributes *:nth-child(23), #Attributes *:nth-child(24) {
  margin-top: 1em;
}

#VehicleDrone {
  page-break-before: always;
}
            
          
!
            
              // Verify the JSON is JSON
// https://jsonformatter.curiousconcept.com/
// Minify the JSON for use below
// https://www.cleancss.com/json-minify/
// Minify the HTML node
// https://www.willpeavy.com/minifier/
// Escape the HTML for the JSON
// https://www.freeformatter.com/json-escape.html
var stuff = {
   "title":"Shadowrun",
   "items":[
      {
         "card":"Core",
         "type":"",
         "name":"Personal Data",
         "attributes":{
            "Name / Primary Alias":"Fender / Benjamin Toma",
            "Metatype":"Human",
            "Ethnicity":"Caucasian / Japanese",
            "Age":"24",
            "Sex":"Male",
            "Height":"5&#8242;6&#8243;",
            "Weight":"120# / 54kg",
            "Street Cred":"9",
            "Notoriety":"1",
            "Public Awareness":"1",
            "Karma":"0",
            "Total Karma":"84"
         }
      },
      {
         "card":"Core",
         "type":"",
         "name":"Attributes",
         "attributes":{
            "Body":"3",
            "Agility":"3",
            "Reaction":"5",
            "Strength":"3",
            "Willpower":"4",
            "Logic":"3",
            "Intuition":"4",
            "Charisma":"2",
            "Edge":"3",
            "Magic":"4",
            "Essence":"4.04",
            "Initiative":"9+1D6",
            "Matrix Initiative":"9+3D6/4D6",
            "Astral Initiative":"8+2D6",
            "Composure":"6",
            "Judge Intentions":"6",
            "Memory":"7",
            "Lift/Carry":"45kg/30kg",
            "Movement":"Walk 6; Run 12",
            "Physical Limit":"5(6)",
            "Mental Limit":"5",
            "Social Limit":"4"
         }
      },
      {
         "card":"Core",
         "type":"",
         "name":"Condition Monitor",
         "attributes":{
            "Overflow":"3"
         },
         "Notes":"For every 3 boxes of damage on any one damage track, the character takes a -1 Dice Pool modifier on tests; these modifiers are cumulative within and across damage tracks. See <em>Wound Modifiers<\/em> p.169.",
         "table":"Condition Monitor",
         "row":[
            {
               "Track":"Physical",
               "&minus;⅓":"&#9711;",
               "&minus;‌⅔":"&#9711;",
               "&minus;1":"&#9711;",
               "&minus;1⅓":"&#9711;",
               "&minus;‌1⅔":"&#9711;",
               "&minus;2":"&#9711;",
               "&minus;2⅓":"&#9711;",
               "&minus;‌2⅔":"&#9711;",
               "&minus;3":"&#9711;",
               "&minus;3⅓":"&#9711;"
            },
            {
               "Track":"Mental",
               "&minus;⅓":"&#9711;",
               "&minus;‌⅔":"&#9711;",
               "&minus;1":"&#9711;",
               "&minus;1⅓":"&#9711;",
               "&minus;‌1⅔":"&#9711;",
               "&minus;2":"&#9711;",
               "&minus;2⅓":"&#9711;",
               "&minus;‌2⅔":"&#9711;",
               "&minus;3":"&#9711;",
               "&minus;3⅓":"&#9711;"
            }
         ]
      },
      {
         "card":"Core",
         "type":"",
         "name":"Skills",
         "table":"Skills",
         "row":[
            {
               "Name":"Pilot Aircraft",
               "Attribute":"Reaction",
               "Rating":"4+2",
               "Type":"A"
            },
            {
               "Name":"Pilot Ground Craft",
               "Attribute":"Reaction",
               "Rating":"4",
               "Type":"A"
            },
            {
               "Name":"Spellcasting",
               "Attribute":"Magic",
               "Rating":"4",
               "Type":"A"
            },
            {
               "Name":"Counterspelling",
               "Attribute":"Magic",
               "Rating":"4",
               "Type":"A"
            },
            {
               "Name":"Gunnery",
               "Attribute":"Agility",
               "Rating":"3",
               "Type":"A"
            },
            {
               "Name":"Hardware",
               "Attribute":"Logic",
               "Rating":"3",
               "Type":"A"
            },
            {
               "Name":"Automotive Mechanic",
               "Attribute":"Logic",
               "Rating":"2",
               "Type":"A"
            },
            {
               "Name":"Aeronautics Mechanic",
               "Attribute":"Logic",
               "Rating":"2",
               "Type":"A"
            },
            {
               "Name":"Computer",
               "Attribute":"Logic",
               "Rating":"2",
               "Type":"A"
            },
            {
               "Name":"Electronic Warfare",
               "Attribute":"Logic",
               "Rating":"2",
               "Type":"A"
            },
            {
               "Name":"Perception",
               "Attribute":"Intuition",
               "Rating":"2",
               "Type":"A"
            },
            {
               "Name":"Automatics",
               "Attribute":"Agility",
               "Rating":"2",
               "Type":"A"
            },
            {
               "Name":"Pilot Watercraft",
               "Attribute":"Reaction",
               "Rating":"2",
               "Type":"A"
            },
            {
               "Name":"Sneaking",
               "Attribute":"Agility",
               "Rating":"1",
               "Type":"A"
            },
            {
               "Name":"Cybercombat",
               "Attribute":"Logic",
               "Rating":"1",
               "Type":"A"
            },
            {
               "Name":"Etiquette",
               "Attribute":"Charisma",
               "Rating":"1",
               "Type":"A"
            },
            {
               "Name":"Assensing",
               "Attribute":"Intuition",
               "Rating":"1",
               "Type":"A"
            },
            {
               "Name":"Demolitions",
               "Attribute":"Logic",
               "Rating":"1",
               "Type":"A"
            },
            {
               "Name":"Drone Designs (Academic)",
               "Attribute":"Logic",
               "Rating":"4",
               "Type":"K"
            },
            {
               "Name":"Mechanics (Street)",
               "Attribute":"Intuition",
               "Rating":"3",
               "Type":"K"
            },
            {
               "Name":"Smuggling Routes (Street)",
               "Attribute":"Intuition",
               "Rating":"2",
               "Type":"K"
            },
            {
               "Name":"Law Enforcement Tactics (Street)",
               "Attribute":"Intuition",
               "Rating":"1",
               "Type":"K"
            },
            {
               "Name":"Runner Hangouts (Street)",
               "Attribute":"Intuition",
               "Rating":"1",
               "Type":"K"
            },
            {
               "Name":"Gang Identification (Street)",
               "Attribute":"Intuition",
               "Rating":"1",
               "Type":"K"
            },
            {
               "Name":"Local Knowledge (Street)",
               "Attribute":"Intuition",
               "Rating":"1",
               "Type":"K"
            },
            {
               "Name":"Vehicle Identification (Academic)",
               "Attribute":"Logic",
               "Rating":"1",
               "Type":"K"
            },
            {
               "Name":"English",
               "Attribute":"",
               "Rating":"N",
               "Type":"K"
            },
            {
               "Name":"Japanese",
               "Attribute":"",
               "Rating":"3",
               "Type":"K"
            },
            {
               "Name":"Korean",
               "Attribute":"",
               "Rating":"1",
               "Type":"K"
            },
            {
               "Name":"Spanish",
               "Attribute":"",
               "Rating":"1",
               "Type":"K"
            }
         ]
      },
      {
         "card":"Core",
         "type":"",
         "name":"ID / Lifestyle / Currency",
         "attributes":{
            "Primary Lifestyle":"Middle, 7 months pre-paid.",
            "Nuyen":"139,050.66 ¥",
            "Licenses":"Gun ×3, Magic ×3, Drive ×6"
         },
         "HTML":"<ul><li>Ben Toma: SIN 4, SMG License 4, Magic License 4, Drivers 4, Drone 4<\/li><li>James Itoh: SIN 4, SMG License 4, Magic License 4, Drivers 4, Drone 4, SAG<\/li><li>Harold Kanagawa: SIN 4, SMG License 4, Magic License 4, Drivers 4, Drone 4<\/li><li>Jon Hikaru: SIN 6, SMG License 6, Magic License 6, Drivers 6, Drone 6<\/ul>"
      },
      {
         "card":"Core",
         "type":"",
         "name":"Armor",
         "table":"Armor",
         "row":[
            {
               "Armor":"Armor Jacket: Fire 6, Chemical 4",
               "Rating":"12",
               "Notes":"Shock Frills, p.438"
            },
            {
               "Armor":"Armor Clothing: Non-conductive 6",
               "Rating":"6",
               "Notes":""
            },
            {
               "Armor":"Formfitting: Non-conductive 6",
               "Rating":"8",
               "Notes":""
            },
            {
               "Armor":"Helmet",
               "Rating":"+2",
               "Notes":""
            }
         ]
      },
      {
         "card":"Core",
         "type":"",
         "name":"Ranged Weapons",
         "table":"Ranged Weapons",
         "row":[
            {
               "Weapon":"Ingram Smartgun X",
               "Dam":"8P",
               "Acc":"4(6)",
               "AP":"—",
               "Mode":"BF/FA",
               "RC":"2",
               "Ammo":"32(c)"
            }
         ]
      },
      {
         "card":"Core",
         "type":"",
         "name":"Melee Weapons",
         "table":"Melee Weapons",
         "row":[
            {
               "Weapon":"Survival Knife",
               "Reach":"—",
               "Dam":"(Str+2)P",
               "Acc":"5",
               "AP":"-1"
            }
         ]
      },
      {
         "card":"Core",
         "type":"",
         "name":"Qualities",
         "table":"Qualities",
         "row":[
            {
               "Quality":"Burnout’s Way",
               "Notes":"Treat augmentation as Alphaware for Essence drain. SG.177",
               "Type":"P"
            },
            {
               "Quality":"Focused Concentration",
               "Notes":"Rating 3: Sustain a Force 3 spell without a -2 penalty. p.74",
               "Type":"P"
            },
            {
               "Quality":"Allergy: Mild: Seafood",
               "Notes":"-2 to physical tests while affected. p.78",
               "Type":"N"
            },
            {
               "Quality":"Insomnia",
               "Notes":"Int + Will (4) to recover Stun at normal rate, otherwise at 2× rate. p.81",
               "Type":"N"
            },
            {
               "Quality":"Spirit Bane: Fire",
               "Notes":"May not obey a party member; will attack me first. p.85",
               "Type":"N"
            }
         ]
      },
      {
         "card":"Core",
         "type":"",
         "name":"Contacts",
         "table":"Contacts",
         "row":[
            {
               "Type":"Fixer",
               "Name":"‘Rerun’ Gibson (LA)",
               "Loyalty":"1",
               "Connection":"3",
               "Favor":""
            },
            {
               "Type":"Smuggler",
               "Name":"Addonis, The (LA)",
               "Loyalty":"1",
               "Connection":"3",
               "Favor":""
            },
            {
               "Type":"Mechanic",
               "Name":"Cathy ‘Crybaby’ Monroe (LA)",
               "Loyalty":"3",
               "Connection":"2",
               "Favor":""
            },
            {
               "Type":"Fixer",
               "Name":"Ganeff (LA)",
               "Loyalty":"2",
               "Connection":"4",
               "Favor":""
            },
            {
               "Type":"Smuggler",
               "Name":"DC (Double-Clutch) (Seattle)",
               "Loyalty":"1",
               "Connection":"3",
               "Favor":""
            },
            {
               "Type":"Madame",
               "Name":"June (LA)",
               "Loyalty":"0",
               "Connection":"",
               "Favor":"2,000¥ credit"
            },
            {
               "Type":"Rigger",
               "Name":"Wheels (LA?)",
               "Loyalty":"1",
               "Connection":"1",
               "Favor":""
            },
            {
               "Type":"Fixer",
               "Name":"Kaz (LA)",
               "Loyalty":"5",
               "Connection":"4",
               "Favor":""
            }
         ]
      },
      {
         "card":"Core",
         "type":"",
         "name":"Gear",
         "HTML":"<ul><li>Commlink: Transys Avalon 6: biometric reader, sub-vocal mic. Rating 6<\/li><li>Glasses: low-light, vision mag, image link, SmartLink Rating 4<\/li><li>Ear buds: audio enhancement 3 Rating 3<\/li><li>Jammer, area Rating 4<\/li><li>Jammer, directional Rating 6<\/li><li>White noise generator Rating 6<\/li><li>Repair shop Rating 3<\/li><li>Respirator Rating 6<\/li><li>Spell Focus: Spellcasting: Manipulation. p.320 Rating 2<\/li><li>Medkit Rating 6<\/li><li>Qi focus: 1951 Nash \u201CCountry Club\u201D 2-door hardtop, chest, licensed (\u00D72) Rating 2<\/li><li>MagLock Passkey Rating 4<\/li><li>Sequencer Rating 6<\/li><li>Flashlight, Toolkit<\/li><li>Tag Eraser<\/li><li>Metal Restraints<\/li><li>Rope (50m), Survival Kit (van)<\/li><li>Rubber bullets (2 boxes, 200 rounds)<\/li><li>Cheap suit<\/li><li>Scuba gear + belt of 4 tanks<\/li><li>200 rounds regular ammo for Ingram Smartgun X<\/li><\/ul>"
      },
      {
         "card":"Magic",
         "type":"",
         "name":"Spells",
         "Notes":"Hermetic: Logic + Willpower to resist Drain.",
         "table":"Spells",
         "row":[
            {
               "Spell":"Stunbolt (Combat, p.284): Stun damage.",
               "Type":"M",
               "Range":"LoS",
               "Duration":"I",
               "Drain":"F-3"
            },
            {
               "Spell":"Levitate (Manip, p.293): Target # = Mass/200kg.",
               "Type":"P",
               "Range":"LoS",
               "Duration":"S",
               "Drain":"F-2"
            },
            {
               "Spell":"Deflection (Manip, SG.115): Bonus to dice pool.",
               "Type":"P",
               "Range":"LoS",
               "Duration":"S",
               "Drain":"F-1"
            },
            {
               "Spell":"Fix (Manip, SG.116): Force × Hits in Kg.",
               "Type":"P",
               "Range":"T",
               "Duration":"P",
               "Drain":"F"
            },
            {
               "Spell":"Physical Barrier (Manip, p.294): Armor/Structure=hits.",
               "Type":"P",
               "Range":"LoS",
               "Duration":"S",
               "Drain":"F-1"
            },
            {
               "Spell":"Mana Barrier (Manip, p.294): Barrier rating = hits.",
               "Type":"M",
               "Range":"LoS",
               "Duration":"S",
               "Drain":"F-2"
            },
            {
               "Spell":"Influence (Manip, p.293): 1 command, minutes=hits.",
               "Type":"P",
               "Range":"LoS",
               "Duration":"P",
               "Drain":"F-1"
            },
            {
               "Spell":"Improved Invisibility (Illusion, p.291): Affects tech.",
               "Type":"P",
               "Range":"LoS",
               "Duration":"S",
               "Drain":"F-1"
            }
         ]
      },
      {
         "card":"Magic",
         "type":"",
         "name":"Adept Powers",
         "table":"Adept Powers",
         "row":[
            {
               "Name":"Metabolic Control",
               "Notes":"Takes 3 hrs instead of 1 for fatigue / sleep deprivation damage. SG.172",
               "Rating":"—"
            },
            {
               "Name":"Hang Time",
               "Notes":"+2 to climb; stick to wall for 10 minutes. SG.171",
               "Rating":"2"
            },
            {
               "Name":"Astral Perception",
               "Notes":"Dual-natured when used. p.309",
               "Rating":"—"
            },
            {
               "Name":"Spell Resistance",
               "Notes":"+2 to resistance tests. p.311",
               "Rating":"2"
            },
            {
               "Name":"Improved Ability",
               "Notes":"Pilot Aircraft: +2 to skill. p.309",
               "Rating":"2"
            },
            {
               "Name":"Improved Potential",
               "Notes":"Raise physical limit by 1 (Qi focus ×2, 1951 Nash ‘Country Club’ 2-door hardtop, chest, licensed)",
               "Rating":"2"
            }
         ]
      },
      {
         "card":"Cyber",
         "type":"",
         "name":"Augmentation",
         "table":"Augmentation",
         "row":[
            {
               "Augmentation":"Control Rig",
               "Rating":"2",
               "Notes":"Add rating to vehicle tests, Speed, Handling, reduce threshold for tests, built-in sim, p.452",
               "Essence":"1.6"
            },
            {
               "Augmentation":"Damage Compensator",
               "Rating":"2",
               "Notes":"Ignore 2 boxes of damage for modifiers, p.460",
               "Essence":"0.16"
            },
            {
               "Augmentation":"Hand",
               "Rating":"",
               "Notes":"Capacity 4, obvious",
               "Essence":"0.2"
            },
            {
               "Augmentation":"• Commlink",
               "Rating":"",
               "Notes":"Takes up 2 in hand",
               "Essence":"—"
            },
            {
               "Augmentation":"• Fingertip Compartment ×2",
               "Rating":"",
               "Notes":"Takes up 1 in hand each, 1 holds microdrone",
               "Essence":""
            }
         ]
      },
      {
         "card":"Cyber",
         "type":"Deck",
         "name":"Proteus Poseidon RCC",
         "attributes":{
            "Rating":"5",
            "Processing":"5",
            "Firewall":"6",
            "Noise Reduc":"4*",
            "Sharing":"1*"
         },
         "Boxes":11,
         "Notes":"Matrix Condition Monitor: 8 + (Device Rating / 2) = 11 (p.228). Resist with Device Rating + Firewall = 11.  p.267. RCC can handle up to 15 slaved drones (Device Rating × 3) (p.267). *Noise Reduction & Sharing combined cannot exceed device Device Rating (p.267). ",
         "table":"Condition Monitor",
         "HTML":"<ul><li>Mapsofts: LA (6), Las Vegas (6), Hong Kong (6)<\/li><li>Common: Encryption (+1 to Firewall)<\/li><li>Common: Signal Scrub (Noise Reduction 2)<\/li><li>Hacking: Armor (+2 to resist damage)<\/li><li>Hacking: Guard (reduce damage 1DV/Mark)<\/li><li>Hacking: Shell (+1 resist damage, stacks)<\/li><li>Hacking: Sneak (+2 resist Trace User)<\/li><li>Hacking: Wrapper (override Matrix icons)<\/li><\/ul>"
      },
      {
         "card":"VehicleDrone",
         "type":"Vehicle (in LA)",
         "name":"GMC Bulldog",
         "attributes":{
            "Handling":"3/3",
            "Acceleration":"2",
            "Speed":"3",
            "Pilot":"1",
            "Body":"16",
            "Armor":"15",
            "Sensor":"4",
            "Anti-theft":"3",
            "ECM":"4",
            "Seats":"9"
         },
         "Boxes":20,
         "Notes":"Condition Monitor: 12 + (Bod/2) = 20. p.463. Rigger control, tinted windows, medkit (5), toolkit, smuggling compartment, chameleon skin, concealed turret, Gridlink override, drone racks: micro, medium ×3 (1 landing).",
         "table":"Armament",
         "row":[
            {
               "Weapon":"AK-97",
               "Dam":"10P",
               "Acc":"5",
               "AP":"−2",
               "Mode":"SA/BF/FA",
               "RC":"—",
               "Ammo":"38(c)"
            }
         ],
         "HTML":"<ul> <li>Morphing license plates, complex action to change, R5.152<\/li><li>Spoof chip, R5.152<\/li><li>Run-flat tires, continue to work if punctured, R5.153<\/li><li>Power-train (14 slots remain) <ul> <li>Acceleration Enhancement 1 (4 slots), R5.154<\/li><li>Rigger cocoon (2 slots), Armor 12, Structure 8, +6 resist, R5.156<\/li><\/ul> <\/li><li>Protection (4 slots remain) <ul> <li>Anti-theft system 3 (4 slots), Lockdown, Shock 9S(e), R5.159<\/li><li>Armor, concealed 3 (12 slots), Perception (4) to notice, R5.159<\/li><\/ul> <\/li><li>Weapons (1 slot remains) <ul> <li>Drone rack: micro, landing (2 slots), holds 10 minidrones, R5.160<\/li><li>Drone rack: medium, x2 (6 slots), total of two medium, R5.160<\/li><li>Drone rack: medium, landing (8 slots), 1 medium, complex action, R5.160<\/li><li>Mount: standard, concealed, turret, remote (+4 slots), R5.163<\/li><li>Gun ports: x3 (3 slots), 4 point recoil compensation harness, R5.160<\/li><\/ul> <\/li><li>Body (13 slots remain) <ul> <li>Chameleon coating (2 slots), simple action to change, R5.163<\/li><li>Smuggling compartment (3 slots), 10-20% vehicle size, R5.165<\/li><li>Increased seating (1 slot), R5.164<\/li><li>Fridge (1 slot), as Special Equipment for 500\u00A5, R5.165<\/li><\/ul> <\/li><li>Electronics (5 slots remain) <ul> <li>ECM 4 (2 slots), as Area Jammer, R5.166<\/li><li>GridLink override (1 slot), presents as normal to GridLink, R5.167<\/li><li>Sensor Upgrade 4 (12 slots), R5.168<\/li><\/ul> <\/li><\/ul>"
      },
      {
         "card":"VehicleDrone",
         "type":"Drone (in LA)",
         "name":"GM-Nissan Doberman",
         "attributes":{
            "Handling":"5",
            "Acceleration":"1",
            "Speed":"3",
            "Pilot":"1",
            "Body":"4",
            "Armor":"4",
            "Sensor":"3"
         },
         "Boxes":8,
         "Notes":"Condition Monitor: 6 + (Bod/2) = 8. p.466, Medium drone. External flexible weapon mount. Clearsight (from RCC) 3, Doberman Stealth 3, Doberman Maneuvering 3, AK-97 Targeting 3, Recoil comp = Body (4).",
         "table":"Armament",
         "row":[
            {
               "Weapon":"AK-97",
               "Dam":"10P",
               "Acc":"5",
               "AP":"−2",
               "Mode":"SA/BF/FA",
               "RC":"—",
               "Ammo":"38(c)"
            }
         ]
      },
      {
         "card":"VehicleDrone",
         "type":"Drone",
         "name":"MCT-Nissan Roto-drone",
         "attributes":{
            "Handling":"4",
            "Acceleration":"4",
            "Speed":"3",
            "Pilot":"3",
            "Body":"4",
            "Armor":"4",
            "Sensor":"3"
         },
         "Boxes":8,
         "Notes":"Condition Monitor: 6 + (Bod/2) = 8. p.466, Medium roto-drone ×2. Light fixed external weapon mount. Clearsight (from RCC) 3, Roto-Drone Stealth 3, RD Maneuvering 3, Ingram Smartgun Targeting 3, Recoil comp = Body (4).",
         "table":"Armament",
         "row":[
            {
               "Weapon":"Ingram Smartgun X",
               "Dam":"8P",
               "Acc":"4(6)",
               "AP":"—",
               "Mode":"BF/FA",
               "RC":"2",
               "Ammo":"32(c)"
            }
         ]
      },
      {
         "card":"VehicleDrone",
         "type":"Drone",
         "name":"MCT Fly-spy",
         "attributes":{
            "Handling":"4",
            "Acceleration":"2",
            "Speed":"3",
            "Pilot":"3",
            "Body":"1",
            "Armor":"0",
            "Sensor":"3"
         },
         "Boxes":7,
         "Notes":"Condition Monitor: 6 + (Bod/2) = 7. p.466, Minidrone. Two of these, same configuration. Clearsight 3, Fly-Spy Stealth 3, Fly-Spy Manuevering 3, Fly-Spy Evasion 3."
      },
      {
         "card":"VehicleDrone",
         "type":"Drone",
         "name":"Horizon “Noizquito”",
         "attributes":{
            "Handling":"4",
            "Acceleration":"2",
            "Speed":"3R",
            "Pilot":"3",
            "Body":"1",
            "Armor":"0",
            "Sensor":"3"
         },
         "Boxes":7,
         "Notes":"Condition Monitor: 6 + (Bod/2) = 7. R5.128, Microdrone. Can produce audio at 160db, strobe patterns. Strobes impose −2 looking in direction of drone, −1 with compensation. Speakers impose −2 for those in earshot, −1 if sound dampener."
      },
      {
         "card":"VehicleDrone",
         "type":"Drone",
         "name":"Sony Nightingale",
         "attributes":{
            "Handling":"4",
            "Acceleration":"1",
            "Speed":"2R",
            "Pilot":"2",
            "Body":"1(1)",
            "Armor":"0",
            "Sensor":"2"
         },
         "Boxes":7,
         "Notes":"Condition Monitor: 6 + (Bod/2) = 7. R5.129, Minidrone. Realistic features (1). Clearsight (from RCC) 3, Nightingale Stealth 3, Nightingale Maneuvering 3, requires Pilot Exotic Vehicle skill (default to Reaction)."
      },
      {
         "card":"VehicleDrone",
         "type":"Drone",
         "name":"MCT Seven “Swims”",
         "attributes":{
            "Handling":"3",
            "Acceleration":"1",
            "Speed":"2W",
            "Pilot":"1",
            "Body":"1(3)",
            "Armor":"0",
            "Sensor":"1"
         },
         "Boxes":7,
         "Notes":"Condition Monitor: 6 + (Bod/2) = 7. R5.134, Small water drone."
      },
      {
         "card":"Notes",
         "type":"",
         "name":"Rigging Pools",
         "HTML":"<ul><li>Maneuver (rigged): Skill + Int + 2 [Handling]<ul><li>Van: 4 + 4 + 2 [3 + 2]<\/li><li>MCT: 5 + 4 + 2 [4 + 2]<\/li><li>Fly spy: 6 + 4 + 2 [4 + 2]<\/li><li>Bird: 6 + 4 + 2 [4 + 2]<\/li><\/ul><\/li><li>Dog Brain Maneuver: Pilot + Maneuvering [Handling]<ul><li>Van: 1 [3]<\/li><li>MCT: 3 + 3 [4]<\/li><li>Dob: 3 + 3 [5]<\/li><li>Fly spy: 3 + 3 [4]<\/li><li>Bird: 2 + 3 [4]<\/li><li>Noiz: 3 [4]<\/li><\/ul><\/li><li>Perception (rigged): Perception + Int [Sensor]<ul><li>Van: 2 + 4 + 2 [4 + 2]<\/li><li>MCT: 2 + 4 + 2 [3 + 2]<\/li><li>Fly spy: 2 + 4 + 2 [3 + 2]<\/li><li>Bird: 2 + 4 + 2 [2 + 2]<\/li><\/ul><\/li><li>Dog Brain Perception: Pilot + Clearsight [Sensor]<ul><li>Van: 1 + 3 [4]<\/li><li>MCT: 3 + 3 [3]<\/li><li>Dob: 3 + 3 [3]<\/li><li>Fly spy: 3 + 3 [3]<\/li><li>Bird: 2 + 3 [2]<\/li><li>Noiz: 3 [3]<\/li><\/ul><\/li><li>Attack (rigged): Gunner + Logic [Accuracy]<ul><li>Van\/Dob: 3 + 3 + 2 [5 + 2]<\/li><li>MCT: 3 + 3 + 2 [6 + 2]<\/li><\/ul><\/li><li>Dog Brain Attack: Pilot + Targeting [Accuracy]<ul><li>Van: 1 + 3 [5]<\/li><li>MCT: 3 + 3 [6]<\/li><li>Dob: 3 + 3 [5]<\/li><\/ul><\/li><\/ul>"
      },
      {
         "card":"Notes",
         "type":"",
         "name":"Background",
         "HTML":"<p>A skinny half-Japanese kid who grew up in Koreatown in LA, Ben always enjoyed tinkering and playing with RC toys. He did assorted technical jobs for local mechanic shops where he met a smuggler who eventually took him along on some small runs, mentoring him for a future career in the trade.<\/p><p>As Ben learned more and earned more, he saved up for a Control Rig and was introduced to some street docs through his smuggling mentor. Ben never realized he had magical ability until after the surgery. The doctors who performed the surgery did not tell him either \u2014 they just wanted to get paid and keep a relationship with the smuggling world.<\/p><p>Frustrated and disenchanted with the smugglers and doctors, Ben turned to learning about his magical abilities. As he grew in spellcasting and channeling adept powers he worked to combine these with his passion and skill for vehicles and drones.<\/p><p>Ben makes a good living by doing odd jobs, from simple mechanic work to the occasional driver. He maintains a good relationship with his former mentor, though it was not without its problems. Some of Ben\u2019s mentor\u2019s loyalty comes from a sense of responsibility for the street doc fiasco, even as Ben has turned it into an asset.<\/p>"
      }
   ]
}

function ParseJSON(data, elmID, nodeType) {
  try {
    // Use this if the JSON is coming over the wire
    // var JSONdata = JSON.parse(data);
    var JSONdata = data;

    var divContainer = document.getElementById(elmID);
    divContainer.innerHTML = "";

    var filteredNodes = JSONdata.items;

    for (var a = 0; a < filteredNodes.length; a++) {
      var json = filteredNodes[a];
      if (json.card === nodeType) {
        // I have to find a way to filter
        var article = document.createElement("article");
        article.className = json.type
          .split(" ")
          .join("-")
          .toLowerCase();
        article.setAttribute('id', removeSpecialChars(json.name));

        // heading
        var h2 = document.createElement("h2");
        var span = document.createElement("span");
        h2.appendChild(span);
        span.innerHTML = json.name;
        if (json.type !== undefined && json.type != "") {
          span.innerHTML = json.type + ": " + span.innerHTML;
        }
        var span2 = document.createElement("span");
        h2.appendChild(span2);

        // attributes
        if (json.attributes !== undefined) {
          var attrs = Object.keys(json.attributes);
          var attrVals = Object.values(json.attributes);
          var dl = document.createElement("dl");
          for (var i = 0; i < attrs.length; i++) {
            var dt = document.createElement("dt");
            dt.innerHTML = attrs[i];
            dl.appendChild(dt);
            var dd = document.createElement("dd");
            dd.innerHTML = attrVals[i];
            dl.appendChild(dd);
          }
        }

        // boxes
        if (json.Boxes !== undefined) {
          var pB = document.createElement("p");
          pB.className = "boxes";
          var boxen = "";
          for (var i = 0; i < json.Boxes; i++) {
            boxen = "<span>◯</span>" + boxen;
          }
          pB.innerHTML = "<strong>Condition Monitor:</strong> " + boxen;
        }

        // notes
        if (json.Notes !== undefined) {
          var p = document.createElement("p");
          p.innerHTML = "<strong>Notes:</strong> " + json.Notes;
        }

        // data grid
        if (json.table !== undefined && json.row !== undefined) {
          var table = document.createElement("table");
          var caption = document.createElement("caption");
          caption.innerHTML = json.table;
          table.appendChild(caption);

          var tableHead = Object.keys(json.row[0]);
          var tableRows = Object.values(json.row);

          var tr = table.insertRow(-1);
          for (var i = 0; i < tableHead.length; i++) {
            var th = document.createElement("th");
            th.innerHTML = tableHead[i];
            tr.appendChild(th);
          }

          for (var j = 0; j < tableRows.length; j++) {
            var tableCells = Object.values(json.row[j]);
            var tr = table.insertRow(-1);
            for (var k = 0; k < tableCells.length; k++) {
              var tabCell = tr.insertCell(-1);
              tabCell.innerHTML = tableCells[k];
            }
          }
        }

        // raw HTML
        if (json.HTML !== undefined) {
          var div = document.createElement("div");
          div.innerHTML = json.HTML;
        }

        // build it
        divContainer.appendChild(article);
        article.appendChild(h2);
        if (json.attributes !== undefined) {
          article.appendChild(dl);
        }
        if (json.Boxes !== undefined) {
          article.appendChild(pB);
        }
        if (json.Notes !== undefined) {
          article.appendChild(p);
        }
        if (json.table !== undefined && json.row !== undefined) {
          article.appendChild(table);
        }
        if (json.HTML !== undefined) {
          article.appendChild(div);
        }
      }
    }
  } catch (e) {
    console.log("ParseJSON(): " + e);
  }
}

// Need a simpler one
function removeSpecialChars(str) {
  return str.replace(/(?!\w|\s)./g, '')
    .replace(/\s+/g, ' ')
    .replace(/^(\s*)([\W\w]*)(\b\s*$)/g, '$2')
    .replace(" ","")
    .replace(" ","");
}

ParseJSON(stuff, "Core", "Core");
ParseJSON(stuff, "Magic", "Magic");
ParseJSON(stuff, "Cyber", "Cyber");
ParseJSON(stuff, "VehicleDrone", "VehicleDrone");
ParseJSON(stuff, "Notes", "Notes");

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console