qsharp-lang 1.13.1-dev → 1.13.3-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/dist/browser.d.ts +1 -0
  2. package/dist/compiler/compiler.d.ts +3 -3
  3. package/dist/compiler/compiler.js +2 -2
  4. package/dist/debug-service/debug-service.d.ts +1 -1
  5. package/dist/katas-content.generated.js +1 -1
  6. package/dist/katas-content.generated.md.js +1 -1
  7. package/dist/shared/circuit.d.ts +64 -0
  8. package/dist/shared/circuit.js +16 -0
  9. package/dist/shared/register.d.ts +35 -0
  10. package/dist/shared/register.js +10 -0
  11. package/docs/Microsoft.Quantum.Core/Length.md +1 -1
  12. package/docs/Microsoft.Quantum.Core/Repeated.md +1 -1
  13. package/docs/Microsoft.Quantum.Core/index.md +1 -1
  14. package/docs/Std.Arithmetic/AddLE.md +1 -1
  15. package/docs/Std.Arithmetic/ApplyIfEqualL.md +1 -1
  16. package/docs/Std.Arithmetic/ApplyIfEqualLE.md +1 -1
  17. package/docs/Std.Arithmetic/ApplyIfGreaterL.md +1 -1
  18. package/docs/Std.Arithmetic/ApplyIfGreaterLE.md +1 -1
  19. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualL.md +1 -1
  20. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualLE.md +1 -1
  21. package/docs/Std.Arithmetic/ApplyIfLessL.md +1 -1
  22. package/docs/Std.Arithmetic/ApplyIfLessLE.md +1 -1
  23. package/docs/Std.Arithmetic/ApplyIfLessOrEqualL.md +1 -1
  24. package/docs/Std.Arithmetic/ApplyIfLessOrEqualLE.md +1 -1
  25. package/docs/Std.Arithmetic/FourierTDIncByLE.md +1 -1
  26. package/docs/Std.Arithmetic/IncByI.md +1 -1
  27. package/docs/Std.Arithmetic/IncByIUsingIncByLE.md +1 -1
  28. package/docs/Std.Arithmetic/IncByL.md +1 -1
  29. package/docs/Std.Arithmetic/IncByLE.md +1 -1
  30. package/docs/Std.Arithmetic/IncByLEUsingAddLE.md +1 -1
  31. package/docs/Std.Arithmetic/IncByLUsingIncByLE.md +1 -1
  32. package/docs/Std.Arithmetic/LookAheadDKRSAddLE.md +1 -1
  33. package/docs/Std.Arithmetic/MAJ.md +1 -1
  34. package/docs/Std.Arithmetic/ReflectAboutInteger.md +1 -1
  35. package/docs/Std.Arithmetic/RippleCarryCGAddLE.md +1 -1
  36. package/docs/Std.Arithmetic/RippleCarryCGIncByLE.md +1 -1
  37. package/docs/Std.Arithmetic/RippleCarryTTKIncByLE.md +1 -1
  38. package/docs/Std.Arithmetic/index.md +1 -1
  39. package/docs/Std.Arrays/All.md +1 -1
  40. package/docs/Std.Arrays/Any.md +1 -1
  41. package/docs/Std.Arrays/Chunks.md +1 -1
  42. package/docs/Std.Arrays/CircularlyShifted.md +1 -1
  43. package/docs/Std.Arrays/ColumnAt.md +1 -1
  44. package/docs/Std.Arrays/Count.md +1 -1
  45. package/docs/Std.Arrays/Diagonal.md +1 -1
  46. package/docs/Std.Arrays/DrawMany.md +1 -1
  47. package/docs/Std.Arrays/Enumerated.md +1 -1
  48. package/docs/Std.Arrays/Excluding.md +1 -1
  49. package/docs/Std.Arrays/Filtered.md +1 -1
  50. package/docs/Std.Arrays/FlatMapped.md +1 -1
  51. package/docs/Std.Arrays/Flattened.md +1 -1
  52. package/docs/Std.Arrays/Fold.md +1 -1
  53. package/docs/Std.Arrays/ForEach.md +1 -1
  54. package/docs/Std.Arrays/Head.md +1 -1
  55. package/docs/Std.Arrays/HeadAndRest.md +1 -1
  56. package/docs/Std.Arrays/IndexOf.md +1 -1
  57. package/docs/Std.Arrays/IndexRange.md +1 -1
  58. package/docs/Std.Arrays/Interleaved.md +1 -1
  59. package/docs/Std.Arrays/IsEmpty.md +1 -1
  60. package/docs/Std.Arrays/IsRectangularArray.md +1 -1
  61. package/docs/Std.Arrays/IsSorted.md +1 -1
  62. package/docs/Std.Arrays/IsSquareArray.md +1 -1
  63. package/docs/Std.Arrays/Mapped.md +1 -1
  64. package/docs/Std.Arrays/MappedByIndex.md +1 -1
  65. package/docs/Std.Arrays/MappedOverRange.md +1 -1
  66. package/docs/Std.Arrays/Most.md +1 -1
  67. package/docs/Std.Arrays/MostAndTail.md +1 -1
  68. package/docs/Std.Arrays/Padded.md +1 -1
  69. package/docs/Std.Arrays/Partitioned.md +1 -1
  70. package/docs/Std.Arrays/Rest.md +1 -1
  71. package/docs/Std.Arrays/Reversed.md +1 -1
  72. package/docs/Std.Arrays/SequenceI.md +1 -1
  73. package/docs/Std.Arrays/SequenceL.md +1 -1
  74. package/docs/Std.Arrays/Sorted.md +1 -1
  75. package/docs/Std.Arrays/Subarray.md +1 -1
  76. package/docs/Std.Arrays/Swapped.md +1 -1
  77. package/docs/Std.Arrays/Tail.md +1 -1
  78. package/docs/Std.Arrays/Transposed.md +1 -1
  79. package/docs/Std.Arrays/Unzipped.md +1 -1
  80. package/docs/Std.Arrays/Where.md +1 -1
  81. package/docs/Std.Arrays/Windows.md +1 -1
  82. package/docs/Std.Arrays/Zipped.md +1 -1
  83. package/docs/Std.Arrays/index.md +1 -1
  84. package/docs/Std.Canon/ApplyCNOTChain.md +1 -1
  85. package/docs/Std.Canon/ApplyControlledOnBitString.md +1 -1
  86. package/docs/Std.Canon/ApplyControlledOnInt.md +1 -1
  87. package/docs/Std.Canon/ApplyP.md +1 -1
  88. package/docs/Std.Canon/ApplyPauli.md +1 -1
  89. package/docs/Std.Canon/ApplyPauliFromBitString.md +1 -1
  90. package/docs/Std.Canon/ApplyPauliFromInt.md +1 -1
  91. package/docs/Std.Canon/ApplyQFT.md +1 -1
  92. package/docs/Std.Canon/ApplyToEach.md +1 -1
  93. package/docs/Std.Canon/ApplyToEachA.md +1 -1
  94. package/docs/Std.Canon/ApplyToEachC.md +1 -1
  95. package/docs/Std.Canon/ApplyToEachCA.md +1 -1
  96. package/docs/Std.Canon/ApplyXorInPlace.md +1 -1
  97. package/docs/Std.Canon/ApplyXorInPlaceL.md +1 -1
  98. package/docs/Std.Canon/CX.md +1 -1
  99. package/docs/Std.Canon/CY.md +1 -1
  100. package/docs/Std.Canon/CZ.md +1 -1
  101. package/docs/Std.Canon/Fst.md +1 -1
  102. package/docs/Std.Canon/Relabel.md +1 -1
  103. package/docs/Std.Canon/Snd.md +1 -1
  104. package/docs/Std.Canon/SwapReverseRegister.md +1 -1
  105. package/docs/Std.Canon/index.md +1 -1
  106. package/docs/Std.Convert/BigIntAsBoolArray.md +1 -1
  107. package/docs/Std.Convert/BoolArrayAsBigInt.md +1 -1
  108. package/docs/Std.Convert/BoolArrayAsInt.md +1 -1
  109. package/docs/Std.Convert/BoolArrayAsResultArray.md +1 -1
  110. package/docs/Std.Convert/BoolAsResult.md +1 -1
  111. package/docs/Std.Convert/ComplexAsComplexPolar.md +1 -1
  112. package/docs/Std.Convert/ComplexPolarAsComplex.md +1 -1
  113. package/docs/Std.Convert/DoubleAsStringWithPrecision.md +1 -1
  114. package/docs/Std.Convert/IntAsBigInt.md +1 -1
  115. package/docs/Std.Convert/IntAsBoolArray.md +1 -1
  116. package/docs/Std.Convert/IntAsDouble.md +1 -1
  117. package/docs/Std.Convert/ResultArrayAsBoolArray.md +1 -1
  118. package/docs/Std.Convert/ResultArrayAsInt.md +1 -1
  119. package/docs/Std.Convert/ResultAsBool.md +1 -1
  120. package/docs/Std.Convert/index.md +1 -1
  121. package/docs/Std.Core/Length.md +1 -1
  122. package/docs/Std.Core/Repeated.md +1 -1
  123. package/docs/Std.Core/index.md +1 -1
  124. package/docs/Std.Diagnostics/ApplyIdleNoise.md +1 -1
  125. package/docs/Std.Diagnostics/BitFlipNoise.md +1 -1
  126. package/docs/Std.Diagnostics/CheckAllZero.md +1 -1
  127. package/docs/Std.Diagnostics/CheckOperationsAreEqual.md +1 -1
  128. package/docs/Std.Diagnostics/CheckZero.md +1 -1
  129. package/docs/Std.Diagnostics/ConfigurePauliNoise.md +1 -1
  130. package/docs/Std.Diagnostics/DepolarizingNoise.md +1 -1
  131. package/docs/Std.Diagnostics/DumpMachine.md +1 -1
  132. package/docs/Std.Diagnostics/DumpOperation.md +1 -1
  133. package/docs/Std.Diagnostics/DumpRegister.md +1 -1
  134. package/docs/Std.Diagnostics/Fact.md +1 -1
  135. package/docs/Std.Diagnostics/NoNoise.md +1 -1
  136. package/docs/Std.Diagnostics/PhaseFlipNoise.md +1 -1
  137. package/docs/Std.Diagnostics/StartCountingFunction.md +1 -1
  138. package/docs/Std.Diagnostics/StartCountingOperation.md +1 -1
  139. package/docs/Std.Diagnostics/StartCountingQubits.md +1 -1
  140. package/docs/Std.Diagnostics/StopCountingFunction.md +1 -1
  141. package/docs/Std.Diagnostics/StopCountingOperation.md +1 -1
  142. package/docs/Std.Diagnostics/StopCountingQubits.md +1 -1
  143. package/docs/Std.Diagnostics/index.md +1 -1
  144. package/docs/Std.Intrinsic/AND.md +1 -1
  145. package/docs/Std.Intrinsic/ApplyUnitary.md +1 -1
  146. package/docs/Std.Intrinsic/CCNOT.md +1 -1
  147. package/docs/Std.Intrinsic/CNOT.md +1 -1
  148. package/docs/Std.Intrinsic/Exp.md +1 -1
  149. package/docs/Std.Intrinsic/H.md +1 -1
  150. package/docs/Std.Intrinsic/I.md +1 -1
  151. package/docs/Std.Intrinsic/M.md +1 -1
  152. package/docs/Std.Intrinsic/Measure.md +1 -1
  153. package/docs/Std.Intrinsic/Message.md +1 -1
  154. package/docs/Std.Intrinsic/R.md +1 -1
  155. package/docs/Std.Intrinsic/R1.md +1 -1
  156. package/docs/Std.Intrinsic/R1Frac.md +1 -1
  157. package/docs/Std.Intrinsic/RFrac.md +1 -1
  158. package/docs/Std.Intrinsic/Reset.md +1 -1
  159. package/docs/Std.Intrinsic/ResetAll.md +1 -1
  160. package/docs/Std.Intrinsic/Rx.md +1 -1
  161. package/docs/Std.Intrinsic/Rxx.md +1 -1
  162. package/docs/Std.Intrinsic/Ry.md +1 -1
  163. package/docs/Std.Intrinsic/Ryy.md +1 -1
  164. package/docs/Std.Intrinsic/Rz.md +1 -1
  165. package/docs/Std.Intrinsic/Rzz.md +1 -1
  166. package/docs/Std.Intrinsic/S.md +1 -1
  167. package/docs/Std.Intrinsic/SWAP.md +1 -1
  168. package/docs/Std.Intrinsic/T.md +1 -1
  169. package/docs/Std.Intrinsic/X.md +1 -1
  170. package/docs/Std.Intrinsic/Y.md +1 -1
  171. package/docs/Std.Intrinsic/Z.md +1 -1
  172. package/docs/Std.Intrinsic/index.md +1 -1
  173. package/docs/Std.Logical/Xor.md +1 -1
  174. package/docs/Std.Logical/index.md +1 -1
  175. package/docs/Std.Math/AbsComplex.md +1 -1
  176. package/docs/Std.Math/AbsComplexPolar.md +1 -1
  177. package/docs/Std.Math/AbsD.md +1 -1
  178. package/docs/Std.Math/AbsI.md +1 -1
  179. package/docs/Std.Math/AbsL.md +1 -1
  180. package/docs/Std.Math/AbsSquaredComplex.md +1 -1
  181. package/docs/Std.Math/AbsSquaredComplexPolar.md +1 -1
  182. package/docs/Std.Math/ApproximateFactorial.md +1 -1
  183. package/docs/Std.Math/ArcCos.md +1 -1
  184. package/docs/Std.Math/ArcCosh.md +1 -1
  185. package/docs/Std.Math/ArcSin.md +1 -1
  186. package/docs/Std.Math/ArcSinh.md +1 -1
  187. package/docs/Std.Math/ArcTan.md +1 -1
  188. package/docs/Std.Math/ArcTan2.md +1 -1
  189. package/docs/Std.Math/ArcTanh.md +1 -1
  190. package/docs/Std.Math/ArgComplex.md +1 -1
  191. package/docs/Std.Math/ArgComplexPolar.md +1 -1
  192. package/docs/Std.Math/Binom.md +1 -1
  193. package/docs/Std.Math/BitSizeI.md +1 -1
  194. package/docs/Std.Math/BitSizeL.md +1 -1
  195. package/docs/Std.Math/Ceiling.md +1 -1
  196. package/docs/Std.Math/Complex.md +1 -1
  197. package/docs/Std.Math/ComplexPolar.md +1 -1
  198. package/docs/Std.Math/ContinuedFractionConvergentI.md +1 -1
  199. package/docs/Std.Math/ContinuedFractionConvergentL.md +1 -1
  200. package/docs/Std.Math/Cos.md +1 -1
  201. package/docs/Std.Math/Cosh.md +1 -1
  202. package/docs/Std.Math/DivRemI.md +1 -1
  203. package/docs/Std.Math/DivRemL.md +1 -1
  204. package/docs/Std.Math/DividedByC.md +1 -1
  205. package/docs/Std.Math/DividedByCP.md +1 -1
  206. package/docs/Std.Math/E.md +1 -1
  207. package/docs/Std.Math/ExpModI.md +1 -1
  208. package/docs/Std.Math/ExpModL.md +1 -1
  209. package/docs/Std.Math/ExtendedGreatestCommonDivisorI.md +1 -1
  210. package/docs/Std.Math/ExtendedGreatestCommonDivisorL.md +1 -1
  211. package/docs/Std.Math/FactorialI.md +1 -1
  212. package/docs/Std.Math/FactorialL.md +1 -1
  213. package/docs/Std.Math/Floor.md +1 -1
  214. package/docs/Std.Math/GreatestCommonDivisorI.md +1 -1
  215. package/docs/Std.Math/GreatestCommonDivisorL.md +1 -1
  216. package/docs/Std.Math/HammingWeightI.md +1 -1
  217. package/docs/Std.Math/InverseModI.md +1 -1
  218. package/docs/Std.Math/InverseModL.md +1 -1
  219. package/docs/Std.Math/IsCoprimeI.md +1 -1
  220. package/docs/Std.Math/IsCoprimeL.md +1 -1
  221. package/docs/Std.Math/IsInfinite.md +1 -1
  222. package/docs/Std.Math/IsNaN.md +1 -1
  223. package/docs/Std.Math/LargestFixedPoint.md +1 -1
  224. package/docs/Std.Math/Lg.md +1 -1
  225. package/docs/Std.Math/Log.md +1 -1
  226. package/docs/Std.Math/Log10.md +1 -1
  227. package/docs/Std.Math/LogFactorialD.md +1 -1
  228. package/docs/Std.Math/LogGammaD.md +1 -1
  229. package/docs/Std.Math/LogOf2.md +1 -1
  230. package/docs/Std.Math/Max.md +1 -1
  231. package/docs/Std.Math/MaxD.md +1 -1
  232. package/docs/Std.Math/MaxI.md +1 -1
  233. package/docs/Std.Math/MaxL.md +1 -1
  234. package/docs/Std.Math/Min.md +1 -1
  235. package/docs/Std.Math/MinD.md +1 -1
  236. package/docs/Std.Math/MinI.md +1 -1
  237. package/docs/Std.Math/MinL.md +1 -1
  238. package/docs/Std.Math/MinusC.md +1 -1
  239. package/docs/Std.Math/MinusCP.md +1 -1
  240. package/docs/Std.Math/ModulusI.md +1 -1
  241. package/docs/Std.Math/ModulusL.md +1 -1
  242. package/docs/Std.Math/NegationC.md +1 -1
  243. package/docs/Std.Math/NegationCP.md +1 -1
  244. package/docs/Std.Math/PI.md +1 -1
  245. package/docs/Std.Math/PNorm.md +1 -1
  246. package/docs/Std.Math/PNormalized.md +1 -1
  247. package/docs/Std.Math/PlusC.md +1 -1
  248. package/docs/Std.Math/PlusCP.md +1 -1
  249. package/docs/Std.Math/PowC.md +1 -1
  250. package/docs/Std.Math/PowCP.md +1 -1
  251. package/docs/Std.Math/RealMod.md +1 -1
  252. package/docs/Std.Math/Round.md +1 -1
  253. package/docs/Std.Math/SignD.md +1 -1
  254. package/docs/Std.Math/SignI.md +1 -1
  255. package/docs/Std.Math/SignL.md +1 -1
  256. package/docs/Std.Math/Sin.md +1 -1
  257. package/docs/Std.Math/Sinh.md +1 -1
  258. package/docs/Std.Math/SmallestFixedPoint.md +1 -1
  259. package/docs/Std.Math/Sqrt.md +1 -1
  260. package/docs/Std.Math/SquaredNorm.md +1 -1
  261. package/docs/Std.Math/Tan.md +1 -1
  262. package/docs/Std.Math/Tanh.md +1 -1
  263. package/docs/Std.Math/TimesC.md +1 -1
  264. package/docs/Std.Math/TimesCP.md +1 -1
  265. package/docs/Std.Math/TrailingZeroCountI.md +1 -1
  266. package/docs/Std.Math/TrailingZeroCountL.md +1 -1
  267. package/docs/Std.Math/Truncate.md +1 -1
  268. package/docs/Std.Math/index.md +1 -1
  269. package/docs/Std.Measurement/MResetEachZ.md +1 -1
  270. package/docs/Std.Measurement/MResetX.md +1 -1
  271. package/docs/Std.Measurement/MResetY.md +1 -1
  272. package/docs/Std.Measurement/MResetZ.md +1 -1
  273. package/docs/Std.Measurement/MeasureAllZ.md +1 -1
  274. package/docs/Std.Measurement/MeasureEachZ.md +1 -1
  275. package/docs/Std.Measurement/MeasureInteger.md +1 -1
  276. package/docs/Std.Measurement/index.md +1 -1
  277. package/docs/Std.Random/DrawRandomBool.md +1 -1
  278. package/docs/Std.Random/DrawRandomDouble.md +1 -1
  279. package/docs/Std.Random/DrawRandomInt.md +1 -1
  280. package/docs/Std.Random/index.md +1 -1
  281. package/docs/Std.Range/IsRangeEmpty.md +1 -1
  282. package/docs/Std.Range/RangeEnd.md +1 -1
  283. package/docs/Std.Range/RangeReverse.md +1 -1
  284. package/docs/Std.Range/RangeStart.md +1 -1
  285. package/docs/Std.Range/RangeStep.md +1 -1
  286. package/docs/Std.Range/index.md +1 -1
  287. package/docs/Std.ResourceEstimation/AccountForEstimates.md +1 -1
  288. package/docs/Std.ResourceEstimation/AuxQubitCount.md +1 -1
  289. package/docs/Std.ResourceEstimation/BeginEstimateCaching.md +1 -1
  290. package/docs/Std.ResourceEstimation/BeginRepeatEstimates.md +1 -1
  291. package/docs/Std.ResourceEstimation/CczCount.md +1 -1
  292. package/docs/Std.ResourceEstimation/EndEstimateCaching.md +1 -1
  293. package/docs/Std.ResourceEstimation/EndRepeatEstimates.md +1 -1
  294. package/docs/Std.ResourceEstimation/MeasurementCount.md +1 -1
  295. package/docs/Std.ResourceEstimation/PSSPCLayout.md +1 -1
  296. package/docs/Std.ResourceEstimation/RepeatEstimates.md +1 -1
  297. package/docs/Std.ResourceEstimation/RotationCount.md +1 -1
  298. package/docs/Std.ResourceEstimation/RotationDepth.md +1 -1
  299. package/docs/Std.ResourceEstimation/SingleVariant.md +1 -1
  300. package/docs/Std.ResourceEstimation/TCount.md +1 -1
  301. package/docs/Std.ResourceEstimation/index.md +1 -1
  302. package/docs/Std.StatePreparation/ApproximatelyPreparePureStateCP.md +1 -1
  303. package/docs/Std.StatePreparation/PreparePureStateD.md +1 -1
  304. package/docs/Std.StatePreparation/index.md +1 -1
  305. package/docs/Std.TableLookup/Select.md +1 -1
  306. package/docs/Std.TableLookup/index.md +1 -1
  307. package/docs/index.md +1 -1
  308. package/lib/node/qsc_wasm.cjs +17 -14
  309. package/lib/node/qsc_wasm.d.cts +3 -6
  310. package/lib/node/qsc_wasm_bg.wasm +0 -0
  311. package/lib/web/qsc_wasm.d.ts +4 -7
  312. package/lib/web/qsc_wasm.js +17 -14
  313. package/lib/web/qsc_wasm_bg.wasm +0 -0
  314. package/package.json +1 -1
  315. package/ux/circuit-vis/README.md +1 -0
  316. package/ux/circuit-vis/circuit.ts +10 -0
  317. package/ux/circuit-vis/constants.ts +39 -0
  318. package/ux/circuit-vis/formatters/formatUtils.ts +220 -0
  319. package/ux/circuit-vis/formatters/gateFormatter.ts +557 -0
  320. package/ux/circuit-vis/formatters/inputFormatter.ts +78 -0
  321. package/ux/circuit-vis/formatters/registerFormatter.ts +118 -0
  322. package/ux/circuit-vis/index.ts +30 -0
  323. package/ux/circuit-vis/metadata.ts +56 -0
  324. package/ux/circuit-vis/process.ts +536 -0
  325. package/ux/circuit-vis/register.ts +9 -0
  326. package/ux/circuit-vis/sqore.ts +376 -0
  327. package/ux/circuit-vis/styles.ts +236 -0
  328. package/ux/circuit-vis/utils.ts +77 -0
  329. package/ux/circuit.tsx +2 -2
  330. package/ux/data.ts +1 -1
