@featurevisor/sdk 1.35.3 → 2.0.1
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/CHANGELOG.md +8 -0
- package/README.md +2 -381
- package/coverage/clover.xml +707 -645
- package/coverage/coverage-final.json +11 -9
- package/coverage/lcov-report/{segments.ts.html → bucketer.ts.html} +155 -77
- package/coverage/lcov-report/child.ts.html +940 -0
- package/coverage/lcov-report/conditions.ts.html +107 -158
- package/coverage/lcov-report/datafileReader.ts.html +763 -103
- package/coverage/lcov-report/emitter.ts.html +77 -59
- package/coverage/lcov-report/evaluate.ts.html +689 -416
- package/coverage/lcov-report/events.ts.html +334 -0
- package/coverage/lcov-report/helpers.ts.html +184 -0
- package/coverage/lcov-report/{bucket.ts.html → hooks.ts.html} +86 -239
- package/coverage/lcov-report/index.html +119 -89
- package/coverage/lcov-report/instance.ts.html +341 -773
- package/coverage/lcov-report/logger.ts.html +64 -64
- package/coverage/lcov.info +1433 -1226
- package/dist/bucketer.d.ts +11 -0
- package/dist/child.d.ts +26 -0
- package/dist/compareVersions.d.ts +4 -0
- package/dist/conditions.d.ts +4 -4
- package/dist/datafileReader.d.ts +26 -6
- package/dist/emitter.d.ts +8 -9
- package/dist/evaluate.d.ts +31 -29
- package/dist/events.d.ts +5 -0
- package/dist/helpers.d.ts +5 -0
- package/dist/hooks.d.ts +45 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.gz +0 -0
- package/dist/index.mjs.map +1 -1
- package/dist/instance.d.ts +40 -72
- package/dist/logger.d.ts +6 -5
- package/dist/murmurhash.d.ts +1 -0
- package/jest.config.js +2 -0
- package/lib/bucketer.d.ts +11 -0
- package/lib/child.d.ts +26 -0
- package/lib/compareVersions.d.ts +4 -0
- package/lib/conditions.d.ts +4 -4
- package/lib/datafileReader.d.ts +26 -6
- package/lib/emitter.d.ts +8 -9
- package/lib/evaluate.d.ts +31 -29
- package/lib/events.d.ts +5 -0
- package/lib/helpers.d.ts +5 -0
- package/lib/hooks.d.ts +45 -0
- package/lib/index.d.ts +3 -2
- package/lib/instance.d.ts +40 -72
- package/lib/logger.d.ts +6 -5
- package/lib/murmurhash.d.ts +1 -0
- package/package.json +3 -5
- package/src/bucketer.spec.ts +165 -0
- package/src/bucketer.ts +84 -0
- package/src/child.spec.ts +267 -0
- package/src/child.ts +285 -0
- package/src/compareVersions.ts +93 -0
- package/src/conditions.spec.ts +563 -353
- package/src/conditions.ts +46 -63
- package/src/datafileReader.spec.ts +396 -84
- package/src/datafileReader.ts +280 -60
- package/src/emitter.spec.ts +27 -86
- package/src/emitter.ts +38 -32
- package/src/evaluate.ts +349 -258
- package/src/events.spec.ts +154 -0
- package/src/events.ts +83 -0
- package/src/helpers.ts +33 -0
- package/src/hooks.ts +88 -0
- package/src/index.ts +3 -2
- package/src/instance.spec.ts +305 -489
- package/src/instance.ts +247 -391
- package/src/logger.spec.ts +212 -134
- package/src/logger.ts +36 -36
- package/src/murmurhash.ts +71 -0
- package/coverage/lcov-report/feature.ts.html +0 -508
- package/dist/bucket.d.ts +0 -30
- package/dist/feature.d.ts +0 -16
- package/dist/segments.d.ts +0 -5
- package/lib/bucket.d.ts +0 -30
- package/lib/feature.d.ts +0 -16
- package/lib/segments.d.ts +0 -5
- package/src/bucket.spec.ts +0 -37
- package/src/bucket.ts +0 -139
- package/src/feature.ts +0 -141
- package/src/segments.spec.ts +0 -468
- package/src/segments.ts +0 -58
|
@@ -23,30 +23,30 @@
|
|
|
23
23
|
<div class='clearfix'>
|
|
24
24
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
|
-
<span class="strong">
|
|
26
|
+
<span class="strong">81.9% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>86/105</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">
|
|
33
|
+
<span class="strong">59.15% </span>
|
|
34
34
|
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>
|
|
35
|
+
<span class='fraction'>42/71</span>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
|
-
<span class="strong">
|
|
40
|
+
<span class="strong">75% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>21/28</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
|
-
<span class="strong">
|
|
47
|
+
<span class="strong">81.9% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>
|
|
49
|
+
<span class='fraction'>86/105</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -507,151 +507,7 @@
|
|
|
507
507
|
<a name='L442'></a><a href='#L442'>442</a>
|
|
508
508
|
<a name='L443'></a><a href='#L443'>443</a>
|
|
509
509
|
<a name='L444'></a><a href='#L444'>444</a>
|
|
510
|
-
<a name='L445'></a><a href='#L445'>445</a>
|
|
511
|
-
<a name='L446'></a><a href='#L446'>446</a>
|
|
512
|
-
<a name='L447'></a><a href='#L447'>447</a>
|
|
513
|
-
<a name='L448'></a><a href='#L448'>448</a>
|
|
514
|
-
<a name='L449'></a><a href='#L449'>449</a>
|
|
515
|
-
<a name='L450'></a><a href='#L450'>450</a>
|
|
516
|
-
<a name='L451'></a><a href='#L451'>451</a>
|
|
517
|
-
<a name='L452'></a><a href='#L452'>452</a>
|
|
518
|
-
<a name='L453'></a><a href='#L453'>453</a>
|
|
519
|
-
<a name='L454'></a><a href='#L454'>454</a>
|
|
520
|
-
<a name='L455'></a><a href='#L455'>455</a>
|
|
521
|
-
<a name='L456'></a><a href='#L456'>456</a>
|
|
522
|
-
<a name='L457'></a><a href='#L457'>457</a>
|
|
523
|
-
<a name='L458'></a><a href='#L458'>458</a>
|
|
524
|
-
<a name='L459'></a><a href='#L459'>459</a>
|
|
525
|
-
<a name='L460'></a><a href='#L460'>460</a>
|
|
526
|
-
<a name='L461'></a><a href='#L461'>461</a>
|
|
527
|
-
<a name='L462'></a><a href='#L462'>462</a>
|
|
528
|
-
<a name='L463'></a><a href='#L463'>463</a>
|
|
529
|
-
<a name='L464'></a><a href='#L464'>464</a>
|
|
530
|
-
<a name='L465'></a><a href='#L465'>465</a>
|
|
531
|
-
<a name='L466'></a><a href='#L466'>466</a>
|
|
532
|
-
<a name='L467'></a><a href='#L467'>467</a>
|
|
533
|
-
<a name='L468'></a><a href='#L468'>468</a>
|
|
534
|
-
<a name='L469'></a><a href='#L469'>469</a>
|
|
535
|
-
<a name='L470'></a><a href='#L470'>470</a>
|
|
536
|
-
<a name='L471'></a><a href='#L471'>471</a>
|
|
537
|
-
<a name='L472'></a><a href='#L472'>472</a>
|
|
538
|
-
<a name='L473'></a><a href='#L473'>473</a>
|
|
539
|
-
<a name='L474'></a><a href='#L474'>474</a>
|
|
540
|
-
<a name='L475'></a><a href='#L475'>475</a>
|
|
541
|
-
<a name='L476'></a><a href='#L476'>476</a>
|
|
542
|
-
<a name='L477'></a><a href='#L477'>477</a>
|
|
543
|
-
<a name='L478'></a><a href='#L478'>478</a>
|
|
544
|
-
<a name='L479'></a><a href='#L479'>479</a>
|
|
545
|
-
<a name='L480'></a><a href='#L480'>480</a>
|
|
546
|
-
<a name='L481'></a><a href='#L481'>481</a>
|
|
547
|
-
<a name='L482'></a><a href='#L482'>482</a>
|
|
548
|
-
<a name='L483'></a><a href='#L483'>483</a>
|
|
549
|
-
<a name='L484'></a><a href='#L484'>484</a>
|
|
550
|
-
<a name='L485'></a><a href='#L485'>485</a>
|
|
551
|
-
<a name='L486'></a><a href='#L486'>486</a>
|
|
552
|
-
<a name='L487'></a><a href='#L487'>487</a>
|
|
553
|
-
<a name='L488'></a><a href='#L488'>488</a>
|
|
554
|
-
<a name='L489'></a><a href='#L489'>489</a>
|
|
555
|
-
<a name='L490'></a><a href='#L490'>490</a>
|
|
556
|
-
<a name='L491'></a><a href='#L491'>491</a>
|
|
557
|
-
<a name='L492'></a><a href='#L492'>492</a>
|
|
558
|
-
<a name='L493'></a><a href='#L493'>493</a>
|
|
559
|
-
<a name='L494'></a><a href='#L494'>494</a>
|
|
560
|
-
<a name='L495'></a><a href='#L495'>495</a>
|
|
561
|
-
<a name='L496'></a><a href='#L496'>496</a>
|
|
562
|
-
<a name='L497'></a><a href='#L497'>497</a>
|
|
563
|
-
<a name='L498'></a><a href='#L498'>498</a>
|
|
564
|
-
<a name='L499'></a><a href='#L499'>499</a>
|
|
565
|
-
<a name='L500'></a><a href='#L500'>500</a>
|
|
566
|
-
<a name='L501'></a><a href='#L501'>501</a>
|
|
567
|
-
<a name='L502'></a><a href='#L502'>502</a>
|
|
568
|
-
<a name='L503'></a><a href='#L503'>503</a>
|
|
569
|
-
<a name='L504'></a><a href='#L504'>504</a>
|
|
570
|
-
<a name='L505'></a><a href='#L505'>505</a>
|
|
571
|
-
<a name='L506'></a><a href='#L506'>506</a>
|
|
572
|
-
<a name='L507'></a><a href='#L507'>507</a>
|
|
573
|
-
<a name='L508'></a><a href='#L508'>508</a>
|
|
574
|
-
<a name='L509'></a><a href='#L509'>509</a>
|
|
575
|
-
<a name='L510'></a><a href='#L510'>510</a>
|
|
576
|
-
<a name='L511'></a><a href='#L511'>511</a>
|
|
577
|
-
<a name='L512'></a><a href='#L512'>512</a>
|
|
578
|
-
<a name='L513'></a><a href='#L513'>513</a>
|
|
579
|
-
<a name='L514'></a><a href='#L514'>514</a>
|
|
580
|
-
<a name='L515'></a><a href='#L515'>515</a>
|
|
581
|
-
<a name='L516'></a><a href='#L516'>516</a>
|
|
582
|
-
<a name='L517'></a><a href='#L517'>517</a>
|
|
583
|
-
<a name='L518'></a><a href='#L518'>518</a>
|
|
584
|
-
<a name='L519'></a><a href='#L519'>519</a>
|
|
585
|
-
<a name='L520'></a><a href='#L520'>520</a>
|
|
586
|
-
<a name='L521'></a><a href='#L521'>521</a>
|
|
587
|
-
<a name='L522'></a><a href='#L522'>522</a>
|
|
588
|
-
<a name='L523'></a><a href='#L523'>523</a>
|
|
589
|
-
<a name='L524'></a><a href='#L524'>524</a>
|
|
590
|
-
<a name='L525'></a><a href='#L525'>525</a>
|
|
591
|
-
<a name='L526'></a><a href='#L526'>526</a>
|
|
592
|
-
<a name='L527'></a><a href='#L527'>527</a>
|
|
593
|
-
<a name='L528'></a><a href='#L528'>528</a>
|
|
594
|
-
<a name='L529'></a><a href='#L529'>529</a>
|
|
595
|
-
<a name='L530'></a><a href='#L530'>530</a>
|
|
596
|
-
<a name='L531'></a><a href='#L531'>531</a>
|
|
597
|
-
<a name='L532'></a><a href='#L532'>532</a>
|
|
598
|
-
<a name='L533'></a><a href='#L533'>533</a>
|
|
599
|
-
<a name='L534'></a><a href='#L534'>534</a>
|
|
600
|
-
<a name='L535'></a><a href='#L535'>535</a>
|
|
601
|
-
<a name='L536'></a><a href='#L536'>536</a>
|
|
602
|
-
<a name='L537'></a><a href='#L537'>537</a>
|
|
603
|
-
<a name='L538'></a><a href='#L538'>538</a>
|
|
604
|
-
<a name='L539'></a><a href='#L539'>539</a>
|
|
605
|
-
<a name='L540'></a><a href='#L540'>540</a>
|
|
606
|
-
<a name='L541'></a><a href='#L541'>541</a>
|
|
607
|
-
<a name='L542'></a><a href='#L542'>542</a>
|
|
608
|
-
<a name='L543'></a><a href='#L543'>543</a>
|
|
609
|
-
<a name='L544'></a><a href='#L544'>544</a>
|
|
610
|
-
<a name='L545'></a><a href='#L545'>545</a>
|
|
611
|
-
<a name='L546'></a><a href='#L546'>546</a>
|
|
612
|
-
<a name='L547'></a><a href='#L547'>547</a>
|
|
613
|
-
<a name='L548'></a><a href='#L548'>548</a>
|
|
614
|
-
<a name='L549'></a><a href='#L549'>549</a>
|
|
615
|
-
<a name='L550'></a><a href='#L550'>550</a>
|
|
616
|
-
<a name='L551'></a><a href='#L551'>551</a>
|
|
617
|
-
<a name='L552'></a><a href='#L552'>552</a>
|
|
618
|
-
<a name='L553'></a><a href='#L553'>553</a>
|
|
619
|
-
<a name='L554'></a><a href='#L554'>554</a>
|
|
620
|
-
<a name='L555'></a><a href='#L555'>555</a>
|
|
621
|
-
<a name='L556'></a><a href='#L556'>556</a>
|
|
622
|
-
<a name='L557'></a><a href='#L557'>557</a>
|
|
623
|
-
<a name='L558'></a><a href='#L558'>558</a>
|
|
624
|
-
<a name='L559'></a><a href='#L559'>559</a>
|
|
625
|
-
<a name='L560'></a><a href='#L560'>560</a>
|
|
626
|
-
<a name='L561'></a><a href='#L561'>561</a>
|
|
627
|
-
<a name='L562'></a><a href='#L562'>562</a>
|
|
628
|
-
<a name='L563'></a><a href='#L563'>563</a>
|
|
629
|
-
<a name='L564'></a><a href='#L564'>564</a>
|
|
630
|
-
<a name='L565'></a><a href='#L565'>565</a>
|
|
631
|
-
<a name='L566'></a><a href='#L566'>566</a>
|
|
632
|
-
<a name='L567'></a><a href='#L567'>567</a>
|
|
633
|
-
<a name='L568'></a><a href='#L568'>568</a>
|
|
634
|
-
<a name='L569'></a><a href='#L569'>569</a>
|
|
635
|
-
<a name='L570'></a><a href='#L570'>570</a>
|
|
636
|
-
<a name='L571'></a><a href='#L571'>571</a>
|
|
637
|
-
<a name='L572'></a><a href='#L572'>572</a>
|
|
638
|
-
<a name='L573'></a><a href='#L573'>573</a>
|
|
639
|
-
<a name='L574'></a><a href='#L574'>574</a>
|
|
640
|
-
<a name='L575'></a><a href='#L575'>575</a>
|
|
641
|
-
<a name='L576'></a><a href='#L576'>576</a>
|
|
642
|
-
<a name='L577'></a><a href='#L577'>577</a>
|
|
643
|
-
<a name='L578'></a><a href='#L578'>578</a>
|
|
644
|
-
<a name='L579'></a><a href='#L579'>579</a>
|
|
645
|
-
<a name='L580'></a><a href='#L580'>580</a>
|
|
646
|
-
<a name='L581'></a><a href='#L581'>581</a>
|
|
647
|
-
<a name='L582'></a><a href='#L582'>582</a>
|
|
648
|
-
<a name='L583'></a><a href='#L583'>583</a>
|
|
649
|
-
<a name='L584'></a><a href='#L584'>584</a>
|
|
650
|
-
<a name='L585'></a><a href='#L585'>585</a>
|
|
651
|
-
<a name='L586'></a><a href='#L586'>586</a>
|
|
652
|
-
<a name='L587'></a><a href='#L587'>587</a>
|
|
653
|
-
<a name='L588'></a><a href='#L588'>588</a>
|
|
654
|
-
<a name='L589'></a><a href='#L589'>589</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
510
|
+
<a name='L445'></a><a href='#L445'>445</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
655
511
|
<span class="cline-any cline-neutral"> </span>
|
|
656
512
|
<span class="cline-any cline-neutral"> </span>
|
|
657
513
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -664,13 +520,16 @@
|
|
|
664
520
|
<span class="cline-any cline-neutral"> </span>
|
|
665
521
|
<span class="cline-any cline-neutral"> </span>
|
|
666
522
|
<span class="cline-any cline-neutral"> </span>
|
|
667
|
-
<span class="cline-any cline-yes">
|
|
668
|
-
<span class="cline-any cline-yes">
|
|
669
|
-
<span class="cline-any cline-yes">
|
|
670
|
-
<span class="cline-any cline-
|
|
671
|
-
<span class="cline-any cline-yes">
|
|
672
|
-
<span class="cline-any cline-
|
|
523
|
+
<span class="cline-any cline-yes">2x</span>
|
|
524
|
+
<span class="cline-any cline-yes">2x</span>
|
|
525
|
+
<span class="cline-any cline-yes">2x</span>
|
|
526
|
+
<span class="cline-any cline-yes">2x</span>
|
|
527
|
+
<span class="cline-any cline-yes">2x</span>
|
|
528
|
+
<span class="cline-any cline-yes">2x</span>
|
|
529
|
+
<span class="cline-any cline-yes">2x</span>
|
|
530
|
+
<span class="cline-any cline-yes">2x</span>
|
|
673
531
|
<span class="cline-any cline-neutral"> </span>
|
|
532
|
+
<span class="cline-any cline-yes">2x</span>
|
|
674
533
|
<span class="cline-any cline-neutral"> </span>
|
|
675
534
|
<span class="cline-any cline-neutral"> </span>
|
|
676
535
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -684,7 +543,6 @@
|
|
|
684
543
|
<span class="cline-any cline-neutral"> </span>
|
|
685
544
|
<span class="cline-any cline-neutral"> </span>
|
|
686
545
|
<span class="cline-any cline-neutral"> </span>
|
|
687
|
-
<span class="cline-any cline-yes">1x</span>
|
|
688
546
|
<span class="cline-any cline-neutral"> </span>
|
|
689
547
|
<span class="cline-any cline-neutral"> </span>
|
|
690
548
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -694,7 +552,9 @@
|
|
|
694
552
|
<span class="cline-any cline-neutral"> </span>
|
|
695
553
|
<span class="cline-any cline-neutral"> </span>
|
|
696
554
|
<span class="cline-any cline-neutral"> </span>
|
|
555
|
+
<span class="cline-any cline-yes">2x</span>
|
|
697
556
|
<span class="cline-any cline-neutral"> </span>
|
|
557
|
+
<span class="cline-any cline-yes">19x</span>
|
|
698
558
|
<span class="cline-any cline-neutral"> </span>
|
|
699
559
|
<span class="cline-any cline-neutral"> </span>
|
|
700
560
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -705,201 +565,81 @@
|
|
|
705
565
|
<span class="cline-any cline-neutral"> </span>
|
|
706
566
|
<span class="cline-any cline-neutral"> </span>
|
|
707
567
|
<span class="cline-any cline-neutral"> </span>
|
|
568
|
+
<span class="cline-any cline-yes">19x</span>
|
|
569
|
+
<span class="cline-any cline-yes">19x</span>
|
|
708
570
|
<span class="cline-any cline-neutral"> </span>
|
|
709
|
-
<span class="cline-any cline-yes">1x</span>
|
|
710
571
|
<span class="cline-any cline-neutral"> </span>
|
|
711
572
|
<span class="cline-any cline-neutral"> </span>
|
|
712
573
|
<span class="cline-any cline-neutral"> </span>
|
|
574
|
+
<span class="cline-any cline-yes">19x</span>
|
|
713
575
|
<span class="cline-any cline-neutral"> </span>
|
|
714
576
|
<span class="cline-any cline-neutral"> </span>
|
|
715
577
|
<span class="cline-any cline-neutral"> </span>
|
|
578
|
+
<span class="cline-any cline-yes">19x</span>
|
|
579
|
+
<span class="cline-any cline-yes">19x</span>
|
|
716
580
|
<span class="cline-any cline-neutral"> </span>
|
|
717
581
|
<span class="cline-any cline-neutral"> </span>
|
|
582
|
+
<span class="cline-any cline-yes">19x</span>
|
|
718
583
|
<span class="cline-any cline-neutral"> </span>
|
|
719
584
|
<span class="cline-any cline-neutral"> </span>
|
|
720
585
|
<span class="cline-any cline-neutral"> </span>
|
|
586
|
+
<span class="cline-any cline-yes">19x</span>
|
|
587
|
+
<span class="cline-any cline-yes">18x</span>
|
|
721
588
|
<span class="cline-any cline-neutral"> </span>
|
|
722
589
|
<span class="cline-any cline-neutral"> </span>
|
|
723
|
-
<span class="cline-any cline-yes">5x</span>
|
|
724
|
-
<span class="cline-any cline-yes">5x</span>
|
|
725
590
|
<span class="cline-any cline-neutral"> </span>
|
|
726
591
|
<span class="cline-any cline-neutral"> </span>
|
|
727
|
-
<span class="cline-any cline-no"> </span>
|
|
728
592
|
<span class="cline-any cline-neutral"> </span>
|
|
729
593
|
<span class="cline-any cline-neutral"> </span>
|
|
594
|
+
<span class="cline-any cline-yes">19x</span>
|
|
730
595
|
<span class="cline-any cline-neutral"> </span>
|
|
731
596
|
<span class="cline-any cline-neutral"> </span>
|
|
732
597
|
<span class="cline-any cline-neutral"> </span>
|
|
733
|
-
<span class="cline-any cline-yes">1x</span>
|
|
734
|
-
<span class="cline-any cline-yes">12x</span>
|
|
735
|
-
<span class="cline-any cline-yes">12x</span>
|
|
736
598
|
<span class="cline-any cline-no"> </span>
|
|
737
599
|
<span class="cline-any cline-neutral"> </span>
|
|
738
600
|
<span class="cline-any cline-neutral"> </span>
|
|
739
|
-
<span class="cline-any cline-yes">12x</span>
|
|
740
|
-
<span class="cline-any cline-neutral"> </span>
|
|
741
|
-
<span class="cline-any cline-yes">4x</span>
|
|
742
601
|
<span class="cline-any cline-neutral"> </span>
|
|
743
602
|
<span class="cline-any cline-yes">1x</span>
|
|
744
|
-
<span class="cline-any cline-neutral"> </span>
|
|
745
603
|
<span class="cline-any cline-yes">1x</span>
|
|
746
604
|
<span class="cline-any cline-neutral"> </span>
|
|
747
|
-
<span class="cline-any cline-yes">3x</span>
|
|
748
605
|
<span class="cline-any cline-neutral"> </span>
|
|
749
|
-
<span class="cline-any cline-yes">1x</span>
|
|
750
|
-
<span class="cline-any cline-neutral"> </span>
|
|
751
|
-
<span class="cline-any cline-yes">1x</span>
|
|
752
606
|
<span class="cline-any cline-neutral"> </span>
|
|
753
607
|
<span class="cline-any cline-neutral"> </span>
|
|
754
608
|
<span class="cline-any cline-yes">1x</span>
|
|
755
609
|
<span class="cline-any cline-neutral"> </span>
|
|
756
|
-
<span class="cline-any cline-neutral"> </span>
|
|
757
|
-
<span class="cline-any cline-no"> </span>
|
|
758
|
-
<span class="cline-any cline-neutral"> </span>
|
|
759
|
-
<span class="cline-any cline-neutral"> </span>
|
|
760
|
-
<span class="cline-any cline-neutral"> </span>
|
|
761
610
|
<span class="cline-any cline-yes">1x</span>
|
|
762
611
|
<span class="cline-any cline-neutral"> </span>
|
|
763
|
-
<span class="cline-any cline-neutral"> </span>
|
|
764
|
-
<span class="cline-any cline-neutral"> </span>
|
|
765
|
-
<span class="cline-any cline-neutral"> </span>
|
|
766
|
-
<span class="cline-any cline-neutral"> </span>
|
|
767
|
-
<span class="cline-any cline-neutral"> </span>
|
|
768
|
-
<span class="cline-any cline-neutral"> </span>
|
|
769
|
-
<span class="cline-any cline-neutral"> </span>
|
|
770
|
-
<span class="cline-any cline-neutral"> </span>
|
|
771
|
-
<span class="cline-any cline-neutral"> </span>
|
|
772
|
-
<span class="cline-any cline-neutral"> </span>
|
|
773
|
-
<span class="cline-any cline-neutral"> </span>
|
|
774
|
-
<span class="cline-any cline-neutral"> </span>
|
|
775
|
-
<span class="cline-any cline-neutral"> </span>
|
|
776
|
-
<span class="cline-any cline-neutral"> </span>
|
|
777
|
-
<span class="cline-any cline-neutral"> </span>
|
|
778
|
-
<span class="cline-any cline-neutral"> </span>
|
|
779
|
-
<span class="cline-any cline-neutral"> </span>
|
|
780
|
-
<span class="cline-any cline-neutral"> </span>
|
|
781
|
-
<span class="cline-any cline-neutral"> </span>
|
|
782
|
-
<span class="cline-any cline-neutral"> </span>
|
|
783
|
-
<span class="cline-any cline-neutral"> </span>
|
|
784
|
-
<span class="cline-any cline-neutral"> </span>
|
|
785
|
-
<span class="cline-any cline-neutral"> </span>
|
|
786
|
-
<span class="cline-any cline-neutral"> </span>
|
|
787
|
-
<span class="cline-any cline-neutral"> </span>
|
|
788
|
-
<span class="cline-any cline-neutral"> </span>
|
|
789
|
-
<span class="cline-any cline-yes">23x</span>
|
|
790
|
-
<span class="cline-any cline-yes">23x</span>
|
|
791
|
-
<span class="cline-any cline-yes">23x</span>
|
|
792
|
-
<span class="cline-any cline-yes">23x</span>
|
|
793
|
-
<span class="cline-any cline-yes">23x</span>
|
|
794
|
-
<span class="cline-any cline-yes">23x</span>
|
|
795
|
-
<span class="cline-any cline-yes">23x</span>
|
|
796
|
-
<span class="cline-any cline-yes">23x</span>
|
|
797
|
-
<span class="cline-any cline-yes">23x</span>
|
|
798
|
-
<span class="cline-any cline-yes">23x</span>
|
|
799
|
-
<span class="cline-any cline-neutral"> </span>
|
|
800
|
-
<span class="cline-any cline-neutral"> </span>
|
|
801
|
-
<span class="cline-any cline-yes">23x</span>
|
|
802
|
-
<span class="cline-any cline-yes">23x</span>
|
|
803
|
-
<span class="cline-any cline-neutral"> </span>
|
|
804
|
-
<span class="cline-any cline-neutral"> </span>
|
|
805
|
-
<span class="cline-any cline-neutral"> </span>
|
|
806
|
-
<span class="cline-any cline-neutral"> </span>
|
|
807
|
-
<span class="cline-any cline-neutral"> </span>
|
|
808
|
-
<span class="cline-any cline-yes">23x</span>
|
|
809
|
-
<span class="cline-any cline-yes">3x</span>
|
|
810
|
-
<span class="cline-any cline-neutral"> </span>
|
|
811
|
-
<span class="cline-any cline-neutral"> </span>
|
|
812
|
-
<span class="cline-any cline-yes">23x</span>
|
|
813
|
-
<span class="cline-any cline-yes">1x</span>
|
|
814
|
-
<span class="cline-any cline-neutral"> </span>
|
|
815
|
-
<span class="cline-any cline-neutral"> </span>
|
|
816
|
-
<span class="cline-any cline-yes">23x</span>
|
|
817
|
-
<span class="cline-any cline-yes">1x</span>
|
|
818
|
-
<span class="cline-any cline-neutral"> </span>
|
|
819
|
-
<span class="cline-any cline-neutral"> </span>
|
|
820
|
-
<span class="cline-any cline-yes">23x</span>
|
|
821
612
|
<span class="cline-any cline-yes">1x</span>
|
|
822
|
-
<span class="cline-any cline-neutral"> </span>
|
|
823
|
-
<span class="cline-any cline-neutral"> </span>
|
|
824
|
-
<span class="cline-any cline-neutral"> </span>
|
|
825
|
-
<span class="cline-any cline-yes">23x</span>
|
|
826
|
-
<span class="cline-any cline-yes">23x</span>
|
|
827
|
-
<span class="cline-any cline-yes">23x</span>
|
|
828
|
-
<span class="cline-any cline-neutral"> </span>
|
|
829
|
-
<span class="cline-any cline-yes">23x</span>
|
|
830
|
-
<span class="cline-any cline-yes">23x</span>
|
|
831
|
-
<span class="cline-any cline-yes">23x</span>
|
|
832
|
-
<span class="cline-any cline-neutral"> </span>
|
|
833
|
-
<span class="cline-any cline-yes">23x</span>
|
|
834
|
-
<span class="cline-any cline-neutral"> </span>
|
|
835
|
-
<span class="cline-any cline-neutral"> </span>
|
|
836
|
-
<span class="cline-any cline-yes">23x</span>
|
|
837
|
-
<span class="cline-any cline-yes">4x</span>
|
|
838
|
-
<span class="cline-any cline-neutral"> </span>
|
|
839
|
-
<span class="cline-any cline-yes">4x</span>
|
|
840
|
-
<span class="cline-any cline-neutral"> </span>
|
|
841
|
-
<span class="cline-any cline-yes">4x</span>
|
|
842
|
-
<span class="cline-any cline-neutral"> </span>
|
|
843
|
-
<span class="cline-any cline-yes">4x</span>
|
|
844
|
-
<span class="cline-any cline-yes">4x</span>
|
|
845
|
-
<span class="cline-any cline-neutral"> </span>
|
|
846
|
-
<span class="cline-any cline-yes">4x</span>
|
|
847
613
|
<span class="cline-any cline-yes">1x</span>
|
|
848
614
|
<span class="cline-any cline-neutral"> </span>
|
|
849
|
-
<span class="cline-any cline-neutral"> </span>
|
|
850
|
-
<span class="cline-any cline-neutral"> </span>
|
|
851
|
-
<span class="cline-any cline-no"> </span>
|
|
852
|
-
<span class="cline-any cline-neutral"> </span>
|
|
853
|
-
<span class="cline-any cline-yes">19x</span>
|
|
854
|
-
<span class="cline-any cline-yes">19x</span>
|
|
855
|
-
<span class="cline-any cline-yes">19x</span>
|
|
856
|
-
<span class="cline-any cline-neutral"> </span>
|
|
857
|
-
<span class="cline-any cline-yes">19x</span>
|
|
858
|
-
<span class="cline-any cline-yes">8x</span>
|
|
859
|
-
<span class="cline-any cline-neutral"> </span>
|
|
860
|
-
<span class="cline-any cline-neutral"> </span>
|
|
861
615
|
<span class="cline-any cline-no"> </span>
|
|
862
616
|
<span class="cline-any cline-neutral"> </span>
|
|
863
617
|
<span class="cline-any cline-neutral"> </span>
|
|
864
618
|
<span class="cline-any cline-neutral"> </span>
|
|
865
619
|
<span class="cline-any cline-neutral"> </span>
|
|
620
|
+
<span class="cline-any cline-yes">1x</span>
|
|
866
621
|
<span class="cline-any cline-neutral"> </span>
|
|
622
|
+
<span class="cline-any cline-yes">1x</span>
|
|
623
|
+
<span class="cline-any cline-yes">1x</span>
|
|
867
624
|
<span class="cline-any cline-neutral"> </span>
|
|
868
625
|
<span class="cline-any cline-no"> </span>
|
|
869
626
|
<span class="cline-any cline-neutral"> </span>
|
|
870
627
|
<span class="cline-any cline-neutral"> </span>
|
|
871
628
|
<span class="cline-any cline-neutral"> </span>
|
|
872
|
-
<span class="cline-any cline-yes">2x</span>
|
|
873
|
-
<span class="cline-any cline-yes">2x</span>
|
|
874
|
-
<span class="cline-any cline-yes">1x</span>
|
|
875
629
|
<span class="cline-any cline-neutral"> </span>
|
|
876
630
|
<span class="cline-any cline-neutral"> </span>
|
|
877
631
|
<span class="cline-any cline-yes">1x</span>
|
|
878
|
-
<span class="cline-any cline-yes">1x</span>
|
|
879
632
|
<span class="cline-any cline-neutral"> </span>
|
|
880
633
|
<span class="cline-any cline-yes">1x</span>
|
|
881
|
-
<span class="cline-any cline-neutral"> </span>
|
|
882
|
-
<span class="cline-any cline-neutral"> </span>
|
|
883
634
|
<span class="cline-any cline-yes">1x</span>
|
|
884
635
|
<span class="cline-any cline-neutral"> </span>
|
|
885
636
|
<span class="cline-any cline-neutral"> </span>
|
|
886
637
|
<span class="cline-any cline-neutral"> </span>
|
|
887
|
-
<span class="cline-any cline-neutral"> </span>
|
|
888
|
-
<span class="cline-any cline-yes">28x</span>
|
|
889
|
-
<span class="cline-any cline-yes">28x</span>
|
|
890
|
-
<span class="cline-any cline-neutral"> </span>
|
|
891
|
-
<span class="cline-any cline-neutral"> </span>
|
|
892
|
-
<span class="cline-any cline-neutral"> </span>
|
|
893
638
|
<span class="cline-any cline-no"> </span>
|
|
894
639
|
<span class="cline-any cline-neutral"> </span>
|
|
895
640
|
<span class="cline-any cline-neutral"> </span>
|
|
896
641
|
<span class="cline-any cline-neutral"> </span>
|
|
897
|
-
<span class="cline-any cline-
|
|
898
|
-
<span class="cline-any cline-yes">1x</span>
|
|
899
|
-
<span class="cline-any cline-neutral"> </span>
|
|
900
|
-
<span class="cline-any cline-neutral"> </span>
|
|
901
|
-
<span class="cline-any cline-neutral"> </span>
|
|
902
|
-
<span class="cline-any cline-yes">1x</span>
|
|
642
|
+
<span class="cline-any cline-no"> </span>
|
|
903
643
|
<span class="cline-any cline-neutral"> </span>
|
|
904
644
|
<span class="cline-any cline-neutral"> </span>
|
|
905
645
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -907,84 +647,61 @@
|
|
|
907
647
|
<span class="cline-any cline-neutral"> </span>
|
|
908
648
|
<span class="cline-any cline-neutral"> </span>
|
|
909
649
|
<span class="cline-any cline-neutral"> </span>
|
|
650
|
+
<span class="cline-any cline-no"> </span>
|
|
910
651
|
<span class="cline-any cline-neutral"> </span>
|
|
911
652
|
<span class="cline-any cline-neutral"> </span>
|
|
912
653
|
<span class="cline-any cline-neutral"> </span>
|
|
913
|
-
<span class="cline-any cline-
|
|
914
|
-
<span class="cline-any cline-neutral"> </span>
|
|
915
|
-
<span class="cline-any cline-yes">5x</span>
|
|
654
|
+
<span class="cline-any cline-no"> </span>
|
|
916
655
|
<span class="cline-any cline-neutral"> </span>
|
|
917
656
|
<span class="cline-any cline-neutral"> </span>
|
|
918
657
|
<span class="cline-any cline-neutral"> </span>
|
|
919
658
|
<span class="cline-any cline-neutral"> </span>
|
|
920
659
|
<span class="cline-any cline-neutral"> </span>
|
|
921
660
|
<span class="cline-any cline-neutral"> </span>
|
|
922
|
-
<span class="cline-any cline-
|
|
661
|
+
<span class="cline-any cline-no"> </span>
|
|
662
|
+
<span class="cline-any cline-no"> </span>
|
|
923
663
|
<span class="cline-any cline-neutral"> </span>
|
|
924
|
-
<span class="cline-any cline-yes">1x</span>
|
|
925
664
|
<span class="cline-any cline-no"> </span>
|
|
926
665
|
<span class="cline-any cline-neutral"> </span>
|
|
927
666
|
<span class="cline-any cline-neutral"> </span>
|
|
928
|
-
<span class="cline-any cline-yes">1x</span>
|
|
929
667
|
<span class="cline-any cline-no"> </span>
|
|
930
668
|
<span class="cline-any cline-neutral"> </span>
|
|
931
669
|
<span class="cline-any cline-neutral"> </span>
|
|
932
|
-
<span class="cline-any cline-yes">1x</span>
|
|
933
670
|
<span class="cline-any cline-neutral"> </span>
|
|
934
|
-
<span class="cline-any cline-
|
|
671
|
+
<span class="cline-any cline-no"> </span>
|
|
935
672
|
<span class="cline-any cline-neutral"> </span>
|
|
936
|
-
<span class="cline-any cline-yes">1x</span>
|
|
937
|
-
<span class="cline-any cline-yes">1x</span>
|
|
938
|
-
<span class="cline-any cline-yes">1x</span>
|
|
939
673
|
<span class="cline-any cline-neutral"> </span>
|
|
940
|
-
<span class="cline-any cline-yes">1x</span>
|
|
941
|
-
<span class="cline-any cline-yes">1x</span>
|
|
942
674
|
<span class="cline-any cline-neutral"> </span>
|
|
943
|
-
<span class="cline-any cline-yes">1x</span>
|
|
944
675
|
<span class="cline-any cline-neutral"> </span>
|
|
945
|
-
<span class="cline-any cline-yes">1x</span>
|
|
946
|
-
<span class="cline-any cline-yes">1x</span>
|
|
947
676
|
<span class="cline-any cline-neutral"> </span>
|
|
948
677
|
<span class="cline-any cline-neutral"> </span>
|
|
949
|
-
<span class="cline-any cline-yes">
|
|
678
|
+
<span class="cline-any cline-yes">112x</span>
|
|
950
679
|
<span class="cline-any cline-neutral"> </span>
|
|
951
680
|
<span class="cline-any cline-neutral"> </span>
|
|
952
|
-
<span class="cline-any cline-no"> </span>
|
|
953
|
-
<span class="cline-any cline-no"> </span>
|
|
954
681
|
<span class="cline-any cline-neutral"> </span>
|
|
955
682
|
<span class="cline-any cline-neutral"> </span>
|
|
956
683
|
<span class="cline-any cline-neutral"> </span>
|
|
957
684
|
<span class="cline-any cline-neutral"> </span>
|
|
958
|
-
<span class="cline-any cline-yes">1x</span>
|
|
959
|
-
<span class="cline-any cline-no"> </span>
|
|
960
685
|
<span class="cline-any cline-neutral"> </span>
|
|
961
686
|
<span class="cline-any cline-neutral"> </span>
|
|
962
687
|
<span class="cline-any cline-yes">1x</span>
|
|
963
|
-
<span class="cline-any cline-no"> </span>
|
|
964
688
|
<span class="cline-any cline-neutral"> </span>
|
|
965
689
|
<span class="cline-any cline-neutral"> </span>
|
|
966
|
-
<span class="cline-any cline-yes">1x</span>
|
|
967
|
-
<span class="cline-any cline-no"> </span>
|
|
968
690
|
<span class="cline-any cline-neutral"> </span>
|
|
969
691
|
<span class="cline-any cline-neutral"> </span>
|
|
970
|
-
<span class="cline-any cline-yes">1x</span>
|
|
971
|
-
<span class="cline-any cline-yes">1x</span>
|
|
972
692
|
<span class="cline-any cline-neutral"> </span>
|
|
973
693
|
<span class="cline-any cline-neutral"> </span>
|
|
974
694
|
<span class="cline-any cline-neutral"> </span>
|
|
975
695
|
<span class="cline-any cline-neutral"> </span>
|
|
976
|
-
<span class="cline-any cline-yes">1x</span>
|
|
977
|
-
<span class="cline-any cline-no"> </span>
|
|
978
696
|
<span class="cline-any cline-neutral"> </span>
|
|
979
697
|
<span class="cline-any cline-neutral"> </span>
|
|
980
|
-
<span class="cline-any cline-yes">1x</span>
|
|
981
698
|
<span class="cline-any cline-neutral"> </span>
|
|
982
699
|
<span class="cline-any cline-neutral"> </span>
|
|
983
700
|
<span class="cline-any cline-neutral"> </span>
|
|
701
|
+
<span class="cline-any cline-yes">108x</span>
|
|
984
702
|
<span class="cline-any cline-neutral"> </span>
|
|
985
703
|
<span class="cline-any cline-neutral"> </span>
|
|
986
704
|
<span class="cline-any cline-neutral"> </span>
|
|
987
|
-
<span class="cline-any cline-yes">18x</span>
|
|
988
705
|
<span class="cline-any cline-neutral"> </span>
|
|
989
706
|
<span class="cline-any cline-neutral"> </span>
|
|
990
707
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1005,23 +722,22 @@
|
|
|
1005
722
|
<span class="cline-any cline-neutral"> </span>
|
|
1006
723
|
<span class="cline-any cline-neutral"> </span>
|
|
1007
724
|
<span class="cline-any cline-neutral"> </span>
|
|
1008
|
-
<span class="cline-any cline-yes">
|
|
1009
|
-
<span class="cline-any cline-yes">18x</span>
|
|
725
|
+
<span class="cline-any cline-yes">25x</span>
|
|
1010
726
|
<span class="cline-any cline-neutral"> </span>
|
|
1011
|
-
<span class="cline-any cline-yes">18x</span>
|
|
1012
727
|
<span class="cline-any cline-neutral"> </span>
|
|
1013
|
-
<span class="cline-any cline-no"> </span>
|
|
1014
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1015
|
-
<span class="cline-any cline-no"> </span>
|
|
1016
728
|
<span class="cline-any cline-neutral"> </span>
|
|
1017
729
|
<span class="cline-any cline-neutral"> </span>
|
|
1018
730
|
<span class="cline-any cline-neutral"> </span>
|
|
1019
731
|
<span class="cline-any cline-neutral"> </span>
|
|
1020
732
|
<span class="cline-any cline-neutral"> </span>
|
|
733
|
+
<span class="cline-any cline-yes">25x</span>
|
|
734
|
+
<span class="cline-any cline-yes">25x</span>
|
|
1021
735
|
<span class="cline-any cline-neutral"> </span>
|
|
736
|
+
<span class="cline-any cline-yes">25x</span>
|
|
1022
737
|
<span class="cline-any cline-neutral"> </span>
|
|
1023
|
-
<span class="cline-any cline-
|
|
738
|
+
<span class="cline-any cline-no"> </span>
|
|
1024
739
|
<span class="cline-any cline-neutral"> </span>
|
|
740
|
+
<span class="cline-any cline-no"> </span>
|
|
1025
741
|
<span class="cline-any cline-neutral"> </span>
|
|
1026
742
|
<span class="cline-any cline-neutral"> </span>
|
|
1027
743
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1033,6 +749,7 @@
|
|
|
1033
749
|
<span class="cline-any cline-neutral"> </span>
|
|
1034
750
|
<span class="cline-any cline-neutral"> </span>
|
|
1035
751
|
<span class="cline-any cline-neutral"> </span>
|
|
752
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1036
753
|
<span class="cline-any cline-neutral"> </span>
|
|
1037
754
|
<span class="cline-any cline-neutral"> </span>
|
|
1038
755
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1044,15 +761,15 @@
|
|
|
1044
761
|
<span class="cline-any cline-neutral"> </span>
|
|
1045
762
|
<span class="cline-any cline-neutral"> </span>
|
|
1046
763
|
<span class="cline-any cline-neutral"> </span>
|
|
1047
|
-
<span class="cline-any cline-yes">
|
|
1048
|
-
<span class="cline-any cline-yes">
|
|
764
|
+
<span class="cline-any cline-yes">24x</span>
|
|
765
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1049
766
|
<span class="cline-any cline-neutral"> </span>
|
|
1050
|
-
<span class="cline-any cline-yes">
|
|
767
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1051
768
|
<span class="cline-any cline-yes">3x</span>
|
|
1052
769
|
<span class="cline-any cline-neutral"> </span>
|
|
1053
770
|
<span class="cline-any cline-neutral"> </span>
|
|
1054
|
-
<span class="cline-any cline-yes">
|
|
1055
|
-
<span class="cline-any cline-yes">
|
|
771
|
+
<span class="cline-any cline-yes">21x</span>
|
|
772
|
+
<span class="cline-any cline-yes">16x</span>
|
|
1056
773
|
<span class="cline-any cline-neutral"> </span>
|
|
1057
774
|
<span class="cline-any cline-neutral"> </span>
|
|
1058
775
|
<span class="cline-any cline-yes">5x</span>
|
|
@@ -1067,31 +784,15 @@
|
|
|
1067
784
|
<span class="cline-any cline-neutral"> </span>
|
|
1068
785
|
<span class="cline-any cline-neutral"> </span>
|
|
1069
786
|
<span class="cline-any cline-neutral"> </span>
|
|
1070
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1071
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1072
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1073
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1074
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1075
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1076
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1077
|
-
<span class="cline-any cline-no"> </span>
|
|
1078
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1079
787
|
<span class="cline-any cline-neutral"> </span>
|
|
1080
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1081
788
|
<span class="cline-any cline-neutral"> </span>
|
|
1082
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1083
789
|
<span class="cline-any cline-neutral"> </span>
|
|
1084
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1085
790
|
<span class="cline-any cline-neutral"> </span>
|
|
1086
|
-
<span class="cline-any cline-no"> </span>
|
|
1087
791
|
<span class="cline-any cline-neutral"> </span>
|
|
1088
|
-
<span class="cline-any cline-yes">
|
|
1089
|
-
<span class="cline-any cline-no"> </span>
|
|
1090
|
-
<span class="cline-any cline-no"> </span>
|
|
792
|
+
<span class="cline-any cline-yes">59x</span>
|
|
1091
793
|
<span class="cline-any cline-neutral"> </span>
|
|
1092
794
|
<span class="cline-any cline-neutral"> </span>
|
|
1093
795
|
<span class="cline-any cline-neutral"> </span>
|
|
1094
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1095
796
|
<span class="cline-any cline-neutral"> </span>
|
|
1096
797
|
<span class="cline-any cline-neutral"> </span>
|
|
1097
798
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1100,23 +801,28 @@
|
|
|
1100
801
|
<span class="cline-any cline-neutral"> </span>
|
|
1101
802
|
<span class="cline-any cline-neutral"> </span>
|
|
1102
803
|
<span class="cline-any cline-neutral"> </span>
|
|
1103
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1104
804
|
<span class="cline-any cline-neutral"> </span>
|
|
1105
|
-
<span class="cline-any cline-no"> </span>
|
|
1106
805
|
<span class="cline-any cline-neutral"> </span>
|
|
1107
|
-
<span class="cline-any cline-
|
|
806
|
+
<span class="cline-any cline-yes">59x</span>
|
|
807
|
+
<span class="cline-any cline-yes">59x</span>
|
|
1108
808
|
<span class="cline-any cline-neutral"> </span>
|
|
809
|
+
<span class="cline-any cline-yes">59x</span>
|
|
810
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1109
811
|
<span class="cline-any cline-neutral"> </span>
|
|
1110
812
|
<span class="cline-any cline-neutral"> </span>
|
|
1111
813
|
<span class="cline-any cline-neutral"> </span>
|
|
1112
814
|
<span class="cline-any cline-neutral"> </span>
|
|
815
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1113
816
|
<span class="cline-any cline-neutral"> </span>
|
|
1114
817
|
<span class="cline-any cline-neutral"> </span>
|
|
818
|
+
<span class="cline-any cline-yes">50x</span>
|
|
1115
819
|
<span class="cline-any cline-neutral"> </span>
|
|
1116
820
|
<span class="cline-any cline-neutral"> </span>
|
|
821
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1117
822
|
<span class="cline-any cline-neutral"> </span>
|
|
823
|
+
<span class="cline-any cline-no"> </span>
|
|
1118
824
|
<span class="cline-any cline-neutral"> </span>
|
|
1119
|
-
<span class="cline-any cline-
|
|
825
|
+
<span class="cline-any cline-no"> </span>
|
|
1120
826
|
<span class="cline-any cline-neutral"> </span>
|
|
1121
827
|
<span class="cline-any cline-neutral"> </span>
|
|
1122
828
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1126,7 +832,9 @@
|
|
|
1126
832
|
<span class="cline-any cline-neutral"> </span>
|
|
1127
833
|
<span class="cline-any cline-neutral"> </span>
|
|
1128
834
|
<span class="cline-any cline-neutral"> </span>
|
|
835
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1129
836
|
<span class="cline-any cline-neutral"> </span>
|
|
837
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1130
838
|
<span class="cline-any cline-neutral"> </span>
|
|
1131
839
|
<span class="cline-any cline-neutral"> </span>
|
|
1132
840
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1135,34 +843,31 @@
|
|
|
1135
843
|
<span class="cline-any cline-neutral"> </span>
|
|
1136
844
|
<span class="cline-any cline-neutral"> </span>
|
|
1137
845
|
<span class="cline-any cline-neutral"> </span>
|
|
846
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1138
847
|
<span class="cline-any cline-neutral"> </span>
|
|
848
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1139
849
|
<span class="cline-any cline-neutral"> </span>
|
|
1140
850
|
<span class="cline-any cline-neutral"> </span>
|
|
1141
851
|
<span class="cline-any cline-neutral"> </span>
|
|
1142
852
|
<span class="cline-any cline-neutral"> </span>
|
|
1143
853
|
<span class="cline-any cline-neutral"> </span>
|
|
1144
854
|
<span class="cline-any cline-neutral"> </span>
|
|
1145
|
-
<span class="cline-any cline-yes">28x</span>
|
|
1146
|
-
<span class="cline-any cline-yes">28x</span>
|
|
1147
855
|
<span class="cline-any cline-neutral"> </span>
|
|
1148
|
-
<span class="cline-any cline-yes">28x</span>
|
|
1149
|
-
<span class="cline-any cline-yes">25x</span>
|
|
1150
856
|
<span class="cline-any cline-neutral"> </span>
|
|
857
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1151
858
|
<span class="cline-any cline-neutral"> </span>
|
|
859
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1152
860
|
<span class="cline-any cline-neutral"> </span>
|
|
1153
861
|
<span class="cline-any cline-neutral"> </span>
|
|
1154
|
-
<span class="cline-any cline-yes">2x</span>
|
|
1155
862
|
<span class="cline-any cline-neutral"> </span>
|
|
1156
863
|
<span class="cline-any cline-neutral"> </span>
|
|
1157
|
-
<span class="cline-any cline-yes">23x</span>
|
|
1158
864
|
<span class="cline-any cline-neutral"> </span>
|
|
1159
865
|
<span class="cline-any cline-neutral"> </span>
|
|
1160
|
-
<span class="cline-any cline-yes">3x</span>
|
|
1161
866
|
<span class="cline-any cline-neutral"> </span>
|
|
1162
|
-
<span class="cline-any cline-no"> </span>
|
|
1163
867
|
<span class="cline-any cline-neutral"> </span>
|
|
1164
|
-
<span class="cline-any cline-
|
|
868
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1165
869
|
<span class="cline-any cline-neutral"> </span>
|
|
870
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1166
871
|
<span class="cline-any cline-neutral"> </span>
|
|
1167
872
|
<span class="cline-any cline-neutral"> </span>
|
|
1168
873
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1170,431 +875,307 @@
|
|
|
1170
875
|
<span class="cline-any cline-neutral"> </span>
|
|
1171
876
|
<span class="cline-any cline-neutral"> </span>
|
|
1172
877
|
<span class="cline-any cline-neutral"> </span>
|
|
1173
|
-
<span class="cline-any cline-yes">3x</span>
|
|
1174
878
|
<span class="cline-any cline-neutral"> </span>
|
|
1175
|
-
<span class="cline-any cline-yes">
|
|
879
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1176
880
|
<span class="cline-any cline-neutral"> </span>
|
|
881
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1177
882
|
<span class="cline-any cline-neutral"> </span>
|
|
1178
883
|
<span class="cline-any cline-neutral"> </span>
|
|
1179
884
|
<span class="cline-any cline-neutral"> </span>
|
|
1180
885
|
<span class="cline-any cline-neutral"> </span>
|
|
1181
886
|
<span class="cline-any cline-neutral"> </span>
|
|
1182
887
|
<span class="cline-any cline-neutral"> </span>
|
|
1183
|
-
<span class="cline-any cline-yes">4x</span>
|
|
1184
888
|
<span class="cline-any cline-neutral"> </span>
|
|
1185
|
-
<span class="cline-any cline-yes">4x</span>
|
|
1186
889
|
<span class="cline-any cline-neutral"> </span>
|
|
890
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1187
891
|
<span class="cline-any cline-neutral"> </span>
|
|
892
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1188
893
|
<span class="cline-any cline-neutral"> </span>
|
|
1189
894
|
<span class="cline-any cline-neutral"> </span>
|
|
1190
895
|
<span class="cline-any cline-neutral"> </span>
|
|
1191
896
|
<span class="cline-any cline-neutral"> </span>
|
|
1192
897
|
<span class="cline-any cline-neutral"> </span>
|
|
1193
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1194
898
|
<span class="cline-any cline-neutral"> </span>
|
|
1195
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1196
899
|
<span class="cline-any cline-neutral"> </span>
|
|
1197
900
|
<span class="cline-any cline-neutral"> </span>
|
|
901
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1198
902
|
<span class="cline-any cline-neutral"> </span>
|
|
903
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1199
904
|
<span class="cline-any cline-neutral"> </span>
|
|
1200
905
|
<span class="cline-any cline-neutral"> </span>
|
|
1201
906
|
<span class="cline-any cline-neutral"> </span>
|
|
1202
907
|
<span class="cline-any cline-neutral"> </span>
|
|
1203
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1204
908
|
<span class="cline-any cline-neutral"> </span>
|
|
1205
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1206
909
|
<span class="cline-any cline-neutral"> </span>
|
|
1207
910
|
<span class="cline-any cline-neutral"> </span>
|
|
911
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1208
912
|
<span class="cline-any cline-neutral"> </span>
|
|
913
|
+
<span class="cline-any cline-yes">2x</span>
|
|
914
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1209
915
|
<span class="cline-any cline-neutral"> </span>
|
|
916
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1210
917
|
<span class="cline-any cline-neutral"> </span>
|
|
1211
918
|
<span class="cline-any cline-neutral"> </span>
|
|
1212
919
|
<span class="cline-any cline-neutral"> </span>
|
|
1213
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1214
920
|
<span class="cline-any cline-neutral"> </span>
|
|
1215
|
-
<span class="cline-any cline-yes">
|
|
921
|
+
<span class="cline-any cline-yes">4x</span>
|
|
922
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1216
923
|
<span class="cline-any cline-neutral"> </span>
|
|
924
|
+
<span class="cline-any cline-yes">2x</span>
|
|
925
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1217
926
|
<span class="cline-any cline-neutral"> </span>
|
|
1218
927
|
<span class="cline-any cline-neutral"> </span>
|
|
1219
928
|
<span class="cline-any cline-neutral"> </span>
|
|
1220
929
|
<span class="cline-any cline-neutral"> </span>
|
|
930
|
+
<span class="cline-any cline-yes">4x</span>
|
|
931
|
+
<span class="cline-any cline-yes">4x</span>
|
|
932
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1221
933
|
<span class="cline-any cline-neutral"> </span>
|
|
934
|
+
<span class="cline-any cline-yes">2x</span>
|
|
935
|
+
<span class="cline-any cline-yes">16x</span>
|
|
1222
936
|
<span class="cline-any cline-neutral"> </span>
|
|
1223
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1224
937
|
<span class="cline-any cline-neutral"> </span>
|
|
1225
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1226
938
|
<span class="cline-any cline-neutral"> </span>
|
|
1227
939
|
<span class="cline-any cline-neutral"> </span>
|
|
1228
940
|
<span class="cline-any cline-neutral"> </span>
|
|
1229
941
|
<span class="cline-any cline-neutral"> </span>
|
|
1230
942
|
<span class="cline-any cline-neutral"> </span>
|
|
1231
943
|
<span class="cline-any cline-neutral"> </span>
|
|
944
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1232
945
|
<span class="cline-any cline-neutral"> </span>
|
|
1233
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1234
946
|
<span class="cline-any cline-neutral"> </span>
|
|
1235
|
-
<span class="cline-any cline-yes">
|
|
947
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1236
948
|
<span class="cline-any cline-neutral"> </span>
|
|
1237
949
|
<span class="cline-any cline-neutral"> </span>
|
|
1238
950
|
<span class="cline-any cline-neutral"> </span>
|
|
1239
|
-
<span class="cline-any cline-yes">
|
|
1240
|
-
<span class="cline-any cline-yes">
|
|
951
|
+
<span class="cline-any cline-yes">2x</span>
|
|
952
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1241
953
|
<span class="cline-any cline-neutral"> </span>
|
|
1242
|
-
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import {
|
|
954
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import type {
|
|
1243
955
|
Context,
|
|
1244
|
-
DatafileContent,
|
|
1245
956
|
Feature,
|
|
1246
957
|
FeatureKey,
|
|
1247
|
-
InitialFeatures,
|
|
1248
958
|
StickyFeatures,
|
|
1249
|
-
|
|
959
|
+
EvaluatedFeatures,
|
|
960
|
+
EvaluatedFeature,
|
|
1250
961
|
VariableValue,
|
|
1251
962
|
VariationValue,
|
|
1252
963
|
VariableKey,
|
|
964
|
+
DatafileContent,
|
|
1253
965
|
} from "@featurevisor/types";
|
|
1254
966
|
|
|
1255
967
|
import { createLogger, Logger, LogLevel } from "./logger";
|
|
968
|
+
import { HooksManager, Hook } from "./hooks";
|
|
969
|
+
import { Emitter, EventCallback, EventName } from "./emitter";
|
|
1256
970
|
import { DatafileReader } from "./datafileReader";
|
|
1257
|
-
import {
|
|
1258
|
-
import {
|
|
1259
|
-
import {
|
|
1260
|
-
|
|
1261
|
-
export type ReadyCallback = () => void;
|
|
1262
|
-
|
|
1263
|
-
export type ActivationCallback = (
|
|
1264
|
-
featureName: string,
|
|
1265
|
-
variation: VariationValue,
|
|
1266
|
-
context: Context,
|
|
1267
|
-
captureContext: Context,
|
|
1268
|
-
) => void;
|
|
1269
|
-
|
|
1270
|
-
export interface Statuses {
|
|
1271
|
-
ready: boolean;
|
|
1272
|
-
refreshInProgress: boolean;
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
const DEFAULT_BUCKET_KEY_SEPARATOR = ".";
|
|
1276
|
-
|
|
1277
|
-
export type InterceptContext = (context: Context) => Context;
|
|
1278
|
-
|
|
1279
|
-
export interface InstanceOptions {
|
|
1280
|
-
bucketKeySeparator?: string;
|
|
1281
|
-
configureBucketKey?: ConfigureBucketKey;
|
|
1282
|
-
configureBucketValue?: ConfigureBucketValue;
|
|
1283
|
-
datafile?: DatafileContent | string;
|
|
1284
|
-
datafileUrl?: string;
|
|
1285
|
-
handleDatafileFetch?: (datafileUrl: string) => Promise<DatafileContent>;
|
|
1286
|
-
initialFeatures?: InitialFeatures;
|
|
1287
|
-
interceptContext?: InterceptContext;
|
|
1288
|
-
logger?: Logger;
|
|
1289
|
-
onActivation?: ActivationCallback;
|
|
1290
|
-
onReady?: ReadyCallback;
|
|
1291
|
-
onRefresh?: () => void;
|
|
1292
|
-
onUpdate?: () => void;
|
|
1293
|
-
refreshInterval?: number; // seconds
|
|
1294
|
-
stickyFeatures?: StickyFeatures;
|
|
1295
|
-
}
|
|
971
|
+
import { Evaluation, EvaluateDependencies, evaluateWithHooks } from "./evaluate";
|
|
972
|
+
import { FeaturevisorChildInstance } from "./child";
|
|
973
|
+
import { getParamsForStickySetEvent, getParamsForDatafileSetEvent } from "./events";
|
|
974
|
+
import { getValueByType } from "./helpers";
|
|
1296
975
|
|
|
1297
976
|
const emptyDatafile: DatafileContent = {
|
|
1298
|
-
schemaVersion: "
|
|
977
|
+
schemaVersion: "2",
|
|
1299
978
|
revision: "unknown",
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
features: [],
|
|
979
|
+
segments: {},
|
|
980
|
+
features: {},
|
|
1303
981
|
};
|
|
1304
982
|
|
|
1305
|
-
export
|
|
983
|
+
export interface OverrideOptions {
|
|
984
|
+
sticky?: StickyFeatures;
|
|
1306
985
|
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
handleDatafileFetch?: DatafileFetchHandler,
|
|
1310
|
-
): Promise<DatafileContent> {
|
|
1311
|
-
if (handleDatafileFetch) {
|
|
1312
|
-
return handleDatafileFetch(datafileUrl);
|
|
1313
|
-
}
|
|
1314
|
-
|
|
1315
|
-
<span class="cstat-no" title="statement not covered" > return fetch(datafileUrl).then(<span class="fstat-no" title="function not covered" >(r</span>es) => <span class="cstat-no" title="statement not covered" >res.json())</span>;</span>
|
|
986
|
+
defaultVariationValue?: VariationValue;
|
|
987
|
+
defaultVariableValue?: VariableValue;
|
|
1316
988
|
}
|
|
1317
989
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
switch (fieldType) {
|
|
1328
|
-
case "string":
|
|
1329
|
-
return typeof value === "string" ? value : <span class="branch-1 cbranch-no" title="branch not covered" >undefined;</span>
|
|
1330
|
-
case "integer":
|
|
1331
|
-
return parseInt(value as string, 10);
|
|
1332
|
-
case "double":
|
|
1333
|
-
return parseFloat(value as string);
|
|
1334
|
-
case "boolean":
|
|
1335
|
-
return value === true;
|
|
1336
|
-
case "array":
|
|
1337
|
-
return Array.isArray(value) ? value : <span class="branch-1 cbranch-no" title="branch not covered" >undefined;</span>
|
|
1338
|
-
case "object":
|
|
1339
|
-
return typeof value === "object" ? value : <span class="branch-1 cbranch-no" title="branch not covered" >undefined;</span>
|
|
1340
|
-
// @NOTE: `json` is not handled here intentionally
|
|
1341
|
-
default:
|
|
1342
|
-
return value;
|
|
1343
|
-
}
|
|
1344
|
-
} catch (e) {
|
|
1345
|
-
<span class="cstat-no" title="statement not covered" > return undefined;</span>
|
|
1346
|
-
}
|
|
990
|
+
export interface InstanceOptions {
|
|
991
|
+
datafile?: DatafileContent | string;
|
|
992
|
+
context?: Context;
|
|
993
|
+
logLevel?: LogLevel;
|
|
994
|
+
logger?: Logger;
|
|
995
|
+
sticky?: StickyFeatures;
|
|
996
|
+
hooks?: Hook[];
|
|
1347
997
|
}
|
|
1348
998
|
|
|
1349
999
|
export class FeaturevisorInstance {
|
|
1350
1000
|
// from options
|
|
1351
|
-
private
|
|
1352
|
-
private configureBucketKey?: ConfigureBucketKey;
|
|
1353
|
-
private configureBucketValue?: ConfigureBucketValue;
|
|
1354
|
-
private datafileUrl?: string;
|
|
1355
|
-
private handleDatafileFetch?: DatafileFetchHandler;
|
|
1356
|
-
private initialFeatures?: InitialFeatures;
|
|
1357
|
-
private interceptContext?: InterceptContext;
|
|
1001
|
+
private context: Context = {};
|
|
1358
1002
|
private logger: Logger;
|
|
1359
|
-
private
|
|
1360
|
-
private stickyFeatures?: StickyFeatures;
|
|
1003
|
+
private sticky?: StickyFeatures;
|
|
1361
1004
|
|
|
1362
1005
|
// internally created
|
|
1363
1006
|
private datafileReader: DatafileReader;
|
|
1007
|
+
private hooksManager: HooksManager;
|
|
1364
1008
|
private emitter: Emitter;
|
|
1365
|
-
private statuses: Statuses;
|
|
1366
|
-
private intervalId?: ReturnType<typeof setInterval>;
|
|
1367
|
-
|
|
1368
|
-
// exposed from emitter
|
|
1369
|
-
public on: Emitter["addListener"];
|
|
1370
|
-
public addListener: Emitter["addListener"];
|
|
1371
|
-
public off: Emitter["removeListener"];
|
|
1372
|
-
public removeListener: Emitter["removeListener"];
|
|
1373
|
-
public removeAllListeners: Emitter["removeAllListeners"];
|
|
1374
1009
|
|
|
1375
1010
|
constructor(options: InstanceOptions) {
|
|
1376
1011
|
// from options
|
|
1377
|
-
this.
|
|
1378
|
-
this.
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
this.
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
// internal
|
|
1012
|
+
this.context = options.context || {};
|
|
1013
|
+
this.logger =
|
|
1014
|
+
options.logger ||
|
|
1015
|
+
createLogger({
|
|
1016
|
+
level: options.logLevel || Logger.defaultLevel,
|
|
1017
|
+
});
|
|
1018
|
+
this.hooksManager = new HooksManager({
|
|
1019
|
+
hooks: options.hooks || [],
|
|
1020
|
+
logger: this.logger,
|
|
1021
|
+
});
|
|
1389
1022
|
this.emitter = new Emitter();
|
|
1390
|
-
this.
|
|
1391
|
-
ready: false,
|
|
1392
|
-
refreshInProgress: false,
|
|
1393
|
-
};
|
|
1394
|
-
|
|
1395
|
-
// register events
|
|
1396
|
-
if (options.onReady) {
|
|
1397
|
-
this.emitter.addListener("ready", options.onReady);
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
if (options.onRefresh) {
|
|
1401
|
-
this.emitter.addListener("refresh", options.onRefresh);
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
if (options.onUpdate) {
|
|
1405
|
-
this.emitter.addListener("update", options.onUpdate);
|
|
1406
|
-
}
|
|
1023
|
+
this.sticky = options.sticky;
|
|
1407
1024
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1025
|
+
// datafile
|
|
1026
|
+
this.datafileReader = new DatafileReader({
|
|
1027
|
+
datafile: emptyDatafile,
|
|
1028
|
+
logger: this.logger,
|
|
1029
|
+
});
|
|
1030
|
+
if (options.datafile) {
|
|
1031
|
+
this.datafileReader = new DatafileReader({
|
|
1032
|
+
datafile:
|
|
1033
|
+
typeof options.datafile === "string" ? <span class="branch-0 cbranch-no" title="branch not covered" >JSON.parse(options.datafile) </span>: options.datafile,
|
|
1034
|
+
logger: this.logger,
|
|
1035
|
+
});
|
|
1410
1036
|
}
|
|
1411
1037
|
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
this.on = on;
|
|
1415
|
-
this.addListener = on;
|
|
1416
|
-
|
|
1417
|
-
const off = this.emitter.removeListener.bind(this.emitter);
|
|
1418
|
-
this.off = off;
|
|
1419
|
-
this.removeListener = off;
|
|
1038
|
+
this.logger.info("Featurevisor SDK initialized");
|
|
1039
|
+
}
|
|
1420
1040
|
|
|
1421
|
-
|
|
1041
|
+
<span class="fstat-no" title="function not covered" > setLogLevel(</span>level: LogLevel) {
|
|
1042
|
+
<span class="cstat-no" title="statement not covered" > this.logger.setLevel(level);</span>
|
|
1043
|
+
}
|
|
1422
1044
|
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1045
|
+
setDatafile(datafile: DatafileContent | string) {
|
|
1046
|
+
try {
|
|
1047
|
+
const newDatafileReader = new DatafileReader({
|
|
1048
|
+
datafile: typeof datafile === "string" ? <span class="branch-0 cbranch-no" title="branch not covered" >JSON.parse(datafile) </span>: datafile,
|
|
1049
|
+
logger: this.logger,
|
|
1050
|
+
});
|
|
1426
1051
|
|
|
1427
|
-
|
|
1428
|
-
.then((datafile) => {
|
|
1429
|
-
this.setDatafile(datafile);
|
|
1052
|
+
const details = getParamsForDatafileSetEvent(this.datafileReader, newDatafileReader);
|
|
1430
1053
|
|
|
1431
|
-
|
|
1432
|
-
this.emitter.emit("ready");
|
|
1054
|
+
this.datafileReader = newDatafileReader;
|
|
1433
1055
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
.catch(<span class="fstat-no" title="function not covered" >(e</span>) => {
|
|
1439
|
-
<span class="cstat-no" title="statement not covered" > this.logger.error("failed to fetch datafile", { error: e });</span>
|
|
1440
|
-
});
|
|
1441
|
-
} else if (options.datafile) {
|
|
1442
|
-
this.setDatafile(options.datafile);
|
|
1443
|
-
this.statuses.ready = true;
|
|
1444
|
-
|
|
1445
|
-
setTimeout(() => {
|
|
1446
|
-
this.emitter.emit("ready");
|
|
1447
|
-
}, 0);
|
|
1448
|
-
} else <span class="missing-if-branch" title="else path not taken" >E</span>{
|
|
1449
|
-
<span class="cstat-no" title="statement not covered" > throw new Error(</span>
|
|
1450
|
-
"Featurevisor SDK instance cannot be created without both `datafile` and `datafileUrl` options",
|
|
1451
|
-
);
|
|
1056
|
+
this.logger.info("datafile set", details);
|
|
1057
|
+
this.emitter.trigger("datafile_set", details);
|
|
1058
|
+
} catch (e) {
|
|
1059
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error("could not parse datafile", { error: e });</span>
|
|
1452
1060
|
}
|
|
1453
1061
|
}
|
|
1454
1062
|
|
|
1455
|
-
<span class="
|
|
1456
|
-
<span class="
|
|
1457
|
-
}
|
|
1063
|
+
setSticky(sticky: StickyFeatures, replace = <span class="branch-0 cbranch-no" title="branch not covered" >false)</span> {
|
|
1064
|
+
const previousStickyFeatures = this.sticky || <span class="branch-1 cbranch-no" title="branch not covered" >{};</span>
|
|
1458
1065
|
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
const cb = () => {
|
|
1466
|
-
this.emitter.removeListener("ready", cb);
|
|
1467
|
-
|
|
1468
|
-
resolve(this);
|
|
1066
|
+
if (replace) {
|
|
1067
|
+
this.sticky = { ...sticky };
|
|
1068
|
+
} else <span class="missing-if-branch" title="else path not taken" >E</span>{
|
|
1069
|
+
<span class="cstat-no" title="statement not covered" > this.sticky = {</span>
|
|
1070
|
+
...this.sticky,
|
|
1071
|
+
...sticky,
|
|
1469
1072
|
};
|
|
1073
|
+
}
|
|
1470
1074
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1075
|
+
const params = getParamsForStickySetEvent(previousStickyFeatures, this.sticky, replace);
|
|
1076
|
+
|
|
1077
|
+
this.logger.info("sticky features set", params);
|
|
1078
|
+
this.emitter.trigger("sticky_set", params);
|
|
1473
1079
|
}
|
|
1474
1080
|
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
this.datafileReader = new DatafileReader(
|
|
1478
|
-
typeof datafile === "string" ? <span class="branch-0 cbranch-no" title="branch not covered" >JSON.parse(datafile) </span>: datafile,
|
|
1479
|
-
);
|
|
1480
|
-
} catch (e) {
|
|
1481
|
-
<span class="cstat-no" title="statement not covered" > this.logger.error("could not parse datafile", { error: e });</span>
|
|
1482
|
-
}
|
|
1081
|
+
<span class="fstat-no" title="function not covered" > getRevision(</span>): string {
|
|
1082
|
+
<span class="cstat-no" title="statement not covered" > return this.datafileReader.getRevision();</span>
|
|
1483
1083
|
}
|
|
1484
1084
|
|
|
1485
|
-
|
|
1486
|
-
this.
|
|
1085
|
+
<span class="fstat-no" title="function not covered" > getFeature(</span>featureKey: string): Feature | undefined {
|
|
1086
|
+
<span class="cstat-no" title="statement not covered" > return this.datafileReader.getFeature(featureKey);</span>
|
|
1487
1087
|
}
|
|
1488
1088
|
|
|
1489
|
-
|
|
1490
|
-
return this.
|
|
1089
|
+
<span class="fstat-no" title="function not covered" > addHook(</span>hook: Hook) {
|
|
1090
|
+
<span class="cstat-no" title="statement not covered" > return this.hooksManager.add(hook);</span>
|
|
1491
1091
|
}
|
|
1492
1092
|
|
|
1493
|
-
<span class="fstat-no" title="function not covered" >
|
|
1494
|
-
<span class="cstat-no" title="statement not covered" > return
|
|
1495
|
-
? this.datafileReader.getFeature(featureKey) // only key provided
|
|
1496
|
-
: featureKey; // full feature provided
|
|
1093
|
+
<span class="fstat-no" title="function not covered" > on(</span>eventName: EventName, callback: EventCallback) {
|
|
1094
|
+
<span class="cstat-no" title="statement not covered" > return this.emitter.on(eventName, callback);</span>
|
|
1497
1095
|
}
|
|
1498
1096
|
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
*/
|
|
1502
|
-
isReady(): boolean {
|
|
1503
|
-
return this.statuses.ready;
|
|
1097
|
+
<span class="fstat-no" title="function not covered" > close(</span>) {
|
|
1098
|
+
<span class="cstat-no" title="statement not covered" > this.emitter.clearAll();</span>
|
|
1504
1099
|
}
|
|
1505
1100
|
|
|
1506
1101
|
/**
|
|
1507
|
-
*
|
|
1102
|
+
* Context
|
|
1508
1103
|
*/
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
<span class="cstat-no" title="statement not covered" >
|
|
1104
|
+
<span class="fstat-no" title="function not covered" > setContext(</span>context: Context, replace = <span class="branch-0 cbranch-no" title="branch not covered" >false)</span> {
|
|
1105
|
+
<span class="cstat-no" title="statement not covered" > if (replace) {</span>
|
|
1106
|
+
<span class="cstat-no" title="statement not covered" > this.context = context;</span>
|
|
1107
|
+
} else {
|
|
1108
|
+
<span class="cstat-no" title="statement not covered" > this.context = { ...this.context, ...context };</span>
|
|
1514
1109
|
}
|
|
1515
1110
|
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
this.
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
const currentRevision = this.getRevision();
|
|
1525
|
-
const newRevision = datafile.revision;
|
|
1526
|
-
const isNotSameRevision = currentRevision !== newRevision;
|
|
1527
|
-
|
|
1528
|
-
this.setDatafile(datafile);
|
|
1529
|
-
this.logger.info("refreshed datafile");
|
|
1530
|
-
|
|
1531
|
-
this.emitter.emit("refresh");
|
|
1532
|
-
|
|
1533
|
-
if (isNotSameRevision) {
|
|
1534
|
-
this.emitter.emit("update");
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
|
-
this.statuses.refreshInProgress = false;
|
|
1538
|
-
})
|
|
1539
|
-
.catch(<span class="fstat-no" title="function not covered" >(e</span>) => {
|
|
1540
|
-
<span class="cstat-no" title="statement not covered" > this.logger.error("failed to refresh datafile", { error: e });</span>
|
|
1541
|
-
<span class="cstat-no" title="statement not covered" > this.statuses.refreshInProgress = false;</span>
|
|
1542
|
-
});
|
|
1111
|
+
<span class="cstat-no" title="statement not covered" > this.emitter.trigger("context_set", {</span>
|
|
1112
|
+
context: this.context,
|
|
1113
|
+
replaced: replace,
|
|
1114
|
+
});
|
|
1115
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug(replace ? "context replaced" : "context updated", {</span>
|
|
1116
|
+
context: this.context,
|
|
1117
|
+
replaced: replace,
|
|
1118
|
+
});
|
|
1543
1119
|
}
|
|
1544
1120
|
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
<span class="missing-if-branch" title="if path not taken" >I</span>if (!this.refreshInterval) {
|
|
1555
|
-
<span class="cstat-no" title="statement not covered" > return this.logger.warn("no `refreshInterval` option provided");</span>
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
this.intervalId = setInterval(() => {
|
|
1559
|
-
this.refresh();
|
|
1560
|
-
}, this.refreshInterval * 1000);
|
|
1121
|
+
getContext(context?: Context): Context {
|
|
1122
|
+
return context
|
|
1123
|
+
? {
|
|
1124
|
+
...this.context,
|
|
1125
|
+
...context,
|
|
1126
|
+
}
|
|
1127
|
+
: this.context;
|
|
1561
1128
|
}
|
|
1562
1129
|
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1130
|
+
spawn(context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span> options: OverrideOptions = {}): FeaturevisorChildInstance {
|
|
1131
|
+
return new FeaturevisorChildInstance({
|
|
1132
|
+
parent: this,
|
|
1133
|
+
context: this.getContext(context),
|
|
1134
|
+
sticky: options.sticky,
|
|
1135
|
+
});
|
|
1569
1136
|
}
|
|
1570
1137
|
|
|
1571
1138
|
/**
|
|
1572
1139
|
* Flag
|
|
1573
1140
|
*/
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
context,
|
|
1141
|
+
private getEvaluationDependencies(
|
|
1142
|
+
context: Context,
|
|
1143
|
+
options: OverrideOptions = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1144
|
+
): EvaluateDependencies {
|
|
1145
|
+
return {
|
|
1146
|
+
context: this.getContext(context),
|
|
1580
1147
|
|
|
1581
1148
|
logger: this.logger,
|
|
1149
|
+
hooksManager: this.hooksManager,
|
|
1582
1150
|
datafileReader: this.datafileReader,
|
|
1583
|
-
statuses: this.statuses,
|
|
1584
|
-
interceptContext: this.interceptContext,
|
|
1585
1151
|
|
|
1586
|
-
|
|
1587
|
-
|
|
1152
|
+
// OverrideOptions
|
|
1153
|
+
sticky: options.sticky
|
|
1154
|
+
? {
|
|
1155
|
+
...this.sticky,
|
|
1156
|
+
...options.sticky,
|
|
1157
|
+
}
|
|
1158
|
+
: this.sticky,
|
|
1159
|
+
defaultVariationValue: options.defaultVariationValue,
|
|
1160
|
+
defaultVariableValue: options.defaultVariableValue,
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1588
1163
|
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1164
|
+
evaluateFlag(
|
|
1165
|
+
featureKey: FeatureKey,
|
|
1166
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1167
|
+
options: OverrideOptions = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1168
|
+
): Evaluation {
|
|
1169
|
+
return evaluateWithHooks({
|
|
1170
|
+
...this.getEvaluationDependencies(context, options),
|
|
1171
|
+
type: "flag",
|
|
1172
|
+
featureKey,
|
|
1592
1173
|
});
|
|
1593
1174
|
}
|
|
1594
1175
|
|
|
1595
|
-
isEnabled(featureKey: FeatureKey
|
|
1176
|
+
isEnabled(featureKey: FeatureKey, context: Context = {}, options: OverrideOptions = {}): boolean {
|
|
1596
1177
|
try {
|
|
1597
|
-
const evaluation = this.evaluateFlag(featureKey, context);
|
|
1178
|
+
const evaluation = this.evaluateFlag(featureKey, context, options);
|
|
1598
1179
|
|
|
1599
1180
|
return evaluation.enabled === true;
|
|
1600
1181
|
} catch (e) {
|
|
@@ -1607,33 +1188,25 @@ export class FeaturevisorInstance {
|
|
|
1607
1188
|
/**
|
|
1608
1189
|
* Variation
|
|
1609
1190
|
*/
|
|
1610
|
-
evaluateVariation(
|
|
1611
|
-
|
|
1191
|
+
evaluateVariation(
|
|
1192
|
+
featureKey: FeatureKey,
|
|
1193
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1194
|
+
options: OverrideOptions = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1195
|
+
): Evaluation {
|
|
1196
|
+
return evaluateWithHooks({
|
|
1197
|
+
...this.getEvaluationDependencies(context, options),
|
|
1612
1198
|
type: "variation",
|
|
1613
|
-
|
|
1614
1199
|
featureKey,
|
|
1615
|
-
context,
|
|
1616
|
-
|
|
1617
|
-
logger: this.logger,
|
|
1618
|
-
datafileReader: this.datafileReader,
|
|
1619
|
-
statuses: this.statuses,
|
|
1620
|
-
interceptContext: this.interceptContext,
|
|
1621
|
-
|
|
1622
|
-
stickyFeatures: this.stickyFeatures,
|
|
1623
|
-
initialFeatures: this.initialFeatures,
|
|
1624
|
-
|
|
1625
|
-
bucketKeySeparator: this.bucketKeySeparator,
|
|
1626
|
-
configureBucketKey: this.configureBucketKey,
|
|
1627
|
-
configureBucketValue: this.configureBucketValue,
|
|
1628
1200
|
});
|
|
1629
1201
|
}
|
|
1630
1202
|
|
|
1631
1203
|
getVariation(
|
|
1632
|
-
featureKey: FeatureKey
|
|
1204
|
+
featureKey: FeatureKey,
|
|
1633
1205
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1634
|
-
|
|
1206
|
+
options: OverrideOptions = {},
|
|
1207
|
+
): VariationValue | null {
|
|
1635
1208
|
try {
|
|
1636
|
-
const evaluation = this.evaluateVariation(featureKey, context);
|
|
1209
|
+
const evaluation = this.evaluateVariation(featureKey, context, options);
|
|
1637
1210
|
|
|
1638
1211
|
if (typeof evaluation.variationValue !== "undefined") {
|
|
1639
1212
|
return evaluation.variationValue;
|
|
@@ -1643,56 +1216,11 @@ export class FeaturevisorInstance {
|
|
|
1643
1216
|
return evaluation.variation.value;
|
|
1644
1217
|
}
|
|
1645
1218
|
|
|
1646
|
-
return
|
|
1219
|
+
return null;
|
|
1647
1220
|
} catch (e) {
|
|
1648
1221
|
<span class="cstat-no" title="statement not covered" > this.logger.error("getVariation", { featureKey, error: e });</span>
|
|
1649
1222
|
|
|
1650
|
-
<span class="cstat-no" title="statement not covered" > return
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
|
-
/**
|
|
1655
|
-
* Activate
|
|
1656
|
-
*/
|
|
1657
|
-
activate(featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: VariationValue | undefined {
|
|
1658
|
-
try {
|
|
1659
|
-
const evaluation = this.evaluateVariation(featureKey, context);
|
|
1660
|
-
const variationValue = evaluation.variation
|
|
1661
|
-
? evaluation.variation.value
|
|
1662
|
-
: <span class="branch-1 cbranch-no" title="branch not covered" >evaluation.variationValue;</span>
|
|
1663
|
-
|
|
1664
|
-
<span class="missing-if-branch" title="if path not taken" >I</span>if (typeof variationValue === "undefined") {
|
|
1665
|
-
<span class="cstat-no" title="statement not covered" > return undefined;</span>
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
const finalContext = this.interceptContext ? <span class="branch-0 cbranch-no" title="branch not covered" >this.interceptContext(context) </span>: context;
|
|
1669
|
-
|
|
1670
|
-
const captureContext: Context = {};
|
|
1671
|
-
|
|
1672
|
-
const attributesForCapturing = this.datafileReader
|
|
1673
|
-
.getAllAttributes()
|
|
1674
|
-
.filter(<span class="fstat-no" title="function not covered" >(a</span>) => <span class="cstat-no" title="statement not covered" >a.capture === true)</span>;
|
|
1675
|
-
|
|
1676
|
-
attributesForCapturing.forEach(<span class="fstat-no" title="function not covered" >(a</span>) => {
|
|
1677
|
-
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof finalContext[a.key] !== "undefined") {</span>
|
|
1678
|
-
<span class="cstat-no" title="statement not covered" > captureContext[a.key] = context[a.key];</span>
|
|
1679
|
-
}
|
|
1680
|
-
});
|
|
1681
|
-
|
|
1682
|
-
this.emitter.emit(
|
|
1683
|
-
"activation",
|
|
1684
|
-
featureKey,
|
|
1685
|
-
variationValue,
|
|
1686
|
-
finalContext,
|
|
1687
|
-
captureContext,
|
|
1688
|
-
evaluation,
|
|
1689
|
-
);
|
|
1690
|
-
|
|
1691
|
-
return variationValue;
|
|
1692
|
-
} catch (e) {
|
|
1693
|
-
<span class="cstat-no" title="statement not covered" > this.logger.error("activate", { featureKey, error: e });</span>
|
|
1694
|
-
|
|
1695
|
-
<span class="cstat-no" title="statement not covered" > return undefined;</span>
|
|
1223
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1696
1224
|
}
|
|
1697
1225
|
}
|
|
1698
1226
|
|
|
@@ -1700,38 +1228,27 @@ export class FeaturevisorInstance {
|
|
|
1700
1228
|
* Variable
|
|
1701
1229
|
*/
|
|
1702
1230
|
evaluateVariable(
|
|
1703
|
-
featureKey: FeatureKey
|
|
1231
|
+
featureKey: FeatureKey,
|
|
1704
1232
|
variableKey: VariableKey,
|
|
1705
1233
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1234
|
+
options: OverrideOptions = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1706
1235
|
): Evaluation {
|
|
1707
|
-
return
|
|
1236
|
+
return evaluateWithHooks({
|
|
1237
|
+
...this.getEvaluationDependencies(context, options),
|
|
1708
1238
|
type: "variable",
|
|
1709
|
-
|
|
1710
1239
|
featureKey,
|
|
1711
1240
|
variableKey,
|
|
1712
|
-
context,
|
|
1713
|
-
|
|
1714
|
-
logger: this.logger,
|
|
1715
|
-
datafileReader: this.datafileReader,
|
|
1716
|
-
statuses: this.statuses,
|
|
1717
|
-
interceptContext: this.interceptContext,
|
|
1718
|
-
|
|
1719
|
-
stickyFeatures: this.stickyFeatures,
|
|
1720
|
-
initialFeatures: this.initialFeatures,
|
|
1721
|
-
|
|
1722
|
-
bucketKeySeparator: this.bucketKeySeparator,
|
|
1723
|
-
configureBucketKey: this.configureBucketKey,
|
|
1724
|
-
configureBucketValue: this.configureBucketValue,
|
|
1725
1241
|
});
|
|
1726
1242
|
}
|
|
1727
1243
|
|
|
1728
1244
|
getVariable(
|
|
1729
|
-
featureKey: FeatureKey
|
|
1245
|
+
featureKey: FeatureKey,
|
|
1730
1246
|
variableKey: string,
|
|
1731
1247
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1732
|
-
|
|
1248
|
+
options: OverrideOptions = {},
|
|
1249
|
+
): VariableValue | null {
|
|
1733
1250
|
try {
|
|
1734
|
-
const evaluation = this.evaluateVariable(featureKey, variableKey, context);
|
|
1251
|
+
const evaluation = this.evaluateVariable(featureKey, variableKey, context, options);
|
|
1735
1252
|
|
|
1736
1253
|
if (typeof evaluation.variableValue !== "undefined") {
|
|
1737
1254
|
if (
|
|
@@ -1745,82 +1262,133 @@ export class FeaturevisorInstance {
|
|
|
1745
1262
|
return evaluation.variableValue;
|
|
1746
1263
|
}
|
|
1747
1264
|
|
|
1748
|
-
return
|
|
1265
|
+
return null;
|
|
1749
1266
|
} catch (e) {
|
|
1750
1267
|
<span class="cstat-no" title="statement not covered" > this.logger.error("getVariable", { featureKey, variableKey, error: e });</span>
|
|
1751
1268
|
|
|
1752
|
-
<span class="cstat-no" title="statement not covered" > return
|
|
1269
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1753
1270
|
}
|
|
1754
1271
|
}
|
|
1755
1272
|
|
|
1756
1273
|
getVariableBoolean(
|
|
1757
|
-
featureKey: FeatureKey
|
|
1274
|
+
featureKey: FeatureKey,
|
|
1758
1275
|
variableKey: string,
|
|
1759
1276
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1760
|
-
|
|
1761
|
-
|
|
1277
|
+
options: OverrideOptions = {},
|
|
1278
|
+
): boolean | null {
|
|
1279
|
+
const variableValue = this.getVariable(featureKey, variableKey, context, options);
|
|
1762
1280
|
|
|
1763
|
-
return getValueByType(variableValue, "boolean") as boolean |
|
|
1281
|
+
return getValueByType(variableValue, "boolean") as boolean | null;
|
|
1764
1282
|
}
|
|
1765
1283
|
|
|
1766
1284
|
getVariableString(
|
|
1767
|
-
featureKey: FeatureKey
|
|
1285
|
+
featureKey: FeatureKey,
|
|
1768
1286
|
variableKey: string,
|
|
1769
1287
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1770
|
-
|
|
1771
|
-
|
|
1288
|
+
options: OverrideOptions = {},
|
|
1289
|
+
): string | null {
|
|
1290
|
+
const variableValue = this.getVariable(featureKey, variableKey, context, options);
|
|
1772
1291
|
|
|
1773
|
-
return getValueByType(variableValue, "string") as string |
|
|
1292
|
+
return getValueByType(variableValue, "string") as string | null;
|
|
1774
1293
|
}
|
|
1775
1294
|
|
|
1776
1295
|
getVariableInteger(
|
|
1777
|
-
featureKey: FeatureKey
|
|
1296
|
+
featureKey: FeatureKey,
|
|
1778
1297
|
variableKey: string,
|
|
1779
1298
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1780
|
-
|
|
1781
|
-
|
|
1299
|
+
options: OverrideOptions = {},
|
|
1300
|
+
): number | null {
|
|
1301
|
+
const variableValue = this.getVariable(featureKey, variableKey, context, options);
|
|
1782
1302
|
|
|
1783
|
-
return getValueByType(variableValue, "integer") as number |
|
|
1303
|
+
return getValueByType(variableValue, "integer") as number | null;
|
|
1784
1304
|
}
|
|
1785
1305
|
|
|
1786
1306
|
getVariableDouble(
|
|
1787
|
-
featureKey: FeatureKey
|
|
1307
|
+
featureKey: FeatureKey,
|
|
1788
1308
|
variableKey: string,
|
|
1789
1309
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1790
|
-
|
|
1791
|
-
|
|
1310
|
+
options: OverrideOptions = {},
|
|
1311
|
+
): number | null {
|
|
1312
|
+
const variableValue = this.getVariable(featureKey, variableKey, context, options);
|
|
1792
1313
|
|
|
1793
|
-
return getValueByType(variableValue, "double") as number |
|
|
1314
|
+
return getValueByType(variableValue, "double") as number | null;
|
|
1794
1315
|
}
|
|
1795
1316
|
|
|
1796
1317
|
getVariableArray(
|
|
1797
|
-
featureKey: FeatureKey
|
|
1318
|
+
featureKey: FeatureKey,
|
|
1798
1319
|
variableKey: string,
|
|
1799
1320
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1800
|
-
|
|
1801
|
-
|
|
1321
|
+
options: OverrideOptions = {},
|
|
1322
|
+
): string[] | null {
|
|
1323
|
+
const variableValue = this.getVariable(featureKey, variableKey, context, options);
|
|
1802
1324
|
|
|
1803
|
-
return getValueByType(variableValue, "array") as string[] |
|
|
1325
|
+
return getValueByType(variableValue, "array") as string[] | null;
|
|
1804
1326
|
}
|
|
1805
1327
|
|
|
1806
1328
|
getVariableObject<T>(
|
|
1807
|
-
featureKey: FeatureKey
|
|
1329
|
+
featureKey: FeatureKey,
|
|
1808
1330
|
variableKey: string,
|
|
1809
1331
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1810
|
-
|
|
1811
|
-
|
|
1332
|
+
options: OverrideOptions = {},
|
|
1333
|
+
): T | null {
|
|
1334
|
+
const variableValue = this.getVariable(featureKey, variableKey, context, options);
|
|
1812
1335
|
|
|
1813
|
-
return getValueByType(variableValue, "object") as T |
|
|
1336
|
+
return getValueByType(variableValue, "object") as T | null;
|
|
1814
1337
|
}
|
|
1815
1338
|
|
|
1816
1339
|
getVariableJSON<T>(
|
|
1817
|
-
featureKey: FeatureKey
|
|
1340
|
+
featureKey: FeatureKey,
|
|
1818
1341
|
variableKey: string,
|
|
1819
1342
|
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1820
|
-
|
|
1821
|
-
|
|
1343
|
+
options: OverrideOptions = {},
|
|
1344
|
+
): T | null {
|
|
1345
|
+
const variableValue = this.getVariable(featureKey, variableKey, context, options);
|
|
1346
|
+
|
|
1347
|
+
return getValueByType(variableValue, "json") as T | null;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
getAllEvaluations(
|
|
1351
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1352
|
+
featureKeys: string[] = [],
|
|
1353
|
+
options: OverrideOptions = {},
|
|
1354
|
+
): EvaluatedFeatures {
|
|
1355
|
+
const result: EvaluatedFeatures = {};
|
|
1356
|
+
|
|
1357
|
+
const keys = featureKeys.length > 0 ? <span class="branch-0 cbranch-no" title="branch not covered" >featureKeys </span>: this.datafileReader.getFeatureKeys();
|
|
1358
|
+
for (const featureKey of keys) {
|
|
1359
|
+
// isEnabled
|
|
1360
|
+
const evaluatedFeature: EvaluatedFeature = {
|
|
1361
|
+
enabled: this.isEnabled(featureKey, context, options),
|
|
1362
|
+
};
|
|
1363
|
+
|
|
1364
|
+
// variation
|
|
1365
|
+
if (this.datafileReader.hasVariations(featureKey)) {
|
|
1366
|
+
const variation = this.getVariation(featureKey, context, options);
|
|
1367
|
+
|
|
1368
|
+
if (variation) {
|
|
1369
|
+
evaluatedFeature.variation = variation;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
// variables
|
|
1374
|
+
const variableKeys = this.datafileReader.getVariableKeys(featureKey);
|
|
1375
|
+
if (variableKeys.length > 0) {
|
|
1376
|
+
evaluatedFeature.variables = {};
|
|
1377
|
+
|
|
1378
|
+
for (const variableKey of variableKeys) {
|
|
1379
|
+
evaluatedFeature.variables[variableKey] = this.getVariable(
|
|
1380
|
+
featureKey,
|
|
1381
|
+
variableKey,
|
|
1382
|
+
context,
|
|
1383
|
+
options,
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
result[featureKey] = evaluatedFeature;
|
|
1389
|
+
}
|
|
1822
1390
|
|
|
1823
|
-
return
|
|
1391
|
+
return result;
|
|
1824
1392
|
}
|
|
1825
1393
|
}
|
|
1826
1394
|
|
|
@@ -1834,7 +1402,7 @@ export function createInstance(options: InstanceOptions): FeaturevisorInstance {
|
|
|
1834
1402
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1835
1403
|
Code coverage generated by
|
|
1836
1404
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1837
|
-
at 2025-
|
|
1405
|
+
at 2025-07-19T20:24:32.581Z
|
|
1838
1406
|
</div>
|
|
1839
1407
|
<script src="prettify.js"></script>
|
|
1840
1408
|
<script>
|