{"version":3,"sources":["jsdelivr-header.js","/npm/@merrie/nmbrs-components@0.0.4-7/src/operand/operand.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/operator/operator.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/expression-entry/expression-entry.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/expression/expression.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/display-epression-scroll-arrow/display-expression-scroll-arrow.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/display-epression/display-expression.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/display-operand/display-operand.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/display/display.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/numpad-button/numpad-button.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/numpad/numpad.component.tsx","/npm/@merrie/nmbrs-components@0.0.4-7/src/calculator/calculator.component.tsx"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,qhBCGa,iBAAiD,SAAC,G,IAC7D,EAAO,EAAA,QACP,EAAA,EAAA,aAAK,IAAA,GAAO,EACR,OACJ,6CAAM,UAAW,WAAY,wBAAa,SAAS,EAAS,GADxD,ECLO,kBAAmD,SAAC,GAG/D,OAFQ,EAAA,SAES,UACf,KAAK,uBAAc,IACjB,OAAO,6CAAM,UAAW,YAAU,KACpC,KAAK,uBAAc,OACjB,OAAO,6CAAM,UAAW,YAAU,KACpC,KAAK,uBAAc,SACjB,OAAO,6CAAM,UAAW,YAAU,KACpC,KAAK,uBAAc,SACjB,OAAO,6CAAM,UAAW,YAAU,KACpC,QACE,OAAO,KAEb,ECRa,yBAAiE,SAAC,G,IAC7E,EAAK,EAAA,MAEL,OAAQ,EAAM,MACZ,KAAK,8BAAqB,WACxB,OAAO,KACT,KAAK,8BAAqB,QACxB,OAAO,qCAAC,iBAAgB,CAAC,QAAS,EAAkB,OAAO,IAC7D,KAAK,8BAAqB,SACxB,OAAO,qCAAC,kBAAiB,CAAC,SAAU,IACtC,QACE,OAAO,KAEb,EChBa,oBAAuD,SAAC,G,IACnE,EAAU,EAAA,WACV,EAAO,EAAA,QACP,EAAW,EAAA,YACP,OACJ,4CAAK,UAAW,cACb,EAAW,QAAQ,KAAI,SAAC,EAAO,GAAU,OACxC,qCAAC,yBAAwB,CAAC,MAAO,EAAO,IAAK,GAAS,IAEvD,GAAW,qCAAC,iBAAgB,CAAC,QAAS,EAAS,OAAO,IACtD,GAAe,IANd,E,wzCCPC,IAAM,sCAA2F,SAAC,G,IACvG,EAAS,EAAA,UACT,EAAO,EAAA,QACH,OACJ,+CACE,QAAS,WAAM,OAAA,GAAS,EACxB,UAAW,mEAAmE,GAE/D,SAAd,EAAuB,IAAM,IAL5B,ECEO,2BAAqE,SAAC,G,IACjF,EAAU,EAAA,WACV,EAAW,EAAA,YACX,EAAO,EAAA,QAED,EAA0B,uBAAM,UAAS,GAAxC,EAAQ,EAAA,GAAE,EAAW,EAAA,GACtB,EAA4B,uBAAM,UAAS,GAA1C,EAAS,EAAA,GAAE,EAAY,EAAA,GACxB,EAA8B,uBAAM,UAAS,GAA5C,EAAU,EAAA,GAAE,EAAa,EAAA,GAEhC,uBAAM,WAAU,WAId,OAHA,IAEA,OAAO,iBAAiB,SAAU,GAC3B,WAAM,OAAA,OAAO,oBAAoB,SAAU,EAAqB,C,GACtE,CAAC,EAAY,IAEhB,IAIM,EAAuB,WAC3B,IAAM,EAAgB,SAAS,uBAC7B,8BACA,GAEF,GAAI,EAAe,CACT,IAGF,EAHkB,EAAa,YACb,EAAa,YAGrC,EAAY,GAER,IACF,EAAO,SACP,I,GAKA,EAAY,WAChB,IAAM,EAAgB,SAAS,uBAC7B,8BACA,GAEF,EAAc,GAAiB,EAAc,WAAa,IAAM,GAEhE,EACG,GACC,KAAK,KAAK,EAAc,cACtB,KAAK,MAAM,EAAc,YAAc,EAAc,eACvD,E,EAIA,EAAS,SAAC,GACd,IAAM,EAAgB,SAAS,uBAC7B,8BACA,GAEF,GAAI,EAAe,CACT,IAAA,EAAgB,EAAa,YAErC,EAAc,SAAS,CACrB,KAAoB,SAAd,GAAwB,EAAc,G,GAKlD,OACE,4CAAK,UAAW,sBACb,GAAY,GACX,qCAAC,sCAAqC,CACpC,UAAW,OACX,QAAS,WAAM,OAAA,EAAO,OAAO,IAIjC,4CAAK,UAAW,6BAA8B,SAAU,WA5D1D,GA4D0E,IACpE,EAAW,QAAQ,OAAS,GAC3B,GAAW,EAAQ,cAAc,OAAS,IAAM,IACjD,qCAAC,oBAAmB,CAClB,WAAY,EACZ,QACE,GAAW,EAAQ,cAAc,OAAS,IAAM,EAC5C,OACA,EAEN,YAAa,KAKlB,GAAY,GACX,qCAAC,sCAAqC,CACpC,UAAW,QACX,QAAS,WAAM,OAAA,EAAO,QAAQ,IAKxC,E,mhBCxGO,IAAM,wBAAwD,SAAC,G,IACpE,EAAO,EAAA,QAED,EAA0B,uBAAM,UAAS,GAAxC,EAAS,EAAA,GAAE,EAAU,EAAA,GACtB,EAAkC,uBAAM,UAAS,GAAhD,EAAY,EAAA,GAAE,EAAe,EAAA,GAEpC,uBAAM,WAAU,WAId,OAHA,IAEA,OAAO,iBAAiB,SAAU,GAC3B,WAAM,OAAA,OAAO,oBAAoB,SAAU,EAAW,C,GAC5D,CAAC,IAEJ,IAAM,EAAa,WACjB,IAAM,EAAgB,SAAS,uBAC7B,mBACA,GACI,EACJ,GACC,EAAc,cAAc,YAE/B,GAAK,GAAkB,EAAvB,CAEA,IAAM,EAAQ,EAAe,YAAc,EAAgB,YAEvD,EAAQ,EACV,EAAgB,MAAM,UAAY,SAAS,EAAK,IAEhD,EAAgB,gBAAgB,QAPK,C,EAWzC,OACE,4CACE,SAAU,EACV,UAAW,+BACL,EAAY,0BAA4B,IAAE,gBAC1C,GAAa,EAAe,gCAAkC,IAAE,gBAEhE,IAAc,EAAe,mCAAqC,IAAE,WAG1E,QAAS,WAAM,OAAA,YAAW,WAAM,OAAA,GAAW,EAAK,GAAC,EACjD,OAAQ,WACN,OAAA,YAAW,WACT,GAAW,GACX,GAAgB,E,KAGpB,YAAa,WAAM,OAAC,GAAa,GAAgB,EAAK,EACtD,UAAW,WAAM,OAAC,GAAa,GAAgB,EAAM,GAErD,4CAAK,UAAW,qBACd,qCAAC,iBAAgB,CAAC,QAAS,KAInC,E,0JCtDa,iBAAiD,SAAC,G,IAC7D,EAAU,EAAA,WACV,EAAW,EAAA,YACX,EAAO,EAAA,QACH,OACJ,4CAAK,UAAW,WACd,qCAAC,2BAA0B,CACzB,WAAY,EACZ,QACE,EAAQ,cAAc,OAAS,IAAM,EAAc,OAAU,EAE/D,YAAa,IAEf,qCAAC,wBAAuB,CAAC,QAAS,IAThC,E,m7FCCN,IAAM,aAAe,SAAC,GACpB,OAAQ,EAAO,SACb,KAAK,kCAAyB,KAC5B,OAAO,aAAa,GACtB,KAAK,kCAAyB,KAC5B,OAAO,aAAa,GACtB,QACE,OAAO,KAEb,EAEM,aAAe,SAAC,GAA6B,OAAA,EAAO,IAAI,EAExD,aAAe,SAAC,GAA6B,OAAA,EAAO,IAAI,EAEjD,sBAA+D,SAAC,G,IAC3E,EAAM,EAAA,OACN,EAAS,EAAA,UACT,EAAM,EAAA,OACN,EAAO,EAAA,QACP,EAAO,EAAA,QAED,EAAgB,aAAgC,MAEhD,EAAkC,gBAAe,GAAhD,EAAY,EAAA,GAAE,EAAe,EAAA,GAMpC,OAJA,iBAAgB,WACV,EAAc,SAAW,GAAW,EAAc,QAAQ,O,IAI9D,8BACE,IAAK,EACL,IAAK,IACL,UAAW,qCAEP,EAAO,MAAK,eACZ,EAAY,wBAA0B,IAAE,cACxC,GAAa,EAAe,8BAAgC,IAAE,cAC9D,IAAc,EAAe,iCAAmC,IACpE,OAAQ,WACN,GAAgB,GAChB,G,EAEF,QAAS,WAAM,OAAA,GAAS,EACxB,QAAS,WAAM,OAAA,GAAS,EACxB,YAAa,WAAM,OAAA,GAAgB,EAAK,EACxC,UAAW,SAAC,GAEP,CAAC,UAAW,YAAa,YAAa,cAAc,SACnD,EAAM,MAKV,GAAgB,E,GAGlB,gCAAO,aAAa,IAG1B,ECpEa,gBAA+C,SAAC,G,IAC3D,EAAM,EAAA,OACN,EAAmB,EAAA,oBAEb,EAAgC,uBAAM,UAAU,GAA/C,EAAW,EAAA,GAAE,EAAc,EAAA,GAmElC,OAzDA,UAAU,aAAa,WACrB,GAAe,SAAC,GACd,IAAM,EAAQ,EAAc,EAAO,QACnC,OAAO,EAAQ,EAAO,QAAQ,OAAS,IAAsB,IAAjB,EACxC,EACA,C,OAIR,UAAU,aAAa,WACrB,GAAe,SAAC,GACd,IAAM,EAAQ,EAAc,EAG5B,OAAO,KAFK,KAAK,MAAM,EAAc,GAAK,EAAO,SAEnB,GAAK,EAAO,UAA4B,IAAjB,EACjD,EACA,C,OAIR,UAAU,cAAc,WACtB,GAAe,SAAC,GACd,IAAM,EAAQ,EAAc,EAG5B,OAAO,IAFK,KAAK,MAAM,EAAc,GAAK,EAAO,SAE1B,EAAO,UAA4B,IAAjB,EACrC,EACA,C,OAIR,UAAU,WAAW,WACnB,GAAe,SAAC,GACd,IAAM,EAAQ,EAAc,EAAO,QACnC,OAAO,EAAQ,IAAsB,IAAjB,EAAqB,EAAc,C,OAI3D,EAAO,QAAQ,SAAQ,SAAC,EAAQ,GAC1B,EAAO,MAAQ,EAAO,KAAK,OAAS,GACtC,EAAO,KAAK,SAAQ,SAAC,GACnB,UAAU,GAAK,SAAC,GACd,EAAM,iBACN,IAAM,EAAU,SAAS,uBAAuB,iBAChD,GAAI,EAAS,CACX,IAAM,EAAc,EAAQ,GAC5B,EAAY,UAAU,IAAI,UAC1B,YAAW,WACT,EAAY,UAAU,OAAO,S,GAC5B,KACH,EAAY,O,WAQpB,4CAAK,UAAW,UACb,EAAO,QAAQ,KAAI,SAAC,EAAQ,GAAU,OACrC,4CAAK,UAAW,0BAA2B,IAAK,GAC9C,qCAAC,sBAAqB,CACpB,OAAQ,EACR,UAAW,IAAgB,EAC3B,QAAS,WAAM,OAAA,EAAoB,EAAO,EAC1C,QAAS,WApEjB,EAoEyC,EAAM,EACvC,OAAQ,WAzEhB,GAAgB,EAyEwB,IAE9B,IAId,E,SAEwB,UACtB,EACA,GAEA,uBAAM,WAAU,WACd,IAAM,EAAY,SAAC,GACb,EAAE,MAAQ,GAAQ,EAAE,SAAS,EAAO,E,EAI1C,OADA,OAAO,iBAAiB,UAAW,GAC5B,WAAM,OAAA,OAAO,oBAAoB,UAAW,EAAU,C,GAC5D,GACL,C,uVClGa,oBAAuD,SAAC,G,IACnE,EAAU,EAAA,WACV,EAAmB,EAAA,oBAEb,EAAQ,uBAAM,WAAW,0BACzB,EAAa,gBAEnB,OACE,4CACE,UAAW,cAAc,EACzB,MACE,EAAW,OAAS,CAAE,SAAU,EAAW,OAAS,SAAO,GAG7D,4CAAK,UAAW,qBACd,qCAAC,iBAAgB,CACf,WAAY,EAAW,WACvB,YAAa,EAAW,YACxB,QAAS,EAAW,WAGxB,4CAAK,UAAW,oBACd,qCAAC,gBAAe,CACd,OAAQ,EAAW,QAAQ,GAC3B,oBAAqB,SAAC,GAAW,OAAA,EAAoB,EAAO,KAKtE,E,SAEwB,gBAChB,IAAA,EAA8B,uBAAM,SAGvC,CACD,WAAO,EACP,YAAQ,IALH,EAAU,EAAA,GAAE,EAAa,EAAA,GAqBhC,OAdA,uBAAM,WAAU,WACd,SAAS,IACP,EAAc,CACZ,MAAO,OAAO,WACd,OAAQ,OAAO,a,CAQnB,OAJA,OAAO,iBAAiB,SAAU,GAElC,IAEO,WAAM,OAAA,OAAO,oBAAoB,SAAU,EAAa,C,GAC9D,IACI,CACT,C","file":"/npm/@merrie/nmbrs-components@0.0.4-7/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@merrie/nmbrs-components@0.0.4-7/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import React from \"react\";\nimport { Operand } from \"@merrie/nmbrs-api\";\nimport { OperandUtils } from \"@merrie/nmbrs-utils\";\n\nexport interface IOperandProperties {\n  operand: Operand;\n  total?: boolean;\n}\n\nexport const OperandComponent: React.FC<IOperandProperties> = ({\n  operand,\n  total = true,\n}) => (\n  <span className={\"operand\"}>{OperandUtils.toString(operand, total)}</span>\n);\n","import React from \"react\";\nimport { Operator, OperatorTypes } from \"@merrie/nmbrs-api\";\n\nexport interface IOperatorProperties {\n  operator: Operator;\n}\n\nexport const OperatorComponent: React.FC<IOperatorProperties> = ({\n  operator,\n}) => {\n  switch (operator.operator) {\n    case OperatorTypes.ADD:\n      return <span className={\"operator\"}>+</span>;\n    case OperatorTypes.DIVIDE:\n      return <span className={\"operator\"}>/</span>;\n    case OperatorTypes.MULTIPLY:\n      return <span className={\"operator\"}>*</span>;\n    case OperatorTypes.SUBTRACT:\n      return <span className={\"operator\"}>-</span>;\n    default:\n      return null;\n  }\n};\n","import React from \"react\";\nimport {\n  ExpressionEntry,\n  ExpressionEntryTypes,\n  Operand,\n  Operator,\n} from \"@merrie/nmbrs-api\";\nimport { OperandComponent } from \"../operand/operand.component\";\nimport { OperatorComponent } from \"../operator/operator.component\";\n\nexport interface IExpressionEntryProperties {\n  entry: ExpressionEntry;\n}\n\nexport const ExpressionEntryComponent: React.FC<IExpressionEntryProperties> = ({\n  entry,\n}) => {\n  switch (entry.type) {\n    case ExpressionEntryTypes.EXPRESSION:\n      return null;\n    case ExpressionEntryTypes.OPERAND:\n      return <OperandComponent operand={entry as Operand} total={false} />;\n    case ExpressionEntryTypes.OPERATOR:\n      return <OperatorComponent operator={entry as Operator} />;\n    default:\n      return null;\n  }\n};\n","import React from \"react\";\nimport { Expression, Operand } from \"@merrie/nmbrs-api\";\nimport { ExpressionEntryComponent } from \"../expression-entry/expression-entry.component\";\nimport { OperandComponent } from \"..\";\n\nexport interface IExpressionProperties {\n  expression: Expression;\n  operand?: Operand;\n  isEvaluated?: boolean;\n}\n\nexport const ExpressionComponent: React.FC<IExpressionProperties> = ({\n  expression,\n  operand,\n  isEvaluated,\n}) => (\n  <div className={\"expression\"}>\n    {expression.entries.map((entry, index) => (\n      <ExpressionEntryComponent entry={entry} key={index} />\n    ))}\n    {operand && <OperandComponent operand={operand} total={false} />}\n    {isEvaluated && \"=\"}\n  </div>\n);\n","import React from \"react\";\nimport \"./display-expression-scroll-arrow.component.scss\";\n\nexport interface IDisplayExpressionScrollArrowProperties {\n  direction: \"left\" | \"right\";\n  onClick: () => void;\n}\n\nexport const DisplayExpressionScrollArrowComponent: React.FC<IDisplayExpressionScrollArrowProperties> = ({\n  direction,\n  onClick,\n}) => (\n  <button\n    onClick={() => onClick()}\n    className={`display-expression-scroll-arrow display-expression-scroll-arrow-${direction}`}\n  >\n    {direction === \"left\" ? \"<\" : \">\"}\n  </button>\n);\n","import React from \"react\";\nimport { Expression, Operand } from \"@merrie/nmbrs-api\";\nimport { ExpressionComponent } from \"../expression/expression.component\";\nimport \"./display-expression.component.scss\";\nimport { DisplayExpressionScrollArrowComponent } from \"../display-epression-scroll-arrow/display-expression-scroll-arrow.component\";\n\nexport interface IDisplayExpressionProperties {\n  expression: Expression;\n\n  operand?: Operand;\n  isEvaluated?: boolean;\n}\n\nexport const DisplayExpressionComponent: React.FC<IDisplayExpressionProperties> = ({\n  expression,\n  isEvaluated,\n  operand,\n}) => {\n  const [overflow, setOverflow] = React.useState(false);\n  const [arrowLeft, setArrowLeft] = React.useState(false);\n  const [arrowRight, setArrowRight] = React.useState(false);\n\n  React.useEffect(() => {\n    fitDisplayExpression();\n\n    window.addEventListener(\"resize\", fitDisplayExpression);\n    return () => window.removeEventListener(\"resize\", fitDisplayExpression);\n  }, [expression, operand]);\n\n  const onScroll = () => {\n    setArrows();\n  };\n\n  const fitDisplayExpression = () => {\n    const scrollContent = document.getElementsByClassName(\n      \"display-expression-content\"\n    )[0] as HTMLDivElement;\n\n    if (scrollContent) {\n      const { scrollWidth } = scrollContent;\n      const { offsetWidth } = scrollContent;\n\n      const overflow = scrollWidth > offsetWidth;\n      setOverflow(overflow);\n\n      if (overflow) {\n        scroll(\"right\");\n        setArrows();\n      }\n    }\n  };\n\n  const setArrows = (): void => {\n    const scrollContent = document.getElementsByClassName(\n      \"display-expression-content\"\n    )[0] as HTMLDivElement;\n\n    setArrowLeft((scrollContent && scrollContent.scrollLeft > 0) || false);\n\n    setArrowRight(\n      (scrollContent &&\n        Math.ceil(scrollContent.scrollLeft) !==\n          Math.floor(scrollContent.scrollWidth - scrollContent.offsetWidth)) ||\n        false\n    );\n  };\n\n  const scroll = (direction: \"left\" | \"right\") => {\n    const scrollContent = document.getElementsByClassName(\n      \"display-expression-content\"\n    )[0] as HTMLDivElement;\n\n    if (scrollContent) {\n      const { offsetWidth } = scrollContent;\n\n      scrollContent.scrollBy({\n        left: direction === \"left\" ? -offsetWidth : offsetWidth,\n      });\n    }\n  };\n\n  return (\n    <div className={\"display-expression\"}>\n      {overflow && arrowLeft && (\n        <DisplayExpressionScrollArrowComponent\n          direction={\"left\"}\n          onClick={() => scroll(\"left\")}\n        />\n      )}\n\n      <div className={\"display-expression-content\"} onScroll={() => onScroll()}>\n        {(expression.entries.length > 0 ||\n          (operand && operand.manipulations.length > 0 && !isEvaluated)) && (\n          <ExpressionComponent\n            expression={expression}\n            operand={\n              operand && operand.manipulations.length > 0 && !isEvaluated\n                ? operand\n                : undefined\n            }\n            isEvaluated={isEvaluated}\n          />\n        )}\n      </div>\n\n      {overflow && arrowRight && (\n        <DisplayExpressionScrollArrowComponent\n          direction={\"right\"}\n          onClick={() => scroll(\"right\")}\n        />\n      )}\n    </div>\n  );\n};\n","import React from \"react\";\nimport { Operand } from \"@merrie/nmbrs-api\";\nimport { OperandComponent } from \"../operand/operand.component\";\nimport \"./display-operand.component.scss\";\n\nexport interface IDisplayProperties {\n  operand: Operand;\n}\n\nexport const DisplayOperandComponent: React.FC<IDisplayProperties> = ({\n  operand,\n}) => {\n  const [isFocused, setFocused] = React.useState(false);\n  const [mouseFocused, setMouseFocused] = React.useState(false);\n\n  React.useEffect(() => {\n    fitOperand();\n\n    window.addEventListener(\"resize\", fitOperand);\n    return () => window.removeEventListener(\"resize\", fitOperand);\n  }, [operand]);\n\n  const fitOperand = () => {\n    const buttonElement = document.getElementsByClassName(\n      \"display-operand\"\n    )[0] as HTMLDivElement;\n    const operandElement =\n      buttonElement &&\n      (buttonElement.querySelector(\".operand\") as HTMLSpanElement);\n\n    if (!buttonElement || !operandElement) return;\n\n    const scale = buttonElement!.offsetWidth / operandElement!.offsetWidth;\n\n    if (scale < 1) {\n      operandElement!.style.transform = `scale(${scale})`;\n    } else {\n      operandElement!.removeAttribute(\"style\");\n    }\n  };\n\n  return (\n    <div\n      tabIndex={0}\n      className={`display-operand\n          ${isFocused ? \"display-operand-focused\" : \"\"}\n          ${isFocused && mouseFocused ? \"display-operand-mouse-focused\" : \"\"}\n          ${\n            isFocused && !mouseFocused ? \"display-operand-keyboard-focused\" : \"\"\n          }\n      `}\n      onFocus={() => setTimeout(() => setFocused(true))}\n      onBlur={() =>\n        setTimeout(() => {\n          setFocused(false);\n          setMouseFocused(false);\n        })\n      }\n      onMouseDown={() => !isFocused && setMouseFocused(true)}\n      onKeyDown={() => !isFocused && setMouseFocused(false)}\n    >\n      <div className={\"operand-container\"}>\n        <OperandComponent operand={operand} />\n      </div>\n    </div>\n  );\n};\n","import React from \"react\";\nimport { Expression, Operand } from \"@merrie/nmbrs-api\";\nimport { DisplayExpressionComponent } from \"../display-epression/display-expression.component\";\nimport { DisplayOperandComponent } from \"../display-operand/display-operand.component\";\nimport \"./display.component.scss\";\n\nexport interface IDisplayProperties {\n  expression: Expression;\n  operand: Operand;\n  isEvaluated?: boolean;\n}\n\nexport const DisplayComponent: React.FC<IDisplayProperties> = ({\n  expression,\n  isEvaluated,\n  operand,\n}) => (\n  <div className={`display`}>\n    <DisplayExpressionComponent\n      expression={expression}\n      operand={\n        operand.manipulations.length > 0 && !isEvaluated ? operand : undefined\n      }\n      isEvaluated={isEvaluated}\n    />\n    <DisplayOperandComponent operand={operand} />\n  </div>\n);\n","import * as React from \"react\";\nimport {\n  NumpadButton,\n  NumpadButtonDisplayTypes,\n  NumpadIconButton,\n  NumpadTextButton,\n} from \"@merrie/nmbrs-api\";\nimport \"./numpad-button.component.scss\";\n\ninterface INumpadButtonComponentProps {\n  button: NumpadButton;\n  isFocused: boolean;\n  onBlur: () => void;\n  onClick: () => void;\n  onFocus: () => void;\n}\n\nconst getInnerHtml = (button: NumpadButton) => {\n  switch (button.display) {\n    case NumpadButtonDisplayTypes.ICON:\n      return getInnerIcon(button as NumpadIconButton);\n    case NumpadButtonDisplayTypes.TEXT:\n      return getInnerText(button as NumpadTextButton);\n    default:\n      return null;\n  }\n};\n\nconst getInnerIcon = (button: NumpadIconButton) => button.icon;\n\nconst getInnerText = (button: NumpadTextButton) => button.text;\n\nexport const NumpadButtonComponent: React.FC<INumpadButtonComponentProps> = ({\n  button,\n  isFocused,\n  onBlur,\n  onClick,\n  onFocus,\n}) => {\n  const buttonElement = React.useRef<HTMLButtonElement>(null);\n\n  const [mouseFocused, setMouseFocused] = React.useState(false);\n\n  React.useEffect(() => {\n    if (buttonElement.current && isFocused) buttonElement.current.focus();\n  });\n\n  return (\n    <button\n      ref={buttonElement}\n      key={123}\n      className={`\n        numpad-button \n        ${button.style} \n        ${isFocused ? \"numpad-button-focused\" : \"\"}\n        ${isFocused && mouseFocused ? \"numpad-button-mouse-focused\" : \"\"}\n        ${isFocused && !mouseFocused ? \"numpad-button-keyboard-focused\" : \"\"}`}\n      onBlur={() => {\n        setMouseFocused(false);\n        onBlur();\n      }}\n      onFocus={() => onFocus()}\n      onClick={() => onClick()}\n      onMouseDown={() => setMouseFocused(true)}\n      onKeyDown={(event) => {\n        if (\n          ![\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(\n            event.key\n          )\n        ) {\n          return;\n        }\n        setMouseFocused(false);\n      }}\n    >\n      <span>{getInnerHtml(button)}</span>\n    </button>\n  );\n};\n","import React from \"react\";\nimport \"./numpad.component.scss\";\nimport { Numpad, NumpadButton } from \"@merrie/nmbrs-api\";\nimport { NumpadButtonComponent } from \"../numpad-button/numpad-button.component\";\n\nexport interface INumpadProperties {\n  numpad: Numpad;\n  onNumpadButtonClick: (button: NumpadButton) => void;\n}\n\nexport const NumpadComponent: React.FC<INumpadProperties> = ({\n  numpad,\n  onNumpadButtonClick,\n}) => {\n  const [activeIndex, setActiveIndex] = React.useState(-1);\n\n  const numpadButtonBlur = () => {\n    setActiveIndex(-1);\n  };\n\n  const numpadButtonFocus = (i: number) => {\n    setActiveIndex(i);\n  };\n\n  onKeyDown(\"ArrowDown\", () => {\n    setActiveIndex((activeIndex) => {\n      const index = activeIndex + numpad.columns;\n      return index > numpad.buttons.length - 1 || activeIndex === -1\n        ? activeIndex\n        : index;\n    });\n  });\n\n  onKeyDown(\"ArrowLeft\", () => {\n    setActiveIndex((activeIndex) => {\n      const index = activeIndex - 1;\n      const row = Math.ceil((activeIndex + 1) / numpad.columns);\n\n      return activeIndex === (row - 1) * numpad.columns || activeIndex === -1\n        ? activeIndex\n        : index;\n    });\n  });\n\n  onKeyDown(\"ArrowRight\", () => {\n    setActiveIndex((activeIndex) => {\n      const index = activeIndex + 1;\n      const row = Math.ceil((activeIndex + 1) / numpad.columns);\n\n      return index === row * numpad.columns || activeIndex === -1\n        ? activeIndex\n        : index;\n    });\n  });\n\n  onKeyDown(\"ArrowUp\", () => {\n    setActiveIndex((activeIndex) => {\n      const index = activeIndex - numpad.columns;\n      return index < 0 || activeIndex === -1 ? activeIndex : index;\n    });\n  });\n\n  numpad.buttons.forEach((button, index) => {\n    if (button.keys && button.keys.length > 0) {\n      button.keys.forEach((key) => {\n        onKeyDown(key, (event) => {\n          event.preventDefault();\n          const buttons = document.getElementsByClassName(\"numpad-button\");\n          if (buttons) {\n            const clearButton = buttons[index] as HTMLButtonElement;\n            clearButton.classList.add(\"active\");\n            setTimeout(() => {\n              clearButton.classList.remove(\"active\");\n            }, 100);\n            clearButton.click();\n          }\n        });\n      });\n    }\n  });\n\n  return (\n    <div className={`numpad`}>\n      {numpad.buttons.map((button, index) => (\n        <div className={\"numpad-button-container\"} key={index}>\n          <NumpadButtonComponent\n            button={button}\n            isFocused={activeIndex === index}\n            onClick={() => onNumpadButtonClick(button)}\n            onFocus={() => numpadButtonFocus(index)}\n            onBlur={() => numpadButtonBlur()}\n          />\n        </div>\n      ))}\n    </div>\n  );\n};\n\nexport default function onKeyDown(\n  key: string,\n  action: (e: KeyboardEvent) => void\n) {\n  React.useEffect(() => {\n    const onKeydown = (e: KeyboardEvent) => {\n      if (e.key === key && !e.ctrlKey) action(e);\n    };\n\n    window.addEventListener(\"keydown\", onKeydown);\n    return () => window.removeEventListener(\"keydown\", onKeydown);\n  }, []);\n}\n","import React from \"react\";\nimport { ThemeContext } from \"@merrie/nmbrs-common\";\nimport { Calculator, NumpadButton } from \"@merrie/nmbrs-api\";\nimport { DisplayComponent } from \"../display/display.component\";\nimport { NumpadComponent } from \"../numpad/numpad.component\";\nimport \"./calculator.component.scss\";\n\nexport interface ICalculatorProperties {\n  calculator: Calculator;\n  onNumpadButtonClick: (numpadButton: NumpadButton) => void;\n}\n\nexport const CalculatorComponent: React.FC<ICalculatorProperties> = ({\n  calculator,\n  onNumpadButtonClick,\n}) => {\n  const theme = React.useContext(ThemeContext);\n  const windowSize = getWindowSize();\n\n  return (\n    <div\n      className={`calculator ${theme}`}\n      style={\n        windowSize.height ? { fontSize: windowSize.height / 40 } : undefined\n      }\n    >\n      <div className={\"display-container\"}>\n        <DisplayComponent\n          expression={calculator.expression}\n          isEvaluated={calculator.isEvaluated}\n          operand={calculator.operand}\n        />\n      </div>\n      <div className={\"numpad-container\"}>\n        <NumpadComponent\n          numpad={calculator.numpads[0]}\n          onNumpadButtonClick={(button) => onNumpadButtonClick(button)}\n        />\n      </div>\n    </div>\n  );\n};\n\nexport default function getWindowSize() {\n  const [windowSize, setWindowSize] = React.useState<{\n    width: number | undefined;\n    height: number | undefined;\n  }>({\n    width: undefined,\n    height: undefined,\n  });\n  React.useEffect(() => {\n    function handleResize() {\n      setWindowSize({\n        width: window.innerWidth,\n        height: window.innerHeight,\n      });\n    }\n\n    window.addEventListener(\"resize\", handleResize);\n\n    handleResize();\n\n    return () => window.removeEventListener(\"resize\", handleResize);\n  }, []); // Empty array ensures that effect is only run on mount\n  return windowSize;\n}\n"]}