@@ -0,0 +1,557 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+
4
+ import { Metadata, GateType } from "../metadata";
5
+ import {
6
+ minGateWidth,
7
+ gateHeight,
8
+ labelFontSize,
9
+ argsFontSize,
10
+ controlBtnRadius,
11
+ controlBtnOffset,
12
+ groupBoxPadding,
13
+ classicalRegHeight,
14
+ nestedGroupPadding,
15
+ } from "../constants";
16
+ import {
17
+ createSvgElement,
18
+ group,
19
+ line,
20
+ circle,
21
+ controlDot,
22
+ box,
23
+ text,
24
+ arc,
25
+ dashedLine,
26
+ dashedBox,
27
+ } from "./formatUtils";
28
+
29
+ /**
30
+ * Given an array of operations (in metadata format), return the SVG representation.
31
+ *
32
+ * @param opsMetadata Array of Metadata representation of operations.
33
+ * @param nestedDepth Depth of nested operations (used in classically controlled and grouped operations).
34
+ *
35
+ * @returns SVG representation of operations.
36
+ */
37
+ const formatGates = (opsMetadata: Metadata[], nestedDepth = 0): SVGElement => {
38
+ const formattedGates: SVGElement[] = opsMetadata.map((metadata) =>
39
+ _formatGate(metadata, nestedDepth),
40
+ );
41
+ return group(formattedGates);
42
+ };
43
+
44
+ /**
45
+ * Takes in an operation's metadata and formats it into SVG.
46
+ *
47
+ * @param metadata Metadata object representation of gate.
48
+ * @param nestedDepth Depth of nested operations (used in classically controlled and grouped operations).
49
+ *
50
+ * @returns SVG representation of gate.
51
+ */
52
+ const _formatGate = (metadata: Metadata, nestedDepth = 0): SVGElement => {
53
+ const { type, x, controlsY, targetsY, label, displayArgs, width } = metadata;
54
+ switch (type) {
55
+ case GateType.Measure:
56
+ return _createGate([_measure(x, controlsY[0])], metadata, nestedDepth);
57
+ case GateType.Unitary:
58
+ return _createGate(
59
+ [_unitary(label, x, targetsY as number[][], width, displayArgs)],
60
+ metadata,
61
+ nestedDepth,
62
+ );
63
+ case GateType.X:
64
+ return _createGate([_x(metadata, nestedDepth)], metadata, nestedDepth);
65
+ case GateType.Swap:
66
+ return controlsY.length > 0
67
+ ? _controlledGate(metadata, nestedDepth)
68
+ : _createGate([_swap(metadata, nestedDepth)], metadata, nestedDepth);
69
+ case GateType.Cnot:
70
+ case GateType.ControlledUnitary:
71
+ return _controlledGate(metadata, nestedDepth);
72
+ case GateType.Group:
73
+ return _groupedOperations(metadata, nestedDepth);
74
+ case GateType.ClassicalControlled:
75
+ return _classicalControlled(metadata);
76
+ default:
77
+ throw new Error(`ERROR: unknown gate (${label}) of type ${type}.`);
78
+ }
79
+ };
80
+
81
+ /**
82
+ * Groups SVG elements into a gate SVG group.
83
+ *
84
+ * @param svgElems Array of SVG elements.
85
+ * @param dataAttributes Custom data attributes to be attached to SVG group.
86
+ *
87
+ * @returns SVG representation of a gate.
88
+ */
89
+ const _createGate = (
90
+ svgElems: SVGElement[],
91
+ metadata: Metadata,
92
+ nestedDepth: number,
93
+ ): SVGElement => {
94
+ const { dataAttributes } = metadata || {};
95
+ const attributes: { [attr: string]: string } = { class: "gate" };
96
+ Object.entries(dataAttributes || {}).forEach(
97
+ ([attr, val]) => (attributes[`data-${attr}`] = val),
98
+ );
99
+
100
+ const zoomBtn: SVGElement | null = _zoomButton(metadata, nestedDepth);
101
+ if (zoomBtn != null) svgElems = svgElems.concat([zoomBtn]);
102
+ return group(svgElems, attributes);
103
+ };
104
+
105
+ /**
106
+ * Returns the expand/collapse button for an operation if it can be zoomed-in or zoomed-out,
107
+ * respectively. If neither are allowed, return `null`.
108
+ *
109
+ * @param metadata Operation metadata.
110
+ * @param nestedDepth Depth of nested operation.
111
+ *
112
+ * @returns SVG element for expand/collapse button if needed, or null otherwise.
113
+ */
114
+ const _zoomButton = (
115
+ metadata: Metadata,
116
+ nestedDepth: number,
117
+ ): SVGElement | null => {
118
+ if (metadata == undefined) return null;
119
+
120
+ const [x1, y1] = _gatePosition(metadata, nestedDepth);
121
+ let { dataAttributes } = metadata;
122
+ dataAttributes = dataAttributes || {};
123
+
124
+ const expanded = "expanded" in dataAttributes;
125
+
126
+ const x = x1 + 2;
127
+ const y = y1 + 2;
128
+ const circleBorder: SVGElement = circle(x, y, 10);
129
+
130
+ if (expanded) {
131
+ // Create collapse button if expanded
132
+ const minusSign: SVGElement = createSvgElement("path", {
133
+ d: `M${x - 7},${y} h14`,
134
+ });
135
+ const elements: SVGElement[] = [circleBorder, minusSign];
136
+ return group(elements, { class: "gate-control gate-collapse" });
137
+ } else if (dataAttributes["zoom-in"] == "true") {
138
+ // Create expand button if operation can be zoomed in
139
+ const plusSign: SVGElement = createSvgElement("path", {
140
+ d: `M${x},${y - 7} v14 M${x - 7},${y} h14`,
141
+ });
142
+ const elements: SVGElement[] = [circleBorder, plusSign];
143
+ return group(elements, { class: "gate-control gate-expand" });
144
+ }
145
+
146
+ return null;
147
+ };
148
+
149
+ /**
150
+ * Calculate position of gate.
151
+ *
152
+ * @param metadata Operation metadata.
153
+ * @param nestedDepth Depth of nested operations.
154
+ *
155
+ * @returns Coordinates of gate: [x1, y1, x2, y2].
156
+ */
157
+ const _gatePosition = (
158
+ metadata: Metadata,
159
+ nestedDepth: number,
160
+ ): [number, number, number, number] => {
161
+ const { x, width, type, targetsY } = metadata;
162
+
163
+ const ys = targetsY?.flatMap((y) => y as number[]) || [];
164
+ const maxY = Math.max(...ys);
165
+ const minY = Math.min(...ys);
166
+
167
+ let x1: number, y1: number, x2: number, y2: number;
168
+
169
+ switch (type) {
170
+ case GateType.Group: {
171
+ const padding = groupBoxPadding - nestedDepth * nestedGroupPadding;
172
+
173
+ x1 = x - 2 * padding;
174
+ y1 = minY - gateHeight / 2 - padding;
175
+ x2 = width + 2 * padding;
176
+ y2 = maxY + +gateHeight / 2 + padding - (minY - gateHeight / 2 - padding);
177
+
178
+ return [x1, y1, x2, y2];
179
+ }
180
+
181
+ default:
182
+ x1 = x - width / 2;
183
+ y1 = minY - gateHeight / 2;
184
+ x2 = x + width;
185
+ y2 = maxY + gateHeight / 2;
186
+ }
187
+
188
+ return [x1, y1, x2, y2];
189
+ };
190
+
191
+ /**
192
+ * Creates a measurement gate at position (x, y).
193
+ *
194
+ * @param x x coord of measurement gate.
195
+ * @param y y coord of measurement gate.
196
+ *
197
+ * @returns SVG representation of measurement gate.
198
+ */
199
+ const _measure = (x: number, y: number): SVGElement => {
200
+ x -= minGateWidth / 2;
201
+ const width: number = minGateWidth,
202
+ height = gateHeight;
203
+ // Draw measurement box
204
+ const mBox: SVGElement = box(
205
+ x,
206
+ y - height / 2,
207
+ width,
208
+ height,
209
+ "gate-measure",
210
+ );
211
+ const mArc: SVGElement = arc(x + 5, y + 2, width / 2 - 5, height / 2 - 8);
212
+ const meter: SVGElement = line(
213
+ x + width / 2,
214
+ y + 8,
215
+ x + width - 8,
216
+ y - height / 2 + 8,
217
+ );
218
+ return group([mBox, mArc, meter]);
219
+ };
220
+
221
+ /**
222
+ * Creates the SVG for a unitary gate on an arbitrary number of qubits.
223
+ *
224
+ * @param label Gate label.
225
+ * @param x x coord of gate.
226
+ * @param y Array of y coords of registers acted upon by gate.
227
+ * @param width Width of gate.
228
+ * @param displayArgs Arguments passed in to gate.
229
+ * @param renderDashedLine If true, draw dashed lines between non-adjacent unitaries.
230
+ *
231
+ * @returns SVG representation of unitary gate.
232
+ */
233
+ const _unitary = (
234
+ label: string,
235
+ x: number,
236
+ y: number[][],
237
+ width: number,
238
+ displayArgs?: string,
239
+ renderDashedLine = true,
240
+ ): SVGElement => {
241
+ if (y.length === 0)
242
+ throw new Error(
243
+ `Failed to render unitary gate (${label}): has no y-values`,
244
+ );
245
+
246
+ // Render each group as a separate unitary boxes
247
+ const unitaryBoxes: SVGElement[] = y.map((group: number[]) => {
248
+ const maxY: number = group[group.length - 1],
249
+ minY: number = group[0];
250
+ const height: number = maxY - minY + gateHeight;
251
+ return _unitaryBox(label, x, minY, width, height, displayArgs);
252
+ });
253
+
254
+ // Draw dashed line between disconnected unitaries
255
+ if (renderDashedLine && unitaryBoxes.length > 1) {
256
+ const lastBox: number[] = y[y.length - 1];
257
+ const firstBox: number[] = y[0];
258
+ const maxY: number = lastBox[lastBox.length - 1],
259
+ minY: number = firstBox[0];
260
+ const vertLine: SVGElement = dashedLine(x, minY, x, maxY);
261
+ return group([vertLine, ...unitaryBoxes]);
262
+ }
263
+
264
+ return group(unitaryBoxes);
265
+ };
266
+
267
+ /**
268
+ * Generates SVG representation of the boxed unitary gate symbol.
269
+ *
270
+ * @param label Label for unitary operation.
271
+ * @param x x coord of gate.
272
+ * @param y y coord of gate.
273
+ * @param width Width of gate.
274
+ * @param height Height of gate.
275
+ * @param displayArgs Arguments passed in to gate.
276
+ *
277
+ * @returns SVG representation of unitary box.
278
+ */
279
+ const _unitaryBox = (
280
+ label: string,
281
+ x: number,
282
+ y: number,
283
+ width: number,
284
+ height: number = gateHeight,
285
+ displayArgs?: string,
286
+ ): SVGElement => {
287
+ y -= gateHeight / 2;
288
+ const uBox: SVGElement = box(x - width / 2, y, width, height);
289
+ const labelY = y + height / 2 - (displayArgs == null ? 0 : 7);
290
+ const labelText: SVGElement = text(label, x, labelY);
291
+ const elems = [uBox, labelText];
292
+ if (displayArgs != null) {
293
+ const argStrY = y + height / 2 + 8;
294
+ const argText: SVGElement = text(displayArgs, x, argStrY, argsFontSize);
295
+ elems.push(argText);
296
+ }
297
+ return group(elems);
298
+ };
299
+
300
+ /**
301
+ * Creates the SVG for a SWAP gate on y coords given by targetsY.
302
+ *
303
+ * @param x Centre x coord of SWAP gate.
304
+ * @param targetsY y coords of target registers.
305
+ *
306
+ * @returns SVG representation of SWAP gate.
307
+ */
308
+ const _swap = (metadata: Metadata, nestedDepth: number): SVGElement => {
309
+ const { x, targetsY } = metadata;
310
+
311
+ // Get SVGs of crosses
312
+ const [x1, y1, x2, y2] = _gatePosition(metadata, nestedDepth);
313
+ const ys = targetsY?.flatMap((y) => y as number[]) || [];
314
+
315
+ const bg: SVGElement = box(x1, y1, x2, y2, "gate-swap");
316
+ const crosses: SVGElement[] = ys.map((y) => _cross(x, y));
317
+ const vertLine: SVGElement = line(x, ys[0], x, ys[1]);
318
+ return group([bg, ...crosses, vertLine]);
319
+ };
320
+ /**
321
+ * Creates the SVG for an X gate
322
+ *
323
+ * @returns SVG representation of X gate.
324
+ */
325
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
326
+ const _x = (metadata: Metadata, _: number): SVGElement => {
327
+ const { x, targetsY } = metadata;
328
+ const ys = targetsY.flatMap((y) => y as number[]);
329
+ return _oplus(x, ys[0]);
330
+ };
331
+ /**
332
+ * Generates cross for display in SWAP gate.
333
+ *
334
+ * @param x x coord of gate.
335
+ * @param y y coord of gate.
336
+ *
337
+ * @returns SVG representation for cross.
338
+ */
339
+ const _cross = (x: number, y: number): SVGElement => {
340
+ const radius = 8;
341
+ const line1: SVGElement = line(
342
+ x - radius,
343
+ y - radius,
344
+ x + radius,
345
+ y + radius,
346
+ );
347
+ const line2: SVGElement = line(
348
+ x - radius,
349
+ y + radius,
350
+ x + radius,
351
+ y - radius,
352
+ );
353
+ return group([line1, line2]);
354
+ };
355
+
356
+ /**
357
+ * Produces the SVG representation of a controlled gate on multiple qubits.
358
+ *
359
+ * @param metadata Metadata of controlled gate.
360
+ *
361
+ * @returns SVG representation of controlled gate.
362
+ */
363
+ const _controlledGate = (
364
+ metadata: Metadata,
365
+ nestedDepth: number,
366
+ ): SVGElement => {
367
+ const targetGateSvgs: SVGElement[] = [];
368
+ const { type, x, controlsY, label, displayArgs, width } = metadata;
369
+ let { targetsY } = metadata;
370
+
371
+ // Get SVG for target gates
372
+ switch (type) {
373
+ case GateType.Cnot:
374
+ (targetsY as number[]).forEach((y) => targetGateSvgs.push(_oplus(x, y)));
375
+ break;
376
+ case GateType.Swap:
377
+ (targetsY as number[]).forEach((y) => targetGateSvgs.push(_cross(x, y)));
378
+ break;
379
+ case GateType.ControlledUnitary:
380
+ {
381
+ const groupedTargetsY: number[][] = targetsY as number[][];
382
+ targetGateSvgs.push(
383
+ _unitary(label, x, groupedTargetsY, width, displayArgs, false),
384
+ );
385
+ targetsY = targetsY.flat();
386
+ }
387
+ break;
388
+ default:
389
+ throw new Error(`ERROR: Unrecognized gate: ${label} of type ${type}`);
390
+ }
391
+ // Get SVGs for control dots
392
+ const controlledDotsSvg: SVGElement[] = controlsY.map((y) =>
393
+ controlDot(x, y),
394
+ );
395
+ // Create control lines
396
+ const maxY: number = Math.max(...controlsY, ...(targetsY as number[]));
397
+ const minY: number = Math.min(...controlsY, ...(targetsY as number[]));
398
+ const vertLine: SVGElement = line(x, minY, x, maxY);
399
+ const svg: SVGElement = _createGate(
400
+ [vertLine, ...controlledDotsSvg, ...targetGateSvgs],
401
+ metadata,
402
+ nestedDepth,
403
+ );
404
+ return svg;
405
+ };
406
+
407
+ /**
408
+ * Generates $\oplus$ symbol for display in CNOT gate.
409
+ *
410
+ * @param x x coordinate of gate.
411
+ * @param y y coordinate of gate.
412
+ * @param r radius of circle.
413
+ *
414
+ * @returns SVG representation of $\oplus$ symbol.
415
+ */
416
+ const _oplus = (x: number, y: number, r = 15): SVGElement => {
417
+ const circleBorder: SVGElement = circle(x, y, r);
418
+ const vertLine: SVGElement = line(x, y - r, x, y + r);
419
+ const horLine: SVGElement = line(x - r, y, x + r, y);
420
+ return group([circleBorder, vertLine, horLine], { class: "oplus" });
421
+ };
422
+
423
+ /**
424
+ * Generates the SVG for a group of nested operations.
425
+ *
426
+ * @param metadata Metadata representation of gate.
427
+ * @param nestedDepth Depth of nested operations (used in classically controlled and grouped operations).
428
+ *
429
+ * @returns SVG representation of gate.
430
+ */
431
+ const _groupedOperations = (
432
+ metadata: Metadata,
433
+ nestedDepth: number,
434
+ ): SVGElement => {
435
+ const { children } = metadata;
436
+ const [x1, y1, x2, y2] = _gatePosition(metadata, nestedDepth);
437
+
438
+ // Draw dashed box around children gates
439
+ const box: SVGElement = dashedBox(x1, y1, x2, y2);
440
+ const elems: SVGElement[] = [box];
441
+ if (children != null)
442
+ elems.push(formatGates(children as Metadata[], nestedDepth + 1));
443
+ return _createGate(elems, metadata, nestedDepth);
444
+ };
445
+
446
+ /**
447
+ * Generates the SVG for a classically controlled group of operations.
448
+ *
449
+ * @param metadata Metadata representation of gate.
450
+ * @param padding Padding within dashed box.
451
+ *
452
+ * @returns SVG representation of gate.
453
+ */
454
+ const _classicalControlled = (
455
+ metadata: Metadata,
456
+ padding: number = groupBoxPadding,
457
+ ): SVGElement => {
458
+ const { controlsY, dataAttributes } = metadata;
459
+ const targetsY: number[] = metadata.targetsY as number[];
460
+ const children: Metadata[][] = metadata.children as Metadata[][];
461
+ let { x, width } = metadata;
462
+
463
+ const controlY = controlsY[0];
464
+
465
+ const elems: SVGElement[] = [];
466
+
467
+ if (children != null) {
468
+ if (children.length !== 2)
469
+ throw new Error(
470
+ `Invalid number of children found for classically-controlled gate: ${children.length}`,
471
+ );
472
+
473
+ // Get SVG for gates controlled on 0
474
+ const childrenZero: SVGElement = formatGates(children[0]);
475
+ childrenZero.setAttribute("class", "gates-zero");
476
+ elems.push(childrenZero);
477
+
478
+ // Get SVG for gates controlled on 1
479
+ const childrenOne: SVGElement = formatGates(children[1]);
480
+ childrenOne.setAttribute("class", "gates-one");
481
+ elems.push(childrenOne);
482
+ }
483
+
484
+ // Draw control button and attached dashed line to dashed box
485
+ const controlCircleX: number = x + controlBtnRadius;
486
+ const controlCircle: SVGElement = _controlCircle(controlCircleX, controlY);
487
+ const lineY1: number = controlY + controlBtnRadius,
488
+ lineY2: number = controlY + classicalRegHeight / 2;
489
+ const vertLine: SVGElement = dashedLine(
490
+ controlCircleX,
491
+ lineY1,
492
+ controlCircleX,
493
+ lineY2,
494
+ "classical-line",
495
+ );
496
+ x += controlBtnOffset;
497
+ const horLine: SVGElement = dashedLine(
498
+ controlCircleX,
499
+ lineY2,
500
+ x,
501
+ lineY2,
502
+ "classical-line",
503
+ );
504
+
505
+ width = width - controlBtnOffset + (padding - groupBoxPadding) * 2;
506
+ x += groupBoxPadding - padding;
507
+ const y: number = targetsY[0] - gateHeight / 2 - padding;
508
+ const height: number = targetsY[1] - targetsY[0] + gateHeight + padding * 2;
509
+
510
+ // Draw dashed box around children gates
511
+ const box: SVGElement = dashedBox(x, y, width, height, "classical-container");
512
+
513
+ elems.push(...[horLine, vertLine, controlCircle, box]);
514
+
515
+ // Display controlled operation in initial "unknown" state
516
+ const attributes: { [attr: string]: string } = {
517
+ class: `classically-controlled-group classically-controlled-unknown`,
518
+ };
519
+ if (dataAttributes != null)
520
+ Object.entries(dataAttributes).forEach(
521
+ ([attr, val]) => (attributes[`data-${attr}`] = val),
522
+ );
523
+
524
+ return group(elems, attributes);
525
+ };
526
+
527
+ /**
528
+ * Generates the SVG representation of the control circle on a classical register with interactivity support
529
+ * for toggling between bit values (unknown, 1, and 0).
530
+ *
531
+ * @param x x coord.
532
+ * @param y y coord.
533
+ * @param r Radius of circle.
534
+ *
535
+ * @returns SVG representation of control circle.
536
+ */
537
+ const _controlCircle = (
538
+ x: number,
539
+ y: number,
540
+ r: number = controlBtnRadius,
541
+ ): SVGElement =>
542
+ group([circle(x, y, r), text("?", x, y, labelFontSize)], {
543
+ class: "classically-controlled-btn",
544
+ });
545
+
546
+ export {
547
+ formatGates,
548
+ _formatGate,
549
+ _createGate,
550
+ _zoomButton,
551
+ _measure,
552
+ _unitary,
553
+ _swap,
554
+ _controlledGate,
555
+ _groupedOperations,
556
+ _classicalControlled,
557
+ };
@@ -0,0 +1,78 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+
4
+ import { Qubit } from "../circuit";
5
+ import { RegisterType, RegisterMap, RegisterMetadata } from "../register";
6
+ import {
7
+ leftPadding,
8
+ startY,
9
+ registerHeight,
10
+ classicalRegHeight,
11
+ } from "../constants";
12
+ import { group, text } from "./formatUtils";
13
+
14
+ /**
15
+ * `formatInputs` takes in an array of Qubits and outputs the SVG string of formatted
16
+ * qubit wires and a mapping from register IDs to register metadata (for rendering).
17
+ *
18
+ * @param qubits List of declared qubits.
19
+ *
20
+ * @returns returns the SVG string of formatted qubit wires, a mapping from registers
21
+ * to y coord and total SVG height.
22
+ */
23
+ const formatInputs = (
24
+ qubits: Qubit[],
25
+ ): { qubitWires: SVGElement; registers: RegisterMap; svgHeight: number } => {
26
+ const qubitWires: SVGElement[] = [];
27
+ const registers: RegisterMap = {};
28
+
29
+ let currY: number = startY;
30
+ qubits.forEach(({ id, numChildren }) => {
31
+ // Add qubit wire to list of qubit wires
32
+ qubitWires.push(_qubitInput(currY));
33
+
34
+ // Create qubit register
35
+ registers[id] = { type: RegisterType.Qubit, y: currY };
36
+
37
+ // If there are no attached classical registers, increment y by fixed register height
38
+ if (numChildren == null || numChildren === 0) {
39
+ currY += registerHeight;
40
+ return;
41
+ }
42
+
43
+ // Increment current height by classical register height for attached classical registers
44
+ currY += classicalRegHeight;
45
+
46
+ // Add classical wires
47
+ registers[id].children = Array.from(Array(numChildren), () => {
48
+ const clsReg: RegisterMetadata = {
49
+ type: RegisterType.Classical,
50
+ y: currY,
51
+ };
52
+ currY += classicalRegHeight;
53
+ return clsReg;
54
+ });
55
+ });
56
+
57
+ return {
58
+ qubitWires: group(qubitWires),
59
+ registers,
60
+ svgHeight: currY,
61
+ };
62
+ };
63
+
64
+ /**
65
+ * Generate the SVG text component for the input qubit register.
66
+ *
67
+ * @param y y coord of input wire to render in SVG.
68
+ *
69
+ * @returns SVG text component for the input register.
70
+ */
71
+ const _qubitInput = (y: number): SVGElement => {
72
+ const el: SVGElement = text("|0⟩", leftPadding, y, 16);
73
+ el.setAttribute("text-anchor", "start");
74
+ el.setAttribute("dominant-baseline", "middle");
75
+ return el;
76
+ };
77
+
78
+ export { formatInputs, _qubitInput };