qsharp-lang 1.25.7-dev → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/circuit.d.ts +8 -1
- package/docs/Microsoft.Quantum.Core/IsRangeEmpty.md +1 -1
- package/docs/Microsoft.Quantum.Core/Length.md +1 -1
- package/docs/Microsoft.Quantum.Core/RangeEnd.md +1 -1
- package/docs/Microsoft.Quantum.Core/RangeStart.md +1 -1
- package/docs/Microsoft.Quantum.Core/Repeated.md +1 -1
- package/docs/Microsoft.Quantum.Core/index.md +1 -1
- package/docs/Std.Arithmetic/AddLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfEqualLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessOrEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessOrEqualLE.md +1 -1
- package/docs/Std.Arithmetic/FourierTDIncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByI.md +1 -1
- package/docs/Std.Arithmetic/IncByIUsingIncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByL.md +1 -1
- package/docs/Std.Arithmetic/IncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByLEUsingAddLE.md +1 -1
- package/docs/Std.Arithmetic/IncByLUsingIncByLE.md +1 -1
- package/docs/Std.Arithmetic/LookAheadDKRSAddLE.md +1 -1
- package/docs/Std.Arithmetic/MAJ.md +1 -1
- package/docs/Std.Arithmetic/ReflectAboutInteger.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryCGAddLE.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryCGIncByLE.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryTTKIncByLE.md +1 -1
- package/docs/Std.Arithmetic/index.md +1 -1
- package/docs/Std.Arrays/All.md +1 -1
- package/docs/Std.Arrays/Any.md +1 -1
- package/docs/Std.Arrays/Chunks.md +1 -1
- package/docs/Std.Arrays/CircularlyShifted.md +1 -1
- package/docs/Std.Arrays/ColumnAt.md +1 -1
- package/docs/Std.Arrays/Count.md +1 -1
- package/docs/Std.Arrays/Diagonal.md +1 -1
- package/docs/Std.Arrays/DrawMany.md +1 -1
- package/docs/Std.Arrays/Enumerated.md +1 -1
- package/docs/Std.Arrays/Excluding.md +1 -1
- package/docs/Std.Arrays/Filtered.md +1 -1
- package/docs/Std.Arrays/FlatMapped.md +1 -1
- package/docs/Std.Arrays/Flattened.md +1 -1
- package/docs/Std.Arrays/Fold.md +1 -1
- package/docs/Std.Arrays/ForEach.md +1 -1
- package/docs/Std.Arrays/Head.md +1 -1
- package/docs/Std.Arrays/HeadAndRest.md +1 -1
- package/docs/Std.Arrays/IndexOf.md +1 -1
- package/docs/Std.Arrays/IndexRange.md +1 -1
- package/docs/Std.Arrays/Interleaved.md +1 -1
- package/docs/Std.Arrays/IsEmpty.md +1 -1
- package/docs/Std.Arrays/IsRectangularArray.md +1 -1
- package/docs/Std.Arrays/IsSorted.md +1 -1
- package/docs/Std.Arrays/IsSquareArray.md +1 -1
- package/docs/Std.Arrays/Mapped.md +1 -1
- package/docs/Std.Arrays/MappedByIndex.md +1 -1
- package/docs/Std.Arrays/MappedOverRange.md +1 -1
- package/docs/Std.Arrays/Most.md +1 -1
- package/docs/Std.Arrays/MostAndTail.md +1 -1
- package/docs/Std.Arrays/Padded.md +1 -1
- package/docs/Std.Arrays/Partitioned.md +1 -1
- package/docs/Std.Arrays/Rest.md +1 -1
- package/docs/Std.Arrays/Reversed.md +1 -1
- package/docs/Std.Arrays/SequenceI.md +1 -1
- package/docs/Std.Arrays/SequenceL.md +1 -1
- package/docs/Std.Arrays/Sorted.md +1 -1
- package/docs/Std.Arrays/Subarray.md +1 -1
- package/docs/Std.Arrays/Swapped.md +1 -1
- package/docs/Std.Arrays/Tail.md +1 -1
- package/docs/Std.Arrays/Transposed.md +1 -1
- package/docs/Std.Arrays/Unzipped.md +1 -1
- package/docs/Std.Arrays/Where.md +1 -1
- package/docs/Std.Arrays/Windows.md +1 -1
- package/docs/Std.Arrays/Zipped.md +1 -1
- package/docs/Std.Arrays/index.md +1 -1
- package/docs/Std.Canon/ApplyCNOTChain.md +1 -1
- package/docs/Std.Canon/ApplyControlledOnBitString.md +1 -1
- package/docs/Std.Canon/ApplyControlledOnInt.md +1 -1
- package/docs/Std.Canon/ApplyOperationPowerA.md +1 -1
- package/docs/Std.Canon/ApplyOperationPowerCA.md +1 -1
- package/docs/Std.Canon/ApplyP.md +1 -1
- package/docs/Std.Canon/ApplyPauli.md +1 -1
- package/docs/Std.Canon/ApplyPauliFromBitString.md +1 -1
- package/docs/Std.Canon/ApplyPauliFromInt.md +1 -1
- package/docs/Std.Canon/ApplyQFT.md +1 -1
- package/docs/Std.Canon/ApplyQPE.md +1 -1
- package/docs/Std.Canon/ApplyToEach.md +1 -1
- package/docs/Std.Canon/ApplyToEachA.md +1 -1
- package/docs/Std.Canon/ApplyToEachC.md +1 -1
- package/docs/Std.Canon/ApplyToEachCA.md +1 -1
- package/docs/Std.Canon/ApplyXorInPlace.md +1 -1
- package/docs/Std.Canon/ApplyXorInPlaceL.md +1 -1
- package/docs/Std.Canon/CX.md +1 -1
- package/docs/Std.Canon/CY.md +1 -1
- package/docs/Std.Canon/CZ.md +1 -1
- package/docs/Std.Canon/Fst.md +1 -1
- package/docs/Std.Canon/MapPauliAxis.md +1 -1
- package/docs/Std.Canon/Relabel.md +1 -1
- package/docs/Std.Canon/Snd.md +1 -1
- package/docs/Std.Canon/SwapReverseRegister.md +1 -1
- package/docs/Std.Canon/index.md +1 -1
- package/docs/Std.Convert/BigIntAsBoolArray.md +1 -1
- package/docs/Std.Convert/BigIntAsInt.md +1 -1
- package/docs/Std.Convert/BoolArrayAsBigInt.md +1 -1
- package/docs/Std.Convert/BoolArrayAsInt.md +1 -1
- package/docs/Std.Convert/BoolArrayAsResultArray.md +1 -1
- package/docs/Std.Convert/BoolAsResult.md +1 -1
- package/docs/Std.Convert/ComplexAsComplexPolar.md +1 -1
- package/docs/Std.Convert/ComplexPolarAsComplex.md +1 -1
- package/docs/Std.Convert/DoubleAsStringWithPrecision.md +1 -1
- package/docs/Std.Convert/IntAsBigInt.md +1 -1
- package/docs/Std.Convert/IntAsBoolArray.md +1 -1
- package/docs/Std.Convert/IntAsDouble.md +1 -1
- package/docs/Std.Convert/ResultArrayAsBoolArray.md +1 -1
- package/docs/Std.Convert/ResultArrayAsInt.md +1 -1
- package/docs/Std.Convert/ResultAsBool.md +1 -1
- package/docs/Std.Convert/index.md +1 -1
- package/docs/Std.Core/Complex.md +1 -1
- package/docs/Std.Core/Length.md +1 -1
- package/docs/Std.Core/Repeated.md +1 -1
- package/docs/Std.Core/index.md +1 -1
- package/docs/Std.Diagnostics/ApplyIdleNoise.md +1 -1
- package/docs/Std.Diagnostics/BitFlipNoise.md +1 -1
- package/docs/Std.Diagnostics/CheckAllZero.md +1 -1
- package/docs/Std.Diagnostics/CheckOperationsAreEqual.md +1 -1
- package/docs/Std.Diagnostics/CheckZero.md +1 -1
- package/docs/Std.Diagnostics/ConfigurePauliNoise.md +1 -1
- package/docs/Std.Diagnostics/ConfigureQubitLoss.md +1 -1
- package/docs/Std.Diagnostics/DepolarizingNoise.md +1 -1
- package/docs/Std.Diagnostics/DumpMachine.md +1 -1
- package/docs/Std.Diagnostics/DumpOperation.md +1 -1
- package/docs/Std.Diagnostics/DumpRegister.md +1 -1
- package/docs/Std.Diagnostics/Fact.md +1 -1
- package/docs/Std.Diagnostics/NoNoise.md +1 -1
- package/docs/Std.Diagnostics/PhaseFlipNoise.md +1 -1
- package/docs/Std.Diagnostics/StartCountingFunction.md +1 -1
- package/docs/Std.Diagnostics/StartCountingOperation.md +1 -1
- package/docs/Std.Diagnostics/StartCountingQubits.md +1 -1
- package/docs/Std.Diagnostics/StopCountingFunction.md +1 -1
- package/docs/Std.Diagnostics/StopCountingOperation.md +1 -1
- package/docs/Std.Diagnostics/StopCountingQubits.md +1 -1
- package/docs/Std.Diagnostics/index.md +1 -1
- package/docs/Std.Intrinsic/AND.md +1 -1
- package/docs/Std.Intrinsic/ApplyUnitary.md +1 -1
- package/docs/Std.Intrinsic/CCNOT.md +1 -1
- package/docs/Std.Intrinsic/CNOT.md +1 -1
- package/docs/Std.Intrinsic/Exp.md +1 -1
- package/docs/Std.Intrinsic/H.md +1 -1
- package/docs/Std.Intrinsic/I.md +1 -1
- package/docs/Std.Intrinsic/M.md +1 -1
- package/docs/Std.Intrinsic/Measure.md +1 -1
- package/docs/Std.Intrinsic/Message.md +1 -1
- package/docs/Std.Intrinsic/R.md +1 -1
- package/docs/Std.Intrinsic/R1.md +1 -1
- package/docs/Std.Intrinsic/R1Frac.md +1 -1
- package/docs/Std.Intrinsic/RFrac.md +1 -1
- package/docs/Std.Intrinsic/Reset.md +1 -1
- package/docs/Std.Intrinsic/ResetAll.md +1 -1
- package/docs/Std.Intrinsic/Rx.md +1 -1
- package/docs/Std.Intrinsic/Rxx.md +1 -1
- package/docs/Std.Intrinsic/Ry.md +1 -1
- package/docs/Std.Intrinsic/Ryy.md +1 -1
- package/docs/Std.Intrinsic/Rz.md +1 -1
- package/docs/Std.Intrinsic/Rzz.md +1 -1
- package/docs/Std.Intrinsic/S.md +1 -1
- package/docs/Std.Intrinsic/SWAP.md +1 -1
- package/docs/Std.Intrinsic/SX.md +1 -1
- package/docs/Std.Intrinsic/T.md +1 -1
- package/docs/Std.Intrinsic/X.md +1 -1
- package/docs/Std.Intrinsic/Y.md +1 -1
- package/docs/Std.Intrinsic/Z.md +1 -1
- package/docs/Std.Intrinsic/index.md +1 -1
- package/docs/Std.Logical/Xor.md +1 -1
- package/docs/Std.Logical/index.md +1 -1
- package/docs/Std.Math/AbsComplex.md +1 -1
- package/docs/Std.Math/AbsComplexPolar.md +1 -1
- package/docs/Std.Math/AbsD.md +1 -1
- package/docs/Std.Math/AbsI.md +1 -1
- package/docs/Std.Math/AbsL.md +1 -1
- package/docs/Std.Math/AbsSquaredComplex.md +1 -1
- package/docs/Std.Math/AbsSquaredComplexPolar.md +1 -1
- package/docs/Std.Math/ApproximateFactorial.md +1 -1
- package/docs/Std.Math/ArcCos.md +1 -1
- package/docs/Std.Math/ArcCosh.md +1 -1
- package/docs/Std.Math/ArcSin.md +1 -1
- package/docs/Std.Math/ArcSinh.md +1 -1
- package/docs/Std.Math/ArcTan.md +1 -1
- package/docs/Std.Math/ArcTan2.md +1 -1
- package/docs/Std.Math/ArcTanh.md +1 -1
- package/docs/Std.Math/ArgComplex.md +1 -1
- package/docs/Std.Math/ArgComplexPolar.md +1 -1
- package/docs/Std.Math/Binom.md +1 -1
- package/docs/Std.Math/BitSizeI.md +1 -1
- package/docs/Std.Math/BitSizeL.md +1 -1
- package/docs/Std.Math/Ceiling.md +1 -1
- package/docs/Std.Math/Complex.md +1 -1
- package/docs/Std.Math/ComplexPolar.md +1 -1
- package/docs/Std.Math/ContinuedFractionConvergentI.md +1 -1
- package/docs/Std.Math/ContinuedFractionConvergentL.md +1 -1
- package/docs/Std.Math/Cos.md +1 -1
- package/docs/Std.Math/Cosh.md +1 -1
- package/docs/Std.Math/DivRemI.md +1 -1
- package/docs/Std.Math/DivRemL.md +1 -1
- package/docs/Std.Math/DividedByC.md +1 -1
- package/docs/Std.Math/DividedByCP.md +1 -1
- package/docs/Std.Math/E.md +1 -1
- package/docs/Std.Math/ExpModI.md +1 -1
- package/docs/Std.Math/ExpModL.md +1 -1
- package/docs/Std.Math/ExtendedGreatestCommonDivisorI.md +1 -1
- package/docs/Std.Math/ExtendedGreatestCommonDivisorL.md +1 -1
- package/docs/Std.Math/FactorialI.md +1 -1
- package/docs/Std.Math/FactorialL.md +1 -1
- package/docs/Std.Math/Floor.md +1 -1
- package/docs/Std.Math/GreatestCommonDivisorI.md +1 -1
- package/docs/Std.Math/GreatestCommonDivisorL.md +1 -1
- package/docs/Std.Math/HammingWeightI.md +1 -1
- package/docs/Std.Math/InverseModI.md +1 -1
- package/docs/Std.Math/InverseModL.md +1 -1
- package/docs/Std.Math/IsCoprimeI.md +1 -1
- package/docs/Std.Math/IsCoprimeL.md +1 -1
- package/docs/Std.Math/IsInfinite.md +1 -1
- package/docs/Std.Math/IsNaN.md +1 -1
- package/docs/Std.Math/LargestFixedPoint.md +1 -1
- package/docs/Std.Math/Lg.md +1 -1
- package/docs/Std.Math/Log.md +1 -1
- package/docs/Std.Math/Log10.md +1 -1
- package/docs/Std.Math/LogFactorialD.md +1 -1
- package/docs/Std.Math/LogGammaD.md +1 -1
- package/docs/Std.Math/LogOf2.md +1 -1
- package/docs/Std.Math/Max.md +1 -1
- package/docs/Std.Math/MaxD.md +1 -1
- package/docs/Std.Math/MaxI.md +1 -1
- package/docs/Std.Math/MaxL.md +1 -1
- package/docs/Std.Math/Min.md +1 -1
- package/docs/Std.Math/MinD.md +1 -1
- package/docs/Std.Math/MinI.md +1 -1
- package/docs/Std.Math/MinL.md +1 -1
- package/docs/Std.Math/MinusC.md +1 -1
- package/docs/Std.Math/MinusCP.md +1 -1
- package/docs/Std.Math/ModulusI.md +1 -1
- package/docs/Std.Math/ModulusL.md +1 -1
- package/docs/Std.Math/NegationC.md +1 -1
- package/docs/Std.Math/NegationCP.md +1 -1
- package/docs/Std.Math/PI.md +1 -1
- package/docs/Std.Math/PNorm.md +1 -1
- package/docs/Std.Math/PNormalized.md +1 -1
- package/docs/Std.Math/PlusC.md +1 -1
- package/docs/Std.Math/PlusCP.md +1 -1
- package/docs/Std.Math/PowC.md +1 -1
- package/docs/Std.Math/PowCP.md +1 -1
- package/docs/Std.Math/RealMod.md +1 -1
- package/docs/Std.Math/Round.md +1 -1
- package/docs/Std.Math/RoundHalfAwayFromZero.md +1 -1
- package/docs/Std.Math/SignD.md +1 -1
- package/docs/Std.Math/SignI.md +1 -1
- package/docs/Std.Math/SignL.md +1 -1
- package/docs/Std.Math/Sin.md +1 -1
- package/docs/Std.Math/Sinh.md +1 -1
- package/docs/Std.Math/SmallestFixedPoint.md +1 -1
- package/docs/Std.Math/Sqrt.md +1 -1
- package/docs/Std.Math/SquaredNorm.md +1 -1
- package/docs/Std.Math/Tan.md +1 -1
- package/docs/Std.Math/Tanh.md +1 -1
- package/docs/Std.Math/TimesC.md +1 -1
- package/docs/Std.Math/TimesCP.md +1 -1
- package/docs/Std.Math/TrailingZeroCountI.md +1 -1
- package/docs/Std.Math/TrailingZeroCountL.md +1 -1
- package/docs/Std.Math/Truncate.md +1 -1
- package/docs/Std.Math/index.md +1 -1
- package/docs/Std.Measurement/IsLossResult.md +1 -1
- package/docs/Std.Measurement/MResetEachZ.md +1 -1
- package/docs/Std.Measurement/MResetX.md +1 -1
- package/docs/Std.Measurement/MResetY.md +1 -1
- package/docs/Std.Measurement/MResetZ.md +1 -1
- package/docs/Std.Measurement/MResetZChecked.md +1 -1
- package/docs/Std.Measurement/MeasureAllZ.md +1 -1
- package/docs/Std.Measurement/MeasureEachZ.md +1 -1
- package/docs/Std.Measurement/MeasureInteger.md +1 -1
- package/docs/Std.Measurement/index.md +1 -1
- package/docs/Std.Random/DrawRandomBool.md +1 -1
- package/docs/Std.Random/DrawRandomDouble.md +1 -1
- package/docs/Std.Random/DrawRandomInt.md +1 -1
- package/docs/Std.Random/index.md +1 -1
- package/docs/Std.Range/IsRangeEmpty.md +1 -1
- package/docs/Std.Range/RangeEnd.md +1 -1
- package/docs/Std.Range/RangeReverse.md +1 -1
- package/docs/Std.Range/RangeStart.md +1 -1
- package/docs/Std.Range/RangeStep.md +1 -1
- package/docs/Std.Range/index.md +1 -1
- package/docs/Std.ResourceEstimation/AccountForEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/AuxQubitCount.md +1 -1
- package/docs/Std.ResourceEstimation/BeginEstimateCaching.md +1 -1
- package/docs/Std.ResourceEstimation/BeginRepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/CczCount.md +1 -1
- package/docs/Std.ResourceEstimation/EnableMemoryComputeArchitecture.md +1 -1
- package/docs/Std.ResourceEstimation/EndEstimateCaching.md +1 -1
- package/docs/Std.ResourceEstimation/EndRepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/LeastFrequentlyUsed.md +1 -1
- package/docs/Std.ResourceEstimation/LeastRecentlyUsed.md +1 -1
- package/docs/Std.ResourceEstimation/MeasurementCount.md +1 -1
- package/docs/Std.ResourceEstimation/PSSPCLayout.md +1 -1
- package/docs/Std.ResourceEstimation/RepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/RotationCount.md +1 -1
- package/docs/Std.ResourceEstimation/RotationDepth.md +1 -1
- package/docs/Std.ResourceEstimation/SingleVariant.md +1 -1
- package/docs/Std.ResourceEstimation/TCount.md +1 -1
- package/docs/Std.ResourceEstimation/index.md +1 -1
- package/docs/Std.StatePreparation/ApproximatelyPreparePureStateCP.md +1 -1
- package/docs/Std.StatePreparation/PreparePureStateD.md +1 -1
- package/docs/Std.StatePreparation/PrepareUniformSuperposition.md +1 -1
- package/docs/Std.StatePreparation/index.md +1 -1
- package/docs/Std.TableLookup/Select.md +1 -1
- package/docs/Std.TableLookup/index.md +1 -1
- package/docs/index.md +1 -1
- package/lib/nodejs/qsc_wasm.cjs +2 -2
- package/lib/nodejs/qsc_wasm.d.cts +1 -1
- package/lib/nodejs/qsc_wasm_bg.wasm +0 -0
- package/lib/web/qsc_wasm.d.ts +1 -1
- package/lib/web/qsc_wasm.js +2 -2
- package/lib/web/qsc_wasm_bg.wasm +0 -0
- package/package.json +1 -1
- package/ux/circuit-vis/constants.ts +4 -4
- package/ux/circuit-vis/draggable.ts +1 -1
- package/ux/circuit-vis/events.ts +3 -12
- package/ux/circuit-vis/formatters/gateFormatter.ts +168 -73
- package/ux/circuit-vis/formatters/registerFormatter.ts +7 -2
- package/ux/circuit-vis/gateRenderData.ts +3 -1
- package/ux/circuit-vis/index.ts +9 -1
- package/ux/circuit-vis/process.ts +64 -87
- package/ux/circuit-vis/sqore.ts +103 -55
- package/ux/circuit-vis/utils.ts +9 -19
- package/ux/circuit.tsx +12 -95
- package/ux/qsharp-circuit.css +5 -47
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
minGateWidth,
|
|
6
6
|
startX,
|
|
7
7
|
gatePadding,
|
|
8
|
-
|
|
8
|
+
controlCircleOffset,
|
|
9
9
|
groupPaddingX,
|
|
10
10
|
groupTopPadding,
|
|
11
11
|
groupBottomPadding,
|
|
@@ -242,8 +242,6 @@ const _opToRenderData = (
|
|
|
242
242
|
// Set y coords
|
|
243
243
|
renderData.controlsY = controls?.map((reg) => _getRegY(reg, registers)) || [];
|
|
244
244
|
renderData.targetsY = targets.map((reg) => _getRegY(reg, registers));
|
|
245
|
-
const topY = Math.min(...(renderData.targetsY as number[]));
|
|
246
|
-
const bottomY = Math.max(...(renderData.targetsY as number[]));
|
|
247
245
|
|
|
248
246
|
if (isConditional) {
|
|
249
247
|
// Classically-controlled operations
|
|
@@ -252,95 +250,38 @@ const _opToRenderData = (
|
|
|
252
250
|
"No children operations found for classically-controlled operation.",
|
|
253
251
|
);
|
|
254
252
|
|
|
255
|
-
// Gates to display when classical bit is 0.
|
|
256
|
-
const onZeroOps: ComponentGrid = children
|
|
257
|
-
.map((col) => ({
|
|
258
|
-
components: col.components.filter(
|
|
259
|
-
(op) => op.conditionalRender === ConditionalRender.OnZero,
|
|
260
|
-
),
|
|
261
|
-
}))
|
|
262
|
-
.filter((col) => col.components.length > 0);
|
|
263
|
-
|
|
264
|
-
let childrenInstrs = processOperations(
|
|
265
|
-
onZeroOps,
|
|
266
|
-
topY,
|
|
267
|
-
bottomY,
|
|
268
|
-
registers,
|
|
269
|
-
renderLocations,
|
|
270
|
-
);
|
|
271
|
-
const zeroGates: GateRenderData[][] = childrenInstrs.renderDataArray;
|
|
272
|
-
const zeroChildWidth: number = childrenInstrs.svgWidth;
|
|
273
|
-
const zeroChildMaxTopPadding = childrenInstrs.maxTopPadding;
|
|
274
|
-
const zeroChildMaxBottomPadding = childrenInstrs.maxBottomPadding;
|
|
275
|
-
|
|
276
|
-
// Gates to display when classical bit is 1.
|
|
277
|
-
const onOneOps: ComponentGrid = children
|
|
278
|
-
.map((col) => ({
|
|
279
|
-
components: col.components.filter(
|
|
280
|
-
(op) => op.conditionalRender !== ConditionalRender.OnZero,
|
|
281
|
-
),
|
|
282
|
-
}))
|
|
283
|
-
.filter((col) => col.components.length > 0);
|
|
284
|
-
childrenInstrs = processOperations(
|
|
285
|
-
onOneOps,
|
|
286
|
-
topY,
|
|
287
|
-
bottomY,
|
|
288
|
-
registers,
|
|
289
|
-
renderLocations,
|
|
290
|
-
);
|
|
291
|
-
const oneGates: GateRenderData[][] = childrenInstrs.renderDataArray;
|
|
292
|
-
const oneChildWidth: number = childrenInstrs.svgWidth;
|
|
293
|
-
const oneChildMaxTopPadding = childrenInstrs.maxTopPadding;
|
|
294
|
-
const oneChildMaxBottomPadding = childrenInstrs.maxBottomPadding;
|
|
295
|
-
|
|
296
|
-
// Subtract startX (left-side) and 2*gatePadding (right-side) from nested child gates width
|
|
297
|
-
const width: number =
|
|
298
|
-
Math.max(zeroChildWidth, oneChildWidth) - startX - gatePadding * 2;
|
|
299
|
-
|
|
300
|
-
const maxTopPadding = Math.max(
|
|
301
|
-
zeroChildMaxTopPadding,
|
|
302
|
-
oneChildMaxTopPadding,
|
|
303
|
-
);
|
|
304
|
-
const maxBottomPadding = Math.max(
|
|
305
|
-
zeroChildMaxBottomPadding,
|
|
306
|
-
oneChildMaxBottomPadding,
|
|
307
|
-
);
|
|
308
|
-
|
|
309
253
|
renderData.type = GateType.ClassicalControlled;
|
|
310
|
-
renderData.
|
|
311
|
-
|
|
312
|
-
renderData
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
254
|
+
renderData.label = gate;
|
|
255
|
+
|
|
256
|
+
_processChildren(renderData, children, registers, renderLocations);
|
|
257
|
+
|
|
258
|
+
// Fill in the ID to be displayed in each control wire's circle.
|
|
259
|
+
renderData.classicalControlIds =
|
|
260
|
+
controls
|
|
261
|
+
?.map(
|
|
262
|
+
(reg) =>
|
|
263
|
+
op.metadata?.controlResultIds?.find(
|
|
264
|
+
(e) => e[0].qubit === reg.qubit && e[0].result === reg.result,
|
|
265
|
+
)?.[1],
|
|
266
|
+
)
|
|
267
|
+
.map((id) => id ?? null) || [];
|
|
268
|
+
|
|
269
|
+
// Add additional width for classical control circle
|
|
270
|
+
renderData.width += controlCircleOffset;
|
|
321
271
|
} else if (
|
|
322
272
|
conditionalRender == ConditionalRender.AsGroup &&
|
|
323
|
-
|
|
273
|
+
children &&
|
|
274
|
+
(children.length || 0) > 0
|
|
324
275
|
) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
topY,
|
|
328
|
-
bottomY,
|
|
329
|
-
registers,
|
|
330
|
-
renderLocations,
|
|
331
|
-
);
|
|
276
|
+
// Grouped operations
|
|
277
|
+
|
|
332
278
|
renderData.type = GateType.Group;
|
|
333
|
-
renderData.label = gate;
|
|
334
|
-
renderData.children = childrenInstrs.renderDataArray;
|
|
335
279
|
// _zoomButton function in gateFormatter.ts relies on
|
|
336
280
|
// 'expanded' attribute to render zoom button
|
|
337
281
|
renderData.dataAttributes = { expanded: "true" };
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
renderData.topPadding = childrenInstrs.maxTopPadding + groupTopPadding;
|
|
342
|
-
renderData.bottomPadding =
|
|
343
|
-
childrenInstrs.maxBottomPadding + groupBottomPadding;
|
|
282
|
+
renderData.label = gate;
|
|
283
|
+
|
|
284
|
+
_processChildren(renderData, children, registers, renderLocations);
|
|
344
285
|
} else if (op.kind === "measurement") {
|
|
345
286
|
renderData.type = GateType.Measure;
|
|
346
287
|
} else if (op.kind === "ket") {
|
|
@@ -505,17 +446,20 @@ const _fillRenderDataX = (
|
|
|
505
446
|
{
|
|
506
447
|
// Subtract startX offset from nested gates and add offset and padding
|
|
507
448
|
let offset: number = x - startX + groupPaddingX;
|
|
508
|
-
if (renderData.type === GateType.ClassicalControlled)
|
|
509
|
-
offset +=
|
|
449
|
+
if (renderData.type === GateType.ClassicalControlled) {
|
|
450
|
+
offset += controlCircleOffset;
|
|
451
|
+
}
|
|
510
452
|
|
|
511
453
|
// Offset each x coord in children gates
|
|
512
454
|
_offsetChildrenX(renderData.children, offset);
|
|
513
455
|
|
|
514
|
-
|
|
456
|
+
// Groups should be left-aligned in their column
|
|
457
|
+
renderData.x = x + renderData.width / 2;
|
|
515
458
|
}
|
|
516
459
|
break;
|
|
517
460
|
|
|
518
461
|
default:
|
|
462
|
+
// Center gate in column
|
|
519
463
|
renderData.x = x + columnWidths[colIndex] / 2;
|
|
520
464
|
break;
|
|
521
465
|
}
|
|
@@ -544,4 +488,37 @@ const _offsetChildrenX = (
|
|
|
544
488
|
});
|
|
545
489
|
};
|
|
546
490
|
|
|
491
|
+
/**
|
|
492
|
+
* Processes the children operations and updates the render data accordingly.
|
|
493
|
+
*
|
|
494
|
+
* @param renderData Render data of the parent operation, to be updated with children data.
|
|
495
|
+
* @param children Nested operations to be processed.
|
|
496
|
+
* @param registers Mapping from qubit IDs to register render data.
|
|
497
|
+
* @param renderLocations Optional function to map source locations to link hrefs and titles
|
|
498
|
+
*/
|
|
499
|
+
function _processChildren(
|
|
500
|
+
renderData: GateRenderData,
|
|
501
|
+
children: ComponentGrid,
|
|
502
|
+
registers: RegisterMap,
|
|
503
|
+
renderLocations?: (s: SourceLocation[]) => { title: string; href: string },
|
|
504
|
+
) {
|
|
505
|
+
const topY = Math.min(...(renderData.targetsY as number[]));
|
|
506
|
+
const bottomY = Math.max(...(renderData.targetsY as number[]));
|
|
507
|
+
|
|
508
|
+
const childrenInstrs = processOperations(
|
|
509
|
+
children,
|
|
510
|
+
topY,
|
|
511
|
+
bottomY,
|
|
512
|
+
registers,
|
|
513
|
+
renderLocations,
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
renderData.children = childrenInstrs.renderDataArray;
|
|
517
|
+
renderData.width =
|
|
518
|
+
childrenInstrs.svgWidth - startX - gatePadding * 3 + groupPaddingX * 2; // (svgWidth includes 3 extra gate paddings)
|
|
519
|
+
renderData.topPadding = childrenInstrs.maxTopPadding + groupTopPadding;
|
|
520
|
+
renderData.bottomPadding =
|
|
521
|
+
childrenInstrs.maxBottomPadding + groupBottomPadding;
|
|
522
|
+
}
|
|
523
|
+
|
|
547
524
|
export { processOperations };
|
package/ux/circuit-vis/sqore.ts
CHANGED
|
@@ -64,9 +64,15 @@ export type EditorHandlers = {
|
|
|
64
64
|
export type DrawOptions = {
|
|
65
65
|
renderDepth?: number;
|
|
66
66
|
renderLocations?: (l: SourceLocation[]) => { title: string; href: string };
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
/**
|
|
68
|
+
* When provided, enables editing behaviors (dropzones, run button, etc.) and
|
|
69
|
+
* requires the callbacks necessary to support those behaviors.
|
|
70
|
+
*/
|
|
69
71
|
editor?: EditorHandlers;
|
|
72
|
+
/**
|
|
73
|
+
* When provided, enables zoom-to-fit behavior. The callback is called with the new zoom level whenever it changes.
|
|
74
|
+
*/
|
|
75
|
+
onZoomChange?: (zoomLevel: number) => void;
|
|
70
76
|
};
|
|
71
77
|
|
|
72
78
|
/**
|
|
@@ -76,6 +82,9 @@ export class Sqore {
|
|
|
76
82
|
circuit: Circuit;
|
|
77
83
|
gateRegistry: GateRegistry = {};
|
|
78
84
|
renderDepth: number = this.options.renderDepth ?? 0;
|
|
85
|
+
container: HTMLElement | null = null;
|
|
86
|
+
zoomOnResize: boolean = true;
|
|
87
|
+
zoomLevel: number = 100;
|
|
79
88
|
/**
|
|
80
89
|
* Initializes Sqore object.
|
|
81
90
|
*
|
|
@@ -104,11 +113,86 @@ export class Sqore {
|
|
|
104
113
|
*
|
|
105
114
|
* @param container HTML element for rendering visualization into.
|
|
106
115
|
*/
|
|
107
|
-
draw(container: HTMLElement)
|
|
116
|
+
draw(container: HTMLElement) {
|
|
108
117
|
// Inject into container
|
|
109
118
|
if (container == null) throw new Error(`Container not provided.`);
|
|
110
119
|
|
|
120
|
+
this.container = container;
|
|
121
|
+
|
|
111
122
|
this.renderCircuit(container);
|
|
123
|
+
|
|
124
|
+
if (this.options.onZoomChange != null) {
|
|
125
|
+
this.zoomToFit();
|
|
126
|
+
window.addEventListener("resize", () => this.onResize());
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Window resize handler to recalculate and set the zoom level
|
|
132
|
+
* based on the new window width.
|
|
133
|
+
*/
|
|
134
|
+
private onResize() {
|
|
135
|
+
if (!this.zoomOnResize) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Recalculate the zoom level based on the container width
|
|
140
|
+
this.zoomToFit();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Calculate and set the zoom level to fit the circuit within the container.
|
|
145
|
+
*/
|
|
146
|
+
private zoomToFit() {
|
|
147
|
+
if (this.options.onZoomChange == null || this.container == null) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const zoomLevel = this.calculateZoomToFit(this.container);
|
|
151
|
+
this.updateZoomLevel(zoomLevel);
|
|
152
|
+
this.options.onZoomChange?.(zoomLevel);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Update the zoom level setting and apply it to the SVG element.
|
|
157
|
+
*/
|
|
158
|
+
updateZoomLevel(zoomLevel: number) {
|
|
159
|
+
this.zoomLevel = zoomLevel;
|
|
160
|
+
const svg = this.container?.querySelector("svg.qviz");
|
|
161
|
+
if (svg) {
|
|
162
|
+
this.updateSvgWidth(svg as SVGElement, zoomLevel);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Update the width of the SVG element based on the zoom level.
|
|
168
|
+
*/
|
|
169
|
+
updateSvgWidth(svg: SVGElement, zoomLevel: number) {
|
|
170
|
+
// The width attribute contains the true width.
|
|
171
|
+
// We'll leave this attribute untouched, so we can use it again if the
|
|
172
|
+
// zoom level is ever updated.
|
|
173
|
+
const width = svg.getAttribute("width")!;
|
|
174
|
+
|
|
175
|
+
// We'll set the width in the style attribute to (true width * zoom level).
|
|
176
|
+
// This value takes precedence over the true width in the width attribute.
|
|
177
|
+
svg.setAttribute(
|
|
178
|
+
"style",
|
|
179
|
+
`max-width: ${width}; width: ${(parseInt(width) * (zoomLevel || 100)) / 100}; height: auto`,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Calculate the zoom level that will fit the circuit into the current size of the container.
|
|
185
|
+
*/
|
|
186
|
+
calculateZoomToFit(container: HTMLElement): number {
|
|
187
|
+
const svg = container.querySelector("svg.qviz") as SVGElement;
|
|
188
|
+
const containerWidth = container.clientWidth;
|
|
189
|
+
// width and height are the true dimensions generated by qviz
|
|
190
|
+
const width = parseInt(svg.getAttribute("width")!);
|
|
191
|
+
const height = svg.getAttribute("height")!;
|
|
192
|
+
|
|
193
|
+
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
194
|
+
const zoom = Math.min(Math.ceil((containerWidth / width) * 100), 100);
|
|
195
|
+
return zoom;
|
|
112
196
|
}
|
|
113
197
|
|
|
114
198
|
/**
|
|
@@ -139,6 +223,9 @@ export class Sqore {
|
|
|
139
223
|
const composedSqore: ComposedSqore = this.compose(_circuit);
|
|
140
224
|
const svg: SVGElement = this.generateSvg(composedSqore);
|
|
141
225
|
this.setViewBox(svg);
|
|
226
|
+
if (this.options.onZoomChange != null) {
|
|
227
|
+
this.updateSvgWidth(svg, this.zoomLevel);
|
|
228
|
+
}
|
|
142
229
|
const previousSvg = container.querySelector("svg.qviz");
|
|
143
230
|
if (previousSvg == null) {
|
|
144
231
|
container.appendChild(svg);
|
|
@@ -308,7 +395,6 @@ export class Sqore {
|
|
|
308
395
|
svg.setAttribute("class", "qviz");
|
|
309
396
|
svg.setAttribute("width", width.toString());
|
|
310
397
|
svg.setAttribute("height", height.toString());
|
|
311
|
-
svg.style.setProperty("max-width", "fit-content");
|
|
312
398
|
|
|
313
399
|
// Add styles
|
|
314
400
|
document.documentElement.style.setProperty(
|
|
@@ -368,58 +454,9 @@ export class Sqore {
|
|
|
368
454
|
*
|
|
369
455
|
*/
|
|
370
456
|
private addGateClickHandlers(container: HTMLElement, circuit: Circuit): void {
|
|
371
|
-
this.addClassicalControlHandlers(container);
|
|
372
457
|
this.addZoomHandlers(container, circuit);
|
|
373
458
|
}
|
|
374
459
|
|
|
375
|
-
/**
|
|
376
|
-
* Add interactive click handlers for classically-controlled operations.
|
|
377
|
-
*
|
|
378
|
-
* @param container HTML element containing visualized circuit.
|
|
379
|
-
*
|
|
380
|
-
*/
|
|
381
|
-
private addClassicalControlHandlers(container: HTMLElement): void {
|
|
382
|
-
container.querySelectorAll(".classically-controlled-btn").forEach((btn) => {
|
|
383
|
-
// Zoom in on clicked gate
|
|
384
|
-
btn.addEventListener("click", (evt: Event) => {
|
|
385
|
-
const textSvg = btn.querySelector("text");
|
|
386
|
-
const group = btn.parentElement;
|
|
387
|
-
if (textSvg == null || group == null) return;
|
|
388
|
-
|
|
389
|
-
const currValue = textSvg.firstChild?.nodeValue;
|
|
390
|
-
const zeroGates = group?.querySelector(".gates-zero");
|
|
391
|
-
const oneGates = group?.querySelector(".gates-one");
|
|
392
|
-
switch (currValue) {
|
|
393
|
-
case "?":
|
|
394
|
-
textSvg.childNodes[0].nodeValue = "1";
|
|
395
|
-
group.classList.remove("classically-controlled-unknown");
|
|
396
|
-
group.classList.remove("classically-controlled-zero");
|
|
397
|
-
group.classList.add("classically-controlled-one");
|
|
398
|
-
zeroGates?.classList.add("hidden");
|
|
399
|
-
oneGates?.classList.remove("hidden");
|
|
400
|
-
break;
|
|
401
|
-
case "1":
|
|
402
|
-
textSvg.childNodes[0].nodeValue = "0";
|
|
403
|
-
group.classList.remove("classically-controlled-unknown");
|
|
404
|
-
group.classList.add("classically-controlled-zero");
|
|
405
|
-
group.classList.remove("classically-controlled-one");
|
|
406
|
-
zeroGates?.classList.remove("hidden");
|
|
407
|
-
oneGates?.classList.add("hidden");
|
|
408
|
-
break;
|
|
409
|
-
case "0":
|
|
410
|
-
textSvg.childNodes[0].nodeValue = "?";
|
|
411
|
-
group.classList.add("classically-controlled-unknown");
|
|
412
|
-
group.classList.remove("classically-controlled-zero");
|
|
413
|
-
group.classList.remove("classically-controlled-one");
|
|
414
|
-
zeroGates?.classList.remove("hidden");
|
|
415
|
-
oneGates?.classList.remove("hidden");
|
|
416
|
-
break;
|
|
417
|
-
}
|
|
418
|
-
evt.stopPropagation();
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
|
|
423
460
|
/**
|
|
424
461
|
* Add interactive click handlers for zoom-in/out functionality.
|
|
425
462
|
*
|
|
@@ -439,6 +476,7 @@ export class Sqore {
|
|
|
439
476
|
} else if (ctrl.classList.contains("gate-expand")) {
|
|
440
477
|
this.expandOperation(circuit.componentGrid, gateId);
|
|
441
478
|
}
|
|
479
|
+
this.zoomOnResize = false;
|
|
442
480
|
this.renderCircuit(container, circuit);
|
|
443
481
|
|
|
444
482
|
ev.stopPropagation();
|
|
@@ -580,10 +618,10 @@ function updateRowHeights(
|
|
|
580
618
|
) {
|
|
581
619
|
for (const col of componentGrid) {
|
|
582
620
|
for (const component of col.components) {
|
|
583
|
-
if (component
|
|
621
|
+
if (isExpandedGroup(component)) {
|
|
584
622
|
// We're in an expanded group. There is a dashed border above
|
|
585
623
|
// the top qubit, and below the bottom qubit.
|
|
586
|
-
const [topQubit, bottomQubit] = getMinMaxRegIdx(component
|
|
624
|
+
const [topQubit, bottomQubit] = getMinMaxRegIdx(component);
|
|
587
625
|
|
|
588
626
|
// Increment the current count of dashed group borders for
|
|
589
627
|
// the top and bottom rows for this operation.
|
|
@@ -611,3 +649,13 @@ function updateRowHeights(
|
|
|
611
649
|
}
|
|
612
650
|
}
|
|
613
651
|
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* An "expanded group" here is any operation that is to be rendered showing
|
|
655
|
+
* its children, with a dashed box around the children.
|
|
656
|
+
*/
|
|
657
|
+
function isExpandedGroup(component: Operation) {
|
|
658
|
+
return (
|
|
659
|
+
component.dataAttributes?.["expanded"] === "true" || component.isConditional
|
|
660
|
+
);
|
|
661
|
+
}
|
package/ux/circuit-vis/utils.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
labelPaddingX,
|
|
8
8
|
labelFontSize,
|
|
9
9
|
argsFontSize,
|
|
10
|
+
controlCircleOffset,
|
|
10
11
|
} from "./constants.js";
|
|
11
12
|
import { ComponentGrid, Operation } from "./circuit.js";
|
|
12
13
|
import { Register } from "./register.js";
|
|
@@ -67,11 +68,14 @@ const getMinGateWidth = ({
|
|
|
67
68
|
case GateType.Swap:
|
|
68
69
|
return minGateWidth;
|
|
69
70
|
default: {
|
|
71
|
+
// Classically controlled gates are wider because of the control button on the left
|
|
72
|
+
const controlButtonWidth =
|
|
73
|
+
type === GateType.ClassicalControlled ? controlCircleOffset : 0;
|
|
70
74
|
const labelWidth = _getStringWidth(label);
|
|
71
75
|
const argsWidth =
|
|
72
76
|
displayArgs != null ? _getStringWidth(displayArgs, argsFontSize) : 0;
|
|
73
77
|
const textWidth = Math.max(labelWidth, argsWidth) + labelPaddingX * 2;
|
|
74
|
-
return Math.max(minGateWidth, textWidth);
|
|
78
|
+
return Math.max(minGateWidth, textWidth) + controlButtonWidth;
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
81
|
};
|
|
@@ -239,10 +243,7 @@ const getGateLocationString = (operation: Operation): string | null => {
|
|
|
239
243
|
* @param numQubits The number of qubits in the circuit.
|
|
240
244
|
* @returns A tuple containing the minimum and maximum register indices.
|
|
241
245
|
*/
|
|
242
|
-
function getMinMaxRegIdx(
|
|
243
|
-
operation: Operation,
|
|
244
|
-
numQubits: number,
|
|
245
|
-
): [number, number] {
|
|
246
|
+
function getMinMaxRegIdx(operation: Operation): [number, number] {
|
|
246
247
|
let targets: Register[];
|
|
247
248
|
let controls: Register[];
|
|
248
249
|
switch (operation.kind) {
|
|
@@ -260,20 +261,9 @@ function getMinMaxRegIdx(
|
|
|
260
261
|
break;
|
|
261
262
|
}
|
|
262
263
|
|
|
263
|
-
const qRegs = [...controls, ...targets]
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const clsControls: Register[] = controls.filter(
|
|
267
|
-
({ result }) => result !== undefined,
|
|
268
|
-
);
|
|
269
|
-
const isClassicallyControlled: boolean = clsControls.length > 0;
|
|
270
|
-
if (!isClassicallyControlled && qRegs.length === 0) return [-1, -1];
|
|
271
|
-
// If operation is classically-controlled, pad all qubit registers. Otherwise, only pad
|
|
272
|
-
// the contiguous range of registers that it covers.
|
|
273
|
-
const minRegIdx: number = isClassicallyControlled ? 0 : Math.min(...qRegs);
|
|
274
|
-
const maxRegIdx: number = isClassicallyControlled
|
|
275
|
-
? numQubits - 1
|
|
276
|
-
: Math.max(...qRegs);
|
|
264
|
+
const qRegs = [...controls, ...targets].map(({ qubit }) => qubit);
|
|
265
|
+
const minRegIdx: number = Math.min(...qRegs);
|
|
266
|
+
const maxRegIdx: number = Math.max(...qRegs);
|
|
277
267
|
|
|
278
268
|
return [minRegIdx, maxRegIdx];
|
|
279
269
|
}
|
package/ux/circuit.tsx
CHANGED
|
@@ -68,9 +68,9 @@ function ZoomableCircuit(props: {
|
|
|
68
68
|
editor?: qviz.EditorHandlers;
|
|
69
69
|
}) {
|
|
70
70
|
const circuitDiv = useRef<HTMLDivElement>(null);
|
|
71
|
+
const qvizObj = useRef<ReturnType<typeof qviz.draw> | null>(null);
|
|
71
72
|
const [zoomLevel, setZoomLevel] = useState(100);
|
|
72
73
|
const [rendering, setRendering] = useState(true);
|
|
73
|
-
const [zoomOnResize, setZoomOnResize] = useState(true);
|
|
74
74
|
|
|
75
75
|
const isEditable = props.editor != null;
|
|
76
76
|
|
|
@@ -85,36 +85,18 @@ function ZoomableCircuit(props: {
|
|
|
85
85
|
if (rendering) {
|
|
86
86
|
const container = circuitDiv.current!;
|
|
87
87
|
// Draw the circuits - may take a while for large circuits
|
|
88
|
-
|
|
89
|
-
props.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
qvizObj.current = qviz.draw(props.circuitGroup, container, {
|
|
89
|
+
renderLocations: props.renderLocations,
|
|
90
|
+
editor: props.editor,
|
|
91
|
+
onZoomChange: (zoom) => {
|
|
92
|
+
setZoomLevel(zoom);
|
|
93
|
+
},
|
|
94
|
+
});
|
|
94
95
|
|
|
95
|
-
if (!isEditable) {
|
|
96
|
-
const initialZoom = calculateZoomToFit(container, svg as SVGElement);
|
|
97
|
-
// Set the initial zoom level
|
|
98
|
-
setZoomLevel(initialZoom);
|
|
99
|
-
// Resize the SVG to fit
|
|
100
|
-
updateWidth();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Calculate the initial zoom level based on the container width
|
|
104
96
|
// Disable "rendering" text
|
|
105
97
|
setRendering(false);
|
|
106
|
-
} else if (!isEditable) {
|
|
107
|
-
// Initial drawing done, attach window resize handler
|
|
108
|
-
window.addEventListener("resize", onResize);
|
|
109
|
-
return () => {
|
|
110
|
-
window.removeEventListener("resize", onResize);
|
|
111
|
-
};
|
|
112
98
|
}
|
|
113
|
-
}, [rendering
|
|
114
|
-
|
|
115
|
-
useEffect(() => {
|
|
116
|
-
updateWidth();
|
|
117
|
-
}, [zoomLevel]);
|
|
99
|
+
}, [rendering]);
|
|
118
100
|
|
|
119
101
|
return (
|
|
120
102
|
<div>
|
|
@@ -132,76 +114,11 @@ function ZoomableCircuit(props: {
|
|
|
132
114
|
</div>
|
|
133
115
|
);
|
|
134
116
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
*/
|
|
139
|
-
function onResize() {
|
|
140
|
-
if (!zoomOnResize) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const [container, svg] = [circuitDiv.current, currentSvg()];
|
|
145
|
-
if (container && svg) {
|
|
146
|
-
// Recalculate the zoom level based on the container width
|
|
147
|
-
const initialZoom = calculateZoomToFit(container, svg);
|
|
148
|
-
// Set the zoom level
|
|
149
|
-
setZoomLevel(initialZoom);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Update the width of the SVG element based on the current zoom level.
|
|
155
|
-
*/
|
|
156
|
-
function updateWidth() {
|
|
157
|
-
const svg = currentSvg();
|
|
158
|
-
if (svg) {
|
|
159
|
-
// The width attribute contains the true width, generated by qviz.
|
|
160
|
-
// We'll leave this attribute untouched, so we can use it again if the
|
|
161
|
-
// zoom level is ever updated.
|
|
162
|
-
const width = svg.getAttribute("width")!;
|
|
163
|
-
|
|
164
|
-
// We'll set the width in the style attribute to (true width * zoom level).
|
|
165
|
-
// This value takes precedence over the true width in the width attribute.
|
|
166
|
-
svg.setAttribute(
|
|
167
|
-
"style",
|
|
168
|
-
`max-width: ${width}; width: ${(parseInt(width) * (zoomLevel || 100)) / 100}; height: auto`,
|
|
169
|
-
);
|
|
117
|
+
function userSetZoomLevel(zoomLevel: number) {
|
|
118
|
+
if (qvizObj.current && circuitDiv.current) {
|
|
119
|
+
qvizObj.current.userSetZoomLevel(zoomLevel);
|
|
170
120
|
}
|
|
171
121
|
}
|
|
172
|
-
|
|
173
|
-
function renderCircuits(
|
|
174
|
-
circuitGroup: qviz.CircuitGroup,
|
|
175
|
-
container: HTMLDivElement,
|
|
176
|
-
renderLocations?: (s: SourceLocation[]) => { title: string; href: string },
|
|
177
|
-
editor?: qviz.EditorHandlers,
|
|
178
|
-
) {
|
|
179
|
-
qviz.draw(circuitGroup, container, { renderLocations, editor });
|
|
180
|
-
return container.getElementsByClassName("qviz")[0]!;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Calculate the zoom level that will fit the circuit into the current size of the container.
|
|
185
|
-
*/
|
|
186
|
-
function calculateZoomToFit(container: HTMLDivElement, svg: SVGElement) {
|
|
187
|
-
const containerWidth = container.clientWidth;
|
|
188
|
-
// width and height are the true dimensions generated by qviz
|
|
189
|
-
const width = parseInt(svg.getAttribute("width")!);
|
|
190
|
-
const height = svg.getAttribute("height")!;
|
|
191
|
-
|
|
192
|
-
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
193
|
-
const zoom = Math.min(Math.ceil((containerWidth / width) * 100), 100);
|
|
194
|
-
return zoom;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function currentSvg(): SVGElement | undefined {
|
|
198
|
-
return circuitDiv.current?.querySelector(".qviz") ?? undefined;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function userSetZoomLevel(zoom: number) {
|
|
202
|
-
setZoomOnResize(false);
|
|
203
|
-
setZoomLevel(zoom);
|
|
204
|
-
}
|
|
205
122
|
}
|
|
206
123
|
|
|
207
124
|
function Unrenderable(props: {
|
package/ux/qsharp-circuit.css
CHANGED
|
@@ -180,59 +180,17 @@
|
|
|
180
180
|
display: none;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
.classically-controlled-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
.classically-controlled-one .classical-container,
|
|
188
|
-
.classically-controlled-one .classical-line {
|
|
189
|
-
stroke: #4059bd;
|
|
190
|
-
stroke-width: 1.3;
|
|
191
|
-
fill: #4059bd;
|
|
192
|
-
fill-opacity: 0.1;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.classically-controlled-zero .classical-container,
|
|
196
|
-
.classically-controlled-zero .classical-line {
|
|
197
|
-
stroke: #c40000;
|
|
198
|
-
stroke-width: 1.3;
|
|
199
|
-
fill: #c40000;
|
|
200
|
-
fill-opacity: 0.1;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.classically-controlled-btn {
|
|
204
|
-
cursor: pointer;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.classically-controlled-unknown .classically-controlled-btn {
|
|
208
|
-
fill: #e5e5e5;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.classically-controlled-one .classically-controlled-btn {
|
|
212
|
-
fill: #4059bd;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
.classically-controlled-zero .classically-controlled-btn {
|
|
216
|
-
fill: #c40000;
|
|
183
|
+
.classically-controlled-btn circle {
|
|
184
|
+
fill: var(--main-background);
|
|
185
|
+
stroke-width: 1;
|
|
217
186
|
}
|
|
218
187
|
|
|
219
188
|
.classically-controlled-btn text {
|
|
220
189
|
dominant-baseline: middle;
|
|
221
190
|
text-anchor: middle;
|
|
222
191
|
stroke: none;
|
|
223
|
-
font-family:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
.classically-controlled-unknown .classically-controlled-btn text {
|
|
227
|
-
fill: #000000;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
.classically-controlled-one .classically-controlled-btn text {
|
|
231
|
-
fill: #ffffff;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.classically-controlled-zero .classically-controlled-btn text {
|
|
235
|
-
fill: #ffffff;
|
|
192
|
+
font-family: "KaTeX_Main", "MJXZERO", "MJXTEX", sans-serif;
|
|
193
|
+
fill: var(--main-color);
|
|
236
194
|
}
|
|
237
195
|
|
|
238
196
|
.qviz .gate-collapse,
|