Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate alternatives to our Mixin pattern #1132

Closed
zepumph opened this issue Mar 25, 2024 · 23 comments
Closed

Investigate alternatives to our Mixin pattern #1132

zepumph opened this issue Mar 25, 2024 · 23 comments

Comments

@zepumph
Copy link
Member

zepumph commented Mar 25, 2024

Over in phetsims/chipper#1424, @jonathanolson @samreid and I are very interested in moving towards letting our TypeScript repos generate d.ts files to help improve our code base. Basically we have found (along with the whole TypeScript community) that mixins (anonymous class declarations) are completely unsupported in declaration type files. After some investigation, we are ready to see if our Mixin pattern can be refactored into something else. This is valuable for phet-lib, type checking speed, and documentation capabilities.

From that issue, we will assign @jonathanolson to do some brainstorming about the mixin problem specifically.

Currently I see 25 usages of return class. That isn't a complete or correct list, but it is a reasonable place to start in finding our mixins.

@zepumph
Copy link
Member Author

zepumph commented Mar 25, 2024

I feel like Poolable is the post pervasive and complicated mixin that we have. Perhaps our investigation should start with that class, since it is the most "mixin-ey" item we have (not a trait that depends on Node or something).

@samreid
Copy link
Member

samreid commented Apr 26, 2024

I ran a few searches to see what mixins we have, then searched for the mixin applications. Here is what I have found so far. I have no confidence that this list is complete:

# = DelayedMutate(

InteractiveHighlighting
  InteractiveHighlighting(Path)
  InteractiveHighlighting(Node)
  InteractiveHighlighting(VBox)
  InteractiveHighlighting(NumberDisplay)
  InteractiveHighlighting(ProbeNode)
  InteractiveHighlighting(Type) // See Voicing.ts
  InteractiveHighlighting(ShadedSphereNode) // See Voicing.ts
  InteractiveHighlighting(Rectangle) // See Voicing.ts
  InteractiveHighlighting(ProbeNode) // See Voicing.ts
ReadingBlock
  ReadingBlock(Node)
  ReadingBlock(VBox)
  ReadingBlock(Text)
  ReadingBlock(RichText)
Voicing
  Voicing(Node)
  Voicing(Rectangle)
  Voicing(VBox)
  Voicing(phet.scenery.Rectangle) // see voicing.html
  Voicing(Type) // See ReadingBlock.ts
  Voicing(RichTextCleanable(Node))
  Voicing(Type) // See AccessibleValueHandler.ts
HeightSizable
  HeightSizable(Node)
  HeightSizable(type) // See Sizable.ts
  HeightSizable(Separator)
Sizable
  Sizable(Node)
  Sizable(Path)
  Sizable(AccessibleSlider(Node,0))
  Sizable(Voicing(Node))
WidthSizable
  WidthSizable(Node)
  WidthSizable(MutableOptionsNode)
  WidthSizable(HeightSizable(type)) // Sizable.ts
  WidthSizable(Separator)
  WidthSizable(Voicing(Node))
AccessibleNumberSpinner
  AccessibleNumberSpinner(Node,0)
AccessibleSlider
  AccessibleSlider(Node,0)
AccessibleValueHandler
  AccessibleValueHandler(Type,optionsArgPosition) // see AccessibleNumberSpinner.ts
  AccessibleValueHandler(Type,optionsArgPosition) // see AccessibleSlider.ts

# return class

ThreeInstrumentable
  No Usage Sites
AddStateKeyTests
  Bad search
ChangeStateKeyIOTypeTests
  Bad search
RenameStateKeyTests
  Bad search
FlowConfigurable
  FlowConfigurable(MarginLayoutCell)
  FlowConfigurable(NodeLayoutConstraint)
GridConfigurable
  GridConfigurable(MarginLayoutCell)
  GridConfigurable(NodeLayoutConstraint)
MarginLayoutConfigurable
  MarginLayoutConfigurable(type) // FlowConfigurable.ts
  MarginLayoutConfigurable(type) // GridConfigurable.ts
SpriteListenable
  SpriteListenable(PressListener) // OrganismSprites.ts (natural selection only)
  SpriteListenable(DragListener)  // demoSprites.ts (demo only)
Imageable
  Imageable(Object)
  Imageable(Node)
Leaf
  Leaf(Node)
Paintable
  Paintable(Node)
DelayedMutate
  // different pattern
RichTextCleanable
  RichTextCleanable(Node)
  RichTextCleanable(Text)
Popupable
  Popupable(Node)
  Popupable(Panel)
CircleStatefulDrawable
  CircleStatefulDrawable( DOMSelfDrawable )
  CircleStatefulDrawable( SVGSelfDrawable )
ImageStatefulDrawable
  ImageStatefulDrawable( DOMSelfDrawable )
  ImageStatefulDrawable( SVGSelfDrawable )
  ImageStatefulDrawable( WebGLSelfDrawable )
LineStatefulDrawable
  LineStatefulDrawable( SVGSelfDrawable )
LineStatelessDrawable
  LineStatelessDrawable( CanvasSelfDrawable )
PaintableStatefulDrawable
  PaintableStatefulDrawable(type) // CircleStatefulDrawable.ts
  PaintableStatefulDrawable(type) // LineStatefulDrawable.ts
  PaintableStatefulDrawable(type) // PathStatefulDrawable.ts
  PaintableStatefulDrawable(type) // RectangleStatefulDrawable.ts
  PaintableStatefulDrawable(type) // TextStatefulDrawable.ts
PaintableStatelessDrawable
  PaintableStatelessDrawable( CanvasSelfDrawable ) 
  PaintableStatelessDrawable( type ) {  // LineStatelessDrawable.js
  PaintableStatelessDrawable( CanvasSelfDrawable )
  PaintableStatelessDrawable( CanvasSelfDrawable )
  PaintableStatelessDrawable( CanvasSelfDrawable )
PathStatefulDrawable
  PathStatefulDrawable( SVGSelfDrawable )
RectangleStatefulDrawable
  RectangleStatefulDrawable( DOMSelfDrawable )
  RectangleStatefulDrawable( SVGSelfDrawable )
  RectangleStatefulDrawable( WebGLSelfDrawable )
TextStatefulDrawable
  TextStatefulDrawable( DOMSelfDrawable )
  TextStatefulDrawable( SVGSelfDrawable )

# class extends .*type

(all duplicated from above)

# find applications via
# class\s+([A-Za-z_]\w*)\s+extends\s+([A-Za-z_]\w*)\(\s*([A-Za-z_]\w*)

(all duplicated from above)

Note that some are variables like MyMixin(someType) which I did not track down the applications of--would be nice to have help on that part.

From this list, it seems there are places where we do not need a mixin replacement. For instance:

  • AccessibleNumberSpinner is only ever mixed into AccessibleNumberSpinner(Node,0) so it seems we could convert that into an idiomatic subtype, unless we had planned for future other non-Node mixin applications.
  • AccessibleSlider is only ever mixed into AccessibleSlider(Node), so we could convert it to a subtype
  • Popupable is mixed into Node and Panel, but it doesn't seem important to be mixed into Panel. Why not have Popupable extends Node and the panel one can do this.addChild(myPanel)?
  • LineStatefulDrawable has only one mixin target at the moment, was it planned to have more?
  • LineStatelessDrawable same
  • Paintable only mixes Paintable(Node), was it planned to have more?
  • Mixins like TextStatefulDrawable look trivial and fine to duplicate by hand (perhaps with a type alias interface)

So I feel the next conversation should be to see what of our mixins can be converted to subtypes. This conversation would entail "planned future usages". This will give us a much smaller list of what we have to deal with for duplication or other workarounds.

@jonathanolson
Copy link
Contributor

My working copy "changes"/"notes".

Subject: [PATCH] assorted notes
---
Index: scenery/js/layout/WidthSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/WidthSizable.ts b/scenery/js/layout/WidthSizable.ts
--- a/scenery/js/layout/WidthSizable.ts	(revision d354ba386cb15382a4c69dc8f41ae7cc9cbc7574)
+++ b/scenery/js/layout/WidthSizable.ts	(date 1714166645847)
@@ -55,12 +55,30 @@
   widthSizable?: boolean;
 };
 
+export interface TWidthSizable<MixType extends Node> {
+  preferredWidthProperty: TinyProperty<number | null>;
+  minimumWidthProperty: TinyProperty<number | null>;
+  localPreferredWidthProperty: TinyProperty<number | null>;
+  localMinimumWidthProperty: TinyProperty<number | null>;
+  isWidthResizableProperty: TinyProperty<boolean>;
+
+  preferredWidth: number | null;
+  localPreferredWidth: number | null;
+  minimumWidth: number | null;
+  localMinimumWidth: number | null;
+  // overrides widthSizable / extendsWidthSizable
+
+  validateLocalPreferredWidth(): void;
+
+  // mutate( options?: WidthSizableOptions & Parameters<MixType[ 'mutate' ]>[ 0 ] ): this;
+}
+
 // IMPORTANT: If you're combining this in, typically don't pass options that WidthSizable would take through the
 // constructor. It will hit Node's mutate() likely, and then will fail because we haven't been able to set the
 // values yet. If you're making something WidthSizable, please use a later mutate() to pass these options through.
 // They WILL be caught by assertions if someone adds one of those options, but it could be a silent bug if no one
 // is yet passing those options through.
-const WidthSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const WidthSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ): SuperType & ( new ( ...args: IntentionalAny[] ) => InstanceType<SuperType> & TWidthSizable<InstanceType<SuperType>> ) => {
   const WidthSizableTrait = DelayedMutate( 'WidthSizable', WIDTH_SIZABLE_OPTION_KEYS, class WidthSizableTrait extends type {
 
     // parent/local preferred/minimum Properties. See the options above for more documentation
Index: sun/js/CarouselComboBox.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/CarouselComboBox.ts b/sun/js/CarouselComboBox.ts
--- a/sun/js/CarouselComboBox.ts	(revision b29f9eb9bf3f47a061fcd54eddb612110c24d004)
+++ b/sun/js/CarouselComboBox.ts	(date 1714166645721)
@@ -47,6 +47,10 @@
 type ParentOptions = NodeOptions & WidthSizableOptions;
 export type CarouselComboBoxOptions = SelfOptions & StrictOmit<ParentOptions, 'children'>;
 
+const testClass = class Demo extends WidthSizable( Node ) {
+
+};
+
 export default class CarouselComboBox<T> extends WidthSizable( Node ) {
 
   // See ComboBox for a description of this property.
Index: scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/Voicing.ts b/scenery/js/accessibility/voicing/Voicing.ts
--- a/scenery/js/accessibility/voicing/Voicing.ts	(revision d354ba386cb15382a4c69dc8f41ae7cc9cbc7574)
+++ b/scenery/js/accessibility/voicing/Voicing.ts	(date 1714168992891)
@@ -94,6 +94,23 @@
 
 export type VoicingOptions = SelfOptions & InteractiveHighlightingOptions;
 
+export type TVoicing {
+  voicingSpeakFullResponse( providedOptions?: SpeakingOptions ): void;
+}
+
+export class Voicing {
+  public constructor(
+    private readonly node
+  ) {
+
+  }
+}
+
+@Voicing
+export class VoicingNode implements TVoicing {
+  // .. stubs
+}
+
 export type SpeakingOptions = {
   utterance?: SelfOptions['voicingUtterance'];
 } & SpeakableResolvedOptions;
Index: sun/js/Slider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/Slider.ts b/sun/js/Slider.ts
--- a/sun/js/Slider.ts	(revision b29f9eb9bf3f47a061fcd54eddb612110c24d004)
+++ b/sun/js/Slider.ts	(date 1714171516192)
@@ -42,6 +42,8 @@
 import isSettingPhetioStateProperty from '../../tandem/js/isSettingPhetioStateProperty.js';
 import PhetioObject from '../../tandem/js/PhetioObject.js';
 import PhetioProperty from '../../axon/js/PhetioProperty.js';
+import NumberProperty from '../../axon/js/NumberProperty.js';
+import Constructor from '../../phet-core/js/types/Constructor.js';
 
 // constants
 const DEFAULT_HORIZONTAL_TRACK_SIZE = new Dimension2( 100, 5 );
@@ -117,7 +119,7 @@
 // We provide these options to the super, also enabledRangeProperty is turned from required to optional
 export type SliderOptions = SelfOptions & OptionalParentOptions & PickOptional<ParentOptions, 'enabledRangeProperty'>;
 
-export default class Slider extends Sizable( AccessibleSlider( Node, 0 ) ) {
+class Slider extends Sizable( AccessibleSlider( Node, 0 ) ) {
 
   public readonly enabledRangeProperty: TReadOnlyProperty<Range>;
 
@@ -816,4 +818,127 @@
   }
 }
 
+/* eslint-disable */
+
+//////
+
+class SuperType2 {
+
+  public constructor(
+    public readonly somethingElse: Node
+  ) {}
+
+  // public someOtherMethod(): number {
+  //   return super.someOtherMethod() + 10;
+  // }
+
+  public someOtherMethod( superCallback: () => number ): number {
+  // public actualSomeOtherMethod( superCallback: () => number ): number {
+    return superCallback() + 10;
+  }
+}
+
+interface SuperType {
+  someOtherMethod(): number;
+}
+
+const mixinSuperType2 = ( type: Constructor<Node> ) => {
+  const oldSomeOtherMethod = type.prototype.someOtherMethod;
+  type.prototype.someOtherMethod = function() {
+    return oldSomeOtherMethod.call( this ) + 10;
+  };
+};
+
+//////
+
+interface InteractiveHighlighting2 extends SuperType2 {
+  someMethod2(): number;
+}
+
+interface AccessibleSlider2 extends InteractiveHighlighting2 {
+  someMethod(): void;
+
+}
+
+const mixinAccessibleSlider2 = ( type ) => {
+  mixinSuperType2( type );
+};
+
+// This can live anywhere in your codebase:
+function applyMixins(derivedCtor: any, constructors: any[]) {
+  constructors.forEach((baseCtor) => {
+    Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
+      Object.defineProperty(
+        derivedCtor.prototype,
+        name,
+        Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
+          Object.create(null)
+      );
+    });
+  });
+}
+
+class AccessibleSlider2Node extends Node {}
+
+
+interface AccessibleSlider2Node extends AccessibleSlider2 {
+  // ...
+}
+
+export class Slider2 extends ( AccessibleSlider2( Node ) as Constructor<AccessibleSlider2Node> ) {
+  public someOtherMethod(): number {
+    this.preferredWidth;
+
+    return 5;
+  }
+}
+
+export const Slider2x = AccessibleSlider( Slider2 ) as Constructor<Slider2>;
+
+// some action that applies AccessibleSlider to Slider
+
+
+
+export default Slider;
+
+const s = new Slider2();
+
+s.someMethod();
+s.someMethod2();
+s.someOtherMethod();
+
+
+
+
+
+
+
+class SuperType3 {
+  public constructor(
+    public readonly node: Node
+  ) {}
+
+  public someOtherMethod( superCallback: () => number ): number {
+
+    // actual logic here
+
+    return superCallback() + 10;
+  }
+}
+
+
+class SuperType3Node {
+  public constructor() {
+    this.superType3 = new SuperType3( this );
+  }
+
+  // stub
+  public override someOtherMethod(): number {
+    return this.superType3.someOtherMethod( () => super.someOtherMethod() );
+  }
+}
+
+
+
+
 sun.register( 'Slider', Slider );
\ No newline at end of file
Index: scenery/js/layout/Sizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/Sizable.ts b/scenery/js/layout/Sizable.ts
--- a/scenery/js/layout/Sizable.ts	(revision d354ba386cb15382a4c69dc8f41ae7cc9cbc7574)
+++ b/scenery/js/layout/Sizable.ts	(date 1713987245180)
@@ -8,7 +8,7 @@
  */
 
 import memoize from '../../../phet-core/js/memoize.js';
-import { DelayedMutate, HEIGHT_SIZABLE_OPTION_KEYS, HeightSizable, HeightSizableOptions, Node, REQUIRES_BOUNDS_OPTION_KEYS, scenery, WIDTH_SIZABLE_OPTION_KEYS, WidthSizable, WidthSizableOptions } from '../imports.js';
+import { DelayedMutate, HEIGHT_SIZABLE_OPTION_KEYS, HeightSizable, HeightSizableOptions, Node, REQUIRES_BOUNDS_OPTION_KEYS, scenery, THeightSizable, TWidthSizable, WIDTH_SIZABLE_OPTION_KEYS, WidthSizable, WidthSizableOptions } from '../imports.js';
 import Constructor from '../../../phet-core/js/types/Constructor.js';
 import Dimension2 from '../../../dot/js/Dimension2.js';
 import assertMutuallyExclusiveOptions from '../../../phet-core/js/assertMutuallyExclusiveOptions.js';
@@ -64,6 +64,17 @@
 type ParentOptions = WidthSizableOptions & HeightSizableOptions;
 export type SizableOptions = SelfOptions & ParentOptions;
 
+export interface TSizable<MixType extends Node> extends TWidthSizable<MixType>, THeightSizable<MixType> {
+  preferredSize: Dimension2 | null;
+  localPreferredSize: Dimension2 | null;
+  minimumSize: Dimension2 | null;
+  localMinimumSize: Dimension2 | null;
+
+  validateLocalPreferredSize(): void;
+
+  // mutate( options?: SelfOptions & Parameters<MixType[ 'mutate' ]>[ 0 ] ): this;
+}
+
 const Sizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
   const SuperExtendedType = WidthSizable( HeightSizable( type ) );
   const SizableTrait = DelayedMutate( 'Sizable', SIZABLE_SELF_OPTION_KEYS, class SizableTrait extends SuperExtendedType {
Index: scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision d354ba386cb15382a4c69dc8f41ae7cc9cbc7574)
+++ b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1714168138453)
@@ -32,6 +32,49 @@
 
 export type InteractiveHighlightingOptions = SelfOptions;
 
+export class InteractiveHighlightNode extends Node {
+  // ... stubs
+}
+
+export class VoicingNode extends InteractiveHighlightNode {
+
+}
+
+export class AccessibleValueHandlerNode extends VoicingNode {
+
+}
+
+export class AccessibleSliderNode extends AccessibleValueHandlerNode {
+
+}
+
+export class SizableAccessibleSliderNode extends AccessibleSliderNode {
+
+}
+
+export class Slider extends SizableAccessibleSliderNode {
+
+}
+
+
+
+export class AccessibleNumberSpinnerNode extends AccessibleValueHandlerNode {
+
+}
+
+export class NumberSpinner extends AccessibleNumberSpinnerNode {
+
+}
+
+
+
+
+
+
+export class InteractiveHighlightPath extends Path {
+  // ... stubs
+}
+
 const InteractiveHighlighting = memoize( <SuperType extends Constructor<Node>>( Type: SuperType ) => {
 
   // @ts-expect-error
Index: scenery/js/imports.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/imports.ts b/scenery/js/imports.ts
--- a/scenery/js/imports.ts	(revision d354ba386cb15382a4c69dc8f41ae7cc9cbc7574)
+++ b/scenery/js/imports.ts	(date 1713986533634)
@@ -95,11 +95,11 @@
 export { default as RendererSummary } from './util/RendererSummary.js';
 export { default as PDOMDisplaysInfo } from './accessibility/pdom/PDOMDisplaysInfo.js';
 export { default as WidthSizable, isWidthSizable, extendsWidthSizable, WIDTH_SIZABLE_OPTION_KEYS } from './layout/WidthSizable.js';
-export type { WidthSizableNode, WidthSizableOptions } from './layout/WidthSizable.js';
+export type { WidthSizableNode, WidthSizableOptions, TWidthSizable } from './layout/WidthSizable.js';
 export { default as HeightSizable, isHeightSizable, extendsHeightSizable, HEIGHT_SIZABLE_OPTION_KEYS } from './layout/HeightSizable.js';
-export type { HeightSizableNode, HeightSizableOptions } from './layout/HeightSizable.js';
+export type { HeightSizableNode, HeightSizableOptions, THeightSizable } from './layout/HeightSizable.js';
 export { default as Sizable, isSizable, extendsSizable, SIZABLE_SELF_OPTION_KEYS, SIZABLE_OPTION_KEYS } from './layout/Sizable.js';
-export type { SizableNode, SizableOptions } from './layout/Sizable.js';
+export type { SizableNode, SizableOptions, TSizable } from './layout/Sizable.js';
 
 export { default as Trail } from './util/Trail.js';
 export { default as TrailPointer } from './util/TrailPointer.js';
Index: scenery/js/layout/HeightSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/HeightSizable.ts b/scenery/js/layout/HeightSizable.ts
--- a/scenery/js/layout/HeightSizable.ts	(revision d354ba386cb15382a4c69dc8f41ae7cc9cbc7574)
+++ b/scenery/js/layout/HeightSizable.ts	(date 1714166645825)
@@ -55,12 +55,30 @@
   heightSizable?: boolean;
 };
 
+export interface THeightSizable<MixType extends Node> {
+  preferredHeightProperty: TinyProperty<number | null>;
+  minimumHeightProperty: TinyProperty<number | null>;
+  localPreferredHeightProperty: TinyProperty<number | null>;
+  localMinimumHeightProperty: TinyProperty<number | null>;
+  isHeightResizableProperty: TinyProperty<boolean>;
+
+  preferredHeight: number | null;
+  localPreferredHeight: number | null;
+  minimumHeight: number | null;
+  localMinimumHeight: number | null;
+  // overrides widthSizable / extendsHeightSizable
+
+  validateLocalPreferredHeight(): void;
+
+  // mutate( options?: HeightSizableOptions & Parameters<MixType[ 'mutate' ]>[ 0 ] ): this;
+}
+
 // IMPORTANT: If you're combining this in, typically don't pass options that HeightSizable would take through the
 // constructor. It will hit Node's mutate() likely, and then will fail because we haven't been able to set the
 // values yet. If you're making something HeightSizable, please use a later mutate() to pass these options through.
 // They WILL be caught by assertions if someone adds one of those options, but it could be a silent bug if no one
 // is yet passing those options through.
-const HeightSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const HeightSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ): SuperType & ( new ( ...args: IntentionalAny[] ) => InstanceType<SuperType> & THeightSizable<InstanceType<SuperType>> ) => {
   const HeightSizableTrait = DelayedMutate( 'HeightSizable', HEIGHT_SIZABLE_OPTION_KEYS, class HeightSizableTrait extends type {
 
     // parent/local preferred/minimum Properties. See the options above for more documentation

@zepumph
Copy link
Member Author

zepumph commented Apr 26, 2024

Meeting today with @samreid @jonathanolson yielded some more possibilities.

Here is a patch with interface extension as a potential possibility. We still want to see what the d.ts says from this.

Subject: [PATCH] interface extension
---
Index: sun/js/Slider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/Slider.ts b/sun/js/Slider.ts
--- a/sun/js/Slider.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/Slider.ts	(date 1714172224728)
@@ -26,7 +26,7 @@
 import Tandem from '../../tandem/js/Tandem.js';
 import IOType from '../../tandem/js/types/IOType.js';
 import ValueChangeSoundPlayer, { ValueChangeSoundPlayerOptions } from '../../tambo/js/sound-generators/ValueChangeSoundPlayer.js';
-import AccessibleSlider, { AccessibleSliderOptions } from './accessibility/AccessibleSlider.js';
+import AccessibleSlider, { AccessibleSliderInterface, AccessibleSliderOptions } from './accessibility/AccessibleSlider.js';
 import DefaultSliderTrack from './DefaultSliderTrack.js';
 import SliderThumb from './SliderThumb.js';
 import SliderTrack from './SliderTrack.js';
@@ -42,6 +42,8 @@
 import isSettingPhetioStateProperty from '../../tandem/js/isSettingPhetioStateProperty.js';
 import PhetioObject from '../../tandem/js/PhetioObject.js';
 import PhetioProperty from '../../axon/js/PhetioProperty.js';
+import Constructor from '../../phet-core/js/types/Constructor.js';
+import { SizableInterface } from '../../scenery/js/layout/Sizable.js';
 
 // constants
 const DEFAULT_HORIZONTAL_TRACK_SIZE = new Dimension2( 100, 5 );
@@ -117,7 +119,15 @@
 // We provide these options to the super, also enabledRangeProperty is turned from required to optional
 export type SliderOptions = SelfOptions & OptionalParentOptions & PickOptional<ParentOptions, 'enabledRangeProperty'>;
 
-export default class Slider extends Sizable( AccessibleSlider( Node, 0 ) ) {
+class AccessibleSliderNode extends Node {}
+/*eslint-disable*/
+interface AccessibleSliderNode extends AccessibleSliderInterface {}
+
+class SizableNode extends AccessibleSliderNode {}
+
+interface SizableNode extends SizableInterface {}
+
+export default class Slider extends ( Sizable( AccessibleSlider( Node, 0 ) ) as Constructor<SizableNode> ) {
 
   public readonly enabledRangeProperty: TReadOnlyProperty<Range>;
 
@@ -319,6 +329,7 @@
     this.orientation = superOptions.orientation!;
     this.enabledRangeProperty = superOptions.enabledRangeProperty;
 
+    console.log( this.startDrag );
     this.tickOptions = _.pick( options, 'tickLabelSpacing',
       'majorTickLength', 'majorTickStroke', 'majorTickLineWidth',
       'minorTickLength', 'minorTickStroke', 'minorTickLineWidth' );
Index: sun/js/accessibility/AccessibleSlider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleSlider.ts b/sun/js/accessibility/AccessibleSlider.ts
--- a/sun/js/accessibility/AccessibleSlider.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleSlider.ts	(date 1714172224739)
@@ -40,12 +40,16 @@
 
 type AccessibleSliderOptions = SelfOptions & AccessibleValueHandlerOptions;
 
+export type AccessibleSliderInterface = {
+  startDrag: ( event: SceneryEvent ) => void;
+};
+
 /**
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at in the constructor for Type
  */
 const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
-  const AccessibleSliderClass = DelayedMutate( 'AccessibleSlider', ACCESSIBLE_SLIDER_OPTIONS, class AccessibleSlider extends AccessibleValueHandler( Type, optionsArgPosition ) {
+  const AccessibleSliderClass = DelayedMutate( 'AccessibleSlider', ACCESSIBLE_SLIDER_OPTIONS, class AccessibleSlider extends AccessibleValueHandler( Type, optionsArgPosition ) implements AccessibleSliderInterface {
 
     private readonly _disposeAccessibleSlider: () => void;
 
Index: scenery/js/layout/Sizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/Sizable.ts b/scenery/js/layout/Sizable.ts
--- a/scenery/js/layout/Sizable.ts	(revision d4f5598d7799a7794249051d6092e5a4a095dcd4)
+++ b/scenery/js/layout/Sizable.ts	(date 1714172224734)
@@ -13,6 +13,7 @@
 import Dimension2 from '../../../dot/js/Dimension2.js';
 import assertMutuallyExclusiveOptions from '../../../phet-core/js/assertMutuallyExclusiveOptions.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
+import TinyProperty from '../../../axon/js/TinyProperty.js';
 
 export const SIZABLE_SELF_OPTION_KEYS = [
   'preferredSize',
@@ -64,6 +65,13 @@
 type ParentOptions = WidthSizableOptions & HeightSizableOptions;
 export type SizableOptions = SelfOptions & ParentOptions;
 
+export type SizableInterface = {
+  get widthSizable(): boolean;
+  set widthSizable( x: boolean );
+  heightSizable: boolean;
+  localPreferredHeightProperty: TinyProperty<number | null>;
+};
+
 const Sizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
   const SuperExtendedType = WidthSizable( HeightSizable( type ) );
   const SizableTrait = DelayedMutate( 'Sizable', SIZABLE_SELF_OPTION_KEYS, class SizableTrait extends SuperExtendedType {

@samreid
Copy link
Member

samreid commented Apr 26, 2024

In today's meeting, we also agreed that Paintable and Popupable seem like good candidates to transform into standard class declarations.

@samreid
Copy link
Member

samreid commented Apr 27, 2024

I continued the strategy identified above and got to a point where I could iterate. This patch introduces a pattern like this, here is an example from the end of WidthSizable:

export type TWidthSizable = {
  readonly preferredWidthProperty: TinyProperty<number | null>;
  readonly minimumWidthProperty: TinyProperty<number | null>;
  readonly localPreferredWidthProperty: TinyProperty<number | null>;
  readonly localMinimumWidthProperty: TinyProperty<number | null>;
  readonly isWidthResizableProperty: TinyProperty<boolean>;

  preferredWidth: number | null;
  minimumWidth: number | null;
  localPreferredWidth: number | null;
  localMinimumWidth: number | null;

  _updateLocalPreferredWidthListener: () => void;
  _updatePreferredWidthListener: () => void;
  _updateLocalMinimumWidthListener: () => void;
  _updateMinimumWidthListener: () => void;

  validateLocalPreferredWidth(): void;

  _calculateLocalPreferredWidth(): number | null;
  _calculatePreferredWidth(): number | null;
  _onReentrantLocalMinimumWidth(): void;
  _onReentrantPreferredWidth(): void;
  _calculateLocalMinimumWidth(): number | null;
  _calculateMinimumWidth(): number | null;

  set widthSizable( value: boolean );
};

// Some typescript gymnastics to provide a user-defined type guard that treats something as widthSizable
// We need to define an unused function with a concrete type, so that we can extract the return type of the function
// and provide a type for a Node that extends this type.
export type WidthSizableNode = Node & TWidthSizable;

scenery.register( 'WidthSizable', WidthSizable );
export default WidthSizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TWidthSizable>;

Please note:

  • type alias members must be public
  • the return type is SuperType (which is already a subtype of Constructor<Node>) combined with Constructor<TWidthSizable>.
  • We have a different, straightforward way of providing the WidthSizableNode

In order to iterate, I enabled d.ts generation and with a few ts-expect-error and hacks I was able to get everything type checking, and generating d.ts files, starting at scenery and all its dependencies. I put everything in one big bundle. But the d.ts files are looking nice:

image

Notes and next steps:

  • Review the proposal with @zepumph and @jonathanolson
  • Address TODOs, ts-expect-errors, and basically visit every line of code in the patch to make sure it is sensible. There are many places in the patch where something looks odd or questionable and I didn't try to document the reasoning behind each part, thinking it could be more efficient to chat in person if we don't forget too much over the weekend.
  • I turned on d.ts generation so I could make sure the entire flow would work, but in main, we could do more "one at a time" if we want, if the patch is too rocky.
  • My tests were in scenery/ and testing with tsc --build and tsc --build --clean. Note I did not do anything downstream of scenery. All of my iteration was based on tsc and I have not worked on lint. I tested one sim at runtime after making sure the transpiler was running, and was surprised/excited to see that it launched and ran properly (not thoroughly tested).
  • To begin, we could have "scenery-stack" in one giant bundle for project references and not try to separate, say, tandem from axon, etc.

Here's the patch, spanning 9 repos. No new files:

Subject: [PATCH] Adjust duck p2 and threejs vertical centering, see https://github.com/phetsims/buoyancy/issues/101
---
Index: scenery/js/util/DelayedMutate.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/util/DelayedMutate.ts b/scenery/js/util/DelayedMutate.ts
--- a/scenery/js/util/DelayedMutate.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/util/DelayedMutate.ts	(date 1714184360993)
@@ -84,4 +84,4 @@
 };
 
 scenery.register( 'DelayedMutate', DelayedMutate );
-export default DelayedMutate;
\ No newline at end of file
+export default DelayedMutate as <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => SuperType;
\ No newline at end of file
Index: scenery/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/tsconfig.json b/scenery/tsconfig.json
--- a/scenery/tsconfig.json	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/tsconfig.json	(date 1714196695041)
@@ -4,6 +4,448 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+
+    "../tandem/js/**/*",
+
+    "../chipper/js/sim-tests/qunitStart.js",
+    "../phet-io/js/phetioEngine.ts",
+
+    "../phet-core/js/isHMR.ts",
+    "../phet-core/js/Namespace.ts",
+    "../phet-core/js/phetCore.ts",
+    "../phet-core/js/extend.ts",
+    "../phet-core/js/types/IntentionalAny.ts",
+    "../phet-core/js/deprecationWarning.ts",
+    "../phet-core/js/merge.ts",
+    "../phet-core/js/types/RequiredKeys.ts",
+    "../phet-core/js/types/OptionalKeys.ts",
+    "../phet-core/js/EnumerationDeprecated.js",
+    "../phet-core/js/optionize.ts",
+    "../axon/js/Validation.ts",
+    "../phet-core/js/types/PickRequired.ts",
+    "../phet-core/js/assertMutuallyExclusiveOptions.ts",
+    "../axon/js/Timer.ts",
+    "../phet-core/js/types/Constructor.ts",
+    "../phet-core/js/EnumerationValue.ts",
+    "../phet-core/js/TEnumeration.ts",
+    "../phet-core/js/inheritance.ts",
+    "../phet-core/js/Enumeration.ts",
+    "../axon/js/animationFrameTimer.ts",
+    "../phet-core/js/types/StrictOmit.ts",
+    "../phet-core/js/arrayRemove.ts",
+    "../axon/js/Disposable.ts",
+    "../axon/js/PropertyStatePhase.ts",
+    "../axon/js/PropertyStateHandler.ts",
+    "../axon/js/propertyStateHandlerSingleton.ts",
+    "../axon/js/units.ts",
+    "../axon/js/ReadOnlyProperty.ts",
+    "../axon/js/TReadOnlyProperty.ts",
+    "../axon/js/TProperty.ts",
+    "../axon/js/TinyProperty.ts",
+    "../axon/js/Emitter.ts",
+    "../axon/js/validate.ts",
+    "../dot/js/Vector4.ts",
+    "../dot/js/Vector3.ts",
+    "../phet-core/js/Pool.ts",
+    "../dot/js/dot.js",
+    "../dot/js/Utils.js",
+    "../dot/js/Matrix4.js",
+    "../dot/js/toSVGNumber.js",
+    "../dot/js/Vector2.ts",
+    "../dot/js/Matrix3.ts",
+    "../dot/js/Range.ts",
+    "../phet-core/js/Orientation.ts",
+    "../dot/js/Bounds2.ts",
+    "../axon/js/axon.ts",
+    "../dot/js/Random.ts",
+    "../dot/js/dotRandom.js",
+    "../axon/js/TEmitter.ts",
+    "../axon/js/TinyEmitter.ts",
+    "../phet-core/js/detectPrefix.ts",
+    "../dot/js/Ray2.ts",
+    "../dot/js/Transform3.js",
+    "../phet-core/js/platform.ts",
+    "../axon/js/Property.ts",
+    "../phet-core/js/detectPrefixEvent.ts",
+    "../phet-core/js/Poolable.ts",
+    "../axon/js/Multilink.ts",
+    "../axon/js/DerivedProperty.ts",
+    "../axon/js/BooleanProperty.ts",
+    "../phet-core/js/isArray.ts",
+    "../dot/js/EigenvalueDecomposition.js",
+    "../dot/js/LUDecomposition.js",
+    "../dot/js/QRDecomposition.js",
+    "../dot/js/Matrix.js",
+    "../dot/js/SingularValueDecomposition.js",
+    "../dot/js/Complex.ts",
+    "../phet-core/js/types/KeysMatching.ts",
+    "../phet-core/js/cleanArray.ts",
+    "../kite/js/kite.ts",
+    "../kite/js/util/LineStyles.ts",
+    "../kite/js/util/Overlap.ts",
+    "../kite/js/util/RayIntersection.ts",
+    "../kite/js/util/SegmentIntersection.ts",
+    "../kite/js/util/svgNumber.ts",
+    "../kite/js/util/intersectConicMatrices.ts",
+    "../kite/js/parser/svgPath.js",
+    "../kite/js/segments/Segment.ts",
+    "../kite/js/segments/Line.ts",
+    "../kite/js/segments/Quadratic.ts",
+    "../kite/js/segments/Cubic.ts",
+    "../kite/js/segments/Arc.ts",
+    "../kite/js/segments/EllipticalArc.ts",
+    "../kite/js/util/Subpath.ts",
+    "../kite/js/Shape.ts",
+    "../kite/js/ops/HalfEdge.js",
+    "../kite/js/ops/Vertex.js",
+    "../kite/js/ops/Edge.js",
+    "../kite/js/ops/Face.js",
+    "../kite/js/ops/Loop.js",
+    "../kite/js/ops/Boundary.js",
+    "../kite/js/ops/BoundsIntersection.ts",
+    "../kite/js/ops/SegmentTree.ts",
+    "../kite/js/ops/EdgeSegmentTree.ts",
+    "../kite/js/ops/VertexSegmentTree.ts",
+    "../kite/js/ops/Graph.js",
+    "../kite/js/imports.ts",
+    "../dot/js/BinPacker.ts",
+    "../dot/js/Dimension2.ts",
+    "../phet-core/js/stripEmbeddingMarks.ts",
+    "../axon/js/StringProperty.ts",
+    "../utterance-queue/js/utteranceQueueNamespace.ts",
+    "../utterance-queue/js/ResponsePatternCollection.ts",
+    "../axon/js/PhetioProperty.ts",
+    "../axon/js/TRangedProperty.ts",
+    "../chipper/js/data/localeInfoModule.js",
+    "../phetcommon/js/phetcommon.js",
+    "../phetcommon/js/util/StringUtils.js",
+    "../axon/js/DynamicProperty.ts",
+    "../axon/js/NumberProperty.ts",
+    "../utterance-queue/js/responseCollector.ts",
+    "../utterance-queue/js/ResponsePacket.ts",
+    "../utterance-queue/js/Utterance.ts",
+    "../axon/js/stepTimer.ts",
+    "../utterance-queue/js/Announcer.ts",
+    "../utterance-queue/js/AriaLiveAnnouncer.ts",
+    "../utterance-queue/js/UtteranceWrapper.ts",
+    "../phet-core/js/memoize.ts",
+    "../phet-core/js/arrayDifference.ts",
+    "../utterance-queue/js/UtteranceQueue.ts",
+    "../axon/js/TinyForwardingProperty.ts",
+    "../axon/js/EnabledProperty.ts",
+    "../axon/js/TinyStaticProperty.ts",
+    "../phet-core/js/types/NotNull.ts",
+    "../phet-core/js/types/WithoutNull.ts",
+    "../phet-core/js/assertHasProperties.ts",
+    "../phet-core/js/types/WithRequired.ts",
+    "../phet-core/js/escapeHTML.ts",
+    "../phet-core/js/extendDefined.ts",
+    "../phet-core/js/mutate.ts",
+    "../phet-core/js/types/PickOptional.ts",
+    "../joist/js/joist.ts",
+    "../axon/js/EnabledComponent.ts",
+    "../utterance-queue/js/SpeechSynthesisParentPolyfill.ts",
+    "../joist/js/i18n/localeProperty.ts",
+    "../utterance-queue/js/SpeechSynthesisAnnouncer.ts",
+    "../dot/js/Permutation.ts",
+    "../axon/js/CallbackTimer.ts",
+    "../axon/js/createObservableArray.ts",
+    "../phet-core/js/types/NotUndefined.ts",
+    "../phet-core/js/types/RequiredOption.ts",
+    "../phetcommon/js/view/ModelViewTransform2.ts",
+    "../phet-core/js/EnumerationMap.ts",
+    "../phet-core/js/OrientationPair.ts",
+    "../dot/js/Vector2Property.ts",
+    "../sherpa/lib/himalaya-1.1.0.js",
+    "../phet-core/js/types/CollapsePropertyValue.ts",
+    "../phet-core/js/types/KeysNotMatching.ts",
+    "../axon/js/DerivedStringProperty.ts",
+    "../axon/js/EnumerationDeprecatedProperty.js",
+    "../axon/js/MappedProperty.ts",
+    "../axon/js/PatternStringProperty.ts",
+    "../axon/js/TinyOverrideProperty.ts",
+    "../axon/js/UnitConversionProperty.ts",
+    "../dot/js/Ray3.ts",
+    "../dot/js/Bounds3.ts",
+    "../dot/js/Combination.ts",
+    "../dot/js/CompletePiecewiseLinearFunction.ts",
+    "../dot/js/ConvexHull2.js",
+    "../dot/js/DampedHarmonic.ts",
+    "../dot/js/DelaunayTriangulation.js",
+    "../dot/js/LinearFunction.ts",
+    "../dot/js/MatrixOps3.js",
+    "../dot/js/Plane3.ts",
+    "../dot/js/Quaternion.js",
+    "../dot/js/Rectangle.js",
+    "../dot/js/Sphere3.js",
+    "../dot/js/Transform4.js",
+    "../dot/js/UnivariatePolynomial.ts",
+    "../phet-core/js/collect.ts",
+    "../phet-core/js/dimensionForEach.ts",
+    "../phet-core/js/dimensionMap.ts",
+    "../phet-core/js/EventTimer.ts",
+    "../phet-core/js/interleave.ts",
+    "../phet-core/js/loadScript.ts",
+    "../phet-core/js/pairs.ts",
+    "../phet-core/js/partition.ts",
+    "../utterance-queue/js/ActivationUtterance.ts",
+    "../utterance-queue/js/ValueChangeUtterance.ts",
+    "../axon/js/main.ts",
+    "../dot/js/main.js",
+    "../kite/js/main.js",
+    "../phet-core/js/main.ts",
+    "../utterance-queue/js/main.ts",
+    "../joist/js/i18n/fallbackLocalesProperty.ts",
+    "../joist/js/i18n/localeOrderProperty.ts",
+    "../chipper/js/chipper.ts",
+    "../chipper/js/LocalizedStringProperty.ts",
+    "../chipper/js/LocalizedString.ts",
+    "../chipper/js/getStringModule.ts",
+    "../scenery-phet/js/sceneryPhet.ts",
+    "../scenery-phet/js/SceneryPhetStrings.ts",
+    "../scenery-phet/js/accessibility/PDOMSectionNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ControlAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/PlayAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ScreenSummaryNode.ts",
+    "../joist/js/JoistStrings.ts",
+    "../joist/js/ScreenIcon.ts",
+    "../joist/js/ScreenView.ts",
+    "../joist/js/TModel.ts",
+    "../sun/js/sun.ts",
+    "../phet-core/js/gracefulBind.ts",
+    "../sun/js/Popupable.ts",
+    "../tambo/js/tambo.ts",
+    "../phet-core/js/asyncLoader.ts",
+    "../tambo/js/base64SoundToByteArray.ts",
+    "../tambo/js/WrappedAudioBuffer.ts",
+    "../tambo/js/phetAudioContext.ts",
+    "../tambo/sounds/emptyApartmentBedroom06Resampled_mp3.js",
+    "../tambo/js/audioContextStateChangeMonitor.ts",
+    "../tambo/js/soundConstants.ts",
+    "../tambo/js/SoundLevelEnum.ts",
+    "../tambo/js/sound-generators/SoundGenerator.ts",
+    "../scenery-phet/js/sceneryPhetQueryParameters.ts",
+    "../tambo/js/SoundUtils.ts",
+    "../tambo/js/sound-generators/SoundClip.ts",
+    "../tambo/sounds/grab_mp3.js",
+    "../tambo/sounds/release_mp3.js",
+    "../phet-core/js/documentation/InstanceRegistry.ts",
+    "../scenery-phet/images/measuringTape_png.ts",
+    "../scenery-phet/js/PhetFont.ts",
+    "../scenery-phet/js/RichKeyboardDragListener.ts",
+    "../scenery-phet/js/RichDragListener.ts",
+    "../tambo/sounds/radioButtonV2_mp3.js",
+    "../tambo/js/TSoundPlayer.ts",
+    "../tambo/js/multiSelectionSoundPlayerFactory.ts",
+    "../sun/js/AquaRadioButton.ts",
+    "../sun/js/GroupItemOptions.ts",
+    "../joist/js/preferences/PreferencesStorage.ts",
+    "../joist/js/i18n/regionAndCultureProperty.ts",
+    "../joist/js/preferences/PreferencesModel.ts",
+    "../joist/js/DynamicStringTest.ts",
+    "../joist/js/HighlightVisibilityController.ts",
+    "../tambo/sounds/checkboxChecked_mp3.js",
+    "../tambo/js/sound-generators/SoundClipPlayer.ts",
+    "../tambo/sounds/checkboxUnchecked_mp3.js",
+    "../sherpa/js/fontawesome-4/checkEmptySolidShape.js",
+    "../sherpa/js/fontawesome-4/checkSquareOSolidShape.js",
+    "../tambo/js/shared-sound-players/checkboxCheckedSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/checkboxUncheckedSoundPlayer.ts",
+    "../tambo/sounds/generalButton_mp3.js",
+    "../sun/js/buttons/ButtonModel.ts",
+    "../sun/js/buttons/ButtonInteractionState.ts",
+    "../sun/js/buttons/PushButtonModel.ts",
+    "../sun/js/buttons/RadioButtonInteractionState.ts",
+    "../sun/js/ColorConstants.ts",
+    "../sun/js/buttons/TButtonAppearanceStrategy.ts",
+    "../sun/js/buttons/TContentAppearanceStrategy.ts",
+    "../sun/js/buttons/ButtonNode.ts",
+    "../tambo/js/shared-sound-players/pushButtonSoundPlayer.ts",
+    "../sun/js/buttons/PushButtonInteractionStateProperty.ts",
+    "../sun/js/buttons/RectangularButton.ts",
+    "../sun/js/ToggleNode.ts",
+    "../tambo/sounds/stepBack_mp3.js",
+    "../tambo/sounds/stepForward_mp3.js",
+    "../sun/js/buttons/ToggleButtonModel.ts",
+    "../tambo/js/shared-sound-players/toggleOffSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/toggleOnSoundPlayer.ts",
+    "../sun/js/buttons/ToggleButtonInteractionStateProperty.ts",
+    "../sun/js/BooleanToggleNode.ts",
+    "../sun/js/buttons/RectangularToggleButton.ts",
+    "../sun/js/buttons/BooleanRectangularToggleButton.ts",
+    "../scenery-phet/js/MeasuringTapeNode.ts",
+    "../sun/js/Panel.ts",
+    "../sun/js/AquaRadioButtonGroup.ts",
+    "../joist/js/SimDisplay.ts",
+    "../sun/js/Checkbox.ts",
+    "../axon/js/EnumerationProperty.ts",
+    "../sun/js/buttons/RectangularPushButton.ts",
+    "../sun/js/ExpandCollapseButton.ts",
+    "../scenery-phet/js/keyboard/KeyNode.ts",
+    "../scenery-phet/js/PlusShape.ts",
+    "../scenery-phet/js/PlusNode.ts",
+    "../scenery-phet/js/keyboard/ArrowKeyNode.ts",
+    "../scenery-phet/js/keyboard/LetterKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSectionRow.ts",
+    "../scenery-phet/js/keyboard/TextKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpIconFactory.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/NumberKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/BasicActionsKeyboardHelpSection.ts",
+    "../tambo/js/sound-generators/MultiClip.ts",
+    "../joist/sounds/screenSelectionHomeV3_mp3.js",
+    "../joist/sounds/switchingScreenSelectorIcons003_mp3.js",
+    "../scenery-phet/js/PhetColorScheme.ts",
+    "../joist/js/Frame.ts",
+    "../joist/js/HomeScreenSoundGenerator.ts",
+    "../joist/js/HomeScreenButton.ts",
+    "../joist/js/HomeScreenKeyboardHelpContent.ts",
+    "../joist/js/HomeScreenModel.ts",
+    "../joist/js/HomeScreenView.ts",
+    "../dot/js/RunningAverage.js",
+    "../tambo/sounds/generalClose_mp3.js",
+    "../tambo/sounds/generalOpen_mp3.js",
+    "../phet-core/js/getGlobal.ts",
+    "../scenery-phet/js/buttons/CloseButton.ts",
+    "../tambo/js/shared-sound-players/generalCloseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalOpenSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/nullSoundPlayer.ts",
+    "../sun/js/SunStrings.ts",
+    "../joist/js/HighlightNode.ts",
+    "../sun/js/Dialog.ts",
+    "../joist/images/keyboardIconOnWhite_png.ts",
+    "../joist/images/keyboardIcon_png.ts",
+    "../joist/js/JoistButton.ts",
+    "../joist/js/KeyboardHelpDialog.ts",
+    "../tambo/sounds/switchToLeft_mp3.js",
+    "../tambo/sounds/switchToRight_mp3.js",
+    "../tambo/js/shared-sound-players/switchToLeftSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/switchToRightSoundPlayer.ts",
+    "../sun/js/ToggleSwitch.ts",
+    "../joist/js/preferences/PreferencesPanelSection.ts",
+    "../joist/js/preferences/PreferencesDialogConstants.ts",
+    "../tambo/sounds/generalBoundaryBoop_mp3.js",
+    "../tambo/sounds/generalSoftClick_mp3.js",
+    "../tambo/js/shared-sound-players/generalBoundaryBoopSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalSoftClickSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleValueHandler.ts",
+    "../sun/js/SliderTrack.ts",
+    "../sun/js/SunConstants.ts",
+    "../phet-core/js/swapObjectKeys.ts",
+    "../tambo/js/sound-generators/ValueChangeSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleSlider.ts",
+    "../sun/js/DefaultSliderTrack.ts",
+    "../sun/js/SliderThumb.ts",
+    "../sun/js/SliderTick.ts",
+    "../sun/js/Slider.ts",
+    "../scenery-phet/js/MathSymbols.ts",
+    "../sun/js/buttons/ArrowButton.ts",
+    "../sun/js/HSlider.ts",
+    "../scenery-phet/js/NumberDisplay.ts",
+    "../sun/js/ComboBoxListItemNode.ts",
+    "../sun/js/ComboBoxButton.ts",
+    "../sun/js/ComboBoxListBox.ts",
+    "../scenery-phet/js/NumberControl.ts",
+    "../sun/js/ComboBox.ts",
+    "../joist/js/preferences/PreferencesType.ts",
+    "../joist/js/preferences/PreferencesControl.ts",
+    "../joist/js/preferences/SoundPanelSection.ts",
+    "../joist/js/preferences/VoicingPanelSection.ts",
+    "../joist/js/preferences/PreferencesPanel.ts",
+    "../joist/js/preferences/ProjectorModeToggleSwitch.ts",
+    "../joist/js/preferences/LanguageSelectionNode.ts",
+    "../joist/js/preferences/RegionAndCultureComboBox.ts",
+    "../joist/js/preferences/LocalePanel.ts",
+    "../joist/js/i18n/isLeftToRightProperty.ts",
+    "../sherpa/js/fontawesome-5/globeSolidString.js",
+    "../sherpa/js/fontawesome-5/globeSolidShape.js",
+    "../joist/js/preferences/PreferencesTab.ts",
+    "../joist/js/preferences/AudioPreferencesPanel.ts",
+    "../joist/js/preferences/SimulationPreferencesPanel.ts",
+    "../joist/js/preferences/InputPreferencesPanel.ts",
+    "../joist/js/preferences/VisualPreferencesPanel.ts",
+    "../joist/js/preferences/LocalizationPreferencesPanel.ts",
+    "../joist/js/preferences/OverviewPreferencesPanel.ts",
+    "../joist/js/preferences/PreferencesTabs.ts",
+    "../joist/sounds/cardFlip_mp3.js",
+    "../joist/js/preferences/PreferencesPanels.ts",
+    "../joist/js/preferences/PreferencesTabSwitchSoundGenerator.ts",
+    "../joist/images/preferencesIconOnWhite_png.ts",
+    "../joist/images/preferencesIcon_png.ts",
+    "../joist/js/preferences/PreferencesDialog.ts",
+    "../joist/js/KeyboardHelpButton.ts",
+    "../joist/js/NavigationBarAudioToggleButton.ts",
+    "../joist/js/preferences/NavigationBarPreferencesButton.ts",
+    "../sherpa/js/fontawesome-5/homeSolidString.js",
+    "../sherpa/js/fontawesome-5/homeSolidShape.js",
+    "../brand/js/brand.ts",
+    "../brand/js/getLinks.ts",
+    "../sherpa/js/fontawesome-5/checkSolidString.js",
+    "../sherpa/js/fontawesome-5/checkSolidShape.js",
+    "../joist/js/UpdateState.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidString.js",
+    "../scenery-phet/js/SpinningIndicatorNode.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidShape.js",
+    "../sun/js/buttons/TextPushButton.ts",
+    "../joist/js/UpdateDialog.ts",
+    "../joist/js/CreditsNode.ts",
+    "../joist/js/updateCheck.ts",
+    "../joist/js/UpdateNodes.ts",
+    "../sun/js/MenuItem.ts",
+    "../joist/js/AboutDialog.ts",
+    "../joist/js/ScreenshotGenerator.ts",
+    "../brand/js/TBrand.ts",
+    "../joist/js/KebabMenuIcon.ts",
+    "../joist/js/PhetMenu.ts",
+    "../joist/js/A11yButtonsHBox.ts",
+    "../joist/js/HomeButton.ts",
+    "../joist/js/NavigationBarScreenButton.ts",
+    "../joist/js/PhetButton.ts",
+    "../scenery-phet/images/phetGirlWaggingFinger_png.ts",
+    "../scenery-phet/js/OopsDialog.ts",
+    "../joist/sounds/screenSelection_mp3.js",
+    "../sun/js/buttons/RoundButton.ts",
+    "../sun/js/buttons/RoundToggleButton.ts",
+    "../tambo/sounds/pause_mp3.js",
+    "../tambo/sounds/playPause_mp3.js",
+    "../sun/js/buttons/BooleanRoundToggleButton.ts",
+    "../tambo/js/shared-sound-players/pauseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/playSoundPlayer.ts",
+    "../scenery-phet/js/PlayIconShape.ts",
+    "../scenery-phet/js/SceneryPhetConstants.ts",
+    "../scenery-phet/js/StopIconShape.ts",
+    "../scenery-phet/js/buttons/PlayControlButton.ts",
+    "../scenery-phet/js/buttons/PlayStopButton.ts",
+    "../sun/js/buttons/RoundPushButton.ts",
+    "../joist/js/toolbar/VoicingToolbarAlertManager.ts",
+    "../joist/js/toolbar/VoicingToolbarItem.ts",
+    "../scenery-phet/js/BarrierRectangle.ts",
+    "../sherpa/lib/game-up-camera-1.0.0.js",
+    "../tambo/js/soundManager.ts",
+    "../joist/js/audioManager.ts",
+    "../joist/js/Heartbeat.ts",
+    "../joist/js/Helper.ts",
+    "../joist/js/HomeScreen.ts",
+    "../joist/js/LookAndFeel.ts",
+    "../joist/js/MemoryMonitor.ts",
+    "../joist/js/NavigationBar.ts",
+    "../joist/js/Profiler.ts",
+    "../joist/js/QueryParametersWarningDialog.ts",
+    "../joist/js/ScreenSelectionSoundGenerator.ts",
+    "../joist/js/selectScreens.ts",
+    "../joist/js/thirdPartySupport/LegendsOfLearningSupport.ts",
+    "../joist/js/toolbar/Toolbar.ts",
+    "../joist/js/Screen.ts",
+    "../joist/js/Sim.ts",
+    "../phet-io/js/phetio.ts",
+    "../phet-io/js/PhetioStateEngine.ts",
+    "../joist/js/packageJSON.ts",
+    "../joist/js/SimInfo.ts",
+    "../phet-io/js/dataStream.ts",
+    "../phet-io/js/phetioCommandProcessor.ts",
+    "../phet-io/js/phetioDevSaveLoad.ts",
+    "../phet-core/js/gracefulBind.js",
+    "../sun/js/Popupable.js"
   ]
 }
\ No newline at end of file
Index: scenery/js/util/SpriteImage.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/util/SpriteImage.ts b/scenery/js/util/SpriteImage.ts
--- a/scenery/js/util/SpriteImage.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/util/SpriteImage.ts	(date 1714196530315)
@@ -68,6 +68,8 @@
       this.imageProperty = image;
     }
     else {
+
+      // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
       this.image = image;
     }
 
@@ -121,6 +123,8 @@
    */
   private ensureImageData(): void {
     if ( !this.imageData && this.width && this.height ) {
+
+      // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
       this.imageData = Imageable.getHitTestData( this.image, this.width, this.height );
     }
   }
Index: tandem/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tandem/tsconfig.json b/tandem/tsconfig.json
--- a/tandem/tsconfig.json	(revision 3e9ee585f4413cdf40e991b52191c1e7552720b0)
+++ b/tandem/tsconfig.json	(date 1714181663090)
@@ -4,6 +4,7 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../phet-core/js/arrayRemove.ts"
   ]
 }
\ No newline at end of file
Index: scenery/js/layout/constraints/FlowCell.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/FlowCell.ts b/scenery/js/layout/constraints/FlowCell.ts
--- a/scenery/js/layout/constraints/FlowCell.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/layout/constraints/FlowCell.ts	(date 1714196545865)
@@ -34,6 +34,8 @@
   private readonly flowConstraint: FlowConstraint;
 
   public constructor( constraint: FlowConstraint, node: Node, proxy: LayoutProxy | null ) {
+
+    // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
     super( constraint, node, proxy );
 
     this.flowConstraint = constraint;
Index: sherpa/lib/big-6.2.1.mjs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sherpa/lib/big-6.2.1.mjs b/sherpa/lib/big-6.2.1.mjs
--- a/sherpa/lib/big-6.2.1.mjs	(revision 3cc0c9fcea140cae57994a1ba11d951c8518d65d)
+++ b/sherpa/lib/big-6.2.1.mjs	(date 1714182117761)
@@ -15,7 +15,7 @@
    * The maximum number of decimal places (DP) of the results of operations involving division:
    * div and sqrt, and pow with negative exponents.
    */
-var DP = 20,          // 0 to MAX_DP
+const DP = 20,          // 0 to MAX_DP
 
   /*
    * The rounding mode (RM) used when rounding to the above decimal places.
Index: scenery/js/layout/constraints/MarginLayoutConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/MarginLayoutConfigurable.ts b/scenery/js/layout/constraints/MarginLayoutConfigurable.ts
--- a/scenery/js/layout/constraints/MarginLayoutConfigurable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/layout/constraints/MarginLayoutConfigurable.ts	(date 1714195531424)
@@ -378,5 +378,24 @@
 } );
 
 scenery.register( 'MarginLayoutConfigurable', MarginLayoutConfigurable );
-export default MarginLayoutConfigurable;
+
+export type TMarginLayoutConfigurable = {
+  changedEmitter: TEmitter;
+  margin: number | null;
+  xMargin: number | null;
+  yMargin: number | null;
+  leftMargin: number | null;
+  rightMargin: number | null;
+  topMargin: number | null;
+  bottomMargin: number | null;
+  minContentWidth: number | null;
+  minContentHeight: number | null;
+  maxContentWidth: number | null;
+  maxContentHeight: number | null;
+  setConfigToBaseDefault(): void;
+  setConfigToInherit(): void;
+  mutateConfigurable( options?: MarginLayoutConfigurableOptions ): void;
+};
+
+export default MarginLayoutConfigurable as unknown as <SuperType extends Constructor>( type: SuperType ) => SuperType & Constructor<TMarginLayoutConfigurable>;
 export { MARGIN_LAYOUT_CONFIGURABLE_OPTION_KEYS };
\ No newline at end of file
Index: tandem/js/Tandem.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tandem/js/Tandem.ts b/tandem/js/Tandem.ts
--- a/tandem/js/Tandem.ts	(revision 3e9ee585f4413cdf40e991b52191c1e7552720b0)
+++ b/tandem/js/Tandem.ts	(date 1714181966957)
@@ -487,7 +487,7 @@
   /**
    * The root tandem for a simulation
    */
-  public static readonly ROOT = new Tandem.RootTandem( null, _.camelCase( packageJSON.name ) );
+  public static readonly ROOT: Tandem = new Tandem.RootTandem( null, _.camelCase( packageJSON.name ) );
 
   /**
    * Many simulation elements are nested under "general". This tandem is for elements that exists in all sims. For a
Index: scenery/js/layout/constraints/GridCell.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/GridCell.ts b/scenery/js/layout/constraints/GridCell.ts
--- a/scenery/js/layout/constraints/GridCell.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/layout/constraints/GridCell.ts	(date 1714196555378)
@@ -49,6 +49,7 @@
    */
   public constructor( constraint: GridConstraint, node: Node, proxy: LayoutProxy | null ) {
 
+    // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
     super( constraint, node, proxy );
 
     this.gridConstraint = constraint;
Index: sun/js/accessibility/AccessibleValueHandler.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleValueHandler.ts b/sun/js/accessibility/AccessibleValueHandler.ts
--- a/sun/js/accessibility/AccessibleValueHandler.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleValueHandler.ts	(date 1714195888024)
@@ -20,7 +20,7 @@
 import Range from '../../../dot/js/Range.js';
 import assertHasProperties from '../../../phet-core/js/assertHasProperties.js';
 import Orientation from '../../../phet-core/js/Orientation.js';
-import { animatedPanZoomSingleton, DelayedMutate, KeyboardUtils, Node, NodeOptions, PDOMPointer, PDOMUtils, PDOMValueType, SceneryEvent, SceneryListenerFunction, TInputListener, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
+import { TVoicing, animatedPanZoomSingleton, DelayedMutate, KeyboardUtils, Node, NodeOptions, PDOMPointer, PDOMUtils, PDOMValueType, SceneryEvent, SceneryListenerFunction, TInputListener, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
 import Utterance from '../../../utterance-queue/js/Utterance.js';
 import sun from '../sun.js';
 import optionize, { combineOptions } from '../../../phet-core/js/optionize.js';
@@ -1261,6 +1261,18 @@
   return correctedValue;
 };
 
+export type TAccessibleValueHandler = {
+  voicingOnEndResponse( valueOnStart: number, providedOptions?: VoicingOnEndResponseOptions ): void;
+
+  set startInput( value: SceneryListenerFunction );
+  get startInput(): SceneryListenerFunction;
+  set onInput( value: SceneryListenerFunction );
+  get onInput(): SceneryListenerFunction;
+  set endInput( value: ( ( event: SceneryEvent | null ) => void ) );
+  get endInput(): SceneryListenerFunction;
+  getAccessibleValueHandlerInputListener(): TInputListener;
+} & TVoicing;
+
 AccessibleValueHandler.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;
 
-export default AccessibleValueHandler;
\ No newline at end of file
+export default AccessibleValueHandler as unknown as <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TAccessibleValueHandler>;
\ No newline at end of file
Index: dot/js/Utils.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/dot/js/Utils.js b/dot/js/Utils.js
--- a/dot/js/Utils.js	(revision aef01d114353684eb9678b4cab9c13ca1a9faa99)
+++ b/dot/js/Utils.js	(date 1714182436504)
@@ -6,7 +6,7 @@
  * @author Jonathan Olson <jonathan.olson@colorado.edu>
  */
 
-import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
+// import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
 import dot from './dot.js';
 import Vector2 from './Vector2.js';
 import Vector3 from './Vector3.js';
@@ -565,7 +565,7 @@
     }
 
     // eslint-disable-next-line bad-sim-text
-    const result = new Big( value ).toFixed( decimalPlaces );
+    const result = value.toFixed( decimalPlaces ); // TODO: https://github.com/phetsims/tasks/issues/1132
 
     // Avoid reporting -0.000
     if ( result.startsWith( '-0.' ) && Number.parseFloat( result ) === 0 ) {
Index: sun/js/accessibility/AccessibleSlider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleSlider.ts b/sun/js/accessibility/AccessibleSlider.ts
--- a/sun/js/accessibility/AccessibleSlider.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleSlider.ts	(date 1714193821915)
@@ -18,7 +18,7 @@
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 import { DelayedMutate, Node, SceneryEvent } from '../../../scenery/js/imports.js';
 import sun from '../sun.js';
-import AccessibleValueHandler, { AccessibleValueHandlerOptions } from './AccessibleValueHandler.js';
+import AccessibleValueHandler, { AccessibleValueHandlerOptions, TAccessibleValueHandler } from './AccessibleValueHandler.js';
 
 const ACCESSIBLE_SLIDER_OPTIONS = [
   'startDrag',
@@ -140,5 +140,18 @@
 
 sun.register( 'AccessibleSlider', AccessibleSlider );
 
-export default AccessibleSlider;
+type TAccessibleSlider = {
+
+  // TODO: These may not be needed
+  set startDrag( value: ( event: SceneryEvent ) => void );
+  get startDrag(): ( event: SceneryEvent ) => void;
+
+  set drag( value: ( event: SceneryEvent ) => void );
+  get drag(): ( event: SceneryEvent ) => void;
+
+  set endDrag( value: ( event: SceneryEvent | null ) => void );
+  get endDrag(): ( event: SceneryEvent | null ) => void;
+} & TAccessibleValueHandler;
+
+export default AccessibleSlider as unknown as <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TAccessibleSlider>;
 export type { AccessibleSliderOptions };
\ No newline at end of file
Index: scenery/js/nodes/Leaf.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/nodes/Leaf.ts b/scenery/js/nodes/Leaf.ts
--- a/scenery/js/nodes/Leaf.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/nodes/Leaf.ts	(date 1714186418019)
@@ -30,4 +30,4 @@
 
 scenery.register( 'Leaf', Leaf );
 
-export default Leaf;
\ No newline at end of file
+export default Leaf as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType;
\ No newline at end of file
Index: phet-core/js/EventTimer.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-core/js/EventTimer.ts b/phet-core/js/EventTimer.ts
--- a/phet-core/js/EventTimer.ts	(revision 3716619771c5b9b30210c144e555ad16acf40f65)
+++ b/phet-core/js/EventTimer.ts	(date 1714181616683)
@@ -76,8 +76,9 @@
  */
 
 import phetCore from './phetCore.js';
+import IntentionalAny from './types/IntentionalAny.js';
 
-export default class EventTimer {
+class EventTimer {
 
   private period: number;
   private timeBeforeNextEvent: number;
@@ -140,7 +141,7 @@
   };
 
   public static readonly UniformEventModel = class UniformEventModel {
-    
+
     /*
      * Event model that will fire events averaging a certain rate, but with the time between events being uniformly
      * random.
@@ -189,4 +190,6 @@
   };
 }
 
+export default EventTimer as IntentionalAny;
+
 phetCore.register( 'EventTimer', EventTimer );
\ No newline at end of file
Index: joist/js/HomeScreenView.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/HomeScreenView.ts b/joist/js/HomeScreenView.ts
--- a/joist/js/HomeScreenView.ts	(revision b94d701c92cab77cd4cf554f333a7e0701c5b01b)
+++ b/joist/js/HomeScreenView.ts	(date 1714196588995)
@@ -11,7 +11,6 @@
 import PhetFont from '../../scenery-phet/js/PhetFont.js';
 import { AlignBox, HBox, Node, Text } from '../../scenery/js/imports.js';
 import soundManager from '../../tambo/js/soundManager.js';
-import HomeScreenButton from './HomeScreenButton.js';
 import HomeScreenSoundGenerator from './HomeScreenSoundGenerator.js';
 import joist from './joist.js';
 import JoistStrings from './JoistStrings.js';
@@ -24,6 +23,7 @@
 import PickRequired from '../../phet-core/js/types/PickRequired.js';
 import PatternStringProperty from '../../axon/js/PatternStringProperty.js';
 import Tandem from '../../tandem/js/Tandem.js';
+import HomeScreenButton from './HomeScreenButton.js';
 
 type SelfOptions = {
 
Index: joist/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/tsconfig.json b/joist/tsconfig.json
--- a/joist/tsconfig.json	(revision b94d701c92cab77cd4cf554f333a7e0701c5b01b)
+++ b/joist/tsconfig.json	(date 1714185109799)
@@ -4,6 +4,11 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+
+    "../scenery-phet/js/PhetColorScheme.ts",
+    "../scenery-phet/js/**/*",
+    "../axon/js/**/*",
+    "../sun/js/**/*"
   ]
 }
\ No newline at end of file
Index: sun/js/Popupable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/Popupable.ts b/sun/js/Popupable.ts
--- a/sun/js/Popupable.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/Popupable.ts	(date 1714196026635)
@@ -13,12 +13,12 @@
 import Property from '../../axon/js/Property.js';
 import Bounds2 from '../../dot/js/Bounds2.js';
 import ScreenView from '../../joist/js/ScreenView.js';
-import gracefulBind from '../../phet-core/js/gracefulBind.js';
 import optionize from '../../phet-core/js/optionize.js';
 import Constructor from '../../phet-core/js/types/Constructor.js';
 import PickOptional from '../../phet-core/js/types/PickOptional.js';
 import { FocusManager, Node, NodeOptions } from '../../scenery/js/imports.js';
 import sun from './sun.js';
+import gracefulBind from '../../phet-core/js/gracefulBind.js';
 
 type SelfOptions = {
 
@@ -46,7 +46,7 @@
 type ParentOptions = PickOptional<NodeOptions, 'tandem'>;
 export type PopupableOptions = SelfOptions & ParentOptions;
 
-const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => {
 
   return class extends type {
 
@@ -168,7 +168,7 @@
       }
     }
 
-    protected get focusOnHideNode(): Node | null {
+    public get focusOnHideNode(): Node | null {
       return this._focusOnHideNode;
     }
 
@@ -212,10 +212,18 @@
   }
 }
 
-// Export a type that lets you check if your Node is composed with Popupable
-const wrapper = () => Popupable( Node, 0 );
-export type PopupableNode = InstanceType<ReturnType<typeof wrapper>> & Node;
+type TPopupable = {
+  show(): void;
+  hide(): void;
+  shouldShowPopup(): boolean;
+  isShowingProperty: Property<boolean>;
+  get focusOnHideNode(): Node | null; // treat as protected
+  layout( bounds: Bounds2 ): void;
+  layoutBounds: Bounds2 | null;
+};
+
+export type PopupableNode = Node & TPopupable
 
 sun.register( 'Popupable', Popupable );
 
-export default Popupable;
\ No newline at end of file
+export default Popupable as unknown as <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TPopupable>;
\ No newline at end of file
Index: dot/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/dot/tsconfig.json b/dot/tsconfig.json
--- a/dot/tsconfig.json	(revision aef01d114353684eb9678b4cab9c13ca1a9faa99)
+++ b/dot/tsconfig.json	(date 1714182298706)
@@ -4,6 +4,7 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../sherpa/lib/big-6.2.1.mjs"
   ]
 }
\ No newline at end of file
Index: scenery/js/layout/Sizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/Sizable.ts b/scenery/js/layout/Sizable.ts
--- a/scenery/js/layout/Sizable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/layout/Sizable.ts	(date 1714195570999)
@@ -13,6 +13,8 @@
 import Dimension2 from '../../../dot/js/Dimension2.js';
 import assertMutuallyExclusiveOptions from '../../../phet-core/js/assertMutuallyExclusiveOptions.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
+import { TWidthSizable } from './WidthSizable.js';
+import { THeightSizable } from './HeightSizable.js';
 
 export const SIZABLE_SELF_OPTION_KEYS = [
   'preferredSize',
@@ -187,7 +189,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalPreferredWidth(): number | null {
+    public override _calculateLocalPreferredWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.preferredWidth !== null ) {
@@ -204,7 +206,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalPreferredHeight(): number | null {
+    public override _calculateLocalPreferredHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.preferredHeight !== null ) {
@@ -221,7 +223,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculatePreferredWidth(): number | null {
+    public override _calculatePreferredWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localPreferredWidth !== null ) {
@@ -237,7 +239,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculatePreferredHeight(): number | null {
+    public override _calculatePreferredHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localPreferredHeight !== null ) {
@@ -253,31 +255,31 @@
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantLocalMinimumWidth(): void {
+    public override _onReentrantLocalMinimumWidth(): void {
       this._updateMinimumWidthListener();
       this._updateMinimumHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantLocalMinimumHeight(): void {
+    public override _onReentrantLocalMinimumHeight(): void {
       this._updateMinimumWidthListener();
       this._updateMinimumHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantPreferredWidth(): void {
+    public override _onReentrantPreferredWidth(): void {
       this._updateLocalPreferredWidthListener();
       this._updateLocalPreferredHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantPreferredHeight(): void {
+    public override _onReentrantPreferredHeight(): void {
       this._updateLocalPreferredWidthListener();
       this._updateLocalPreferredHeightListener();
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalMinimumWidth(): number | null {
+    public override _calculateLocalMinimumWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.minimumWidth !== null ) {
@@ -293,7 +295,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalMinimumHeight(): number | null {
+    public override _calculateLocalMinimumHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.minimumHeight !== null ) {
@@ -309,7 +311,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateMinimumWidth(): number | null {
+    public override _calculateMinimumWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localMinimumWidth !== null ) {
@@ -325,7 +327,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateMinimumHeight(): number | null {
+    public override _calculateMinimumHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localMinimumHeight !== null ) {
@@ -356,12 +358,6 @@
   return SizableTrait;
 } );
 
-// Some typescript gymnastics to provide a user-defined type guard that treats something as Sizable
-// We need to define an unused function with a concrete type, so that we can extract the return type of the function
-// and provide a type for a Node that extends this type.
-const wrapper = () => Sizable( Node );
-export type SizableNode = InstanceType<ReturnType<typeof wrapper>>;
-
 const isSizable = ( node: Node ): node is SizableNode => {
   return node.widthSizable && node.heightSizable;
 };
@@ -369,6 +365,12 @@
   return node.extendsSizable;
 };
 
+type TSizable = TWidthSizable & THeightSizable & {
+  validateLocalPreferredSize(): void;
+};
+
+export type SizableNode = Node & TSizable;
+
 scenery.register( 'Sizable', Sizable );
-export default Sizable;
+export default Sizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TSizable>;
 export { isSizable, extendsSizable };
\ No newline at end of file
Index: scenery/js/accessibility/voicing/ReadingBlock.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/ReadingBlock.ts b/scenery/js/accessibility/voicing/ReadingBlock.ts
--- a/scenery/js/accessibility/voicing/ReadingBlock.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/accessibility/voicing/ReadingBlock.ts	(date 1714195852172)
@@ -30,6 +30,7 @@
 import Utterance from '../../../../utterance-queue/js/Utterance.js';
 import TEmitter from '../../../../axon/js/TEmitter.js';
 import memoize from '../../../../phet-core/js/memoize.js';
+import { TVoicing } from './Voicing.js';
 
 const READING_BLOCK_OPTION_KEYS = [
   'readingBlockTagName',
@@ -382,8 +383,9 @@
 
     /**
      * If we created and own the voicingUtterance we can fully dispose of it.
+     * Must be public due to the mixin pattern.
      */
-    protected override cleanVoicingUtterance(): void {
+    public override cleanVoicingUtterance(): void {
       if ( this._voicingUtterance instanceof OwnedReadingBlockUtterance ) {
         this._voicingUtterance.dispose();
       }
@@ -423,8 +425,21 @@
 } );
 
 // Export a type that lets you check if your Node is composed with ReadingBlock
-const wrapper = () => ReadingBlock( Node );
-export type ReadingBlockNode = InstanceType<ReturnType<typeof wrapper>>;
+// const wrapper = () => ReadingBlock( Node );
+
+
+type TReadingBlock = {
+  readingBlockActiveHighlightChangedEmitter: TEmitter;
+  isReadingBlock: true;
+  readingBlockActiveHighlight: Highlight;
+  readingBlockActivated: boolean;
+
+  set readingBlockNameResponse( content: VoicingResponse );
+  get readingBlockNameResponse(): ResolvedResponse;
+  setReadingBlockNameResponse( content: VoicingResponse ): void;
+} & TVoicing;
+
+export type ReadingBlockNode = Node & TReadingBlock;
 
 scenery.register( 'ReadingBlock', ReadingBlock );
-export default ReadingBlock;
\ No newline at end of file
+export default ReadingBlock as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TReadingBlock>;
\ No newline at end of file
Index: scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/Voicing.ts b/scenery/js/accessibility/voicing/Voicing.ts
--- a/scenery/js/accessibility/voicing/Voicing.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/accessibility/voicing/Voicing.ts	(date 1714196513556)
@@ -28,13 +28,14 @@
 import ResponsePacket, { ResolvedResponse, SpeakableResolvedOptions, VoicingResponse } from '../../../../utterance-queue/js/ResponsePacket.js';
 import ResponsePatternCollection from '../../../../utterance-queue/js/ResponsePatternCollection.js';
 import Utterance, { TAlertable, UtteranceOptions } from '../../../../utterance-queue/js/Utterance.js';
-import { DelayedMutate, Instance, InteractiveHighlighting, InteractiveHighlightingOptions, Node, scenery, SceneryListenerFunction, voicingUtteranceQueue } from '../../imports.js';
+import { DelayedMutate, Instance, InteractiveHighlighting, InteractiveHighlightingOptions, Node, ReadingBlockUtterance, scenery, SceneryListenerFunction, voicingUtteranceQueue } from '../../imports.js';
 import { combineOptions } from '../../../../phet-core/js/optionize.js';
 import Constructor from '../../../../phet-core/js/types/Constructor.js';
 import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 import responseCollector from '../../../../utterance-queue/js/responseCollector.js';
 import TinyProperty from '../../../../axon/js/TinyProperty.js';
 import Tandem from '../../../../tandem/js/Tandem.js';
+import { TInteractiveHighlighting } from './InteractiveHighlighting.js';
 
 // Helps enforce that the utterance is defined.
 function assertUtterance( utterance: Utterance | null ): asserts utterance is Utterance {
@@ -98,14 +99,14 @@
   utterance?: SelfOptions['voicingUtterance'];
 } & SpeakableResolvedOptions;
 
-const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => {
 
   assert && assert( _.includes( inheritance( Type ), Node ), 'Only Node subtypes should compose Voicing' );
 
   const VoicingClass = DelayedMutate( 'Voicing', VOICING_OPTION_KEYS, class VoicingClass extends InteractiveHighlighting( Type ) {
 
     // ResponsePacket that holds all the supported responses to be Voiced
-    protected _voicingResponsePacket!: ResponsePacket;
+    public _voicingResponsePacket!: ResponsePacket;
 
     // The utterance that all responses are spoken through.
     protected _voicingUtterance: Utterance | null;
@@ -332,7 +333,7 @@
      * Use the provided function to create content to speak in response to input. The content is then added to the
      * back of the voicing UtteranceQueue.
      */
-    protected speakContent( content: TAlertable ): void {
+    public speakContent( content: TAlertable ): void {
 
       const notPhetioArchetype = !Tandem.PHET_IO_ENABLED || !this.isInsidePhetioArchetype();
 
@@ -475,6 +476,7 @@
           this.cleanVoicingUtterance();
         }
 
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         Voicing.registerUtteranceToVoicingNode( utterance, this );
         this._voicingUtterance = utterance;
       }
@@ -626,6 +628,8 @@
         this._voicingUtterance.dispose();
       }
       else if ( this._voicingUtterance && !this._voicingUtterance.isDisposed ) {
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         Voicing.unregisterUtteranceToVoicingNode( this._voicingUtterance, this );
       }
     }
@@ -667,10 +671,9 @@
  * if the voicingNode is globally visible and voicingVisible in the display.
  * @static
  */
-Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
+Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: TVoicing ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
 
-  // @ts-expect-error Accessing a private member because this is meant to be "private to the file".
   const voicingCanSpeakProperty = voicingNode._voicingCanSpeakProperty;
   if ( !existingCanAnnounceProperties.includes( voicingCanSpeakProperty ) ) {
     utterance.voicingCanAnnounceProperties = existingCanAnnounceProperties.concat( [ voicingCanSpeakProperty ] );
@@ -684,7 +687,6 @@
 Voicing.unregisterUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
 
-  // @ts-expect-error Accessing a private member because this is meant to be "private to the file".
   const voicingCanSpeakProperty = voicingNode._voicingCanSpeakProperty;
   const index = existingCanAnnounceProperties.indexOf( voicingCanSpeakProperty );
   assert && assert( index > -1, 'voicingNode.voicingCanSpeakProperty is not on the Utterance, was it not registered?' );
@@ -726,9 +728,49 @@
   utterance.voicingCanAnnounceProperties = withoutBothProperties;
 };
 
-// Export a type that lets you check if your Node is composed with Voicing.
-const wrapper = () => Voicing( Node );
-export type VoicingNode = InstanceType<ReturnType<typeof wrapper>>;
+export type TVoicing = {
+  _voicingResponsePacket: ResponsePacket;
+  setVoicingUtterance( utterance: ReadingBlockUtterance ): void;
+  set voicingUtterance( utterance: ReadingBlockUtterance );
+  get voicingUtterance(): ReadingBlockUtterance;
+  getVoicingUtterance(): ReadingBlockUtterance;
+  setVoicingNameResponse(): void;
+  getVoicingNameResponse(): IntentionalAny;
+  setVoicingObjectResponse(): void;
+  getVoicingObjectResponse(): IntentionalAny;
+  setVoicingContextResponse(): void;
+  getVoicingContextResponse(): IntentionalAny;
+  setVoicingHintResponse(): void;
+  getVoicingHintResponse(): IntentionalAny;
+  setVoicingResponsePatternCollection(): void;
+  getVoicingResponsePatternCollection(): IntentionalAny;
+
+  cleanVoicingUtterance(): void;
+  _voicingUtterance: ReadingBlockUtterance;
+
+  collectResponse( providedOptions?: SpeakingOptions ): TAlertable;
+
+  voicingIgnoreVoicingManagerProperties: boolean;
+  voicingNameResponse: ResolvedResponse;
+  voicingSpeakResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingSpeakFullResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingSpeakContextResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingObjectResponse: ResolvedResponse;
+  voicingFocusListener: SceneryListenerFunction<FocusEvent> | null;
+  voicingHintResponse: ResolvedResponse;
+  voicingContextResponse: ResolvedResponse;
+  voicingSpeakNameResponse: ( providedOptions?: SpeakingOptions ) => void;
+
+  _voicingCanSpeakProperty: TinyProperty<boolean>;
+
+  speakContent( content: TAlertable ): void;
+
+  defaultFocusListener(): void;
+  initialize( ...args: IntentionalAny[] ): ThisType<IntentionalAny>;
+
+} & TInteractiveHighlighting;
+
+export type VoicingNode = Node & TVoicing;
 
 scenery.register( 'Voicing', Voicing );
-export default Voicing;
\ No newline at end of file
+export default Voicing as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TVoicing>;
\ No newline at end of file
Index: scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1714195102740)
@@ -647,9 +647,21 @@
   return InteractiveHighlightingClass;
 } );
 
-// Provides a way to determine if a Node is composed with InteractiveHighlighting by type
-const wrapper = () => InteractiveHighlighting( Node );
-export type InteractiveHighlightingNode = InstanceType<ReturnType<typeof wrapper>>;
+export type TInteractiveHighlighting = {
+  isInteractiveHighlightActiveProperty: TReadOnlyProperty<boolean>;
+  interactiveHighlightEnabled: boolean;
+  isInteractiveHighlighting: boolean;
+  interactiveHighlightChangedEmitter: TEmitter;
+  handleHighlightActiveChange(): void;
+
+  // we wish these was public, but they are used elsewhere and appears in the mixin, so must be public.
+  displays: Record<string, Display>;
+  getDescendantsUseHighlighting( trail: Trail ): boolean;
+  interactiveHighlightLayerable: boolean;
+  interactiveHighlight: Highlight;
+};
+
+export type InteractiveHighlightingNode = Node & TInteractiveHighlighting;
 
 scenery.register( 'InteractiveHighlighting', InteractiveHighlighting );
-export default InteractiveHighlighting;
\ No newline at end of file
+export default InteractiveHighlighting as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TInteractiveHighlighting>;
\ No newline at end of file
Index: scenery/js/layout/HeightSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/HeightSizable.ts b/scenery/js/layout/HeightSizable.ts
--- a/scenery/js/layout/HeightSizable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/layout/HeightSizable.ts	(date 1714194853971)
@@ -370,8 +370,38 @@
 // Some typescript gymnastics to provide a user-defined type guard that treats something as HeightSizable.
 // We need to define an unused function with a concrete type, so that we can extract the return type of the function
 // and provide a type for a Node that extends this type.
-const wrapper = () => HeightSizable( Node );
-export type HeightSizableNode = InstanceType<ReturnType<typeof wrapper>>;
+// const wrapper = () => HeightSizable( Node );
+
+export type THeightSizable = {
+  readonly preferredHeightProperty: TinyProperty<number | null>;
+  readonly minimumHeightProperty: TinyProperty<number | null>;
+  readonly localPreferredHeightProperty: TinyProperty<number | null>;
+  readonly localMinimumHeightProperty: TinyProperty<number | null>;
+  readonly isHeightResizableProperty: TinyProperty<boolean>;
+
+  preferredHeight: number | null;
+  minimumHeight: number | null;
+  localPreferredHeight: number | null;
+  localMinimumHeight: number | null;
+
+  _updateLocalPreferredHeightListener: () => void;
+  _updatePreferredHeightListener: () => void;
+  _updateLocalMinimumHeightListener: () => void;
+  _updateMinimumHeightListener: () => void;
+
+  validateLocalPreferredHeight(): void;
+
+  _calculateLocalPreferredHeight(): number | null;
+  _calculatePreferredHeight(): number | null;
+  _onReentrantLocalMinimumHeight(): void;
+  _onReentrantPreferredHeight(): void;
+  _calculateLocalMinimumHeight(): number | null;
+  _calculateMinimumHeight(): number | null;
+
+  set heightSizable( value: boolean );
+};
+
+export type HeightSizableNode = Node & THeightSizable;
 
 const isHeightSizable = ( node: Node ): node is HeightSizableNode => {
   return node.heightSizable;
@@ -381,5 +411,5 @@
 };
 
 scenery.register( 'HeightSizable', HeightSizable );
-export default HeightSizable;
+export default HeightSizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<THeightSizable>;
 export { isHeightSizable, extendsHeightSizable };
\ No newline at end of file
Index: scenery/js/imports.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/imports.ts b/scenery/js/imports.ts
--- a/scenery/js/imports.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/imports.ts	(date 1714193785581)
@@ -180,7 +180,7 @@
 export { default as voicingManager } from './accessibility/voicing/voicingManager.js';
 export { default as voicingUtteranceQueue } from './accessibility/voicing/voicingUtteranceQueue.js';
 export { default as Voicing } from './accessibility/voicing/Voicing.js';
-export type { VoicingOptions, VoicingNode, SpeakingOptions } from './accessibility/voicing/Voicing.js';
+export type { VoicingOptions, VoicingNode, SpeakingOptions, TVoicing } from './accessibility/voicing/Voicing.js';
 export { default as ReadingBlockUtterance } from './accessibility/voicing/ReadingBlockUtterance.js';
 export type { ReadingBlockUtteranceOptions } from './accessibility/voicing/ReadingBlockUtterance.js';
 export { default as FocusDisplayedController } from './accessibility/FocusDisplayedController.js';
Index: scenery/js/layout/WidthSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/WidthSizable.ts b/scenery/js/layout/WidthSizable.ts
--- a/scenery/js/layout/WidthSizable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/layout/WidthSizable.ts	(date 1714197234018)
@@ -369,12 +369,6 @@
   return WidthSizableTrait;
 } );
 
-// Some typescript gymnastics to provide a user-defined type guard that treats something as widthSizable
-// We need to define an unused function with a concrete type, so that we can extract the return type of the function
-// and provide a type for a Node that extends this type.
-const wrapper = () => WidthSizable( Node );
-export type WidthSizableNode = InstanceType<ReturnType<typeof wrapper>>;
-
 const isWidthSizable = ( node: Node ): node is WidthSizableNode => {
   return node.widthSizable;
 };
@@ -382,6 +376,40 @@
   return node.extendsWidthSizable;
 };
 
+export type TWidthSizable = {
+  readonly preferredWidthProperty: TinyProperty<number | null>;
+  readonly minimumWidthProperty: TinyProperty<number | null>;
+  readonly localPreferredWidthProperty: TinyProperty<number | null>;
+  readonly localMinimumWidthProperty: TinyProperty<number | null>;
+  readonly isWidthResizableProperty: TinyProperty<boolean>;
+
+  preferredWidth: number | null;
+  minimumWidth: number | null;
+  localPreferredWidth: number | null;
+  localMinimumWidth: number | null;
+
+  _updateLocalPreferredWidthListener: () => void;
+  _updatePreferredWidthListener: () => void;
+  _updateLocalMinimumWidthListener: () => void;
+  _updateMinimumWidthListener: () => void;
+
+  validateLocalPreferredWidth(): void;
+
+  _calculateLocalPreferredWidth(): number | null;
+  _calculatePreferredWidth(): number | null;
+  _onReentrantLocalMinimumWidth(): void;
+  _onReentrantPreferredWidth(): void;
+  _calculateLocalMinimumWidth(): number | null;
+  _calculateMinimumWidth(): number | null;
+
+  set widthSizable( value: boolean );
+};
+
+// Some typescript gymnastics to provide a user-defined type guard that treats something as widthSizable
+// We need to define an unused function with a concrete type, so that we can extract the return type of the function
+// and provide a type for a Node that extends this type.
+export type WidthSizableNode = Node & TWidthSizable;
+
 scenery.register( 'WidthSizable', WidthSizable );
-export default WidthSizable;
+export default WidthSizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TWidthSizable>;
 export { isWidthSizable, extendsWidthSizable };
\ No newline at end of file
Index: utterance-queue/js/AriaLiveAnnouncer.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/utterance-queue/js/AriaLiveAnnouncer.ts b/utterance-queue/js/AriaLiveAnnouncer.ts
--- a/utterance-queue/js/AriaLiveAnnouncer.ts	(revision 0297e932f21a53d59a808585226617df6183dfc0)
+++ b/utterance-queue/js/AriaLiveAnnouncer.ts	(date 1714196470288)
@@ -157,6 +157,8 @@
 
       if ( options.ariaLivePriority === AriaLive.POLITE ) {
         const element = this.politeElements[ this.politeElementIndex ];
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         this.updateLiveElement( element, announceText, utterance );
 
         // update index for next time
@@ -164,6 +166,8 @@
       }
       else if ( options.ariaLivePriority === AriaLive.ASSERTIVE ) {
         const element = this.assertiveElements[ this.assertiveElementIndex ];
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         this.updateLiveElement( element, announceText, utterance );
         // update index for next time
         this.assertiveElementIndex = ( this.assertiveElementIndex + 1 ) % this.assertiveElements.length;
Index: scenery/js/accessibility/voicing/voicingUtteranceQueue.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts b/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts
--- a/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts	(date 1714181722433)
@@ -10,6 +10,7 @@
 
 import UtteranceQueue from '../../../../utterance-queue/js/UtteranceQueue.js';
 import { scenery, voicingManager } from '../../imports.js';
+import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 
 const voicingUtteranceQueue = new UtteranceQueue( voicingManager, {
   featureSpecificAnnouncingControlPropertyName: 'voicingCanAnnounceProperty'
@@ -19,4 +20,4 @@
 voicingUtteranceQueue.enabled = false;
 
 scenery.register( 'voicingUtteranceQueue', voicingUtteranceQueue );
-export default voicingUtteranceQueue;
\ No newline at end of file
+export default voicingUtteranceQueue as IntentionalAny;
\ No newline at end of file
Index: scenery/js/listeners/SpriteListenable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/listeners/SpriteListenable.ts b/scenery/js/listeners/SpriteListenable.ts
--- a/scenery/js/listeners/SpriteListenable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/listeners/SpriteListenable.ts	(date 1714183135878)
@@ -55,4 +55,4 @@
 } );
 
 scenery.register( 'SpriteListenable', SpriteListenable );
-export default SpriteListenable;
\ No newline at end of file
+export default SpriteListenable as unknown as PressListener;
\ No newline at end of file
Index: chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig-core.json b/chipper/tsconfig-core.json
--- a/chipper/tsconfig-core.json	(revision b9b8d46a42df39318878f027a9855be68c5b82b4)
+++ b/chipper/tsconfig-core.json	(date 1714196863759)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+    "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: scenery/js/nodes/Paintable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/nodes/Paintable.ts b/scenery/js/nodes/Paintable.ts
--- a/scenery/js/nodes/Paintable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/nodes/Paintable.ts	(date 1714195776191)
@@ -829,9 +829,62 @@
 Paintable.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
 
 export {
-  Paintable as default,
   PAINTABLE_DRAWABLE_MARK_FLAGS,
   PAINTABLE_OPTION_KEYS,
   DEFAULT_OPTIONS,
   DEFAULT_OPTIONS as PAINTABLE_DEFAULT_OPTIONS
-};
\ No newline at end of file
+};
+
+export type MyPaintable = {
+  // (scenery-internal)
+  fill: TPaint;
+  fillPickable: boolean;
+
+  // (scenery-internal)
+  stroke: TPaint;
+  strokePickable: boolean;
+
+  // (scenery-internal)
+  cachedPaints: TPaint[];
+  lineDrawingStyles: LineStyles;
+
+  lineWidth: number;
+  lineCap: LineCap;
+  lineJoin: LineJoin;
+  miterLimit: number;
+  lineDash: number[];
+  lineDashOffset: number;
+
+  getStrokeRendererBitmask(): number;
+  getStroke(): TPaint;
+  hasStroke(): boolean;
+  hasPaintableStroke(): boolean;
+  hasLineDash(): boolean;
+  getLineJoin(): LineJoin;
+  getLineWidth(): number;
+
+  _stroke: TPaint;
+
+  setStroke<T>( stroke: TPaint ): T;
+  setLineStyles<T>( lineStyles: LineStyles ): T;
+
+  setFill<T>( fill: TPaint ): T;
+  setLineWidth<T>( lineWidth: number ): T;
+
+  _strokePickable: boolean;
+
+  invalidateStroke(): void;
+  getFillRendererBitmask(): number;
+
+  _fillPickable: boolean;
+
+  invalidateFill(): void;
+  getLineCap(): LineCap;
+
+  _lineDrawingStyles: LineStyles;
+  getLineStyles(): LineStyles;
+
+  getMiterLimit(): number;
+};
+
+export default Paintable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<MyPaintable>;
\ No newline at end of file
Index: utterance-queue/js/ResponsePacket.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/utterance-queue/js/ResponsePacket.ts b/utterance-queue/js/ResponsePacket.ts
--- a/utterance-queue/js/ResponsePacket.ts	(revision 0297e932f21a53d59a808585226617df6183dfc0)
+++ b/utterance-queue/js/ResponsePacket.ts	(date 1714195984303)
@@ -23,7 +23,7 @@
 import utteranceQueueNamespace from './utteranceQueueNamespace.js';
 
 // The text sent to an Announcer technology, after resolving it from potentially more complicated structures holding a response
-export type ResolvedResponse = string | number | null;
+export type ResolvedResponse = string | number | null | TReadOnlyProperty<string>;
 
 type ResponseCreator = TReadOnlyProperty<string> | ( () => ResolvedResponse );
 export type VoicingResponse = ResponseCreator | ResolvedResponse;
Index: scenery/js/layout/constraints/FlowConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/FlowConfigurable.ts b/scenery/js/layout/constraints/FlowConfigurable.ts
--- a/scenery/js/layout/constraints/FlowConfigurable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/layout/constraints/FlowConfigurable.ts	(date 1714192351547)
@@ -29,6 +29,7 @@
 import WithoutNull from '../../../../phet-core/js/types/WithoutNull.js';
 import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 import TEmitter from '../../../../axon/js/TEmitter.js';
+import { TMarginLayoutConfigurable } from './MarginLayoutConfigurable.js';
 
 const FLOW_CONFIGURABLE_OPTION_KEYS = [
   'orientation',
@@ -223,6 +224,24 @@
   };
 } );
 
+type TFlowConfigurable = {
+  _orientation: Orientation;
+  _align: LayoutAlign | null;
+  _stretch: boolean | null;
+  _grow: number | null;
+
+  orientationChangedEmitter: TEmitter;
+
+  mutateConfigurable( options?: FlowConfigurableOptions ): void;
+  setConfigToBaseDefault(): void;
+  setConfigToInherit(): void;
+
+  orientation: LayoutOrientation;
+  align: HorizontalLayoutAlign | VerticalLayoutAlign | null;
+  stretch: boolean | null;
+  grow: number | null;
+} & TMarginLayoutConfigurable;
+
 scenery.register( 'FlowConfigurable', FlowConfigurable );
-export default FlowConfigurable;
+export default FlowConfigurable as unknown as <SuperType extends Constructor>( type: SuperType ) => SuperType & Constructor<TFlowConfigurable>;
 export { FLOW_CONFIGURABLE_OPTION_KEYS };
\ No newline at end of file
Index: scenery/js/nodes/Imageable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/nodes/Imageable.ts b/scenery/js/nodes/Imageable.ts
--- a/scenery/js/nodes/Imageable.ts	(revision 7552d65674a0545ad0ea1d48ce2a7e88ff526175)
+++ b/scenery/js/nodes/Imageable.ts	(date 1714195289372)
@@ -133,7 +133,7 @@
 };
 
 const Imageable = <SuperType extends Constructor>( type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
-  return class ImageableMixin extends type {
+  return class ImageableMixin extends type implements TImageable {
 
     // (scenery-internal) Internal stateful value, see onImagePropertyChange()
     public _image: ParsedImage | null;
@@ -163,7 +163,7 @@
     public _mipmapMaxLevel: number;
 
     // Internal stateful value, see setHitTestPixels() for documentation
-    protected _hitTestPixels: boolean;
+    public _hitTestPixels: boolean; // treat as protected in the mixin
 
     // Array of Canvases for each level, constructed internally so that Canvas-based drawables (Canvas, WebGL) can quickly draw mipmaps.
     private _mipmapCanvases: HTMLCanvasElement[];
@@ -182,7 +182,7 @@
     private _imageLoadListenerAttached: boolean;
 
     // Used for pixel hit testing.
-    protected _hitTestImageData: ImageData | null;
+    public _hitTestImageData: ImageData | null; // we wish it was protected, but it's exported in a mixin
 
     // Emits when mipmaps are (re)generated
     public mipmapEmitter: TEmitter;
@@ -1105,5 +1105,40 @@
 // {Object} - Initial values for most Node mutator options
 Imageable.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
 
+export type TImageable = {
+  getImage(): ParsedImage;
+  _image: ParsedImage | null;
+  imageWidth: number;
+  imageHeight: number;
+  imageOpacity: number;
+  initialWidth: number;
+  initialHeight: number;
+  hitTestPixels: boolean;
+
+  invalidateImage(): void;
+  getImageWidth(): number;
+  getImageHeight(): number;
+
+  setImageOpacity( imageOpacity: number ): void;
+  _imageOpacity: number;
+
+  _hitTestImageData: ImageData | null;
+  _hitTestPixels: boolean;
+  _mipmap: boolean;
+  _mipmapData: Mipmap | null;
+  image: ParsedImage | null;
+  invalidateMipmaps(): void;
+
+  set imageProperty( property: TReadOnlyProperty<ImageableImage> | null );
+  get imageProperty(): TProperty<ImageableImage>;
+};
+
 scenery.register( 'Imageable', Imageable );
-export default Imageable;
\ No newline at end of file
+export default Imageable as unknown as ( <SuperType extends Constructor>( type: SuperType ) => SuperType & Constructor<TImageable> ) & {
+
+  // static interface
+  testHitTestData( imageData: ImageData, width: number, height: number, point: Vector2 ): boolean;
+  hitTestDataToShape( imageData: ImageData, width: number, height: number ): Shape;
+  DEFAULT_OPTIONS: ImageableOptions;
+  getHitTestData( image: ParsedImage, width: number, height: number ): ImageData | null;
+};
\ No newline at end of file

samreid added a commit to phetsims/tandem that referenced this issue Apr 28, 2024
samreid added a commit to phetsims/phet-core that referenced this issue Apr 28, 2024
samreid added a commit to phetsims/phet-core that referenced this issue Apr 28, 2024
@samreid
Copy link
Member

samreid commented Apr 28, 2024

I'm adding a few straightforward mini-commits to help move in this direction. Note some of the changes obviate or conflict with changes proposed in the patch.

@samreid
Copy link
Member

samreid commented Apr 28, 2024

New patch after the commits above:

Subject: [PATCH] imageable
---
Index: scenery/js/util/DelayedMutate.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/util/DelayedMutate.ts b/scenery/js/util/DelayedMutate.ts
--- a/scenery/js/util/DelayedMutate.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/util/DelayedMutate.ts	(date 1714337996844)
@@ -38,7 +38,7 @@
  * @param keys - An array of the mutate option names that should be delayed
  * @param type - The class we're mixing into
  */
-const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => {
   // We typecast these to strings to satisfy the type-checker without large amounts of grief. It doesn't seem to be
   // able to parse that we're using the same keys for each call of this.
   const pendingOptionsKey = `_${name}PendingOptions` as '_fakePendingOptionsType';
@@ -84,4 +84,4 @@
 };
 
 scenery.register( 'DelayedMutate', DelayedMutate );
-export default DelayedMutate;
\ No newline at end of file
+export default DelayedMutate as <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => SuperType;
\ No newline at end of file
Index: scenery/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/tsconfig.json b/scenery/tsconfig.json
--- a/scenery/tsconfig.json	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/tsconfig.json	(date 1714337711604)
@@ -4,6 +4,449 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+
+    "../tandem/js/**/*",
+
+    "../chipper/js/sim-tests/qunitStart.js",
+    "../phet-io/js/phetioEngine.ts",
+
+    "../phet-core/js/isHMR.ts",
+    "../phet-core/js/Namespace.ts",
+    "../phet-core/js/phetCore.ts",
+    "../phet-core/js/extend.ts",
+    "../phet-core/js/types/IntentionalAny.ts",
+    "../phet-core/js/deprecationWarning.ts",
+    "../phet-core/js/merge.ts",
+    "../phet-core/js/types/RequiredKeys.ts",
+    "../phet-core/js/types/OptionalKeys.ts",
+    "../phet-core/js/EnumerationDeprecated.js",
+    "../phet-core/js/optionize.ts",
+    "../axon/js/Validation.ts",
+    "../phet-core/js/types/PickRequired.ts",
+    "../phet-core/js/assertMutuallyExclusiveOptions.ts",
+    "../axon/js/Timer.ts",
+    "../phet-core/js/types/Constructor.ts",
+    "../phet-core/js/EnumerationValue.ts",
+    "../phet-core/js/TEnumeration.ts",
+    "../phet-core/js/inheritance.ts",
+    "../phet-core/js/Enumeration.ts",
+    "../axon/js/animationFrameTimer.ts",
+    "../phet-core/js/types/StrictOmit.ts",
+    "../phet-core/js/arrayRemove.ts",
+    "../axon/js/Disposable.ts",
+    "../axon/js/PropertyStatePhase.ts",
+    "../axon/js/PropertyStateHandler.ts",
+    "../axon/js/propertyStateHandlerSingleton.ts",
+    "../axon/js/units.ts",
+    "../axon/js/ReadOnlyProperty.ts",
+    "../axon/js/TReadOnlyProperty.ts",
+    "../axon/js/TProperty.ts",
+    "../axon/js/TinyProperty.ts",
+    "../axon/js/Emitter.ts",
+    "../axon/js/validate.ts",
+    "../dot/js/Vector4.ts",
+    "../dot/js/Vector3.ts",
+    "../phet-core/js/Pool.ts",
+    "../dot/js/dot.js",
+    "../dot/js/Utils.js",
+    "../dot/js/Matrix4.js",
+    "../dot/js/toSVGNumber.js",
+    "../dot/js/Vector2.ts",
+    "../dot/js/Matrix3.ts",
+    "../dot/js/Range.ts",
+    "../phet-core/js/Orientation.ts",
+    "../dot/js/Bounds2.ts",
+    "../axon/js/axon.ts",
+    "../dot/js/Random.ts",
+    "../dot/js/dotRandom.js",
+    "../axon/js/TEmitter.ts",
+    "../axon/js/TinyEmitter.ts",
+    "../phet-core/js/detectPrefix.ts",
+    "../dot/js/Ray2.ts",
+    "../dot/js/Transform3.js",
+    "../phet-core/js/platform.ts",
+    "../axon/js/Property.ts",
+    "../phet-core/js/detectPrefixEvent.ts",
+    "../phet-core/js/Poolable.ts",
+    "../axon/js/Multilink.ts",
+    "../axon/js/DerivedProperty.ts",
+    "../axon/js/BooleanProperty.ts",
+    "../phet-core/js/isArray.ts",
+    "../dot/js/EigenvalueDecomposition.js",
+    "../dot/js/LUDecomposition.js",
+    "../dot/js/QRDecomposition.js",
+    "../dot/js/Matrix.js",
+    "../dot/js/SingularValueDecomposition.js",
+    "../dot/js/Complex.ts",
+    "../phet-core/js/types/KeysMatching.ts",
+    "../phet-core/js/cleanArray.ts",
+    "../kite/js/kite.ts",
+    "../kite/js/util/LineStyles.ts",
+    "../kite/js/util/Overlap.ts",
+    "../kite/js/util/RayIntersection.ts",
+    "../kite/js/util/SegmentIntersection.ts",
+    "../kite/js/util/svgNumber.ts",
+    "../kite/js/util/intersectConicMatrices.ts",
+    "../kite/js/parser/svgPath.js",
+    "../kite/js/segments/Segment.ts",
+    "../kite/js/segments/Line.ts",
+    "../kite/js/segments/Quadratic.ts",
+    "../kite/js/segments/Cubic.ts",
+    "../kite/js/segments/Arc.ts",
+    "../kite/js/segments/EllipticalArc.ts",
+    "../kite/js/util/Subpath.ts",
+    "../kite/js/Shape.ts",
+    "../kite/js/ops/HalfEdge.js",
+    "../kite/js/ops/Vertex.js",
+    "../kite/js/ops/Edge.js",
+    "../kite/js/ops/Face.js",
+    "../kite/js/ops/Loop.js",
+    "../kite/js/ops/Boundary.js",
+    "../kite/js/ops/BoundsIntersection.ts",
+    "../kite/js/ops/SegmentTree.ts",
+    "../kite/js/ops/EdgeSegmentTree.ts",
+    "../kite/js/ops/VertexSegmentTree.ts",
+    "../kite/js/ops/Graph.js",
+    "../kite/js/imports.ts",
+    "../dot/js/BinPacker.ts",
+    "../dot/js/Dimension2.ts",
+    "../phet-core/js/stripEmbeddingMarks.ts",
+    "../axon/js/StringProperty.ts",
+    "../utterance-queue/js/utteranceQueueNamespace.ts",
+    "../utterance-queue/js/ResponsePatternCollection.ts",
+    "../axon/js/PhetioProperty.ts",
+    "../axon/js/TRangedProperty.ts",
+    "../chipper/js/data/localeInfoModule.js",
+    "../phetcommon/js/phetcommon.js",
+    "../phetcommon/js/util/StringUtils.js",
+    "../axon/js/DynamicProperty.ts",
+    "../axon/js/NumberProperty.ts",
+    "../utterance-queue/js/responseCollector.ts",
+    "../utterance-queue/js/ResponsePacket.ts",
+    "../utterance-queue/js/Utterance.ts",
+    "../axon/js/stepTimer.ts",
+    "../utterance-queue/js/Announcer.ts",
+    "../utterance-queue/js/AriaLiveAnnouncer.ts",
+    "../utterance-queue/js/UtteranceWrapper.ts",
+    "../phet-core/js/memoize.ts",
+    "../phet-core/js/arrayDifference.ts",
+    "../utterance-queue/js/UtteranceQueue.ts",
+    "../axon/js/TinyForwardingProperty.ts",
+    "../axon/js/EnabledProperty.ts",
+    "../axon/js/TinyStaticProperty.ts",
+    "../phet-core/js/types/NotNull.ts",
+    "../phet-core/js/types/WithoutNull.ts",
+    "../phet-core/js/assertHasProperties.ts",
+    "../phet-core/js/types/WithRequired.ts",
+    "../phet-core/js/escapeHTML.ts",
+    "../phet-core/js/extendDefined.ts",
+    "../phet-core/js/mutate.ts",
+    "../phet-core/js/types/PickOptional.ts",
+    "../joist/js/joist.ts",
+    "../axon/js/EnabledComponent.ts",
+    "../utterance-queue/js/SpeechSynthesisParentPolyfill.ts",
+    "../joist/js/i18n/localeProperty.ts",
+    "../utterance-queue/js/SpeechSynthesisAnnouncer.ts",
+    "../dot/js/Permutation.ts",
+    "../axon/js/CallbackTimer.ts",
+    "../axon/js/createObservableArray.ts",
+    "../phet-core/js/types/NotUndefined.ts",
+    "../phet-core/js/types/RequiredOption.ts",
+    "../phetcommon/js/view/ModelViewTransform2.ts",
+    "../phet-core/js/EnumerationMap.ts",
+    "../phet-core/js/OrientationPair.ts",
+    "../dot/js/Vector2Property.ts",
+    "../sherpa/lib/himalaya-1.1.0.js",
+    "../phet-core/js/types/CollapsePropertyValue.ts",
+    "../phet-core/js/types/KeysNotMatching.ts",
+    "../axon/js/DerivedStringProperty.ts",
+    "../axon/js/EnumerationDeprecatedProperty.js",
+    "../axon/js/MappedProperty.ts",
+    "../axon/js/PatternStringProperty.ts",
+    "../axon/js/TinyOverrideProperty.ts",
+    "../axon/js/UnitConversionProperty.ts",
+    "../dot/js/Ray3.ts",
+    "../dot/js/Bounds3.ts",
+    "../dot/js/Combination.ts",
+    "../dot/js/CompletePiecewiseLinearFunction.ts",
+    "../dot/js/ConvexHull2.js",
+    "../dot/js/DampedHarmonic.ts",
+    "../dot/js/DelaunayTriangulation.js",
+    "../dot/js/LinearFunction.ts",
+    "../dot/js/MatrixOps3.js",
+    "../dot/js/Plane3.ts",
+    "../dot/js/Quaternion.js",
+    "../dot/js/Rectangle.js",
+    "../dot/js/Sphere3.js",
+    "../dot/js/Transform4.js",
+    "../dot/js/UnivariatePolynomial.ts",
+    "../phet-core/js/collect.ts",
+    "../phet-core/js/dimensionForEach.ts",
+    "../phet-core/js/dimensionMap.ts",
+    "../phet-core/js/EventTimer.ts",
+    "../phet-core/js/interleave.ts",
+    "../phet-core/js/loadScript.ts",
+    "../phet-core/js/pairs.ts",
+    "../phet-core/js/partition.ts",
+    "../utterance-queue/js/ActivationUtterance.ts",
+    "../utterance-queue/js/ValueChangeUtterance.ts",
+    "../axon/js/main.ts",
+    "../dot/js/main.js",
+    "../kite/js/main.js",
+    "../phet-core/js/main.ts",
+    "../utterance-queue/js/main.ts",
+    "../joist/js/i18n/fallbackLocalesProperty.ts",
+    "../joist/js/i18n/localeOrderProperty.ts",
+    "../chipper/js/chipper.ts",
+    "../chipper/js/LocalizedStringProperty.ts",
+    "../chipper/js/LocalizedString.ts",
+    "../chipper/js/getStringModule.ts",
+    "../scenery-phet/js/sceneryPhet.ts",
+    "../scenery-phet/js/SceneryPhetStrings.ts",
+    "../scenery-phet/js/accessibility/PDOMSectionNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ControlAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/PlayAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ScreenSummaryNode.ts",
+    "../joist/js/JoistStrings.ts",
+    "../joist/js/ScreenIcon.ts",
+    "../joist/js/ScreenView.ts",
+    "../joist/js/TModel.ts",
+    "../sun/js/sun.ts",
+    "../phet-core/js/gracefulBind.ts",
+    "../sun/js/Popupable.ts",
+    "../tambo/js/tambo.ts",
+    "../phet-core/js/asyncLoader.ts",
+    "../tambo/js/base64SoundToByteArray.ts",
+    "../tambo/js/WrappedAudioBuffer.ts",
+    "../tambo/js/phetAudioContext.ts",
+    "../tambo/sounds/emptyApartmentBedroom06Resampled_mp3.js",
+    "../tambo/js/audioContextStateChangeMonitor.ts",
+    "../tambo/js/soundConstants.ts",
+    "../tambo/js/SoundLevelEnum.ts",
+    "../tambo/js/sound-generators/SoundGenerator.ts",
+    "../scenery-phet/js/sceneryPhetQueryParameters.ts",
+    "../tambo/js/SoundUtils.ts",
+    "../tambo/js/sound-generators/SoundClip.ts",
+    "../tambo/sounds/grab_mp3.js",
+    "../tambo/sounds/release_mp3.js",
+    "../phet-core/js/documentation/InstanceRegistry.ts",
+    "../scenery-phet/images/measuringTape_png.ts",
+    "../scenery-phet/js/PhetFont.ts",
+    "../scenery-phet/js/RichKeyboardDragListener.ts",
+    "../scenery-phet/js/RichDragListener.ts",
+    "../tambo/sounds/radioButtonV2_mp3.js",
+    "../tambo/js/TSoundPlayer.ts",
+    "../tambo/js/multiSelectionSoundPlayerFactory.ts",
+    "../sun/js/AquaRadioButton.ts",
+    "../sun/js/GroupItemOptions.ts",
+    "../joist/js/preferences/PreferencesStorage.ts",
+    "../joist/js/i18n/regionAndCultureProperty.ts",
+    "../joist/js/preferences/PreferencesModel.ts",
+    "../joist/js/DynamicStringTest.ts",
+    "../joist/js/HighlightVisibilityController.ts",
+    "../tambo/sounds/checkboxChecked_mp3.js",
+    "../tambo/js/sound-generators/SoundClipPlayer.ts",
+    "../tambo/sounds/checkboxUnchecked_mp3.js",
+    "../sherpa/js/fontawesome-4/checkEmptySolidShape.js",
+    "../sherpa/js/fontawesome-4/checkSquareOSolidShape.js",
+    "../tambo/js/shared-sound-players/checkboxCheckedSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/checkboxUncheckedSoundPlayer.ts",
+    "../tambo/sounds/generalButton_mp3.js",
+    "../sun/js/buttons/ButtonModel.ts",
+    "../sun/js/buttons/ButtonInteractionState.ts",
+    "../sun/js/buttons/PushButtonModel.ts",
+    "../sun/js/buttons/RadioButtonInteractionState.ts",
+    "../sun/js/ColorConstants.ts",
+    "../sun/js/buttons/TButtonAppearanceStrategy.ts",
+    "../sun/js/buttons/TContentAppearanceStrategy.ts",
+    "../sun/js/buttons/ButtonNode.ts",
+    "../tambo/js/shared-sound-players/pushButtonSoundPlayer.ts",
+    "../sun/js/buttons/PushButtonInteractionStateProperty.ts",
+    "../sun/js/buttons/RectangularButton.ts",
+    "../sun/js/ToggleNode.ts",
+    "../tambo/sounds/stepBack_mp3.js",
+    "../tambo/sounds/stepForward_mp3.js",
+    "../sun/js/buttons/ToggleButtonModel.ts",
+    "../tambo/js/shared-sound-players/toggleOffSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/toggleOnSoundPlayer.ts",
+    "../sun/js/buttons/ToggleButtonInteractionStateProperty.ts",
+    "../sun/js/BooleanToggleNode.ts",
+    "../sun/js/buttons/RectangularToggleButton.ts",
+    "../sun/js/buttons/BooleanRectangularToggleButton.ts",
+    "../scenery-phet/js/MeasuringTapeNode.ts",
+    "../sun/js/Panel.ts",
+    "../sun/js/AquaRadioButtonGroup.ts",
+    "../joist/js/SimDisplay.ts",
+    "../sun/js/Checkbox.ts",
+    "../axon/js/EnumerationProperty.ts",
+    "../sun/js/buttons/RectangularPushButton.ts",
+    "../sun/js/ExpandCollapseButton.ts",
+    "../scenery-phet/js/keyboard/KeyNode.ts",
+    "../scenery-phet/js/PlusShape.ts",
+    "../scenery-phet/js/PlusNode.ts",
+    "../scenery-phet/js/keyboard/ArrowKeyNode.ts",
+    "../scenery-phet/js/keyboard/LetterKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSectionRow.ts",
+    "../scenery-phet/js/keyboard/TextKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpIconFactory.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/NumberKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/BasicActionsKeyboardHelpSection.ts",
+    "../tambo/js/sound-generators/MultiClip.ts",
+    "../joist/sounds/screenSelectionHomeV3_mp3.js",
+    "../joist/sounds/switchingScreenSelectorIcons003_mp3.js",
+    "../scenery-phet/js/PhetColorScheme.ts",
+    "../joist/js/Frame.ts",
+    "../joist/js/HomeScreenSoundGenerator.ts",
+    "../joist/js/HomeScreenButton.ts",
+    "../joist/js/HomeScreenKeyboardHelpContent.ts",
+    "../joist/js/HomeScreenModel.ts",
+    "../joist/js/HomeScreenView.ts",
+    "../dot/js/RunningAverage.js",
+    "../tambo/sounds/generalClose_mp3.js",
+    "../tambo/sounds/generalOpen_mp3.js",
+    "../phet-core/js/getGlobal.ts",
+    "../scenery-phet/js/buttons/CloseButton.ts",
+    "../tambo/js/shared-sound-players/generalCloseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalOpenSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/nullSoundPlayer.ts",
+    "../sun/js/SunStrings.ts",
+    "../joist/js/HighlightNode.ts",
+    "../sun/js/Dialog.ts",
+    "../joist/images/keyboardIconOnWhite_png.ts",
+    "../joist/images/keyboardIcon_png.ts",
+    "../joist/js/JoistButton.ts",
+    "../joist/js/KeyboardHelpDialog.ts",
+    "../tambo/sounds/switchToLeft_mp3.js",
+    "../tambo/sounds/switchToRight_mp3.js",
+    "../tambo/js/shared-sound-players/switchToLeftSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/switchToRightSoundPlayer.ts",
+    "../sun/js/ToggleSwitch.ts",
+    "../joist/js/preferences/PreferencesPanelSection.ts",
+    "../joist/js/preferences/PreferencesDialogConstants.ts",
+    "../tambo/sounds/generalBoundaryBoop_mp3.js",
+    "../tambo/sounds/generalSoftClick_mp3.js",
+    "../tambo/js/shared-sound-players/generalBoundaryBoopSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalSoftClickSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleValueHandler.ts",
+    "../sun/js/SliderTrack.ts",
+    "../sun/js/SunConstants.ts",
+    "../phet-core/js/swapObjectKeys.ts",
+    "../tambo/js/sound-generators/ValueChangeSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleSlider.ts",
+    "../sun/js/DefaultSliderTrack.ts",
+    "../sun/js/SliderThumb.ts",
+    "../sun/js/SliderTick.ts",
+    "../sun/js/Slider.ts",
+    "../scenery-phet/js/MathSymbols.ts",
+    "../sun/js/buttons/ArrowButton.ts",
+    "../sun/js/HSlider.ts",
+    "../scenery-phet/js/NumberDisplay.ts",
+    "../sun/js/ComboBoxListItemNode.ts",
+    "../sun/js/ComboBoxButton.ts",
+    "../sun/js/ComboBoxListBox.ts",
+    "../scenery-phet/js/NumberControl.ts",
+    "../sun/js/ComboBox.ts",
+    "../joist/js/preferences/PreferencesType.ts",
+    "../joist/js/preferences/PreferencesControl.ts",
+    "../joist/js/preferences/SoundPanelSection.ts",
+    "../joist/js/preferences/VoicingPanelSection.ts",
+    "../joist/js/preferences/PreferencesPanel.ts",
+    "../joist/js/preferences/ProjectorModeToggleSwitch.ts",
+    "../joist/js/preferences/LanguageSelectionNode.ts",
+    "../joist/js/preferences/RegionAndCultureComboBox.ts",
+    "../joist/js/preferences/LocalePanel.ts",
+    "../joist/js/i18n/isLeftToRightProperty.ts",
+    "../sherpa/js/fontawesome-5/globeSolidString.js",
+    "../sherpa/js/fontawesome-5/globeSolidShape.js",
+    "../joist/js/preferences/PreferencesTab.ts",
+    "../joist/js/preferences/AudioPreferencesPanel.ts",
+    "../joist/js/preferences/SimulationPreferencesPanel.ts",
+    "../joist/js/preferences/InputPreferencesPanel.ts",
+    "../joist/js/preferences/VisualPreferencesPanel.ts",
+    "../joist/js/preferences/LocalizationPreferencesPanel.ts",
+    "../joist/js/preferences/OverviewPreferencesPanel.ts",
+    "../joist/js/preferences/PreferencesTabs.ts",
+    "../joist/sounds/cardFlip_mp3.js",
+    "../joist/js/preferences/PreferencesPanels.ts",
+    "../joist/js/preferences/PreferencesTabSwitchSoundGenerator.ts",
+    "../joist/images/preferencesIconOnWhite_png.ts",
+    "../joist/images/preferencesIcon_png.ts",
+    "../joist/js/preferences/PreferencesDialog.ts",
+    "../joist/js/KeyboardHelpButton.ts",
+    "../joist/js/NavigationBarAudioToggleButton.ts",
+    "../joist/js/preferences/NavigationBarPreferencesButton.ts",
+    "../sherpa/js/fontawesome-5/homeSolidString.js",
+    "../sherpa/js/fontawesome-5/homeSolidShape.js",
+    "../brand/js/brand.ts",
+    "../brand/js/getLinks.ts",
+    "../sherpa/js/fontawesome-5/checkSolidString.js",
+    "../sherpa/js/fontawesome-5/checkSolidShape.js",
+    "../joist/js/UpdateState.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidString.js",
+    "../scenery-phet/js/SpinningIndicatorNode.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidShape.js",
+    "../sun/js/buttons/TextPushButton.ts",
+    "../joist/js/UpdateDialog.ts",
+    "../joist/js/CreditsNode.ts",
+    "../joist/js/updateCheck.ts",
+    "../joist/js/UpdateNodes.ts",
+    "../sun/js/MenuItem.ts",
+    "../joist/js/AboutDialog.ts",
+    "../joist/js/ScreenshotGenerator.ts",
+    "../brand/js/TBrand.ts",
+    "../joist/js/KebabMenuIcon.ts",
+    "../joist/js/PhetMenu.ts",
+    "../joist/js/A11yButtonsHBox.ts",
+    "../joist/js/HomeButton.ts",
+    "../joist/js/NavigationBarScreenButton.ts",
+    "../joist/js/PhetButton.ts",
+    "../scenery-phet/images/phetGirlWaggingFinger_png.ts",
+    "../scenery-phet/js/OopsDialog.ts",
+    "../joist/sounds/screenSelection_mp3.js",
+    "../sun/js/buttons/RoundButton.ts",
+    "../sun/js/buttons/RoundToggleButton.ts",
+    "../tambo/sounds/pause_mp3.js",
+    "../tambo/sounds/playPause_mp3.js",
+    "../sun/js/buttons/BooleanRoundToggleButton.ts",
+    "../tambo/js/shared-sound-players/pauseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/playSoundPlayer.ts",
+    "../scenery-phet/js/PlayIconShape.ts",
+    "../scenery-phet/js/SceneryPhetConstants.ts",
+    "../scenery-phet/js/StopIconShape.ts",
+    "../scenery-phet/js/buttons/PlayControlButton.ts",
+    "../scenery-phet/js/buttons/PlayStopButton.ts",
+    "../sun/js/buttons/RoundPushButton.ts",
+    "../joist/js/toolbar/VoicingToolbarAlertManager.ts",
+    "../joist/js/toolbar/VoicingToolbarItem.ts",
+    "../scenery-phet/js/BarrierRectangle.ts",
+    "../sherpa/lib/game-up-camera-1.0.0.js",
+    "../tambo/js/soundManager.ts",
+    "../joist/js/audioManager.ts",
+    "../joist/js/Heartbeat.ts",
+    "../joist/js/Helper.ts",
+    "../joist/js/HomeScreen.ts",
+    "../joist/js/LookAndFeel.ts",
+    "../joist/js/MemoryMonitor.ts",
+    "../joist/js/NavigationBar.ts",
+    "../joist/js/Profiler.ts",
+    "../joist/js/QueryParametersWarningDialog.ts",
+    "../joist/js/ScreenSelectionSoundGenerator.ts",
+    "../joist/js/selectScreens.ts",
+    "../joist/js/thirdPartySupport/LegendsOfLearningSupport.ts",
+    "../joist/js/toolbar/Toolbar.ts",
+    "../joist/js/Screen.ts",
+    "../joist/js/Sim.ts",
+    "../phet-io/js/phetio.ts",
+    "../phet-io/js/PhetioStateEngine.ts",
+    "../joist/js/packageJSON.ts",
+    "../joist/js/SimInfo.ts",
+    "../phet-io/js/dataStream.ts",
+    "../phet-io/js/phetioCommandProcessor.ts",
+    "../phet-io/js/phetioDevSaveLoad.ts",
+    "../phet-core/js/gracefulBind.js",
+    "../sun/js/Popupable.js",
+    "../phet-core/js/types/TMixin.ts"
   ]
 }
\ No newline at end of file
Index: tandem/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tandem/tsconfig.json b/tandem/tsconfig.json
--- a/tandem/tsconfig.json	(revision 3f619280b74dcf067ceca7a85fb4c8f9f4d380d9)
+++ b/tandem/tsconfig.json	(date 1714337279289)
@@ -4,6 +4,7 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../phet-core/js/arrayRemove.ts"
   ]
 }
\ No newline at end of file
Index: scenery/js/layout/constraints/FlowCell.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/FlowCell.ts b/scenery/js/layout/constraints/FlowCell.ts
--- a/scenery/js/layout/constraints/FlowCell.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/FlowCell.ts	(date 1714337263148)
@@ -34,6 +34,8 @@
   private readonly flowConstraint: FlowConstraint;
 
   public constructor( constraint: FlowConstraint, node: Node, proxy: LayoutProxy | null ) {
+
+    // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
     super( constraint, node, proxy );
 
     this.flowConstraint = constraint;
Index: sherpa/lib/big-6.2.1.mjs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sherpa/lib/big-6.2.1.mjs b/sherpa/lib/big-6.2.1.mjs
--- a/sherpa/lib/big-6.2.1.mjs	(revision 3cc0c9fcea140cae57994a1ba11d951c8518d65d)
+++ b/sherpa/lib/big-6.2.1.mjs	(date 1714337279267)
@@ -15,7 +15,7 @@
    * The maximum number of decimal places (DP) of the results of operations involving division:
    * div and sqrt, and pow with negative exponents.
    */
-var DP = 20,          // 0 to MAX_DP
+const DP = 20,          // 0 to MAX_DP
 
   /*
    * The rounding mode (RM) used when rounding to the above decimal places.
Index: scenery/js/layout/constraints/MarginLayoutConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/MarginLayoutConfigurable.ts b/scenery/js/layout/constraints/MarginLayoutConfigurable.ts
--- a/scenery/js/layout/constraints/MarginLayoutConfigurable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/MarginLayoutConfigurable.ts	(date 1714337263164)
@@ -378,5 +378,24 @@
 } );
 
 scenery.register( 'MarginLayoutConfigurable', MarginLayoutConfigurable );
-export default MarginLayoutConfigurable;
+
+export type TMarginLayoutConfigurable = {
+  changedEmitter: TEmitter;
+  margin: number | null;
+  xMargin: number | null;
+  yMargin: number | null;
+  leftMargin: number | null;
+  rightMargin: number | null;
+  topMargin: number | null;
+  bottomMargin: number | null;
+  minContentWidth: number | null;
+  minContentHeight: number | null;
+  maxContentWidth: number | null;
+  maxContentHeight: number | null;
+  setConfigToBaseDefault(): void;
+  setConfigToInherit(): void;
+  mutateConfigurable( options?: MarginLayoutConfigurableOptions ): void;
+};
+
+export default MarginLayoutConfigurable as unknown as <SuperType extends Constructor>( type: SuperType ) => SuperType & Constructor<TMarginLayoutConfigurable>;
 export { MARGIN_LAYOUT_CONFIGURABLE_OPTION_KEYS };
\ No newline at end of file
Index: scenery/js/layout/constraints/GridCell.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/GridCell.ts b/scenery/js/layout/constraints/GridCell.ts
--- a/scenery/js/layout/constraints/GridCell.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/GridCell.ts	(date 1714337263160)
@@ -49,6 +49,7 @@
    */
   public constructor( constraint: GridConstraint, node: Node, proxy: LayoutProxy | null ) {
 
+    // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
     super( constraint, node, proxy );
 
     this.gridConstraint = constraint;
Index: sun/js/accessibility/AccessibleValueHandler.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleValueHandler.ts b/sun/js/accessibility/AccessibleValueHandler.ts
--- a/sun/js/accessibility/AccessibleValueHandler.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleValueHandler.ts	(date 1714338050386)
@@ -20,7 +20,7 @@
 import Range from '../../../dot/js/Range.js';
 import assertHasProperties from '../../../phet-core/js/assertHasProperties.js';
 import Orientation from '../../../phet-core/js/Orientation.js';
-import { animatedPanZoomSingleton, DelayedMutate, KeyboardUtils, Node, NodeOptions, PDOMPointer, PDOMUtils, PDOMValueType, SceneryEvent, SceneryListenerFunction, TInputListener, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
+import { TVoicing, animatedPanZoomSingleton, DelayedMutate, KeyboardUtils, Node, NodeOptions, PDOMPointer, PDOMUtils, PDOMValueType, SceneryEvent, SceneryListenerFunction, TInputListener, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
 import Utterance from '../../../utterance-queue/js/Utterance.js';
 import sun from '../sun.js';
 import optionize, { combineOptions } from '../../../phet-core/js/optionize.js';
@@ -234,7 +234,7 @@
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => {
   const AccessibleValueHandlerClass = DelayedMutate( 'AccessibleValueHandler', ACCESSIBLE_VALUE_HANDLER_OPTIONS, class AccessibleValueHandler extends Voicing( Type ) {
     private readonly _valueProperty: TProperty<number>;
     private _enabledRangeProperty: TReadOnlyProperty<Range>;
@@ -1261,6 +1261,18 @@
   return correctedValue;
 };
 
+export type TAccessibleValueHandler = {
+  voicingOnEndResponse( valueOnStart: number, providedOptions?: VoicingOnEndResponseOptions ): void;
+
+  set startInput( value: SceneryListenerFunction );
+  get startInput(): SceneryListenerFunction;
+  set onInput( value: SceneryListenerFunction );
+  get onInput(): SceneryListenerFunction;
+  set endInput( value: ( ( event: SceneryEvent | null ) => void ) );
+  get endInput(): SceneryListenerFunction;
+  getAccessibleValueHandlerInputListener(): TInputListener;
+} & TVoicing;
+
 AccessibleValueHandler.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;
 
-export default AccessibleValueHandler;
\ No newline at end of file
+export default AccessibleValueHandler as unknown as <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TAccessibleValueHandler>;
\ No newline at end of file
Index: dot/js/Utils.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/dot/js/Utils.js b/dot/js/Utils.js
--- a/dot/js/Utils.js	(revision aef01d114353684eb9678b4cab9c13ca1a9faa99)
+++ b/dot/js/Utils.js	(date 1714337263079)
@@ -6,7 +6,7 @@
  * @author Jonathan Olson <jonathan.olson@colorado.edu>
  */
 
-import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
+// import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
 import dot from './dot.js';
 import Vector2 from './Vector2.js';
 import Vector3 from './Vector3.js';
@@ -565,7 +565,7 @@
     }
 
     // eslint-disable-next-line bad-sim-text
-    const result = new Big( value ).toFixed( decimalPlaces );
+    const result = value.toFixed( decimalPlaces ); // TODO: https://github.com/phetsims/tasks/issues/1132
 
     // Avoid reporting -0.000
     if ( result.startsWith( '-0.' ) && Number.parseFloat( result ) === 0 ) {
Index: sun/js/accessibility/AccessibleSlider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleSlider.ts b/sun/js/accessibility/AccessibleSlider.ts
--- a/sun/js/accessibility/AccessibleSlider.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleSlider.ts	(date 1714338039013)
@@ -18,7 +18,7 @@
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 import { DelayedMutate, Node, SceneryEvent } from '../../../scenery/js/imports.js';
 import sun from '../sun.js';
-import AccessibleValueHandler, { AccessibleValueHandlerOptions } from './AccessibleValueHandler.js';
+import AccessibleValueHandler, { AccessibleValueHandlerOptions, TAccessibleValueHandler } from './AccessibleValueHandler.js';
 
 const ACCESSIBLE_SLIDER_OPTIONS = [
   'startDrag',
@@ -44,7 +44,7 @@
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at in the constructor for Type
  */
-const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => {
   const AccessibleSliderClass = DelayedMutate( 'AccessibleSlider', ACCESSIBLE_SLIDER_OPTIONS, class AccessibleSlider extends AccessibleValueHandler( Type, optionsArgPosition ) {
 
     private readonly _disposeAccessibleSlider: () => void;
@@ -140,5 +140,18 @@
 
 sun.register( 'AccessibleSlider', AccessibleSlider );
 
-export default AccessibleSlider;
+type TAccessibleSlider = {
+
+  // TODO: These may not be needed, see https://github.com/phetsims/tasks/issues/1132
+  set startDrag( value: ( event: SceneryEvent ) => void );
+  get startDrag(): ( event: SceneryEvent ) => void;
+
+  set drag( value: ( event: SceneryEvent ) => void );
+  get drag(): ( event: SceneryEvent ) => void;
+
+  set endDrag( value: ( event: SceneryEvent | null ) => void );
+  get endDrag(): ( event: SceneryEvent | null ) => void;
+} & TAccessibleValueHandler;
+
+export default AccessibleSlider as unknown as <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TAccessibleSlider>;
 export type { AccessibleSliderOptions };
\ No newline at end of file
Index: phet-core/js/EventTimer.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-core/js/EventTimer.ts b/phet-core/js/EventTimer.ts
--- a/phet-core/js/EventTimer.ts	(revision 334d6e61f57e83b88a34925d58ac48fd093eca23)
+++ b/phet-core/js/EventTimer.ts	(date 1714337263100)
@@ -76,8 +76,9 @@
  */
 
 import phetCore from './phetCore.js';
+import IntentionalAny from './types/IntentionalAny.js';
 
-export default class EventTimer {
+class EventTimer {
 
   private period: number;
   private timeBeforeNextEvent: number;
@@ -140,7 +141,7 @@
   };
 
   public static readonly UniformEventModel = class UniformEventModel {
-    
+
     /*
      * Event model that will fire events averaging a certain rate, but with the time between events being uniformly
      * random.
@@ -189,4 +190,6 @@
   };
 }
 
+export default EventTimer as IntentionalAny;
+
 phetCore.register( 'EventTimer', EventTimer );
\ No newline at end of file
Index: joist/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/tsconfig.json b/joist/tsconfig.json
--- a/joist/tsconfig.json	(revision b94d701c92cab77cd4cf554f333a7e0701c5b01b)
+++ b/joist/tsconfig.json	(date 1714337263096)
@@ -4,6 +4,11 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+
+    "../scenery-phet/js/PhetColorScheme.ts",
+    "../scenery-phet/js/**/*",
+    "../axon/js/**/*",
+    "../sun/js/**/*"
   ]
 }
\ No newline at end of file
Index: sun/js/Popupable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/Popupable.ts b/sun/js/Popupable.ts
--- a/sun/js/Popupable.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/Popupable.ts	(date 1714338007299)
@@ -13,12 +13,12 @@
 import Property from '../../axon/js/Property.js';
 import Bounds2 from '../../dot/js/Bounds2.js';
 import ScreenView from '../../joist/js/ScreenView.js';
-import gracefulBind from '../../phet-core/js/gracefulBind.js';
 import optionize from '../../phet-core/js/optionize.js';
 import Constructor from '../../phet-core/js/types/Constructor.js';
 import PickOptional from '../../phet-core/js/types/PickOptional.js';
 import { FocusManager, Node, NodeOptions } from '../../scenery/js/imports.js';
 import sun from './sun.js';
+import gracefulBind from '../../phet-core/js/gracefulBind.js';
 
 type SelfOptions = {
 
@@ -46,7 +46,7 @@
 type ParentOptions = PickOptional<NodeOptions, 'tandem'>;
 export type PopupableOptions = SelfOptions & ParentOptions;
 
-const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => {
 
   return class extends type {
 
@@ -168,7 +168,7 @@
       }
     }
 
-    protected get focusOnHideNode(): Node | null {
+    public get focusOnHideNode(): Node | null {
       return this._focusOnHideNode;
     }
 
@@ -212,10 +212,18 @@
   }
 }
 
-// Export a type that lets you check if your Node is composed with Popupable
-const wrapper = () => Popupable( Node, 0 );
-export type PopupableNode = InstanceType<ReturnType<typeof wrapper>> & Node;
+type TPopupable = {
+  show(): void;
+  hide(): void;
+  shouldShowPopup(): boolean;
+  isShowingProperty: Property<boolean>;
+  get focusOnHideNode(): Node | null; // treat as protected
+  layout( bounds: Bounds2 ): void;
+  layoutBounds: Bounds2 | null;
+};
+
+export type PopupableNode = Node & TPopupable;
 
 sun.register( 'Popupable', Popupable );
 
-export default Popupable;
\ No newline at end of file
+export default Popupable as unknown as <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TPopupable>;
\ No newline at end of file
Index: dot/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/dot/tsconfig.json b/dot/tsconfig.json
--- a/dot/tsconfig.json	(revision aef01d114353684eb9678b4cab9c13ca1a9faa99)
+++ b/dot/tsconfig.json	(date 1714337263086)
@@ -4,6 +4,7 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../sherpa/lib/big-6.2.1.mjs"
   ]
 }
\ No newline at end of file
Index: scenery/js/layout/Sizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/Sizable.ts b/scenery/js/layout/Sizable.ts
--- a/scenery/js/layout/Sizable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/Sizable.ts	(date 1714337263172)
@@ -13,6 +13,8 @@
 import Dimension2 from '../../../dot/js/Dimension2.js';
 import assertMutuallyExclusiveOptions from '../../../phet-core/js/assertMutuallyExclusiveOptions.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
+import { TWidthSizable } from './WidthSizable.js';
+import { THeightSizable } from './HeightSizable.js';
 
 export const SIZABLE_SELF_OPTION_KEYS = [
   'preferredSize',
@@ -187,7 +189,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalPreferredWidth(): number | null {
+    public override _calculateLocalPreferredWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.preferredWidth !== null ) {
@@ -204,7 +206,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalPreferredHeight(): number | null {
+    public override _calculateLocalPreferredHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.preferredHeight !== null ) {
@@ -221,7 +223,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculatePreferredWidth(): number | null {
+    public override _calculatePreferredWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localPreferredWidth !== null ) {
@@ -237,7 +239,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculatePreferredHeight(): number | null {
+    public override _calculatePreferredHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localPreferredHeight !== null ) {
@@ -253,31 +255,31 @@
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantLocalMinimumWidth(): void {
+    public override _onReentrantLocalMinimumWidth(): void {
       this._updateMinimumWidthListener();
       this._updateMinimumHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantLocalMinimumHeight(): void {
+    public override _onReentrantLocalMinimumHeight(): void {
       this._updateMinimumWidthListener();
       this._updateMinimumHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantPreferredWidth(): void {
+    public override _onReentrantPreferredWidth(): void {
       this._updateLocalPreferredWidthListener();
       this._updateLocalPreferredHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantPreferredHeight(): void {
+    public override _onReentrantPreferredHeight(): void {
       this._updateLocalPreferredWidthListener();
       this._updateLocalPreferredHeightListener();
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalMinimumWidth(): number | null {
+    public override _calculateLocalMinimumWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.minimumWidth !== null ) {
@@ -293,7 +295,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalMinimumHeight(): number | null {
+    public override _calculateLocalMinimumHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.minimumHeight !== null ) {
@@ -309,7 +311,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateMinimumWidth(): number | null {
+    public override _calculateMinimumWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localMinimumWidth !== null ) {
@@ -325,7 +327,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateMinimumHeight(): number | null {
+    public override _calculateMinimumHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localMinimumHeight !== null ) {
@@ -356,12 +358,6 @@
   return SizableTrait;
 } );
 
-// Some typescript gymnastics to provide a user-defined type guard that treats something as Sizable
-// We need to define an unused function with a concrete type, so that we can extract the return type of the function
-// and provide a type for a Node that extends this type.
-const wrapper = () => Sizable( Node );
-export type SizableNode = InstanceType<ReturnType<typeof wrapper>>;
-
 const isSizable = ( node: Node ): node is SizableNode => {
   return node.widthSizable && node.heightSizable;
 };
@@ -369,6 +365,12 @@
   return node.extendsSizable;
 };
 
+type TSizable = TWidthSizable & THeightSizable & {
+  validateLocalPreferredSize(): void;
+};
+
+export type SizableNode = Node & TSizable;
+
 scenery.register( 'Sizable', Sizable );
-export default Sizable;
+export default Sizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TSizable>;
 export { isSizable, extendsSizable };
\ No newline at end of file
Index: scenery/js/accessibility/voicing/ReadingBlock.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/ReadingBlock.ts b/scenery/js/accessibility/voicing/ReadingBlock.ts
--- a/scenery/js/accessibility/voicing/ReadingBlock.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/ReadingBlock.ts	(date 1714337432833)
@@ -30,6 +30,7 @@
 import Utterance from '../../../../utterance-queue/js/Utterance.js';
 import TEmitter from '../../../../axon/js/TEmitter.js';
 import memoize from '../../../../phet-core/js/memoize.js';
+import { TVoicing } from './Voicing.js';
 
 const READING_BLOCK_OPTION_KEYS = [
   'readingBlockTagName',
@@ -382,8 +383,9 @@
 
     /**
      * If we created and own the voicingUtterance we can fully dispose of it.
+     * Must be public due to the mixin pattern.
      */
-    protected override cleanVoicingUtterance(): void {
+    public override cleanVoicingUtterance(): void {
       if ( this._voicingUtterance instanceof OwnedReadingBlockUtterance ) {
         this._voicingUtterance.dispose();
       }
@@ -422,9 +424,19 @@
   return ReadingBlockClass;
 } );
 
+type TReadingBlock = {
+  readingBlockActiveHighlightChangedEmitter: TEmitter;
+  isReadingBlock: true;
+  readingBlockActiveHighlight: Highlight;
+  readingBlockActivated: boolean;
+
+  set readingBlockNameResponse( content: VoicingResponse );
+  get readingBlockNameResponse(): ResolvedResponse;
+  setReadingBlockNameResponse( content: VoicingResponse ): void;
+} & TVoicing;
+
 // Export a type that lets you check if your Node is composed with ReadingBlock
-const wrapper = () => ReadingBlock( Node );
-export type ReadingBlockNode = InstanceType<ReturnType<typeof wrapper>>;
+export type ReadingBlockNode = Node & TReadingBlock;
 
 scenery.register( 'ReadingBlock', ReadingBlock );
-export default ReadingBlock;
\ No newline at end of file
+export default ReadingBlock as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TReadingBlock>;
\ No newline at end of file
Index: scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/Voicing.ts b/scenery/js/accessibility/voicing/Voicing.ts
--- a/scenery/js/accessibility/voicing/Voicing.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/Voicing.ts	(date 1714337263127)
@@ -28,13 +28,14 @@
 import ResponsePacket, { ResolvedResponse, SpeakableResolvedOptions, VoicingResponse } from '../../../../utterance-queue/js/ResponsePacket.js';
 import ResponsePatternCollection from '../../../../utterance-queue/js/ResponsePatternCollection.js';
 import Utterance, { TAlertable, UtteranceOptions } from '../../../../utterance-queue/js/Utterance.js';
-import { DelayedMutate, Instance, InteractiveHighlighting, InteractiveHighlightingOptions, Node, scenery, SceneryListenerFunction, voicingUtteranceQueue } from '../../imports.js';
+import { DelayedMutate, Instance, InteractiveHighlighting, InteractiveHighlightingOptions, Node, ReadingBlockUtterance, scenery, SceneryListenerFunction, voicingUtteranceQueue } from '../../imports.js';
 import { combineOptions } from '../../../../phet-core/js/optionize.js';
 import Constructor from '../../../../phet-core/js/types/Constructor.js';
 import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 import responseCollector from '../../../../utterance-queue/js/responseCollector.js';
 import TinyProperty from '../../../../axon/js/TinyProperty.js';
 import Tandem from '../../../../tandem/js/Tandem.js';
+import { TInteractiveHighlighting } from './InteractiveHighlighting.js';
 
 // Helps enforce that the utterance is defined.
 function assertUtterance( utterance: Utterance | null ): asserts utterance is Utterance {
@@ -98,14 +99,14 @@
   utterance?: SelfOptions['voicingUtterance'];
 } & SpeakableResolvedOptions;
 
-const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => {
 
   assert && assert( _.includes( inheritance( Type ), Node ), 'Only Node subtypes should compose Voicing' );
 
   const VoicingClass = DelayedMutate( 'Voicing', VOICING_OPTION_KEYS, class VoicingClass extends InteractiveHighlighting( Type ) {
 
     // ResponsePacket that holds all the supported responses to be Voiced
-    protected _voicingResponsePacket!: ResponsePacket;
+    public _voicingResponsePacket!: ResponsePacket;
 
     // The utterance that all responses are spoken through.
     protected _voicingUtterance: Utterance | null;
@@ -332,7 +333,7 @@
      * Use the provided function to create content to speak in response to input. The content is then added to the
      * back of the voicing UtteranceQueue.
      */
-    protected speakContent( content: TAlertable ): void {
+    public speakContent( content: TAlertable ): void {
 
       const notPhetioArchetype = !Tandem.PHET_IO_ENABLED || !this.isInsidePhetioArchetype();
 
@@ -475,6 +476,7 @@
           this.cleanVoicingUtterance();
         }
 
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         Voicing.registerUtteranceToVoicingNode( utterance, this );
         this._voicingUtterance = utterance;
       }
@@ -626,6 +628,8 @@
         this._voicingUtterance.dispose();
       }
       else if ( this._voicingUtterance && !this._voicingUtterance.isDisposed ) {
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         Voicing.unregisterUtteranceToVoicingNode( this._voicingUtterance, this );
       }
     }
@@ -667,10 +671,9 @@
  * if the voicingNode is globally visible and voicingVisible in the display.
  * @static
  */
-Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
+Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: TVoicing ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
 
-  // @ts-expect-error Accessing a private member because this is meant to be "private to the file".
   const voicingCanSpeakProperty = voicingNode._voicingCanSpeakProperty;
   if ( !existingCanAnnounceProperties.includes( voicingCanSpeakProperty ) ) {
     utterance.voicingCanAnnounceProperties = existingCanAnnounceProperties.concat( [ voicingCanSpeakProperty ] );
@@ -684,7 +687,6 @@
 Voicing.unregisterUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
 
-  // @ts-expect-error Accessing a private member because this is meant to be "private to the file".
   const voicingCanSpeakProperty = voicingNode._voicingCanSpeakProperty;
   const index = existingCanAnnounceProperties.indexOf( voicingCanSpeakProperty );
   assert && assert( index > -1, 'voicingNode.voicingCanSpeakProperty is not on the Utterance, was it not registered?' );
@@ -726,9 +728,49 @@
   utterance.voicingCanAnnounceProperties = withoutBothProperties;
 };
 
-// Export a type that lets you check if your Node is composed with Voicing.
-const wrapper = () => Voicing( Node );
-export type VoicingNode = InstanceType<ReturnType<typeof wrapper>>;
+export type TVoicing = {
+  _voicingResponsePacket: ResponsePacket;
+  setVoicingUtterance( utterance: ReadingBlockUtterance ): void;
+  set voicingUtterance( utterance: ReadingBlockUtterance );
+  get voicingUtterance(): ReadingBlockUtterance;
+  getVoicingUtterance(): ReadingBlockUtterance;
+  setVoicingNameResponse(): void;
+  getVoicingNameResponse(): IntentionalAny;
+  setVoicingObjectResponse(): void;
+  getVoicingObjectResponse(): IntentionalAny;
+  setVoicingContextResponse(): void;
+  getVoicingContextResponse(): IntentionalAny;
+  setVoicingHintResponse(): void;
+  getVoicingHintResponse(): IntentionalAny;
+  setVoicingResponsePatternCollection(): void;
+  getVoicingResponsePatternCollection(): IntentionalAny;
+
+  cleanVoicingUtterance(): void;
+  _voicingUtterance: ReadingBlockUtterance;
+
+  collectResponse( providedOptions?: SpeakingOptions ): TAlertable;
+
+  voicingIgnoreVoicingManagerProperties: boolean;
+  voicingNameResponse: ResolvedResponse;
+  voicingSpeakResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingSpeakFullResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingSpeakContextResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingObjectResponse: ResolvedResponse;
+  voicingFocusListener: SceneryListenerFunction<FocusEvent> | null;
+  voicingHintResponse: ResolvedResponse;
+  voicingContextResponse: ResolvedResponse;
+  voicingSpeakNameResponse: ( providedOptions?: SpeakingOptions ) => void;
+
+  _voicingCanSpeakProperty: TinyProperty<boolean>;
+
+  speakContent( content: TAlertable ): void;
+
+  defaultFocusListener(): void;
+  initialize( ...args: IntentionalAny[] ): ThisType<IntentionalAny>;
+
+} & TInteractiveHighlighting;
+
+export type VoicingNode = Node & TVoicing;
 
 scenery.register( 'Voicing', Voicing );
-export default Voicing;
\ No newline at end of file
+export default Voicing as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TVoicing>;
\ No newline at end of file
Index: scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1714337263104)
@@ -647,9 +647,21 @@
   return InteractiveHighlightingClass;
 } );
 
-// Provides a way to determine if a Node is composed with InteractiveHighlighting by type
-const wrapper = () => InteractiveHighlighting( Node );
-export type InteractiveHighlightingNode = InstanceType<ReturnType<typeof wrapper>>;
+export type TInteractiveHighlighting = {
+  isInteractiveHighlightActiveProperty: TReadOnlyProperty<boolean>;
+  interactiveHighlightEnabled: boolean;
+  isInteractiveHighlighting: boolean;
+  interactiveHighlightChangedEmitter: TEmitter;
+  handleHighlightActiveChange(): void;
+
+  // we wish these was public, but they are used elsewhere and appears in the mixin, so must be public.
+  displays: Record<string, Display>;
+  getDescendantsUseHighlighting( trail: Trail ): boolean;
+  interactiveHighlightLayerable: boolean;
+  interactiveHighlight: Highlight;
+};
+
+export type InteractiveHighlightingNode = Node & TInteractiveHighlighting;
 
 scenery.register( 'InteractiveHighlighting', InteractiveHighlighting );
-export default InteractiveHighlighting;
\ No newline at end of file
+export default InteractiveHighlighting as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TInteractiveHighlighting>;
\ No newline at end of file
Index: scenery/js/layout/HeightSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/HeightSizable.ts b/scenery/js/layout/HeightSizable.ts
--- a/scenery/js/layout/HeightSizable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/HeightSizable.ts	(date 1714337432847)
@@ -367,11 +367,39 @@
   return HeightSizableTrait;
 } );
 
+export type THeightSizable = {
+  readonly preferredHeightProperty: TinyProperty<number | null>;
+  readonly minimumHeightProperty: TinyProperty<number | null>;
+  readonly localPreferredHeightProperty: TinyProperty<number | null>;
+  readonly localMinimumHeightProperty: TinyProperty<number | null>;
+  readonly isHeightResizableProperty: TinyProperty<boolean>;
+
+  preferredHeight: number | null;
+  minimumHeight: number | null;
+  localPreferredHeight: number | null;
+  localMinimumHeight: number | null;
+
+  _updateLocalPreferredHeightListener: () => void;
+  _updatePreferredHeightListener: () => void;
+  _updateLocalMinimumHeightListener: () => void;
+  _updateMinimumHeightListener: () => void;
+
+  validateLocalPreferredHeight(): void;
+
+  _calculateLocalPreferredHeight(): number | null;
+  _calculatePreferredHeight(): number | null;
+  _onReentrantLocalMinimumHeight(): void;
+  _onReentrantPreferredHeight(): void;
+  _calculateLocalMinimumHeight(): number | null;
+  _calculateMinimumHeight(): number | null;
+
+  set heightSizable( value: boolean );
+};
+
 // Some typescript gymnastics to provide a user-defined type guard that treats something as HeightSizable.
 // We need to define an unused function with a concrete type, so that we can extract the return type of the function
 // and provide a type for a Node that extends this type.
-const wrapper = () => HeightSizable( Node );
-export type HeightSizableNode = InstanceType<ReturnType<typeof wrapper>>;
+export type HeightSizableNode = Node & THeightSizable;
 
 const isHeightSizable = ( node: Node ): node is HeightSizableNode => {
   return node.heightSizable;
@@ -381,5 +409,5 @@
 };
 
 scenery.register( 'HeightSizable', HeightSizable );
-export default HeightSizable;
+export default HeightSizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<THeightSizable>;
 export { isHeightSizable, extendsHeightSizable };
\ No newline at end of file
Index: scenery/js/imports.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/imports.ts b/scenery/js/imports.ts
--- a/scenery/js/imports.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/imports.ts	(date 1714337279255)
@@ -180,7 +180,7 @@
 export { default as voicingManager } from './accessibility/voicing/voicingManager.js';
 export { default as voicingUtteranceQueue } from './accessibility/voicing/voicingUtteranceQueue.js';
 export { default as Voicing } from './accessibility/voicing/Voicing.js';
-export type { VoicingOptions, VoicingNode, SpeakingOptions } from './accessibility/voicing/Voicing.js';
+export type { VoicingOptions, VoicingNode, SpeakingOptions, TVoicing } from './accessibility/voicing/Voicing.js';
 export { default as ReadingBlockUtterance } from './accessibility/voicing/ReadingBlockUtterance.js';
 export type { ReadingBlockUtteranceOptions } from './accessibility/voicing/ReadingBlockUtterance.js';
 export { default as FocusDisplayedController } from './accessibility/FocusDisplayedController.js';
Index: scenery/js/layout/WidthSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/WidthSizable.ts b/scenery/js/layout/WidthSizable.ts
--- a/scenery/js/layout/WidthSizable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/WidthSizable.ts	(date 1714337263176)
@@ -369,12 +369,6 @@
   return WidthSizableTrait;
 } );
 
-// Some typescript gymnastics to provide a user-defined type guard that treats something as widthSizable
-// We need to define an unused function with a concrete type, so that we can extract the return type of the function
-// and provide a type for a Node that extends this type.
-const wrapper = () => WidthSizable( Node );
-export type WidthSizableNode = InstanceType<ReturnType<typeof wrapper>>;
-
 const isWidthSizable = ( node: Node ): node is WidthSizableNode => {
   return node.widthSizable;
 };
@@ -382,6 +376,40 @@
   return node.extendsWidthSizable;
 };
 
+export type TWidthSizable = {
+  readonly preferredWidthProperty: TinyProperty<number | null>;
+  readonly minimumWidthProperty: TinyProperty<number | null>;
+  readonly localPreferredWidthProperty: TinyProperty<number | null>;
+  readonly localMinimumWidthProperty: TinyProperty<number | null>;
+  readonly isWidthResizableProperty: TinyProperty<boolean>;
+
+  preferredWidth: number | null;
+  minimumWidth: number | null;
+  localPreferredWidth: number | null;
+  localMinimumWidth: number | null;
+
+  _updateLocalPreferredWidthListener: () => void;
+  _updatePreferredWidthListener: () => void;
+  _updateLocalMinimumWidthListener: () => void;
+  _updateMinimumWidthListener: () => void;
+
+  validateLocalPreferredWidth(): void;
+
+  _calculateLocalPreferredWidth(): number | null;
+  _calculatePreferredWidth(): number | null;
+  _onReentrantLocalMinimumWidth(): void;
+  _onReentrantPreferredWidth(): void;
+  _calculateLocalMinimumWidth(): number | null;
+  _calculateMinimumWidth(): number | null;
+
+  set widthSizable( value: boolean );
+};
+
+// Some typescript gymnastics to provide a user-defined type guard that treats something as widthSizable
+// We need to define an unused function with a concrete type, so that we can extract the return type of the function
+// and provide a type for a Node that extends this type.
+export type WidthSizableNode = Node & TWidthSizable;
+
 scenery.register( 'WidthSizable', WidthSizable );
-export default WidthSizable;
+export default WidthSizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TWidthSizable>;
 export { isWidthSizable, extendsWidthSizable };
\ No newline at end of file
Index: utterance-queue/js/AriaLiveAnnouncer.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/utterance-queue/js/AriaLiveAnnouncer.ts b/utterance-queue/js/AriaLiveAnnouncer.ts
--- a/utterance-queue/js/AriaLiveAnnouncer.ts	(revision 0297e932f21a53d59a808585226617df6183dfc0)
+++ b/utterance-queue/js/AriaLiveAnnouncer.ts	(date 1714337279295)
@@ -157,6 +157,8 @@
 
       if ( options.ariaLivePriority === AriaLive.POLITE ) {
         const element = this.politeElements[ this.politeElementIndex ];
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         this.updateLiveElement( element, announceText, utterance );
 
         // update index for next time
@@ -164,6 +166,8 @@
       }
       else if ( options.ariaLivePriority === AriaLive.ASSERTIVE ) {
         const element = this.assertiveElements[ this.assertiveElementIndex ];
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         this.updateLiveElement( element, announceText, utterance );
         // update index for next time
         this.assertiveElementIndex = ( this.assertiveElementIndex + 1 ) % this.assertiveElements.length;
Index: scenery/js/accessibility/voicing/voicingUtteranceQueue.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts b/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts
--- a/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts	(date 1714337263130)
@@ -10,6 +10,7 @@
 
 import UtteranceQueue from '../../../../utterance-queue/js/UtteranceQueue.js';
 import { scenery, voicingManager } from '../../imports.js';
+import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 
 const voicingUtteranceQueue = new UtteranceQueue( voicingManager, {
   featureSpecificAnnouncingControlPropertyName: 'voicingCanAnnounceProperty'
@@ -19,4 +20,4 @@
 voicingUtteranceQueue.enabled = false;
 
 scenery.register( 'voicingUtteranceQueue', voicingUtteranceQueue );
-export default voicingUtteranceQueue;
\ No newline at end of file
+export default voicingUtteranceQueue as IntentionalAny;
\ No newline at end of file
Index: scenery/js/listeners/SpriteListenable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/listeners/SpriteListenable.ts b/scenery/js/listeners/SpriteListenable.ts
--- a/scenery/js/listeners/SpriteListenable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/listeners/SpriteListenable.ts	(date 1714337263210)
@@ -55,4 +55,4 @@
 } );
 
 scenery.register( 'SpriteListenable', SpriteListenable );
-export default SpriteListenable;
\ No newline at end of file
+export default SpriteListenable as unknown as PressListener;
\ No newline at end of file
Index: chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig-core.json b/chipper/tsconfig-core.json
--- a/chipper/tsconfig-core.json	(revision b9b8d46a42df39318878f027a9855be68c5b82b4)
+++ b/chipper/tsconfig-core.json	(date 1714337263069)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+    "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: scenery/js/nodes/Paintable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/nodes/Paintable.ts b/scenery/js/nodes/Paintable.ts
--- a/scenery/js/nodes/Paintable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/nodes/Paintable.ts	(date 1714337279236)
@@ -829,9 +829,62 @@
 Paintable.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
 
 export {
-  Paintable as default,
   PAINTABLE_DRAWABLE_MARK_FLAGS,
   PAINTABLE_OPTION_KEYS,
   DEFAULT_OPTIONS,
   DEFAULT_OPTIONS as PAINTABLE_DEFAULT_OPTIONS
-};
\ No newline at end of file
+};
+
+export type MyPaintable = {
+  // (scenery-internal)
+  fill: TPaint;
+  fillPickable: boolean;
+
+  // (scenery-internal)
+  stroke: TPaint;
+  strokePickable: boolean;
+
+  // (scenery-internal)
+  cachedPaints: TPaint[];
+  lineDrawingStyles: LineStyles;
+
+  lineWidth: number;
+  lineCap: LineCap;
+  lineJoin: LineJoin;
+  miterLimit: number;
+  lineDash: number[];
+  lineDashOffset: number;
+
+  getStrokeRendererBitmask(): number;
+  getStroke(): TPaint;
+  hasStroke(): boolean;
+  hasPaintableStroke(): boolean;
+  hasLineDash(): boolean;
+  getLineJoin(): LineJoin;
+  getLineWidth(): number;
+
+  _stroke: TPaint;
+
+  setStroke<T>( stroke: TPaint ): T;
+  setLineStyles<T>( lineStyles: LineStyles ): T;
+
+  setFill<T>( fill: TPaint ): T;
+  setLineWidth<T>( lineWidth: number ): T;
+
+  _strokePickable: boolean;
+
+  invalidateStroke(): void;
+  getFillRendererBitmask(): number;
+
+  _fillPickable: boolean;
+
+  invalidateFill(): void;
+  getLineCap(): LineCap;
+
+  _lineDrawingStyles: LineStyles;
+  getLineStyles(): LineStyles;
+
+  getMiterLimit(): number;
+};
+
+export default Paintable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<MyPaintable>;
\ No newline at end of file
Index: utterance-queue/js/ResponsePacket.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/utterance-queue/js/ResponsePacket.ts b/utterance-queue/js/ResponsePacket.ts
--- a/utterance-queue/js/ResponsePacket.ts	(revision 0297e932f21a53d59a808585226617df6183dfc0)
+++ b/utterance-queue/js/ResponsePacket.ts	(date 1714337279299)
@@ -23,7 +23,7 @@
 import utteranceQueueNamespace from './utteranceQueueNamespace.js';
 
 // The text sent to an Announcer technology, after resolving it from potentially more complicated structures holding a response
-export type ResolvedResponse = string | number | null;
+export type ResolvedResponse = string | number | null | TReadOnlyProperty<string>;
 
 type ResponseCreator = TReadOnlyProperty<string> | ( () => ResolvedResponse );
 export type VoicingResponse = ResponseCreator | ResolvedResponse;
Index: scenery/js/layout/constraints/FlowConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/FlowConfigurable.ts b/scenery/js/layout/constraints/FlowConfigurable.ts
--- a/scenery/js/layout/constraints/FlowConfigurable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/FlowConfigurable.ts	(date 1714337263154)
@@ -29,6 +29,7 @@
 import WithoutNull from '../../../../phet-core/js/types/WithoutNull.js';
 import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 import TEmitter from '../../../../axon/js/TEmitter.js';
+import { TMarginLayoutConfigurable } from './MarginLayoutConfigurable.js';
 
 const FLOW_CONFIGURABLE_OPTION_KEYS = [
   'orientation',
@@ -223,6 +224,24 @@
   };
 } );
 
+type TFlowConfigurable = {
+  _orientation: Orientation;
+  _align: LayoutAlign | null;
+  _stretch: boolean | null;
+  _grow: number | null;
+
+  orientationChangedEmitter: TEmitter;
+
+  mutateConfigurable( options?: FlowConfigurableOptions ): void;
+  setConfigToBaseDefault(): void;
+  setConfigToInherit(): void;
+
+  orientation: LayoutOrientation;
+  align: HorizontalLayoutAlign | VerticalLayoutAlign | null;
+  stretch: boolean | null;
+  grow: number | null;
+} & TMarginLayoutConfigurable;
+
 scenery.register( 'FlowConfigurable', FlowConfigurable );
-export default FlowConfigurable;
+export default FlowConfigurable as unknown as <SuperType extends Constructor>( type: SuperType ) => SuperType & Constructor<TFlowConfigurable>;
 export { FLOW_CONFIGURABLE_OPTION_KEYS };
\ No newline at end of file

@samreid
Copy link
Member

samreid commented Apr 28, 2024

This patch brings projectile data lab and a standalone sim projectile sampling distributions along (adds support for another mixin in scenery)

Subject: [PATCH] imageable
---
Index: scenery/js/util/DelayedMutate.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/util/DelayedMutate.ts b/scenery/js/util/DelayedMutate.ts
--- a/scenery/js/util/DelayedMutate.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/util/DelayedMutate.ts	(date 1714337996844)
@@ -38,7 +38,7 @@
  * @param keys - An array of the mutate option names that should be delayed
  * @param type - The class we're mixing into
  */
-const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => {
   // We typecast these to strings to satisfy the type-checker without large amounts of grief. It doesn't seem to be
   // able to parse that we're using the same keys for each call of this.
   const pendingOptionsKey = `_${name}PendingOptions` as '_fakePendingOptionsType';
@@ -84,4 +84,4 @@
 };
 
 scenery.register( 'DelayedMutate', DelayedMutate );
-export default DelayedMutate;
\ No newline at end of file
+export default DelayedMutate as <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => SuperType;
\ No newline at end of file
Index: scenery/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/tsconfig.json b/scenery/tsconfig.json
--- a/scenery/tsconfig.json	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/tsconfig.json	(date 1714337711604)
@@ -4,6 +4,449 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+
+    "../tandem/js/**/*",
+
+    "../chipper/js/sim-tests/qunitStart.js",
+    "../phet-io/js/phetioEngine.ts",
+
+    "../phet-core/js/isHMR.ts",
+    "../phet-core/js/Namespace.ts",
+    "../phet-core/js/phetCore.ts",
+    "../phet-core/js/extend.ts",
+    "../phet-core/js/types/IntentionalAny.ts",
+    "../phet-core/js/deprecationWarning.ts",
+    "../phet-core/js/merge.ts",
+    "../phet-core/js/types/RequiredKeys.ts",
+    "../phet-core/js/types/OptionalKeys.ts",
+    "../phet-core/js/EnumerationDeprecated.js",
+    "../phet-core/js/optionize.ts",
+    "../axon/js/Validation.ts",
+    "../phet-core/js/types/PickRequired.ts",
+    "../phet-core/js/assertMutuallyExclusiveOptions.ts",
+    "../axon/js/Timer.ts",
+    "../phet-core/js/types/Constructor.ts",
+    "../phet-core/js/EnumerationValue.ts",
+    "../phet-core/js/TEnumeration.ts",
+    "../phet-core/js/inheritance.ts",
+    "../phet-core/js/Enumeration.ts",
+    "../axon/js/animationFrameTimer.ts",
+    "../phet-core/js/types/StrictOmit.ts",
+    "../phet-core/js/arrayRemove.ts",
+    "../axon/js/Disposable.ts",
+    "../axon/js/PropertyStatePhase.ts",
+    "../axon/js/PropertyStateHandler.ts",
+    "../axon/js/propertyStateHandlerSingleton.ts",
+    "../axon/js/units.ts",
+    "../axon/js/ReadOnlyProperty.ts",
+    "../axon/js/TReadOnlyProperty.ts",
+    "../axon/js/TProperty.ts",
+    "../axon/js/TinyProperty.ts",
+    "../axon/js/Emitter.ts",
+    "../axon/js/validate.ts",
+    "../dot/js/Vector4.ts",
+    "../dot/js/Vector3.ts",
+    "../phet-core/js/Pool.ts",
+    "../dot/js/dot.js",
+    "../dot/js/Utils.js",
+    "../dot/js/Matrix4.js",
+    "../dot/js/toSVGNumber.js",
+    "../dot/js/Vector2.ts",
+    "../dot/js/Matrix3.ts",
+    "../dot/js/Range.ts",
+    "../phet-core/js/Orientation.ts",
+    "../dot/js/Bounds2.ts",
+    "../axon/js/axon.ts",
+    "../dot/js/Random.ts",
+    "../dot/js/dotRandom.js",
+    "../axon/js/TEmitter.ts",
+    "../axon/js/TinyEmitter.ts",
+    "../phet-core/js/detectPrefix.ts",
+    "../dot/js/Ray2.ts",
+    "../dot/js/Transform3.js",
+    "../phet-core/js/platform.ts",
+    "../axon/js/Property.ts",
+    "../phet-core/js/detectPrefixEvent.ts",
+    "../phet-core/js/Poolable.ts",
+    "../axon/js/Multilink.ts",
+    "../axon/js/DerivedProperty.ts",
+    "../axon/js/BooleanProperty.ts",
+    "../phet-core/js/isArray.ts",
+    "../dot/js/EigenvalueDecomposition.js",
+    "../dot/js/LUDecomposition.js",
+    "../dot/js/QRDecomposition.js",
+    "../dot/js/Matrix.js",
+    "../dot/js/SingularValueDecomposition.js",
+    "../dot/js/Complex.ts",
+    "../phet-core/js/types/KeysMatching.ts",
+    "../phet-core/js/cleanArray.ts",
+    "../kite/js/kite.ts",
+    "../kite/js/util/LineStyles.ts",
+    "../kite/js/util/Overlap.ts",
+    "../kite/js/util/RayIntersection.ts",
+    "../kite/js/util/SegmentIntersection.ts",
+    "../kite/js/util/svgNumber.ts",
+    "../kite/js/util/intersectConicMatrices.ts",
+    "../kite/js/parser/svgPath.js",
+    "../kite/js/segments/Segment.ts",
+    "../kite/js/segments/Line.ts",
+    "../kite/js/segments/Quadratic.ts",
+    "../kite/js/segments/Cubic.ts",
+    "../kite/js/segments/Arc.ts",
+    "../kite/js/segments/EllipticalArc.ts",
+    "../kite/js/util/Subpath.ts",
+    "../kite/js/Shape.ts",
+    "../kite/js/ops/HalfEdge.js",
+    "../kite/js/ops/Vertex.js",
+    "../kite/js/ops/Edge.js",
+    "../kite/js/ops/Face.js",
+    "../kite/js/ops/Loop.js",
+    "../kite/js/ops/Boundary.js",
+    "../kite/js/ops/BoundsIntersection.ts",
+    "../kite/js/ops/SegmentTree.ts",
+    "../kite/js/ops/EdgeSegmentTree.ts",
+    "../kite/js/ops/VertexSegmentTree.ts",
+    "../kite/js/ops/Graph.js",
+    "../kite/js/imports.ts",
+    "../dot/js/BinPacker.ts",
+    "../dot/js/Dimension2.ts",
+    "../phet-core/js/stripEmbeddingMarks.ts",
+    "../axon/js/StringProperty.ts",
+    "../utterance-queue/js/utteranceQueueNamespace.ts",
+    "../utterance-queue/js/ResponsePatternCollection.ts",
+    "../axon/js/PhetioProperty.ts",
+    "../axon/js/TRangedProperty.ts",
+    "../chipper/js/data/localeInfoModule.js",
+    "../phetcommon/js/phetcommon.js",
+    "../phetcommon/js/util/StringUtils.js",
+    "../axon/js/DynamicProperty.ts",
+    "../axon/js/NumberProperty.ts",
+    "../utterance-queue/js/responseCollector.ts",
+    "../utterance-queue/js/ResponsePacket.ts",
+    "../utterance-queue/js/Utterance.ts",
+    "../axon/js/stepTimer.ts",
+    "../utterance-queue/js/Announcer.ts",
+    "../utterance-queue/js/AriaLiveAnnouncer.ts",
+    "../utterance-queue/js/UtteranceWrapper.ts",
+    "../phet-core/js/memoize.ts",
+    "../phet-core/js/arrayDifference.ts",
+    "../utterance-queue/js/UtteranceQueue.ts",
+    "../axon/js/TinyForwardingProperty.ts",
+    "../axon/js/EnabledProperty.ts",
+    "../axon/js/TinyStaticProperty.ts",
+    "../phet-core/js/types/NotNull.ts",
+    "../phet-core/js/types/WithoutNull.ts",
+    "../phet-core/js/assertHasProperties.ts",
+    "../phet-core/js/types/WithRequired.ts",
+    "../phet-core/js/escapeHTML.ts",
+    "../phet-core/js/extendDefined.ts",
+    "../phet-core/js/mutate.ts",
+    "../phet-core/js/types/PickOptional.ts",
+    "../joist/js/joist.ts",
+    "../axon/js/EnabledComponent.ts",
+    "../utterance-queue/js/SpeechSynthesisParentPolyfill.ts",
+    "../joist/js/i18n/localeProperty.ts",
+    "../utterance-queue/js/SpeechSynthesisAnnouncer.ts",
+    "../dot/js/Permutation.ts",
+    "../axon/js/CallbackTimer.ts",
+    "../axon/js/createObservableArray.ts",
+    "../phet-core/js/types/NotUndefined.ts",
+    "../phet-core/js/types/RequiredOption.ts",
+    "../phetcommon/js/view/ModelViewTransform2.ts",
+    "../phet-core/js/EnumerationMap.ts",
+    "../phet-core/js/OrientationPair.ts",
+    "../dot/js/Vector2Property.ts",
+    "../sherpa/lib/himalaya-1.1.0.js",
+    "../phet-core/js/types/CollapsePropertyValue.ts",
+    "../phet-core/js/types/KeysNotMatching.ts",
+    "../axon/js/DerivedStringProperty.ts",
+    "../axon/js/EnumerationDeprecatedProperty.js",
+    "../axon/js/MappedProperty.ts",
+    "../axon/js/PatternStringProperty.ts",
+    "../axon/js/TinyOverrideProperty.ts",
+    "../axon/js/UnitConversionProperty.ts",
+    "../dot/js/Ray3.ts",
+    "../dot/js/Bounds3.ts",
+    "../dot/js/Combination.ts",
+    "../dot/js/CompletePiecewiseLinearFunction.ts",
+    "../dot/js/ConvexHull2.js",
+    "../dot/js/DampedHarmonic.ts",
+    "../dot/js/DelaunayTriangulation.js",
+    "../dot/js/LinearFunction.ts",
+    "../dot/js/MatrixOps3.js",
+    "../dot/js/Plane3.ts",
+    "../dot/js/Quaternion.js",
+    "../dot/js/Rectangle.js",
+    "../dot/js/Sphere3.js",
+    "../dot/js/Transform4.js",
+    "../dot/js/UnivariatePolynomial.ts",
+    "../phet-core/js/collect.ts",
+    "../phet-core/js/dimensionForEach.ts",
+    "../phet-core/js/dimensionMap.ts",
+    "../phet-core/js/EventTimer.ts",
+    "../phet-core/js/interleave.ts",
+    "../phet-core/js/loadScript.ts",
+    "../phet-core/js/pairs.ts",
+    "../phet-core/js/partition.ts",
+    "../utterance-queue/js/ActivationUtterance.ts",
+    "../utterance-queue/js/ValueChangeUtterance.ts",
+    "../axon/js/main.ts",
+    "../dot/js/main.js",
+    "../kite/js/main.js",
+    "../phet-core/js/main.ts",
+    "../utterance-queue/js/main.ts",
+    "../joist/js/i18n/fallbackLocalesProperty.ts",
+    "../joist/js/i18n/localeOrderProperty.ts",
+    "../chipper/js/chipper.ts",
+    "../chipper/js/LocalizedStringProperty.ts",
+    "../chipper/js/LocalizedString.ts",
+    "../chipper/js/getStringModule.ts",
+    "../scenery-phet/js/sceneryPhet.ts",
+    "../scenery-phet/js/SceneryPhetStrings.ts",
+    "../scenery-phet/js/accessibility/PDOMSectionNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ControlAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/PlayAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ScreenSummaryNode.ts",
+    "../joist/js/JoistStrings.ts",
+    "../joist/js/ScreenIcon.ts",
+    "../joist/js/ScreenView.ts",
+    "../joist/js/TModel.ts",
+    "../sun/js/sun.ts",
+    "../phet-core/js/gracefulBind.ts",
+    "../sun/js/Popupable.ts",
+    "../tambo/js/tambo.ts",
+    "../phet-core/js/asyncLoader.ts",
+    "../tambo/js/base64SoundToByteArray.ts",
+    "../tambo/js/WrappedAudioBuffer.ts",
+    "../tambo/js/phetAudioContext.ts",
+    "../tambo/sounds/emptyApartmentBedroom06Resampled_mp3.js",
+    "../tambo/js/audioContextStateChangeMonitor.ts",
+    "../tambo/js/soundConstants.ts",
+    "../tambo/js/SoundLevelEnum.ts",
+    "../tambo/js/sound-generators/SoundGenerator.ts",
+    "../scenery-phet/js/sceneryPhetQueryParameters.ts",
+    "../tambo/js/SoundUtils.ts",
+    "../tambo/js/sound-generators/SoundClip.ts",
+    "../tambo/sounds/grab_mp3.js",
+    "../tambo/sounds/release_mp3.js",
+    "../phet-core/js/documentation/InstanceRegistry.ts",
+    "../scenery-phet/images/measuringTape_png.ts",
+    "../scenery-phet/js/PhetFont.ts",
+    "../scenery-phet/js/RichKeyboardDragListener.ts",
+    "../scenery-phet/js/RichDragListener.ts",
+    "../tambo/sounds/radioButtonV2_mp3.js",
+    "../tambo/js/TSoundPlayer.ts",
+    "../tambo/js/multiSelectionSoundPlayerFactory.ts",
+    "../sun/js/AquaRadioButton.ts",
+    "../sun/js/GroupItemOptions.ts",
+    "../joist/js/preferences/PreferencesStorage.ts",
+    "../joist/js/i18n/regionAndCultureProperty.ts",
+    "../joist/js/preferences/PreferencesModel.ts",
+    "../joist/js/DynamicStringTest.ts",
+    "../joist/js/HighlightVisibilityController.ts",
+    "../tambo/sounds/checkboxChecked_mp3.js",
+    "../tambo/js/sound-generators/SoundClipPlayer.ts",
+    "../tambo/sounds/checkboxUnchecked_mp3.js",
+    "../sherpa/js/fontawesome-4/checkEmptySolidShape.js",
+    "../sherpa/js/fontawesome-4/checkSquareOSolidShape.js",
+    "../tambo/js/shared-sound-players/checkboxCheckedSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/checkboxUncheckedSoundPlayer.ts",
+    "../tambo/sounds/generalButton_mp3.js",
+    "../sun/js/buttons/ButtonModel.ts",
+    "../sun/js/buttons/ButtonInteractionState.ts",
+    "../sun/js/buttons/PushButtonModel.ts",
+    "../sun/js/buttons/RadioButtonInteractionState.ts",
+    "../sun/js/ColorConstants.ts",
+    "../sun/js/buttons/TButtonAppearanceStrategy.ts",
+    "../sun/js/buttons/TContentAppearanceStrategy.ts",
+    "../sun/js/buttons/ButtonNode.ts",
+    "../tambo/js/shared-sound-players/pushButtonSoundPlayer.ts",
+    "../sun/js/buttons/PushButtonInteractionStateProperty.ts",
+    "../sun/js/buttons/RectangularButton.ts",
+    "../sun/js/ToggleNode.ts",
+    "../tambo/sounds/stepBack_mp3.js",
+    "../tambo/sounds/stepForward_mp3.js",
+    "../sun/js/buttons/ToggleButtonModel.ts",
+    "../tambo/js/shared-sound-players/toggleOffSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/toggleOnSoundPlayer.ts",
+    "../sun/js/buttons/ToggleButtonInteractionStateProperty.ts",
+    "../sun/js/BooleanToggleNode.ts",
+    "../sun/js/buttons/RectangularToggleButton.ts",
+    "../sun/js/buttons/BooleanRectangularToggleButton.ts",
+    "../scenery-phet/js/MeasuringTapeNode.ts",
+    "../sun/js/Panel.ts",
+    "../sun/js/AquaRadioButtonGroup.ts",
+    "../joist/js/SimDisplay.ts",
+    "../sun/js/Checkbox.ts",
+    "../axon/js/EnumerationProperty.ts",
+    "../sun/js/buttons/RectangularPushButton.ts",
+    "../sun/js/ExpandCollapseButton.ts",
+    "../scenery-phet/js/keyboard/KeyNode.ts",
+    "../scenery-phet/js/PlusShape.ts",
+    "../scenery-phet/js/PlusNode.ts",
+    "../scenery-phet/js/keyboard/ArrowKeyNode.ts",
+    "../scenery-phet/js/keyboard/LetterKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSectionRow.ts",
+    "../scenery-phet/js/keyboard/TextKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpIconFactory.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/NumberKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/BasicActionsKeyboardHelpSection.ts",
+    "../tambo/js/sound-generators/MultiClip.ts",
+    "../joist/sounds/screenSelectionHomeV3_mp3.js",
+    "../joist/sounds/switchingScreenSelectorIcons003_mp3.js",
+    "../scenery-phet/js/PhetColorScheme.ts",
+    "../joist/js/Frame.ts",
+    "../joist/js/HomeScreenSoundGenerator.ts",
+    "../joist/js/HomeScreenButton.ts",
+    "../joist/js/HomeScreenKeyboardHelpContent.ts",
+    "../joist/js/HomeScreenModel.ts",
+    "../joist/js/HomeScreenView.ts",
+    "../dot/js/RunningAverage.js",
+    "../tambo/sounds/generalClose_mp3.js",
+    "../tambo/sounds/generalOpen_mp3.js",
+    "../phet-core/js/getGlobal.ts",
+    "../scenery-phet/js/buttons/CloseButton.ts",
+    "../tambo/js/shared-sound-players/generalCloseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalOpenSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/nullSoundPlayer.ts",
+    "../sun/js/SunStrings.ts",
+    "../joist/js/HighlightNode.ts",
+    "../sun/js/Dialog.ts",
+    "../joist/images/keyboardIconOnWhite_png.ts",
+    "../joist/images/keyboardIcon_png.ts",
+    "../joist/js/JoistButton.ts",
+    "../joist/js/KeyboardHelpDialog.ts",
+    "../tambo/sounds/switchToLeft_mp3.js",
+    "../tambo/sounds/switchToRight_mp3.js",
+    "../tambo/js/shared-sound-players/switchToLeftSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/switchToRightSoundPlayer.ts",
+    "../sun/js/ToggleSwitch.ts",
+    "../joist/js/preferences/PreferencesPanelSection.ts",
+    "../joist/js/preferences/PreferencesDialogConstants.ts",
+    "../tambo/sounds/generalBoundaryBoop_mp3.js",
+    "../tambo/sounds/generalSoftClick_mp3.js",
+    "../tambo/js/shared-sound-players/generalBoundaryBoopSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalSoftClickSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleValueHandler.ts",
+    "../sun/js/SliderTrack.ts",
+    "../sun/js/SunConstants.ts",
+    "../phet-core/js/swapObjectKeys.ts",
+    "../tambo/js/sound-generators/ValueChangeSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleSlider.ts",
+    "../sun/js/DefaultSliderTrack.ts",
+    "../sun/js/SliderThumb.ts",
+    "../sun/js/SliderTick.ts",
+    "../sun/js/Slider.ts",
+    "../scenery-phet/js/MathSymbols.ts",
+    "../sun/js/buttons/ArrowButton.ts",
+    "../sun/js/HSlider.ts",
+    "../scenery-phet/js/NumberDisplay.ts",
+    "../sun/js/ComboBoxListItemNode.ts",
+    "../sun/js/ComboBoxButton.ts",
+    "../sun/js/ComboBoxListBox.ts",
+    "../scenery-phet/js/NumberControl.ts",
+    "../sun/js/ComboBox.ts",
+    "../joist/js/preferences/PreferencesType.ts",
+    "../joist/js/preferences/PreferencesControl.ts",
+    "../joist/js/preferences/SoundPanelSection.ts",
+    "../joist/js/preferences/VoicingPanelSection.ts",
+    "../joist/js/preferences/PreferencesPanel.ts",
+    "../joist/js/preferences/ProjectorModeToggleSwitch.ts",
+    "../joist/js/preferences/LanguageSelectionNode.ts",
+    "../joist/js/preferences/RegionAndCultureComboBox.ts",
+    "../joist/js/preferences/LocalePanel.ts",
+    "../joist/js/i18n/isLeftToRightProperty.ts",
+    "../sherpa/js/fontawesome-5/globeSolidString.js",
+    "../sherpa/js/fontawesome-5/globeSolidShape.js",
+    "../joist/js/preferences/PreferencesTab.ts",
+    "../joist/js/preferences/AudioPreferencesPanel.ts",
+    "../joist/js/preferences/SimulationPreferencesPanel.ts",
+    "../joist/js/preferences/InputPreferencesPanel.ts",
+    "../joist/js/preferences/VisualPreferencesPanel.ts",
+    "../joist/js/preferences/LocalizationPreferencesPanel.ts",
+    "../joist/js/preferences/OverviewPreferencesPanel.ts",
+    "../joist/js/preferences/PreferencesTabs.ts",
+    "../joist/sounds/cardFlip_mp3.js",
+    "../joist/js/preferences/PreferencesPanels.ts",
+    "../joist/js/preferences/PreferencesTabSwitchSoundGenerator.ts",
+    "../joist/images/preferencesIconOnWhite_png.ts",
+    "../joist/images/preferencesIcon_png.ts",
+    "../joist/js/preferences/PreferencesDialog.ts",
+    "../joist/js/KeyboardHelpButton.ts",
+    "../joist/js/NavigationBarAudioToggleButton.ts",
+    "../joist/js/preferences/NavigationBarPreferencesButton.ts",
+    "../sherpa/js/fontawesome-5/homeSolidString.js",
+    "../sherpa/js/fontawesome-5/homeSolidShape.js",
+    "../brand/js/brand.ts",
+    "../brand/js/getLinks.ts",
+    "../sherpa/js/fontawesome-5/checkSolidString.js",
+    "../sherpa/js/fontawesome-5/checkSolidShape.js",
+    "../joist/js/UpdateState.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidString.js",
+    "../scenery-phet/js/SpinningIndicatorNode.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidShape.js",
+    "../sun/js/buttons/TextPushButton.ts",
+    "../joist/js/UpdateDialog.ts",
+    "../joist/js/CreditsNode.ts",
+    "../joist/js/updateCheck.ts",
+    "../joist/js/UpdateNodes.ts",
+    "../sun/js/MenuItem.ts",
+    "../joist/js/AboutDialog.ts",
+    "../joist/js/ScreenshotGenerator.ts",
+    "../brand/js/TBrand.ts",
+    "../joist/js/KebabMenuIcon.ts",
+    "../joist/js/PhetMenu.ts",
+    "../joist/js/A11yButtonsHBox.ts",
+    "../joist/js/HomeButton.ts",
+    "../joist/js/NavigationBarScreenButton.ts",
+    "../joist/js/PhetButton.ts",
+    "../scenery-phet/images/phetGirlWaggingFinger_png.ts",
+    "../scenery-phet/js/OopsDialog.ts",
+    "../joist/sounds/screenSelection_mp3.js",
+    "../sun/js/buttons/RoundButton.ts",
+    "../sun/js/buttons/RoundToggleButton.ts",
+    "../tambo/sounds/pause_mp3.js",
+    "../tambo/sounds/playPause_mp3.js",
+    "../sun/js/buttons/BooleanRoundToggleButton.ts",
+    "../tambo/js/shared-sound-players/pauseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/playSoundPlayer.ts",
+    "../scenery-phet/js/PlayIconShape.ts",
+    "../scenery-phet/js/SceneryPhetConstants.ts",
+    "../scenery-phet/js/StopIconShape.ts",
+    "../scenery-phet/js/buttons/PlayControlButton.ts",
+    "../scenery-phet/js/buttons/PlayStopButton.ts",
+    "../sun/js/buttons/RoundPushButton.ts",
+    "../joist/js/toolbar/VoicingToolbarAlertManager.ts",
+    "../joist/js/toolbar/VoicingToolbarItem.ts",
+    "../scenery-phet/js/BarrierRectangle.ts",
+    "../sherpa/lib/game-up-camera-1.0.0.js",
+    "../tambo/js/soundManager.ts",
+    "../joist/js/audioManager.ts",
+    "../joist/js/Heartbeat.ts",
+    "../joist/js/Helper.ts",
+    "../joist/js/HomeScreen.ts",
+    "../joist/js/LookAndFeel.ts",
+    "../joist/js/MemoryMonitor.ts",
+    "../joist/js/NavigationBar.ts",
+    "../joist/js/Profiler.ts",
+    "../joist/js/QueryParametersWarningDialog.ts",
+    "../joist/js/ScreenSelectionSoundGenerator.ts",
+    "../joist/js/selectScreens.ts",
+    "../joist/js/thirdPartySupport/LegendsOfLearningSupport.ts",
+    "../joist/js/toolbar/Toolbar.ts",
+    "../joist/js/Screen.ts",
+    "../joist/js/Sim.ts",
+    "../phet-io/js/phetio.ts",
+    "../phet-io/js/PhetioStateEngine.ts",
+    "../joist/js/packageJSON.ts",
+    "../joist/js/SimInfo.ts",
+    "../phet-io/js/dataStream.ts",
+    "../phet-io/js/phetioCommandProcessor.ts",
+    "../phet-io/js/phetioDevSaveLoad.ts",
+    "../phet-core/js/gracefulBind.js",
+    "../sun/js/Popupable.js",
+    "../phet-core/js/types/TMixin.ts"
   ]
 }
\ No newline at end of file
Index: tandem/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tandem/tsconfig.json b/tandem/tsconfig.json
--- a/tandem/tsconfig.json	(revision 3f619280b74dcf067ceca7a85fb4c8f9f4d380d9)
+++ b/tandem/tsconfig.json	(date 1714337279289)
@@ -4,6 +4,7 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../phet-core/js/arrayRemove.ts"
   ]
 }
\ No newline at end of file
Index: scenery/js/layout/constraints/FlowCell.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/FlowCell.ts b/scenery/js/layout/constraints/FlowCell.ts
--- a/scenery/js/layout/constraints/FlowCell.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/FlowCell.ts	(date 1714337263148)
@@ -34,6 +34,8 @@
   private readonly flowConstraint: FlowConstraint;
 
   public constructor( constraint: FlowConstraint, node: Node, proxy: LayoutProxy | null ) {
+
+    // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
     super( constraint, node, proxy );
 
     this.flowConstraint = constraint;
Index: sherpa/lib/big-6.2.1.mjs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sherpa/lib/big-6.2.1.mjs b/sherpa/lib/big-6.2.1.mjs
--- a/sherpa/lib/big-6.2.1.mjs	(revision 3cc0c9fcea140cae57994a1ba11d951c8518d65d)
+++ b/sherpa/lib/big-6.2.1.mjs	(date 1714337279267)
@@ -15,7 +15,7 @@
    * The maximum number of decimal places (DP) of the results of operations involving division:
    * div and sqrt, and pow with negative exponents.
    */
-var DP = 20,          // 0 to MAX_DP
+const DP = 20,          // 0 to MAX_DP
 
   /*
    * The rounding mode (RM) used when rounding to the above decimal places.
Index: scenery/js/layout/constraints/MarginLayoutConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/MarginLayoutConfigurable.ts b/scenery/js/layout/constraints/MarginLayoutConfigurable.ts
--- a/scenery/js/layout/constraints/MarginLayoutConfigurable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/MarginLayoutConfigurable.ts	(date 1714337263164)
@@ -378,5 +378,24 @@
 } );
 
 scenery.register( 'MarginLayoutConfigurable', MarginLayoutConfigurable );
-export default MarginLayoutConfigurable;
+
+export type TMarginLayoutConfigurable = {
+  changedEmitter: TEmitter;
+  margin: number | null;
+  xMargin: number | null;
+  yMargin: number | null;
+  leftMargin: number | null;
+  rightMargin: number | null;
+  topMargin: number | null;
+  bottomMargin: number | null;
+  minContentWidth: number | null;
+  minContentHeight: number | null;
+  maxContentWidth: number | null;
+  maxContentHeight: number | null;
+  setConfigToBaseDefault(): void;
+  setConfigToInherit(): void;
+  mutateConfigurable( options?: MarginLayoutConfigurableOptions ): void;
+};
+
+export default MarginLayoutConfigurable as unknown as <SuperType extends Constructor>( type: SuperType ) => SuperType & Constructor<TMarginLayoutConfigurable>;
 export { MARGIN_LAYOUT_CONFIGURABLE_OPTION_KEYS };
\ No newline at end of file
Index: scenery/js/layout/constraints/GridCell.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/GridCell.ts b/scenery/js/layout/constraints/GridCell.ts
--- a/scenery/js/layout/constraints/GridCell.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/GridCell.ts	(date 1714337263160)
@@ -49,6 +49,7 @@
    */
   public constructor( constraint: GridConstraint, node: Node, proxy: LayoutProxy | null ) {
 
+    // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
     super( constraint, node, proxy );
 
     this.gridConstraint = constraint;
Index: projectile-data-lab/js/projectile-data-lab-main.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/js/projectile-data-lab-main.ts b/projectile-data-lab/js/projectile-data-lab-main.ts
--- a/projectile-data-lab/js/projectile-data-lab-main.ts	(revision 696b26fcc9c93da4a00fa45fd5b9fe4a69ec55a1)
+++ b/projectile-data-lab/js/projectile-data-lab-main.ts	(date 1714345647967)
@@ -47,6 +47,8 @@
   } );
 
   const screens = [
+
+
     new VariabilityScreen( { tandem: Tandem.ROOT.createTandem( 'variabilityScreen' ) } ),
     new SourcesScreen( { tandem: Tandem.ROOT.createTandem( 'sourcesScreen' ) } ),
     new MeasuresScreen( { tandem: Tandem.ROOT.createTandem( 'measuresScreen' ) } ),
Index: sun/js/accessibility/AccessibleNumberSpinner.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleNumberSpinner.ts b/sun/js/accessibility/AccessibleNumberSpinner.ts
--- a/sun/js/accessibility/AccessibleNumberSpinner.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleNumberSpinner.ts	(date 1714346377109)
@@ -32,7 +32,7 @@
 import { DelayedMutate, KeyboardUtils, Node, SceneryEvent, TInputListener } from '../../../scenery/js/imports.js';
 import sun from '../sun.js';
 import SunStrings from '../SunStrings.js';
-import AccessibleValueHandler, { AccessibleValueHandlerOptions } from './AccessibleValueHandler.js';
+import AccessibleValueHandler, { AccessibleValueHandlerOptions, TAccessibleValueHandler } from './AccessibleValueHandler.js';
 import TEmitter from '../../../axon/js/TEmitter.js';
 
 const ACCESSIBLE_NUMBER_SPINNER_OPTIONS = [
@@ -55,7 +55,7 @@
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleNumberSpinner = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleNumberSpinner = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => {
 
   const AccessibleNumberSpinnerClass = DelayedMutate( 'AccessibleNumberSpinner', ACCESSIBLE_NUMBER_SPINNER_OPTIONS, class AccessibleNumberSpinner extends AccessibleValueHandler( Type, optionsArgPosition ) {
 
@@ -65,8 +65,8 @@
     // Emits events when increment and decrement actions occur, but only for changes of keyboardStep and
     // shiftKeyboardStep (not pageKeyboardStep). Indicates "normal" usage with a keyboard, so that components
     // composed with this trait can style themselves differently when the keyboard is being used.
-    protected readonly pdomIncrementDownEmitter: TEmitter<[ boolean ]>;
-    protected readonly pdomDecrementDownEmitter: TEmitter<[ boolean ]>;
+    public readonly pdomIncrementDownEmitter: TEmitter<[ boolean ]>;
+    public readonly pdomDecrementDownEmitter: TEmitter<[ boolean ]>;
 
     private _pdomTimerDelay = 400;
     private _pdomTimerInterval = 100;
@@ -259,5 +259,10 @@
 
 sun.register( 'AccessibleNumberSpinner', AccessibleNumberSpinner );
 
-export default AccessibleNumberSpinner;
+type TAccessibleNumberSpinner = {
+  readonly pdomIncrementDownEmitter: TEmitter<[ boolean ]>;
+  readonly pdomDecrementDownEmitter: TEmitter<[ boolean ]>;
+} & TAccessibleValueHandler;
+
+export default AccessibleNumberSpinner as <T extends Constructor<Node>>( type: T, index: number ) => T & Constructor<TAccessibleNumberSpinner>;
 export type { AccessibleNumberSpinnerOptions };
\ No newline at end of file
Index: sun/js/accessibility/AccessibleValueHandler.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleValueHandler.ts b/sun/js/accessibility/AccessibleValueHandler.ts
--- a/sun/js/accessibility/AccessibleValueHandler.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleValueHandler.ts	(date 1714345330469)
@@ -20,7 +20,7 @@
 import Range from '../../../dot/js/Range.js';
 import assertHasProperties from '../../../phet-core/js/assertHasProperties.js';
 import Orientation from '../../../phet-core/js/Orientation.js';
-import { animatedPanZoomSingleton, DelayedMutate, KeyboardUtils, Node, NodeOptions, PDOMPointer, PDOMUtils, PDOMValueType, SceneryEvent, SceneryListenerFunction, TInputListener, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
+import { TVoicing, animatedPanZoomSingleton, DelayedMutate, KeyboardUtils, Node, NodeOptions, PDOMPointer, PDOMUtils, PDOMValueType, SceneryEvent, SceneryListenerFunction, TInputListener, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
 import Utterance from '../../../utterance-queue/js/Utterance.js';
 import sun from '../sun.js';
 import optionize, { combineOptions } from '../../../phet-core/js/optionize.js';
@@ -234,8 +234,8 @@
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
-  const AccessibleValueHandlerClass = DelayedMutate( 'AccessibleValueHandler', ACCESSIBLE_VALUE_HANDLER_OPTIONS, class AccessibleValueHandler extends Voicing( Type ) {
+const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => {
+  const AccessibleValueHandlerClass = DelayedMutate( 'AccessibleValueHandler', ACCESSIBLE_VALUE_HANDLER_OPTIONS, class AccessibleValueHandler extends Voicing( Type ) implements TAccessibleValueHandler {
     private readonly _valueProperty: TProperty<number>;
     private _enabledRangeProperty: TReadOnlyProperty<Range>;
     private _startInput: SceneryListenerFunction = _.noop;
@@ -841,7 +841,7 @@
      * Handle key up event on this accessible slider, managing the shift key, and calling an optional endDrag
      * function on release. Add this as an input listener to the node mixing in AccessibleValueHandler.
      */
-    protected handleKeyUp( event: SceneryEvent<KeyboardEvent> ): void {
+    public handleKeyUp( event: SceneryEvent<KeyboardEvent> ): void {
       const key = KeyboardUtils.getEventCode( event.domEvent )!;
 
       // handle case where user tabbed to this input while an arrow key might have been held down
@@ -873,7 +873,7 @@
      *
      * Add this as a listener to the 'change' input event on the Node that is mixing in AccessibleValueHandler.
      */
-    protected handleChange( event: SceneryEvent ): void {
+    public handleChange( event: SceneryEvent ): void {
 
       if ( !this._a11yInputHandled ) {
         this.handleInput( event );
@@ -895,7 +895,7 @@
      *
      * Add this as a listener to the `input` event on the Node that is mixing in AccessibleValueHandler.
      */
-    protected handleInput( event: SceneryEvent ): void {
+    public handleInput( event: SceneryEvent ): void {
       if ( this.enabledProperty.get() && !this._blockInput ) {
 
         // don't handle again on "change" event
@@ -945,7 +945,7 @@
      *
      * Add this as a listener on the `blur` event to the Node that is mixing in AccessibleValueHandler.
      */
-    protected handleBlur( event: SceneryEvent<FocusEvent> ): void {
+    public handleBlur( event: SceneryEvent<FocusEvent> ): void {
 
       // if any range keys are currently down, call end drag because user has stopped dragging to do something else
       if ( this._anyKeysDown() ) {
@@ -1261,6 +1261,24 @@
   return correctedValue;
 };
 
+export type TAccessibleValueHandler = {
+  voicingOnEndResponse( valueOnStart: number, providedOptions?: VoicingOnEndResponseOptions ): void;
+
+  set startInput( value: SceneryListenerFunction );
+  get startInput(): SceneryListenerFunction;
+  set onInput( value: SceneryListenerFunction );
+  get onInput(): SceneryListenerFunction;
+  set endInput( value: ( ( event: SceneryEvent | null ) => void ) );
+  get endInput(): SceneryListenerFunction;
+  getAccessibleValueHandlerInputListener(): TInputListener;
+
+  handleKeyDown( event: SceneryEvent<KeyboardEvent> ): void;
+  handleKeyUp( event: SceneryEvent<KeyboardEvent> ): void;
+  handleBlur( event: SceneryEvent<FocusEvent> ): void;
+  handleInput( event: SceneryEvent ): void;
+  handleChange( event: SceneryEvent ): void;
+} & TVoicing;
+
 AccessibleValueHandler.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;
 
-export default AccessibleValueHandler;
\ No newline at end of file
+export default AccessibleValueHandler as unknown as <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TAccessibleValueHandler>;
\ No newline at end of file
Index: dot/js/Utils.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/dot/js/Utils.js b/dot/js/Utils.js
--- a/dot/js/Utils.js	(revision aef01d114353684eb9678b4cab9c13ca1a9faa99)
+++ b/dot/js/Utils.js	(date 1714337263079)
@@ -6,7 +6,7 @@
  * @author Jonathan Olson <jonathan.olson@colorado.edu>
  */
 
-import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
+// import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
 import dot from './dot.js';
 import Vector2 from './Vector2.js';
 import Vector3 from './Vector3.js';
@@ -565,7 +565,7 @@
     }
 
     // eslint-disable-next-line bad-sim-text
-    const result = new Big( value ).toFixed( decimalPlaces );
+    const result = value.toFixed( decimalPlaces ); // TODO: https://github.com/phetsims/tasks/issues/1132
 
     // Avoid reporting -0.000
     if ( result.startsWith( '-0.' ) && Number.parseFloat( result ) === 0 ) {
Index: sun/js/accessibility/AccessibleSlider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/accessibility/AccessibleSlider.ts b/sun/js/accessibility/AccessibleSlider.ts
--- a/sun/js/accessibility/AccessibleSlider.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/accessibility/AccessibleSlider.ts	(date 1714338039013)
@@ -18,7 +18,7 @@
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 import { DelayedMutate, Node, SceneryEvent } from '../../../scenery/js/imports.js';
 import sun from '../sun.js';
-import AccessibleValueHandler, { AccessibleValueHandlerOptions } from './AccessibleValueHandler.js';
+import AccessibleValueHandler, { AccessibleValueHandlerOptions, TAccessibleValueHandler } from './AccessibleValueHandler.js';
 
 const ACCESSIBLE_SLIDER_OPTIONS = [
   'startDrag',
@@ -44,7 +44,7 @@
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at in the constructor for Type
  */
-const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => {
   const AccessibleSliderClass = DelayedMutate( 'AccessibleSlider', ACCESSIBLE_SLIDER_OPTIONS, class AccessibleSlider extends AccessibleValueHandler( Type, optionsArgPosition ) {
 
     private readonly _disposeAccessibleSlider: () => void;
@@ -140,5 +140,18 @@
 
 sun.register( 'AccessibleSlider', AccessibleSlider );
 
-export default AccessibleSlider;
+type TAccessibleSlider = {
+
+  // TODO: These may not be needed, see https://github.com/phetsims/tasks/issues/1132
+  set startDrag( value: ( event: SceneryEvent ) => void );
+  get startDrag(): ( event: SceneryEvent ) => void;
+
+  set drag( value: ( event: SceneryEvent ) => void );
+  get drag(): ( event: SceneryEvent ) => void;
+
+  set endDrag( value: ( event: SceneryEvent | null ) => void );
+  get endDrag(): ( event: SceneryEvent | null ) => void;
+} & TAccessibleValueHandler;
+
+export default AccessibleSlider as unknown as <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TAccessibleSlider>;
 export type { AccessibleSliderOptions };
\ No newline at end of file
Index: phet-core/js/EventTimer.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-core/js/EventTimer.ts b/phet-core/js/EventTimer.ts
--- a/phet-core/js/EventTimer.ts	(revision 334d6e61f57e83b88a34925d58ac48fd093eca23)
+++ b/phet-core/js/EventTimer.ts	(date 1714337263100)
@@ -76,8 +76,9 @@
  */
 
 import phetCore from './phetCore.js';
+import IntentionalAny from './types/IntentionalAny.js';
 
-export default class EventTimer {
+class EventTimer {
 
   private period: number;
   private timeBeforeNextEvent: number;
@@ -140,7 +141,7 @@
   };
 
   public static readonly UniformEventModel = class UniformEventModel {
-    
+
     /*
      * Event model that will fire events averaging a certain rate, but with the time between events being uniformly
      * random.
@@ -189,4 +190,6 @@
   };
 }
 
+export default EventTimer as IntentionalAny;
+
 phetCore.register( 'EventTimer', EventTimer );
\ No newline at end of file
Index: joist/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/tsconfig.json b/joist/tsconfig.json
--- a/joist/tsconfig.json	(revision b94d701c92cab77cd4cf554f333a7e0701c5b01b)
+++ b/joist/tsconfig.json	(date 1714337263096)
@@ -4,6 +4,11 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+
+    "../scenery-phet/js/PhetColorScheme.ts",
+    "../scenery-phet/js/**/*",
+    "../axon/js/**/*",
+    "../sun/js/**/*"
   ]
 }
\ No newline at end of file
Index: sun/js/Popupable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sun/js/Popupable.ts b/sun/js/Popupable.ts
--- a/sun/js/Popupable.ts	(revision deca9aef0c7699701cd4a016a47e6ac704bd608f)
+++ b/sun/js/Popupable.ts	(date 1714338007299)
@@ -13,12 +13,12 @@
 import Property from '../../axon/js/Property.js';
 import Bounds2 from '../../dot/js/Bounds2.js';
 import ScreenView from '../../joist/js/ScreenView.js';
-import gracefulBind from '../../phet-core/js/gracefulBind.js';
 import optionize from '../../phet-core/js/optionize.js';
 import Constructor from '../../phet-core/js/types/Constructor.js';
 import PickOptional from '../../phet-core/js/types/PickOptional.js';
 import { FocusManager, Node, NodeOptions } from '../../scenery/js/imports.js';
 import sun from './sun.js';
+import gracefulBind from '../../phet-core/js/gracefulBind.js';
 
 type SelfOptions = {
 
@@ -46,7 +46,7 @@
 type ParentOptions = PickOptional<NodeOptions, 'tandem'>;
 export type PopupableOptions = SelfOptions & ParentOptions;
 
-const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => {
 
   return class extends type {
 
@@ -168,7 +168,7 @@
       }
     }
 
-    protected get focusOnHideNode(): Node | null {
+    public get focusOnHideNode(): Node | null {
       return this._focusOnHideNode;
     }
 
@@ -212,10 +212,18 @@
   }
 }
 
-// Export a type that lets you check if your Node is composed with Popupable
-const wrapper = () => Popupable( Node, 0 );
-export type PopupableNode = InstanceType<ReturnType<typeof wrapper>> & Node;
+type TPopupable = {
+  show(): void;
+  hide(): void;
+  shouldShowPopup(): boolean;
+  isShowingProperty: Property<boolean>;
+  get focusOnHideNode(): Node | null; // treat as protected
+  layout( bounds: Bounds2 ): void;
+  layoutBounds: Bounds2 | null;
+};
+
+export type PopupableNode = Node & TPopupable;
 
 sun.register( 'Popupable', Popupable );
 
-export default Popupable;
\ No newline at end of file
+export default Popupable as unknown as <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => SuperType & Constructor<TPopupable>;
\ No newline at end of file
Index: dot/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/dot/tsconfig.json b/dot/tsconfig.json
--- a/dot/tsconfig.json	(revision aef01d114353684eb9678b4cab9c13ca1a9faa99)
+++ b/dot/tsconfig.json	(date 1714337263086)
@@ -4,6 +4,7 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../sherpa/lib/big-6.2.1.mjs"
   ]
 }
\ No newline at end of file
Index: scenery/js/layout/Sizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/Sizable.ts b/scenery/js/layout/Sizable.ts
--- a/scenery/js/layout/Sizable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/Sizable.ts	(date 1714337263172)
@@ -13,6 +13,8 @@
 import Dimension2 from '../../../dot/js/Dimension2.js';
 import assertMutuallyExclusiveOptions from '../../../phet-core/js/assertMutuallyExclusiveOptions.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
+import { TWidthSizable } from './WidthSizable.js';
+import { THeightSizable } from './HeightSizable.js';
 
 export const SIZABLE_SELF_OPTION_KEYS = [
   'preferredSize',
@@ -187,7 +189,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalPreferredWidth(): number | null {
+    public override _calculateLocalPreferredWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.preferredWidth !== null ) {
@@ -204,7 +206,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalPreferredHeight(): number | null {
+    public override _calculateLocalPreferredHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.preferredHeight !== null ) {
@@ -221,7 +223,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculatePreferredWidth(): number | null {
+    public override _calculatePreferredWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localPreferredWidth !== null ) {
@@ -237,7 +239,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculatePreferredHeight(): number | null {
+    public override _calculatePreferredHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localPreferredHeight !== null ) {
@@ -253,31 +255,31 @@
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantLocalMinimumWidth(): void {
+    public override _onReentrantLocalMinimumWidth(): void {
       this._updateMinimumWidthListener();
       this._updateMinimumHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantLocalMinimumHeight(): void {
+    public override _onReentrantLocalMinimumHeight(): void {
       this._updateMinimumWidthListener();
       this._updateMinimumHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantPreferredWidth(): void {
+    public override _onReentrantPreferredWidth(): void {
       this._updateLocalPreferredWidthListener();
       this._updateLocalPreferredHeightListener();
     }
 
     // We'll need to cross-link because we might need to update either the width or height when the other changes
-    protected override _onReentrantPreferredHeight(): void {
+    public override _onReentrantPreferredHeight(): void {
       this._updateLocalPreferredWidthListener();
       this._updateLocalPreferredHeightListener();
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalMinimumWidth(): number | null {
+    public override _calculateLocalMinimumWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.minimumWidth !== null ) {
@@ -293,7 +295,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateLocalMinimumHeight(): number | null {
+    public override _calculateLocalMinimumHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.minimumHeight !== null ) {
@@ -309,7 +311,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateMinimumWidth(): number | null {
+    public override _calculateMinimumWidth(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localMinimumWidth !== null ) {
@@ -325,7 +327,7 @@
     }
 
     // Override the calculation to potentially include the opposite dimension (if we have a rotation of that type)
-    protected override _calculateMinimumHeight(): number | null {
+    public override _calculateMinimumHeight(): number | null {
       if ( this.matrix.isAxisAligned() ) {
         if ( this.matrix.isAligned() ) {
           if ( this.localMinimumHeight !== null ) {
@@ -356,12 +358,6 @@
   return SizableTrait;
 } );
 
-// Some typescript gymnastics to provide a user-defined type guard that treats something as Sizable
-// We need to define an unused function with a concrete type, so that we can extract the return type of the function
-// and provide a type for a Node that extends this type.
-const wrapper = () => Sizable( Node );
-export type SizableNode = InstanceType<ReturnType<typeof wrapper>>;
-
 const isSizable = ( node: Node ): node is SizableNode => {
   return node.widthSizable && node.heightSizable;
 };
@@ -369,6 +365,12 @@
   return node.extendsSizable;
 };
 
+type TSizable = TWidthSizable & THeightSizable & {
+  validateLocalPreferredSize(): void;
+};
+
+export type SizableNode = Node & TSizable;
+
 scenery.register( 'Sizable', Sizable );
-export default Sizable;
+export default Sizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TSizable>;
 export { isSizable, extendsSizable };
\ No newline at end of file
Index: scenery/js/accessibility/voicing/ReadingBlock.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/ReadingBlock.ts b/scenery/js/accessibility/voicing/ReadingBlock.ts
--- a/scenery/js/accessibility/voicing/ReadingBlock.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/ReadingBlock.ts	(date 1714337432833)
@@ -30,6 +30,7 @@
 import Utterance from '../../../../utterance-queue/js/Utterance.js';
 import TEmitter from '../../../../axon/js/TEmitter.js';
 import memoize from '../../../../phet-core/js/memoize.js';
+import { TVoicing } from './Voicing.js';
 
 const READING_BLOCK_OPTION_KEYS = [
   'readingBlockTagName',
@@ -382,8 +383,9 @@
 
     /**
      * If we created and own the voicingUtterance we can fully dispose of it.
+     * Must be public due to the mixin pattern.
      */
-    protected override cleanVoicingUtterance(): void {
+    public override cleanVoicingUtterance(): void {
       if ( this._voicingUtterance instanceof OwnedReadingBlockUtterance ) {
         this._voicingUtterance.dispose();
       }
@@ -422,9 +424,19 @@
   return ReadingBlockClass;
 } );
 
+type TReadingBlock = {
+  readingBlockActiveHighlightChangedEmitter: TEmitter;
+  isReadingBlock: true;
+  readingBlockActiveHighlight: Highlight;
+  readingBlockActivated: boolean;
+
+  set readingBlockNameResponse( content: VoicingResponse );
+  get readingBlockNameResponse(): ResolvedResponse;
+  setReadingBlockNameResponse( content: VoicingResponse ): void;
+} & TVoicing;
+
 // Export a type that lets you check if your Node is composed with ReadingBlock
-const wrapper = () => ReadingBlock( Node );
-export type ReadingBlockNode = InstanceType<ReturnType<typeof wrapper>>;
+export type ReadingBlockNode = Node & TReadingBlock;
 
 scenery.register( 'ReadingBlock', ReadingBlock );
-export default ReadingBlock;
\ No newline at end of file
+export default ReadingBlock as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TReadingBlock>;
\ No newline at end of file
Index: scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/Voicing.ts b/scenery/js/accessibility/voicing/Voicing.ts
--- a/scenery/js/accessibility/voicing/Voicing.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/Voicing.ts	(date 1714337263127)
@@ -28,13 +28,14 @@
 import ResponsePacket, { ResolvedResponse, SpeakableResolvedOptions, VoicingResponse } from '../../../../utterance-queue/js/ResponsePacket.js';
 import ResponsePatternCollection from '../../../../utterance-queue/js/ResponsePatternCollection.js';
 import Utterance, { TAlertable, UtteranceOptions } from '../../../../utterance-queue/js/Utterance.js';
-import { DelayedMutate, Instance, InteractiveHighlighting, InteractiveHighlightingOptions, Node, scenery, SceneryListenerFunction, voicingUtteranceQueue } from '../../imports.js';
+import { DelayedMutate, Instance, InteractiveHighlighting, InteractiveHighlightingOptions, Node, ReadingBlockUtterance, scenery, SceneryListenerFunction, voicingUtteranceQueue } from '../../imports.js';
 import { combineOptions } from '../../../../phet-core/js/optionize.js';
 import Constructor from '../../../../phet-core/js/types/Constructor.js';
 import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 import responseCollector from '../../../../utterance-queue/js/responseCollector.js';
 import TinyProperty from '../../../../axon/js/TinyProperty.js';
 import Tandem from '../../../../tandem/js/Tandem.js';
+import { TInteractiveHighlighting } from './InteractiveHighlighting.js';
 
 // Helps enforce that the utterance is defined.
 function assertUtterance( utterance: Utterance | null ): asserts utterance is Utterance {
@@ -98,14 +99,14 @@
   utterance?: SelfOptions['voicingUtterance'];
 } & SpeakableResolvedOptions;
 
-const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => {
 
   assert && assert( _.includes( inheritance( Type ), Node ), 'Only Node subtypes should compose Voicing' );
 
   const VoicingClass = DelayedMutate( 'Voicing', VOICING_OPTION_KEYS, class VoicingClass extends InteractiveHighlighting( Type ) {
 
     // ResponsePacket that holds all the supported responses to be Voiced
-    protected _voicingResponsePacket!: ResponsePacket;
+    public _voicingResponsePacket!: ResponsePacket;
 
     // The utterance that all responses are spoken through.
     protected _voicingUtterance: Utterance | null;
@@ -332,7 +333,7 @@
      * Use the provided function to create content to speak in response to input. The content is then added to the
      * back of the voicing UtteranceQueue.
      */
-    protected speakContent( content: TAlertable ): void {
+    public speakContent( content: TAlertable ): void {
 
       const notPhetioArchetype = !Tandem.PHET_IO_ENABLED || !this.isInsidePhetioArchetype();
 
@@ -475,6 +476,7 @@
           this.cleanVoicingUtterance();
         }
 
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         Voicing.registerUtteranceToVoicingNode( utterance, this );
         this._voicingUtterance = utterance;
       }
@@ -626,6 +628,8 @@
         this._voicingUtterance.dispose();
       }
       else if ( this._voicingUtterance && !this._voicingUtterance.isDisposed ) {
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         Voicing.unregisterUtteranceToVoicingNode( this._voicingUtterance, this );
       }
     }
@@ -667,10 +671,9 @@
  * if the voicingNode is globally visible and voicingVisible in the display.
  * @static
  */
-Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
+Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: TVoicing ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
 
-  // @ts-expect-error Accessing a private member because this is meant to be "private to the file".
   const voicingCanSpeakProperty = voicingNode._voicingCanSpeakProperty;
   if ( !existingCanAnnounceProperties.includes( voicingCanSpeakProperty ) ) {
     utterance.voicingCanAnnounceProperties = existingCanAnnounceProperties.concat( [ voicingCanSpeakProperty ] );
@@ -684,7 +687,6 @@
 Voicing.unregisterUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
 
-  // @ts-expect-error Accessing a private member because this is meant to be "private to the file".
   const voicingCanSpeakProperty = voicingNode._voicingCanSpeakProperty;
   const index = existingCanAnnounceProperties.indexOf( voicingCanSpeakProperty );
   assert && assert( index > -1, 'voicingNode.voicingCanSpeakProperty is not on the Utterance, was it not registered?' );
@@ -726,9 +728,49 @@
   utterance.voicingCanAnnounceProperties = withoutBothProperties;
 };
 
-// Export a type that lets you check if your Node is composed with Voicing.
-const wrapper = () => Voicing( Node );
-export type VoicingNode = InstanceType<ReturnType<typeof wrapper>>;
+export type TVoicing = {
+  _voicingResponsePacket: ResponsePacket;
+  setVoicingUtterance( utterance: ReadingBlockUtterance ): void;
+  set voicingUtterance( utterance: ReadingBlockUtterance );
+  get voicingUtterance(): ReadingBlockUtterance;
+  getVoicingUtterance(): ReadingBlockUtterance;
+  setVoicingNameResponse(): void;
+  getVoicingNameResponse(): IntentionalAny;
+  setVoicingObjectResponse(): void;
+  getVoicingObjectResponse(): IntentionalAny;
+  setVoicingContextResponse(): void;
+  getVoicingContextResponse(): IntentionalAny;
+  setVoicingHintResponse(): void;
+  getVoicingHintResponse(): IntentionalAny;
+  setVoicingResponsePatternCollection(): void;
+  getVoicingResponsePatternCollection(): IntentionalAny;
+
+  cleanVoicingUtterance(): void;
+  _voicingUtterance: ReadingBlockUtterance;
+
+  collectResponse( providedOptions?: SpeakingOptions ): TAlertable;
+
+  voicingIgnoreVoicingManagerProperties: boolean;
+  voicingNameResponse: ResolvedResponse;
+  voicingSpeakResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingSpeakFullResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingSpeakContextResponse: ( providedOptions?: SpeakingOptions ) => void;
+  voicingObjectResponse: ResolvedResponse;
+  voicingFocusListener: SceneryListenerFunction<FocusEvent> | null;
+  voicingHintResponse: ResolvedResponse;
+  voicingContextResponse: ResolvedResponse;
+  voicingSpeakNameResponse: ( providedOptions?: SpeakingOptions ) => void;
+
+  _voicingCanSpeakProperty: TinyProperty<boolean>;
+
+  speakContent( content: TAlertable ): void;
+
+  defaultFocusListener(): void;
+  initialize( ...args: IntentionalAny[] ): ThisType<IntentionalAny>;
+
+} & TInteractiveHighlighting;
+
+export type VoicingNode = Node & TVoicing;
 
 scenery.register( 'Voicing', Voicing );
-export default Voicing;
\ No newline at end of file
+export default Voicing as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TVoicing>;
\ No newline at end of file
Index: scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1714337263104)
@@ -647,9 +647,21 @@
   return InteractiveHighlightingClass;
 } );
 
-// Provides a way to determine if a Node is composed with InteractiveHighlighting by type
-const wrapper = () => InteractiveHighlighting( Node );
-export type InteractiveHighlightingNode = InstanceType<ReturnType<typeof wrapper>>;
+export type TInteractiveHighlighting = {
+  isInteractiveHighlightActiveProperty: TReadOnlyProperty<boolean>;
+  interactiveHighlightEnabled: boolean;
+  isInteractiveHighlighting: boolean;
+  interactiveHighlightChangedEmitter: TEmitter;
+  handleHighlightActiveChange(): void;
+
+  // we wish these was public, but they are used elsewhere and appears in the mixin, so must be public.
+  displays: Record<string, Display>;
+  getDescendantsUseHighlighting( trail: Trail ): boolean;
+  interactiveHighlightLayerable: boolean;
+  interactiveHighlight: Highlight;
+};
+
+export type InteractiveHighlightingNode = Node & TInteractiveHighlighting;
 
 scenery.register( 'InteractiveHighlighting', InteractiveHighlighting );
-export default InteractiveHighlighting;
\ No newline at end of file
+export default InteractiveHighlighting as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TInteractiveHighlighting>;
\ No newline at end of file
Index: scenery/js/layout/HeightSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/HeightSizable.ts b/scenery/js/layout/HeightSizable.ts
--- a/scenery/js/layout/HeightSizable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/HeightSizable.ts	(date 1714337432847)
@@ -367,11 +367,39 @@
   return HeightSizableTrait;
 } );
 
+export type THeightSizable = {
+  readonly preferredHeightProperty: TinyProperty<number | null>;
+  readonly minimumHeightProperty: TinyProperty<number | null>;
+  readonly localPreferredHeightProperty: TinyProperty<number | null>;
+  readonly localMinimumHeightProperty: TinyProperty<number | null>;
+  readonly isHeightResizableProperty: TinyProperty<boolean>;
+
+  preferredHeight: number | null;
+  minimumHeight: number | null;
+  localPreferredHeight: number | null;
+  localMinimumHeight: number | null;
+
+  _updateLocalPreferredHeightListener: () => void;
+  _updatePreferredHeightListener: () => void;
+  _updateLocalMinimumHeightListener: () => void;
+  _updateMinimumHeightListener: () => void;
+
+  validateLocalPreferredHeight(): void;
+
+  _calculateLocalPreferredHeight(): number | null;
+  _calculatePreferredHeight(): number | null;
+  _onReentrantLocalMinimumHeight(): void;
+  _onReentrantPreferredHeight(): void;
+  _calculateLocalMinimumHeight(): number | null;
+  _calculateMinimumHeight(): number | null;
+
+  set heightSizable( value: boolean );
+};
+
 // Some typescript gymnastics to provide a user-defined type guard that treats something as HeightSizable.
 // We need to define an unused function with a concrete type, so that we can extract the return type of the function
 // and provide a type for a Node that extends this type.
-const wrapper = () => HeightSizable( Node );
-export type HeightSizableNode = InstanceType<ReturnType<typeof wrapper>>;
+export type HeightSizableNode = Node & THeightSizable;
 
 const isHeightSizable = ( node: Node ): node is HeightSizableNode => {
   return node.heightSizable;
@@ -381,5 +409,5 @@
 };
 
 scenery.register( 'HeightSizable', HeightSizable );
-export default HeightSizable;
+export default HeightSizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<THeightSizable>;
 export { isHeightSizable, extendsHeightSizable };
\ No newline at end of file
Index: scenery/js/imports.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/imports.ts b/scenery/js/imports.ts
--- a/scenery/js/imports.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/imports.ts	(date 1714337279255)
@@ -180,7 +180,7 @@
 export { default as voicingManager } from './accessibility/voicing/voicingManager.js';
 export { default as voicingUtteranceQueue } from './accessibility/voicing/voicingUtteranceQueue.js';
 export { default as Voicing } from './accessibility/voicing/Voicing.js';
-export type { VoicingOptions, VoicingNode, SpeakingOptions } from './accessibility/voicing/Voicing.js';
+export type { VoicingOptions, VoicingNode, SpeakingOptions, TVoicing } from './accessibility/voicing/Voicing.js';
 export { default as ReadingBlockUtterance } from './accessibility/voicing/ReadingBlockUtterance.js';
 export type { ReadingBlockUtteranceOptions } from './accessibility/voicing/ReadingBlockUtterance.js';
 export { default as FocusDisplayedController } from './accessibility/FocusDisplayedController.js';
Index: scenery/js/layout/WidthSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/WidthSizable.ts b/scenery/js/layout/WidthSizable.ts
--- a/scenery/js/layout/WidthSizable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/WidthSizable.ts	(date 1714337263176)
@@ -369,12 +369,6 @@
   return WidthSizableTrait;
 } );
 
-// Some typescript gymnastics to provide a user-defined type guard that treats something as widthSizable
-// We need to define an unused function with a concrete type, so that we can extract the return type of the function
-// and provide a type for a Node that extends this type.
-const wrapper = () => WidthSizable( Node );
-export type WidthSizableNode = InstanceType<ReturnType<typeof wrapper>>;
-
 const isWidthSizable = ( node: Node ): node is WidthSizableNode => {
   return node.widthSizable;
 };
@@ -382,6 +376,40 @@
   return node.extendsWidthSizable;
 };
 
+export type TWidthSizable = {
+  readonly preferredWidthProperty: TinyProperty<number | null>;
+  readonly minimumWidthProperty: TinyProperty<number | null>;
+  readonly localPreferredWidthProperty: TinyProperty<number | null>;
+  readonly localMinimumWidthProperty: TinyProperty<number | null>;
+  readonly isWidthResizableProperty: TinyProperty<boolean>;
+
+  preferredWidth: number | null;
+  minimumWidth: number | null;
+  localPreferredWidth: number | null;
+  localMinimumWidth: number | null;
+
+  _updateLocalPreferredWidthListener: () => void;
+  _updatePreferredWidthListener: () => void;
+  _updateLocalMinimumWidthListener: () => void;
+  _updateMinimumWidthListener: () => void;
+
+  validateLocalPreferredWidth(): void;
+
+  _calculateLocalPreferredWidth(): number | null;
+  _calculatePreferredWidth(): number | null;
+  _onReentrantLocalMinimumWidth(): void;
+  _onReentrantPreferredWidth(): void;
+  _calculateLocalMinimumWidth(): number | null;
+  _calculateMinimumWidth(): number | null;
+
+  set widthSizable( value: boolean );
+};
+
+// Some typescript gymnastics to provide a user-defined type guard that treats something as widthSizable
+// We need to define an unused function with a concrete type, so that we can extract the return type of the function
+// and provide a type for a Node that extends this type.
+export type WidthSizableNode = Node & TWidthSizable;
+
 scenery.register( 'WidthSizable', WidthSizable );
-export default WidthSizable;
+export default WidthSizable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<TWidthSizable>;
 export { isWidthSizable, extendsWidthSizable };
\ No newline at end of file
Index: utterance-queue/js/AriaLiveAnnouncer.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/utterance-queue/js/AriaLiveAnnouncer.ts b/utterance-queue/js/AriaLiveAnnouncer.ts
--- a/utterance-queue/js/AriaLiveAnnouncer.ts	(revision 0297e932f21a53d59a808585226617df6183dfc0)
+++ b/utterance-queue/js/AriaLiveAnnouncer.ts	(date 1714337279295)
@@ -157,6 +157,8 @@
 
       if ( options.ariaLivePriority === AriaLive.POLITE ) {
         const element = this.politeElements[ this.politeElementIndex ];
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         this.updateLiveElement( element, announceText, utterance );
 
         // update index for next time
@@ -164,6 +166,8 @@
       }
       else if ( options.ariaLivePriority === AriaLive.ASSERTIVE ) {
         const element = this.assertiveElements[ this.assertiveElementIndex ];
+
+        // @ts-expect-error https://github.com/phetsims/tasks/issues/1132
         this.updateLiveElement( element, announceText, utterance );
         // update index for next time
         this.assertiveElementIndex = ( this.assertiveElementIndex + 1 ) % this.assertiveElements.length;
Index: scenery/js/accessibility/voicing/voicingUtteranceQueue.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts b/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts
--- a/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/accessibility/voicing/voicingUtteranceQueue.ts	(date 1714337263130)
@@ -10,6 +10,7 @@
 
 import UtteranceQueue from '../../../../utterance-queue/js/UtteranceQueue.js';
 import { scenery, voicingManager } from '../../imports.js';
+import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 
 const voicingUtteranceQueue = new UtteranceQueue( voicingManager, {
   featureSpecificAnnouncingControlPropertyName: 'voicingCanAnnounceProperty'
@@ -19,4 +20,4 @@
 voicingUtteranceQueue.enabled = false;
 
 scenery.register( 'voicingUtteranceQueue', voicingUtteranceQueue );
-export default voicingUtteranceQueue;
\ No newline at end of file
+export default voicingUtteranceQueue as IntentionalAny;
\ No newline at end of file
Index: scenery/js/listeners/SpriteListenable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/listeners/SpriteListenable.ts b/scenery/js/listeners/SpriteListenable.ts
--- a/scenery/js/listeners/SpriteListenable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/listeners/SpriteListenable.ts	(date 1714337263210)
@@ -55,4 +55,4 @@
 } );
 
 scenery.register( 'SpriteListenable', SpriteListenable );
-export default SpriteListenable;
\ No newline at end of file
+export default SpriteListenable as unknown as PressListener;
\ No newline at end of file
Index: projectile-sampling-distributions/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-sampling-distributions/tsconfig.json b/projectile-sampling-distributions/tsconfig.json
--- a/projectile-sampling-distributions/tsconfig.json	(revision df4eed3b5ca052470ed62d1da5304229fd1b511e)
+++ b/projectile-sampling-distributions/tsconfig.json	(date 1714346478506)
@@ -1,5 +1,10 @@
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [
+    {
+      "path": "../projectile-data-lab"
+    }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
Index: chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig-core.json b/chipper/tsconfig-core.json
--- a/chipper/tsconfig-core.json	(revision b9b8d46a42df39318878f027a9855be68c5b82b4)
+++ b/chipper/tsconfig-core.json	(date 1714337263069)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+    "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: scenery/js/nodes/Paintable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/nodes/Paintable.ts b/scenery/js/nodes/Paintable.ts
--- a/scenery/js/nodes/Paintable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/nodes/Paintable.ts	(date 1714337279236)
@@ -829,9 +829,62 @@
 Paintable.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
 
 export {
-  Paintable as default,
   PAINTABLE_DRAWABLE_MARK_FLAGS,
   PAINTABLE_OPTION_KEYS,
   DEFAULT_OPTIONS,
   DEFAULT_OPTIONS as PAINTABLE_DEFAULT_OPTIONS
-};
\ No newline at end of file
+};
+
+export type MyPaintable = {
+  // (scenery-internal)
+  fill: TPaint;
+  fillPickable: boolean;
+
+  // (scenery-internal)
+  stroke: TPaint;
+  strokePickable: boolean;
+
+  // (scenery-internal)
+  cachedPaints: TPaint[];
+  lineDrawingStyles: LineStyles;
+
+  lineWidth: number;
+  lineCap: LineCap;
+  lineJoin: LineJoin;
+  miterLimit: number;
+  lineDash: number[];
+  lineDashOffset: number;
+
+  getStrokeRendererBitmask(): number;
+  getStroke(): TPaint;
+  hasStroke(): boolean;
+  hasPaintableStroke(): boolean;
+  hasLineDash(): boolean;
+  getLineJoin(): LineJoin;
+  getLineWidth(): number;
+
+  _stroke: TPaint;
+
+  setStroke<T>( stroke: TPaint ): T;
+  setLineStyles<T>( lineStyles: LineStyles ): T;
+
+  setFill<T>( fill: TPaint ): T;
+  setLineWidth<T>( lineWidth: number ): T;
+
+  _strokePickable: boolean;
+
+  invalidateStroke(): void;
+  getFillRendererBitmask(): number;
+
+  _fillPickable: boolean;
+
+  invalidateFill(): void;
+  getLineCap(): LineCap;
+
+  _lineDrawingStyles: LineStyles;
+  getLineStyles(): LineStyles;
+
+  getMiterLimit(): number;
+};
+
+export default Paintable as unknown as <SuperType extends Constructor<Node>>( type: SuperType ) => SuperType & Constructor<MyPaintable>;
\ No newline at end of file
Index: utterance-queue/js/ResponsePacket.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/utterance-queue/js/ResponsePacket.ts b/utterance-queue/js/ResponsePacket.ts
--- a/utterance-queue/js/ResponsePacket.ts	(revision 0297e932f21a53d59a808585226617df6183dfc0)
+++ b/utterance-queue/js/ResponsePacket.ts	(date 1714337279299)
@@ -23,7 +23,7 @@
 import utteranceQueueNamespace from './utteranceQueueNamespace.js';
 
 // The text sent to an Announcer technology, after resolving it from potentially more complicated structures holding a response
-export type ResolvedResponse = string | number | null;
+export type ResolvedResponse = string | number | null | TReadOnlyProperty<string>;
 
 type ResponseCreator = TReadOnlyProperty<string> | ( () => ResolvedResponse );
 export type VoicingResponse = ResponseCreator | ResolvedResponse;
Index: scenery/js/layout/constraints/FlowConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/layout/constraints/FlowConfigurable.ts b/scenery/js/layout/constraints/FlowConfigurable.ts
--- a/scenery/js/layout/constraints/FlowConfigurable.ts	(revision b508608c485a23af2e3ce1a0574726a22719fe3b)
+++ b/scenery/js/layout/constraints/FlowConfigurable.ts	(date 1714337263154)
@@ -29,6 +29,7 @@
 import WithoutNull from '../../../../phet-core/js/types/WithoutNull.js';
 import IntentionalAny from '../../../../phet-core/js/types/IntentionalAny.js';
 import TEmitter from '../../../../axon/js/TEmitter.js';
+import { TMarginLayoutConfigurable } from './MarginLayoutConfigurable.js';
 
 const FLOW_CONFIGURABLE_OPTION_KEYS = [
   'orientation',
@@ -223,6 +224,24 @@
   };
 } );
 
+type TFlowConfigurable = {
+  _orientation: Orientation;
+  _align: LayoutAlign | null;
+  _stretch: boolean | null;
+  _grow: number | null;
+
+  orientationChangedEmitter: TEmitter;
+
+  mutateConfigurable( options?: FlowConfigurableOptions ): void;
+  setConfigToBaseDefault(): void;
+  setConfigToInherit(): void;
+
+  orientation: LayoutOrientation;
+  align: HorizontalLayoutAlign | VerticalLayoutAlign | null;
+  stretch: boolean | null;
+  grow: number | null;
+} & TMarginLayoutConfigurable;
+
 scenery.register( 'FlowConfigurable', FlowConfigurable );
-export default FlowConfigurable;
+export default FlowConfigurable as unknown as <SuperType extends Constructor>( type: SuperType ) => SuperType & Constructor<TFlowConfigurable>;
 export { FLOW_CONFIGURABLE_OPTION_KEYS };
\ No newline at end of file
Index: projectile-data-lab/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/tsconfig.json b/projectile-data-lab/tsconfig.json
--- a/projectile-data-lab/tsconfig.json	(revision 696b26fcc9c93da4a00fa45fd5b9fe4a69ec55a1)
+++ b/projectile-data-lab/tsconfig.json	(date 1714346127180)
@@ -1,9 +1,85 @@
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [
+    {
+      "path": "../scenery/tsconfig.json"
+    }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../phet-core/js/logGlobal.ts",
+    "../axon/js/StringUnionProperty.ts",
+    "../scenery-phet/js/TimeSpeed.ts",
+    "../scenery-phet/js/Stopwatch.ts",
+    "../sun/js/buttons/RadioButtonInteractionStateProperty.ts",
+    "../sun/js/buttons/RectangularRadioButton.ts",
+    "../sun/js/buttons/RectangularRadioButtonGroup.ts",
+    "../twixt/js/twixt.ts",
+    "../twixt/js/Easing.ts",
+    "../twixt/js/AnimationTarget.ts",
+    "../twixt/js/Animation.ts",
+    "../sherpa/js/fontawesome-5/angleRightSolidString.js",
+    "../sherpa/js/fontawesome-5/angleLeftSolidString.js",
+    "../sun/js/accessibility/AccessibleNumberSpinner.ts",
+    "../sherpa/js/fontawesome-5/angleRightSolidShape.js",
+    "../sherpa/js/fontawesome-5/angleLeftSolidShape.js",
+    "../tambo/sounds/resetAll_mp3.js",
+    "../scenery-phet/js/ResetShape.ts",
+    "../tambo/js/shared-sound-players/resetAllSoundPlayer.ts",
+    "../scenery-phet/js/buttons/ResetButton.ts",
+    "../tambo/sounds/accordionBoxClose_mp3.js",
+    "../tambo/sounds/accordionBoxOpen_mp3.js",
+    "../tambo/js/shared-sound-players/accordionBoxClosedSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/accordionBoxOpenedSoundPlayer.ts",
+    "../sun/js/AccordionBox.ts",
+    "../scenery-phet/js/PauseIconShape.ts",
+    "../tambo/js/shared-sound-players/stepForwardSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/stepBackwardSoundPlayer.ts",
+    "../scenery-phet/js/buttons/StepButton.ts",
+    "../scenery-phet/js/buttons/PlayPauseButton.ts",
+    "../scenery-phet/js/buttons/StepBackwardButton.ts",
+    "../scenery-phet/js/buttons/StepForwardButton.ts",
+    "../scenery-phet/js/TimeSpeedRadioButtonGroup.ts",
+    "../scenery-phet/js/buttons/PlayPauseStepButtonGroup.ts",
+    "../scenery-phet/images/eraser_png.ts",
+    "../scenery-phet/sounds/erase_mp3.js",
+    "../scenery-phet/js/buttons/ResetAllButton.ts",
+    "../sun/js/VerticalAquaRadioButtonGroup.ts",
+    "../scenery-phet/js/TimeControlNode.ts",
+    "../scenery-phet/js/buttons/EraserButton.ts",
+    "../sun/js/VerticalCheckboxGroup.ts",
+    "../scenery-phet/js/ShadedRectangle.ts",
+    "../scenery-phet/js/UTurnArrowShape.ts",
+    "../scenery-phet/js/StopwatchNode.ts",
+    "../dot/js/Transform1.js",
+    "../bamboo/js/bamboo.ts",
+    "../bamboo/js/ClippingType.ts",
+    "../bamboo/js/TickMarkSet.ts",
+    "../scenery-phet/js/MinusNode.ts",
+    "../scenery-phet/js/ZoomButtonGroup.ts",
+    "../bamboo/js/CanvasPainter.ts",
+    "../sherpa/js/fontawesome-5/bullhornSolidString.js",
+    "../sherpa/js/fontawesome-5/stopSolidString.js",
+    "../bamboo/js/ChartTransform.ts",
+    "../bamboo/js/ChartRectangle.ts",
+    "../bamboo/js/GridLineSet.ts",
+    "../bamboo/js/TickLabelSet.ts",
+    "../scenery-phet/js/PlusMinusZoomButtonGroup.ts",
+    "../bamboo/js/ChartCanvasNode.ts",
+    "../sun/js/ABSwitch.ts",
+    "../sherpa/js/fontawesome-5/bullhornSolidShape.js",
+    "../sherpa/js/fontawesome-5/stopSolidShape.js",
+    "../scenery-phet/js/keyboard/help/TwoColumnKeyboardHelpContent.ts",
+    "../scenery-phet/js/keyboard/help/MoveDraggableItemsKeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/help/SliderControlsKeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/help/ComboBoxKeyboardHelpSection.ts",
+    "../scenery-phet/js/ArrowShape.ts",
+    "../scenery-phet/js/ArrowNode.ts",
+    "../scenery-phet/js/ShadedSphereNode.ts",
+    "../joist/js/preferences/PreferencesPanelContentNode.ts",
+    "../joist/js/simLauncher.ts"
   ]
 }
\ No newline at end of file

@samreid samreid self-assigned this Apr 29, 2024
samreid added a commit to phetsims/scenery that referenced this issue Apr 29, 2024
zepumph added a commit to phetsims/scenery that referenced this issue Apr 29, 2024
Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
zepumph added a commit to phetsims/scenery that referenced this issue Apr 29, 2024
Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
zepumph added a commit to phetsims/phet-core that referenced this issue Apr 29, 2024
Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
@zepumph
Copy link
Member Author

zepumph commented Apr 29, 2024

Working on the a11y mixin stack right now (slider/picker->interactiveHighlighting)

@zepumph
Copy link
Member Author

zepumph commented Apr 29, 2024

  • Second arg of DelayedMutate (class) on a new line.

zepumph added a commit to phetsims/utterance-queue that referenced this issue Apr 29, 2024
…tasks#1132

Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
zepumph added a commit to phetsims/sun that referenced this issue Apr 29, 2024
…tasks#1132

Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
zepumph added a commit to phetsims/scenery that referenced this issue Apr 29, 2024
…tasks#1132

Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
zepumph added a commit to phetsims/scenery that referenced this issue Apr 29, 2024
Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
@zepumph
Copy link
Member Author

zepumph commented Apr 29, 2024

I believe that this is all that is left to convert:

  • Popupable
  • ThreeInstrumentable
  • Paintable
  • HeightSizable
  • Sizable
  • WidthSizable
  • FlowConfigurable
  • GridConfigurable
  • MarginLayoutConfigurable
  • SpriteListenable

samreid added a commit to phetsims/gravity-and-orbits that referenced this issue Apr 30, 2024
samreid added a commit to phetsims/projectile-motion that referenced this issue Apr 30, 2024
samreid added a commit to phetsims/faradays-electromagnetic-lab that referenced this issue Apr 30, 2024
samreid added a commit to phetsims/scenery that referenced this issue Apr 30, 2024
@samreid
Copy link
Member

samreid commented Apr 30, 2024

New minimal patch after the changes above:

Subject: [PATCH] imageable
---
Index: scenery/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/tsconfig.json b/scenery/tsconfig.json
--- a/scenery/tsconfig.json	(revision 240b304053d091ac292db84f82cf30fa92a6de64)
+++ b/scenery/tsconfig.json	(date 1714439766878)
@@ -4,6 +4,449 @@
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+
+    "../tandem/js/**/*",
+
+    "../chipper/js/sim-tests/qunitStart.js",
+    "../phet-io/js/phetioEngine.ts",
+
+    "../phet-core/js/isHMR.ts",
+    "../phet-core/js/Namespace.ts",
+    "../phet-core/js/phetCore.ts",
+    "../phet-core/js/extend.ts",
+    "../phet-core/js/types/IntentionalAny.ts",
+    "../phet-core/js/deprecationWarning.ts",
+    "../phet-core/js/merge.ts",
+    "../phet-core/js/types/RequiredKeys.ts",
+    "../phet-core/js/types/OptionalKeys.ts",
+    "../phet-core/js/EnumerationDeprecated.js",
+    "../phet-core/js/optionize.ts",
+    "../axon/js/Validation.ts",
+    "../phet-core/js/types/PickRequired.ts",
+    "../phet-core/js/assertMutuallyExclusiveOptions.ts",
+    "../axon/js/Timer.ts",
+    "../phet-core/js/types/Constructor.ts",
+    "../phet-core/js/EnumerationValue.ts",
+    "../phet-core/js/TEnumeration.ts",
+    "../phet-core/js/inheritance.ts",
+    "../phet-core/js/Enumeration.ts",
+    "../axon/js/animationFrameTimer.ts",
+    "../phet-core/js/types/StrictOmit.ts",
+    "../phet-core/js/arrayRemove.ts",
+    "../axon/js/Disposable.ts",
+    "../axon/js/PropertyStatePhase.ts",
+    "../axon/js/PropertyStateHandler.ts",
+    "../axon/js/propertyStateHandlerSingleton.ts",
+    "../axon/js/units.ts",
+    "../axon/js/ReadOnlyProperty.ts",
+    "../axon/js/TReadOnlyProperty.ts",
+    "../axon/js/TProperty.ts",
+    "../axon/js/TinyProperty.ts",
+    "../axon/js/Emitter.ts",
+    "../axon/js/validate.ts",
+    "../dot/js/Vector4.ts",
+    "../dot/js/Vector3.ts",
+    "../phet-core/js/Pool.ts",
+    "../dot/js/dot.js",
+    "../dot/js/Utils.js",
+    "../dot/js/Matrix4.js",
+    "../dot/js/toSVGNumber.js",
+    "../dot/js/Vector2.ts",
+    "../dot/js/Matrix3.ts",
+    "../dot/js/Range.ts",
+    "../phet-core/js/Orientation.ts",
+    "../dot/js/Bounds2.ts",
+    "../axon/js/axon.ts",
+    "../dot/js/Random.ts",
+    "../dot/js/dotRandom.js",
+    "../axon/js/TEmitter.ts",
+    "../axon/js/TinyEmitter.ts",
+    "../phet-core/js/detectPrefix.ts",
+    "../dot/js/Ray2.ts",
+    "../dot/js/Transform3.js",
+    "../phet-core/js/platform.ts",
+    "../axon/js/Property.ts",
+    "../phet-core/js/detectPrefixEvent.ts",
+    "../phet-core/js/Poolable.ts",
+    "../axon/js/Multilink.ts",
+    "../axon/js/DerivedProperty.ts",
+    "../axon/js/BooleanProperty.ts",
+    "../phet-core/js/isArray.ts",
+    "../dot/js/EigenvalueDecomposition.js",
+    "../dot/js/LUDecomposition.js",
+    "../dot/js/QRDecomposition.js",
+    "../dot/js/Matrix.js",
+    "../dot/js/SingularValueDecomposition.js",
+    "../dot/js/Complex.ts",
+    "../phet-core/js/types/KeysMatching.ts",
+    "../phet-core/js/cleanArray.ts",
+    "../kite/js/kite.ts",
+    "../kite/js/util/LineStyles.ts",
+    "../kite/js/util/Overlap.ts",
+    "../kite/js/util/RayIntersection.ts",
+    "../kite/js/util/SegmentIntersection.ts",
+    "../kite/js/util/svgNumber.ts",
+    "../kite/js/util/intersectConicMatrices.ts",
+    "../kite/js/parser/svgPath.js",
+    "../kite/js/segments/Segment.ts",
+    "../kite/js/segments/Line.ts",
+    "../kite/js/segments/Quadratic.ts",
+    "../kite/js/segments/Cubic.ts",
+    "../kite/js/segments/Arc.ts",
+    "../kite/js/segments/EllipticalArc.ts",
+    "../kite/js/util/Subpath.ts",
+    "../kite/js/Shape.ts",
+    "../kite/js/ops/HalfEdge.js",
+    "../kite/js/ops/Vertex.js",
+    "../kite/js/ops/Edge.js",
+    "../kite/js/ops/Face.js",
+    "../kite/js/ops/Loop.js",
+    "../kite/js/ops/Boundary.js",
+    "../kite/js/ops/BoundsIntersection.ts",
+    "../kite/js/ops/SegmentTree.ts",
+    "../kite/js/ops/EdgeSegmentTree.ts",
+    "../kite/js/ops/VertexSegmentTree.ts",
+    "../kite/js/ops/Graph.js",
+    "../kite/js/imports.ts",
+    "../dot/js/BinPacker.ts",
+    "../dot/js/Dimension2.ts",
+    "../phet-core/js/stripEmbeddingMarks.ts",
+    "../axon/js/StringProperty.ts",
+    "../utterance-queue/js/utteranceQueueNamespace.ts",
+    "../utterance-queue/js/ResponsePatternCollection.ts",
+    "../axon/js/PhetioProperty.ts",
+    "../axon/js/TRangedProperty.ts",
+    "../chipper/js/data/localeInfoModule.js",
+    "../phetcommon/js/phetcommon.js",
+    "../phetcommon/js/util/StringUtils.js",
+    "../axon/js/DynamicProperty.ts",
+    "../axon/js/NumberProperty.ts",
+    "../utterance-queue/js/responseCollector.ts",
+    "../utterance-queue/js/ResponsePacket.ts",
+    "../utterance-queue/js/Utterance.ts",
+    "../axon/js/stepTimer.ts",
+    "../utterance-queue/js/Announcer.ts",
+    "../utterance-queue/js/AriaLiveAnnouncer.ts",
+    "../utterance-queue/js/UtteranceWrapper.ts",
+    "../phet-core/js/memoize.ts",
+    "../phet-core/js/arrayDifference.ts",
+    "../utterance-queue/js/UtteranceQueue.ts",
+    "../axon/js/TinyForwardingProperty.ts",
+    "../axon/js/EnabledProperty.ts",
+    "../axon/js/TinyStaticProperty.ts",
+    "../phet-core/js/types/NotNull.ts",
+    "../phet-core/js/types/WithoutNull.ts",
+    "../phet-core/js/assertHasProperties.ts",
+    "../phet-core/js/types/WithRequired.ts",
+    "../phet-core/js/escapeHTML.ts",
+    "../phet-core/js/extendDefined.ts",
+    "../phet-core/js/mutate.ts",
+    "../phet-core/js/types/PickOptional.ts",
+    "../joist/js/joist.ts",
+    "../axon/js/EnabledComponent.ts",
+    "../utterance-queue/js/SpeechSynthesisParentPolyfill.ts",
+    "../joist/js/i18n/localeProperty.ts",
+    "../utterance-queue/js/SpeechSynthesisAnnouncer.ts",
+    "../dot/js/Permutation.ts",
+    "../axon/js/CallbackTimer.ts",
+    "../axon/js/createObservableArray.ts",
+    "../phet-core/js/types/NotUndefined.ts",
+    "../phet-core/js/types/RequiredOption.ts",
+    "../phetcommon/js/view/ModelViewTransform2.ts",
+    "../phet-core/js/EnumerationMap.ts",
+    "../phet-core/js/OrientationPair.ts",
+    "../dot/js/Vector2Property.ts",
+    "../sherpa/lib/himalaya-1.1.0.js",
+    "../phet-core/js/types/CollapsePropertyValue.ts",
+    "../phet-core/js/types/KeysNotMatching.ts",
+    "../axon/js/DerivedStringProperty.ts",
+    "../axon/js/EnumerationDeprecatedProperty.js",
+    "../axon/js/MappedProperty.ts",
+    "../axon/js/PatternStringProperty.ts",
+    "../axon/js/TinyOverrideProperty.ts",
+    "../axon/js/UnitConversionProperty.ts",
+    "../dot/js/Ray3.ts",
+    "../dot/js/Bounds3.ts",
+    "../dot/js/Combination.ts",
+    "../dot/js/CompletePiecewiseLinearFunction.ts",
+    "../dot/js/ConvexHull2.js",
+    "../dot/js/DampedHarmonic.ts",
+    "../dot/js/DelaunayTriangulation.js",
+    "../dot/js/LinearFunction.ts",
+    "../dot/js/MatrixOps3.js",
+    "../dot/js/Plane3.ts",
+    "../dot/js/Quaternion.js",
+    "../dot/js/Rectangle.js",
+    "../dot/js/Sphere3.js",
+    "../dot/js/Transform4.js",
+    "../dot/js/UnivariatePolynomial.ts",
+    "../phet-core/js/collect.ts",
+    "../phet-core/js/dimensionForEach.ts",
+    "../phet-core/js/dimensionMap.ts",
+    "../phet-core/js/EventTimer.ts",
+    "../phet-core/js/interleave.ts",
+    "../phet-core/js/loadScript.ts",
+    "../phet-core/js/pairs.ts",
+    "../phet-core/js/partition.ts",
+    "../utterance-queue/js/ActivationUtterance.ts",
+    "../utterance-queue/js/ValueChangeUtterance.ts",
+    "../axon/js/main.ts",
+    "../dot/js/main.js",
+    "../kite/js/main.js",
+    "../phet-core/js/main.ts",
+    "../utterance-queue/js/main.ts",
+    "../joist/js/i18n/fallbackLocalesProperty.ts",
+    "../joist/js/i18n/localeOrderProperty.ts",
+    "../chipper/js/chipper.ts",
+    "../chipper/js/LocalizedStringProperty.ts",
+    "../chipper/js/LocalizedString.ts",
+    "../chipper/js/getStringModule.ts",
+    "../scenery-phet/js/sceneryPhet.ts",
+    "../scenery-phet/js/SceneryPhetStrings.ts",
+    "../scenery-phet/js/accessibility/PDOMSectionNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ControlAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/PlayAreaNode.ts",
+    "../scenery-phet/js/accessibility/nodes/ScreenSummaryNode.ts",
+    "../joist/js/JoistStrings.ts",
+    "../joist/js/ScreenIcon.ts",
+    "../joist/js/ScreenView.ts",
+    "../joist/js/TModel.ts",
+    "../sun/js/sun.ts",
+    "../phet-core/js/gracefulBind.ts",
+    "../sun/js/Popupable.ts",
+    "../tambo/js/tambo.ts",
+    "../phet-core/js/asyncLoader.ts",
+    "../tambo/js/base64SoundToByteArray.ts",
+    "../tambo/js/WrappedAudioBuffer.ts",
+    "../tambo/js/phetAudioContext.ts",
+    "../tambo/sounds/emptyApartmentBedroom06Resampled_mp3.js",
+    "../tambo/js/audioContextStateChangeMonitor.ts",
+    "../tambo/js/soundConstants.ts",
+    "../tambo/js/SoundLevelEnum.ts",
+    "../tambo/js/sound-generators/SoundGenerator.ts",
+    "../scenery-phet/js/sceneryPhetQueryParameters.ts",
+    "../tambo/js/SoundUtils.ts",
+    "../tambo/js/sound-generators/SoundClip.ts",
+    "../tambo/sounds/grab_mp3.js",
+    "../tambo/sounds/release_mp3.js",
+    "../phet-core/js/documentation/InstanceRegistry.ts",
+    "../scenery-phet/images/measuringTape_png.ts",
+    "../scenery-phet/js/PhetFont.ts",
+    "../scenery-phet/js/RichKeyboardDragListener.ts",
+    "../scenery-phet/js/RichDragListener.ts",
+    "../tambo/sounds/radioButtonV2_mp3.js",
+    "../tambo/js/TSoundPlayer.ts",
+    "../tambo/js/multiSelectionSoundPlayerFactory.ts",
+    "../sun/js/AquaRadioButton.ts",
+    "../sun/js/GroupItemOptions.ts",
+    "../joist/js/preferences/PreferencesStorage.ts",
+    "../joist/js/i18n/regionAndCultureProperty.ts",
+    "../joist/js/preferences/PreferencesModel.ts",
+    "../joist/js/DynamicStringTest.ts",
+    "../joist/js/HighlightVisibilityController.ts",
+    "../tambo/sounds/checkboxChecked_mp3.js",
+    "../tambo/js/sound-generators/SoundClipPlayer.ts",
+    "../tambo/sounds/checkboxUnchecked_mp3.js",
+    "../sherpa/js/fontawesome-4/checkEmptySolidShape.js",
+    "../sherpa/js/fontawesome-4/checkSquareOSolidShape.js",
+    "../tambo/js/shared-sound-players/checkboxCheckedSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/checkboxUncheckedSoundPlayer.ts",
+    "../tambo/sounds/generalButton_mp3.js",
+    "../sun/js/buttons/ButtonModel.ts",
+    "../sun/js/buttons/ButtonInteractionState.ts",
+    "../sun/js/buttons/PushButtonModel.ts",
+    "../sun/js/buttons/RadioButtonInteractionState.ts",
+    "../sun/js/ColorConstants.ts",
+    "../sun/js/buttons/TButtonAppearanceStrategy.ts",
+    "../sun/js/buttons/TContentAppearanceStrategy.ts",
+    "../sun/js/buttons/ButtonNode.ts",
+    "../tambo/js/shared-sound-players/pushButtonSoundPlayer.ts",
+    "../sun/js/buttons/PushButtonInteractionStateProperty.ts",
+    "../sun/js/buttons/RectangularButton.ts",
+    "../sun/js/ToggleNode.ts",
+    "../tambo/sounds/stepBack_mp3.js",
+    "../tambo/sounds/stepForward_mp3.js",
+    "../sun/js/buttons/ToggleButtonModel.ts",
+    "../tambo/js/shared-sound-players/toggleOffSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/toggleOnSoundPlayer.ts",
+    "../sun/js/buttons/ToggleButtonInteractionStateProperty.ts",
+    "../sun/js/BooleanToggleNode.ts",
+    "../sun/js/buttons/RectangularToggleButton.ts",
+    "../sun/js/buttons/BooleanRectangularToggleButton.ts",
+    "../scenery-phet/js/MeasuringTapeNode.ts",
+    "../sun/js/Panel.ts",
+    "../sun/js/AquaRadioButtonGroup.ts",
+    "../joist/js/SimDisplay.ts",
+    "../sun/js/Checkbox.ts",
+    "../axon/js/EnumerationProperty.ts",
+    "../sun/js/buttons/RectangularPushButton.ts",
+    "../sun/js/ExpandCollapseButton.ts",
+    "../scenery-phet/js/keyboard/KeyNode.ts",
+    "../scenery-phet/js/PlusShape.ts",
+    "../scenery-phet/js/PlusNode.ts",
+    "../scenery-phet/js/keyboard/ArrowKeyNode.ts",
+    "../scenery-phet/js/keyboard/LetterKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSectionRow.ts",
+    "../scenery-phet/js/keyboard/TextKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpIconFactory.ts",
+    "../scenery-phet/js/keyboard/help/KeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/NumberKeyNode.ts",
+    "../scenery-phet/js/keyboard/help/BasicActionsKeyboardHelpSection.ts",
+    "../tambo/js/sound-generators/MultiClip.ts",
+    "../joist/sounds/screenSelectionHomeV3_mp3.js",
+    "../joist/sounds/switchingScreenSelectorIcons003_mp3.js",
+    "../scenery-phet/js/PhetColorScheme.ts",
+    "../joist/js/Frame.ts",
+    "../joist/js/HomeScreenSoundGenerator.ts",
+    "../joist/js/HomeScreenButton.ts",
+    "../joist/js/HomeScreenKeyboardHelpContent.ts",
+    "../joist/js/HomeScreenModel.ts",
+    "../joist/js/HomeScreenView.ts",
+    "../dot/js/RunningAverage.js",
+    "../tambo/sounds/generalClose_mp3.js",
+    "../tambo/sounds/generalOpen_mp3.js",
+    "../phet-core/js/getGlobal.ts",
+    "../scenery-phet/js/buttons/CloseButton.ts",
+    "../tambo/js/shared-sound-players/generalCloseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalOpenSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/nullSoundPlayer.ts",
+    "../sun/js/SunStrings.ts",
+    "../joist/js/HighlightNode.ts",
+    "../sun/js/Dialog.ts",
+    "../joist/images/keyboardIconOnWhite_png.ts",
+    "../joist/images/keyboardIcon_png.ts",
+    "../joist/js/JoistButton.ts",
+    "../joist/js/KeyboardHelpDialog.ts",
+    "../tambo/sounds/switchToLeft_mp3.js",
+    "../tambo/sounds/switchToRight_mp3.js",
+    "../tambo/js/shared-sound-players/switchToLeftSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/switchToRightSoundPlayer.ts",
+    "../sun/js/ToggleSwitch.ts",
+    "../joist/js/preferences/PreferencesPanelSection.ts",
+    "../joist/js/preferences/PreferencesDialogConstants.ts",
+    "../tambo/sounds/generalBoundaryBoop_mp3.js",
+    "../tambo/sounds/generalSoftClick_mp3.js",
+    "../tambo/js/shared-sound-players/generalBoundaryBoopSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/generalSoftClickSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleValueHandler.ts",
+    "../sun/js/SliderTrack.ts",
+    "../sun/js/SunConstants.ts",
+    "../phet-core/js/swapObjectKeys.ts",
+    "../tambo/js/sound-generators/ValueChangeSoundPlayer.ts",
+    "../sun/js/accessibility/AccessibleSlider.ts",
+    "../sun/js/DefaultSliderTrack.ts",
+    "../sun/js/SliderThumb.ts",
+    "../sun/js/SliderTick.ts",
+    "../sun/js/Slider.ts",
+    "../scenery-phet/js/MathSymbols.ts",
+    "../sun/js/buttons/ArrowButton.ts",
+    "../sun/js/HSlider.ts",
+    "../scenery-phet/js/NumberDisplay.ts",
+    "../sun/js/ComboBoxListItemNode.ts",
+    "../sun/js/ComboBoxButton.ts",
+    "../sun/js/ComboBoxListBox.ts",
+    "../scenery-phet/js/NumberControl.ts",
+    "../sun/js/ComboBox.ts",
+    "../joist/js/preferences/PreferencesType.ts",
+    "../joist/js/preferences/PreferencesControl.ts",
+    "../joist/js/preferences/SoundPanelSection.ts",
+    "../joist/js/preferences/VoicingPanelSection.ts",
+    "../joist/js/preferences/PreferencesPanel.ts",
+    "../joist/js/preferences/ProjectorModeToggleSwitch.ts",
+    "../joist/js/preferences/LanguageSelectionNode.ts",
+    "../joist/js/preferences/RegionAndCultureComboBox.ts",
+    "../joist/js/preferences/LocalePanel.ts",
+    "../joist/js/i18n/isLeftToRightProperty.ts",
+    "../sherpa/js/fontawesome-5/globeSolidString.js",
+    "../sherpa/js/fontawesome-5/globeSolidShape.js",
+    "../joist/js/preferences/PreferencesTab.ts",
+    "../joist/js/preferences/AudioPreferencesPanel.ts",
+    "../joist/js/preferences/SimulationPreferencesPanel.ts",
+    "../joist/js/preferences/InputPreferencesPanel.ts",
+    "../joist/js/preferences/VisualPreferencesPanel.ts",
+    "../joist/js/preferences/LocalizationPreferencesPanel.ts",
+    "../joist/js/preferences/OverviewPreferencesPanel.ts",
+    "../joist/js/preferences/PreferencesTabs.ts",
+    "../joist/sounds/cardFlip_mp3.js",
+    "../joist/js/preferences/PreferencesPanels.ts",
+    "../joist/js/preferences/PreferencesTabSwitchSoundGenerator.ts",
+    "../joist/images/preferencesIconOnWhite_png.ts",
+    "../joist/images/preferencesIcon_png.ts",
+    "../joist/js/preferences/PreferencesDialog.ts",
+    "../joist/js/KeyboardHelpButton.ts",
+    "../joist/js/NavigationBarAudioToggleButton.ts",
+    "../joist/js/preferences/NavigationBarPreferencesButton.ts",
+    "../sherpa/js/fontawesome-5/homeSolidString.js",
+    "../sherpa/js/fontawesome-5/homeSolidShape.js",
+    "../brand/js/brand.ts",
+    "../brand/js/getLinks.ts",
+    "../sherpa/js/fontawesome-5/checkSolidString.js",
+    "../sherpa/js/fontawesome-5/checkSolidShape.js",
+    "../joist/js/UpdateState.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidString.js",
+    "../scenery-phet/js/SpinningIndicatorNode.ts",
+    "../sherpa/js/fontawesome-5/exclamationTriangleSolidShape.js",
+    "../sun/js/buttons/TextPushButton.ts",
+    "../joist/js/UpdateDialog.ts",
+    "../joist/js/CreditsNode.ts",
+    "../joist/js/updateCheck.ts",
+    "../joist/js/UpdateNodes.ts",
+    "../sun/js/MenuItem.ts",
+    "../joist/js/AboutDialog.ts",
+    "../joist/js/ScreenshotGenerator.ts",
+    "../brand/js/TBrand.ts",
+    "../joist/js/KebabMenuIcon.ts",
+    "../joist/js/PhetMenu.ts",
+    "../joist/js/A11yButtonsHBox.ts",
+    "../joist/js/HomeButton.ts",
+    "../joist/js/NavigationBarScreenButton.ts",
+    "../joist/js/PhetButton.ts",
+    "../scenery-phet/images/phetGirlWaggingFinger_png.ts",
+    "../scenery-phet/js/OopsDialog.ts",
+    "../joist/sounds/screenSelection_mp3.js",
+    "../sun/js/buttons/RoundButton.ts",
+    "../sun/js/buttons/RoundToggleButton.ts",
+    "../tambo/sounds/pause_mp3.js",
+    "../tambo/sounds/playPause_mp3.js",
+    "../sun/js/buttons/BooleanRoundToggleButton.ts",
+    "../tambo/js/shared-sound-players/pauseSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/playSoundPlayer.ts",
+    "../scenery-phet/js/PlayIconShape.ts",
+    "../scenery-phet/js/SceneryPhetConstants.ts",
+    "../scenery-phet/js/StopIconShape.ts",
+    "../scenery-phet/js/buttons/PlayControlButton.ts",
+    "../scenery-phet/js/buttons/PlayStopButton.ts",
+    "../sun/js/buttons/RoundPushButton.ts",
+    "../joist/js/toolbar/VoicingToolbarAlertManager.ts",
+    "../joist/js/toolbar/VoicingToolbarItem.ts",
+    "../scenery-phet/js/BarrierRectangle.ts",
+    "../sherpa/lib/game-up-camera-1.0.0.js",
+    "../tambo/js/soundManager.ts",
+    "../joist/js/audioManager.ts",
+    "../joist/js/Heartbeat.ts",
+    "../joist/js/Helper.ts",
+    "../joist/js/HomeScreen.ts",
+    "../joist/js/LookAndFeel.ts",
+    "../joist/js/MemoryMonitor.ts",
+    "../joist/js/NavigationBar.ts",
+    "../joist/js/Profiler.ts",
+    "../joist/js/QueryParametersWarningDialog.ts",
+    "../joist/js/ScreenSelectionSoundGenerator.ts",
+    "../joist/js/selectScreens.ts",
+    "../joist/js/thirdPartySupport/LegendsOfLearningSupport.ts",
+    "../joist/js/toolbar/Toolbar.ts",
+    "../joist/js/Screen.ts",
+    "../joist/js/Sim.ts",
+    "../phet-io/js/phetio.ts",
+    "../phet-io/js/PhetioStateEngine.ts",
+    "../joist/js/packageJSON.ts",
+    "../joist/js/SimInfo.ts",
+    "../phet-io/js/dataStream.ts",
+    "../phet-io/js/phetioCommandProcessor.ts",
+    "../phet-io/js/phetioDevSaveLoad.ts",
+    "../phet-core/js/gracefulBind.js",
+    "../sun/js/Popupable.js",
+    "../phet-core/js/types/TMixin.ts"
   ]
 }
\ No newline at end of file
Index: projectile-sampling-distributions/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-sampling-distributions/tsconfig.json b/projectile-sampling-distributions/tsconfig.json
--- a/projectile-sampling-distributions/tsconfig.json	(revision df4eed3b5ca052470ed62d1da5304229fd1b511e)
+++ b/projectile-sampling-distributions/tsconfig.json	(date 1714439766865)
@@ -1,5 +1,10 @@
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [
+    {
+      "path": "../projectile-data-lab"
+    }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
Index: dot/js/Utils.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/dot/js/Utils.js b/dot/js/Utils.js
--- a/dot/js/Utils.js	(revision aef01d114353684eb9678b4cab9c13ca1a9faa99)
+++ b/dot/js/Utils.js	(date 1714439764742)
@@ -6,7 +6,7 @@
  * @author Jonathan Olson <jonathan.olson@colorado.edu>
  */
 
-import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
+// import Big from '../../sherpa/lib/big-6.2.1.mjs'; // eslint-disable-line default-import-match-filename
 import dot from './dot.js';
 import Vector2 from './Vector2.js';
 import Vector3 from './Vector3.js';
@@ -565,7 +565,7 @@
     }
 
     // eslint-disable-next-line bad-sim-text
-    const result = new Big( value ).toFixed( decimalPlaces );
+    const result = value.toFixed( decimalPlaces ); // TODO: https://github.com/phetsims/tasks/issues/1132
 
     // Avoid reporting -0.000
     if ( result.startsWith( '-0.' ) && Number.parseFloat( result ) === 0 ) {
Index: chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig-core.json b/chipper/tsconfig-core.json
--- a/chipper/tsconfig-core.json	(revision b9b8d46a42df39318878f027a9855be68c5b82b4)
+++ b/chipper/tsconfig-core.json	(date 1714439764737)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+    "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: sherpa/lib/big-6.2.1.mjs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sherpa/lib/big-6.2.1.mjs b/sherpa/lib/big-6.2.1.mjs
--- a/sherpa/lib/big-6.2.1.mjs	(revision 302572b73da562b81aa21ee38464fb8f6f2a935d)
+++ b/sherpa/lib/big-6.2.1.mjs	(date 1714439766885)
@@ -15,7 +15,7 @@
    * The maximum number of decimal places (DP) of the results of operations involving division:
    * div and sqrt, and pow with negative exponents.
    */
-var DP = 20,          // 0 to MAX_DP
+const DP = 20,          // 0 to MAX_DP
 
   /*
    * The rounding mode (RM) used when rounding to the above decimal places.
Index: projectile-data-lab/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/tsconfig.json b/projectile-data-lab/tsconfig.json
--- a/projectile-data-lab/tsconfig.json	(revision 696b26fcc9c93da4a00fa45fd5b9fe4a69ec55a1)
+++ b/projectile-data-lab/tsconfig.json	(date 1714439766860)
@@ -1,9 +1,85 @@
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [
+    {
+      "path": "../scenery/tsconfig.json"
+    }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
     "mipmaps/**/*",
-    "sounds/**/*"
+    "sounds/**/*",
+    "../phet-core/js/logGlobal.ts",
+    "../axon/js/StringUnionProperty.ts",
+    "../scenery-phet/js/TimeSpeed.ts",
+    "../scenery-phet/js/Stopwatch.ts",
+    "../sun/js/buttons/RadioButtonInteractionStateProperty.ts",
+    "../sun/js/buttons/RectangularRadioButton.ts",
+    "../sun/js/buttons/RectangularRadioButtonGroup.ts",
+    "../twixt/js/twixt.ts",
+    "../twixt/js/Easing.ts",
+    "../twixt/js/AnimationTarget.ts",
+    "../twixt/js/Animation.ts",
+    "../sherpa/js/fontawesome-5/angleRightSolidString.js",
+    "../sherpa/js/fontawesome-5/angleLeftSolidString.js",
+    "../sun/js/accessibility/AccessibleNumberSpinner.ts",
+    "../sherpa/js/fontawesome-5/angleRightSolidShape.js",
+    "../sherpa/js/fontawesome-5/angleLeftSolidShape.js",
+    "../tambo/sounds/resetAll_mp3.js",
+    "../scenery-phet/js/ResetShape.ts",
+    "../tambo/js/shared-sound-players/resetAllSoundPlayer.ts",
+    "../scenery-phet/js/buttons/ResetButton.ts",
+    "../tambo/sounds/accordionBoxClose_mp3.js",
+    "../tambo/sounds/accordionBoxOpen_mp3.js",
+    "../tambo/js/shared-sound-players/accordionBoxClosedSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/accordionBoxOpenedSoundPlayer.ts",
+    "../sun/js/AccordionBox.ts",
+    "../scenery-phet/js/PauseIconShape.ts",
+    "../tambo/js/shared-sound-players/stepForwardSoundPlayer.ts",
+    "../tambo/js/shared-sound-players/stepBackwardSoundPlayer.ts",
+    "../scenery-phet/js/buttons/StepButton.ts",
+    "../scenery-phet/js/buttons/PlayPauseButton.ts",
+    "../scenery-phet/js/buttons/StepBackwardButton.ts",
+    "../scenery-phet/js/buttons/StepForwardButton.ts",
+    "../scenery-phet/js/TimeSpeedRadioButtonGroup.ts",
+    "../scenery-phet/js/buttons/PlayPauseStepButtonGroup.ts",
+    "../scenery-phet/images/eraser_png.ts",
+    "../scenery-phet/sounds/erase_mp3.js",
+    "../scenery-phet/js/buttons/ResetAllButton.ts",
+    "../sun/js/VerticalAquaRadioButtonGroup.ts",
+    "../scenery-phet/js/TimeControlNode.ts",
+    "../scenery-phet/js/buttons/EraserButton.ts",
+    "../sun/js/VerticalCheckboxGroup.ts",
+    "../scenery-phet/js/ShadedRectangle.ts",
+    "../scenery-phet/js/UTurnArrowShape.ts",
+    "../scenery-phet/js/StopwatchNode.ts",
+    "../dot/js/Transform1.js",
+    "../bamboo/js/bamboo.ts",
+    "../bamboo/js/ClippingType.ts",
+    "../bamboo/js/TickMarkSet.ts",
+    "../scenery-phet/js/MinusNode.ts",
+    "../scenery-phet/js/ZoomButtonGroup.ts",
+    "../bamboo/js/CanvasPainter.ts",
+    "../sherpa/js/fontawesome-5/bullhornSolidString.js",
+    "../sherpa/js/fontawesome-5/stopSolidString.js",
+    "../bamboo/js/ChartTransform.ts",
+    "../bamboo/js/ChartRectangle.ts",
+    "../bamboo/js/GridLineSet.ts",
+    "../bamboo/js/TickLabelSet.ts",
+    "../scenery-phet/js/PlusMinusZoomButtonGroup.ts",
+    "../bamboo/js/ChartCanvasNode.ts",
+    "../sun/js/ABSwitch.ts",
+    "../sherpa/js/fontawesome-5/bullhornSolidShape.js",
+    "../sherpa/js/fontawesome-5/stopSolidShape.js",
+    "../scenery-phet/js/keyboard/help/TwoColumnKeyboardHelpContent.ts",
+    "../scenery-phet/js/keyboard/help/MoveDraggableItemsKeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/help/SliderControlsKeyboardHelpSection.ts",
+    "../scenery-phet/js/keyboard/help/ComboBoxKeyboardHelpSection.ts",
+    "../scenery-phet/js/ArrowShape.ts",
+    "../scenery-phet/js/ArrowNode.ts",
+    "../scenery-phet/js/ShadedSphereNode.ts",
+    "../joist/js/preferences/PreferencesPanelContentNode.ts",
+    "../joist/js/simLauncher.ts"
   ]
 }
\ No newline at end of file

@samreid
Copy link
Member

samreid commented Apr 30, 2024

I tried many ideas to address the Big.js problem. The only 2 ideas I could get to work were: make it a global, or convert to *.ts (rename only). I'll go with the latter for now since it is less invasive. EDIT: There are references to big in build.js that I'm not sure about. I'll ask for help on this part.

@zepumph
Copy link
Member Author

zepumph commented Apr 30, 2024

@zepumph
Copy link
Member Author

zepumph commented Apr 30, 2024

  Subject: [PATCH] imageable
  ---
  Index: doc/phet-software-design-patterns.md
  IDEA additional info:
  Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  <+>UTF-8
  ===================================================================
  diff --git a/doc/phet-software-design-patterns.md b/doc/phet-software-design-patterns.md
  --- a/doc/phet-software-design-patterns.md	(revision 86181c0cda2f5b88ad9d6fee4775f885eae01461)
  +++ b/doc/phet-software-design-patterns.md	(date 1714504924491)
  @@ -450,8 +450,6 @@
   
   Author: @jessegreenberg
   
  -NOTE: TypeScript does NOT support mixins in ways that work well for our project. Please think twice about adding mixins.
  -
   Descriptions for each standard pattern can be found here:
   
   - Mixin: https://en.wikipedia.org/wiki/Mixin
  @@ -479,6 +477,11 @@
   However, only traits can use properties or methods from the type using the trait. Mixins cannot use anything from the
   class it is mixed into.
   
  +**TypeScript and mixins:**
  +To Type a mixin correctly, especially when supporting `d.ts` file generation, you need to manually specify the return
  +type of your mixin function. This means you must create a Type for the public API of your mixin in addition to the 
  +anonymous class declaration. See examples like `InteractiveHighlighting` and `HeightSizable`.
  +
   ### Shadowing
   
   With the current pattern for mixin/trait, there is no guard against accidentally shadowing properties and methods of the
  @@ -510,86 +513,27 @@
   members, name them prefixed with an underscore (`_myPrivateProperty`). The constructor signature should just pass up
   an `args` param using the spread operator:
   
  -```js
  -const Mixin = Type => {
  +```ts
  +type TMixin = {
  +  myMixedMethod(): boolean;
  +}
  +
  +const Mixin = (Type): Type& Constructor(TMixin) => {
     return class X extends Type {
       constructor( ...args ) {
         super( ...args );
       }
  +
  +    myMixedMethod(): boolean {
  +      return false;
  +    }
     };
   };
   ```
   
  -<details><summary>Old, deprecated Mixin pattern</summary>
  -Creating and using mixins and traits will look similar. Both will have
  -  - A `mixInto` method that is called on the class using the mixin/trait.
  -  - An `initialize{{Name}}` method that will be called in the constructor of the class using the mixin/trait.
  -  - If necessary, the mixin/trait should have a `dispose{{Name}}` method that handles disposal, to be called by the
  -  type using the mixin/trait when it is disposed. Method should not be named `dispose` to avoid overriding the `dispose`
  -  method of the mixing type.
  -  - The class using the mixin/trait will have `@mixes Name` annotation at the constructor.
  -
  -
  -<details><summary>Trait Example</summary>
  -
  -```js
  -// the trait to be mixed into a type
  -const MyTrait = {
  -
  -  /**
  -   * Adds MyTrait methods to the prototype.
  -   * @param {function} myType - must be a subtype of SuperType
  -   */
  -  mixInto: myType => {
  -    assert && assert( _.includes( inheritance( myType ), SuperType ), 'Only SuperType types should mix MyTrait' );
  -
  -    extend( myType.prototype, {
  -
  -      /**
  -       * This should be called in the constructor of a SuperType.
  -       */
  -      initializeMyTrait: () => {},
  -
  -      /**
  -       * Called when disposing the type mixing in this trait
  -       */
  -      disposeMyTrait: () => {},
   
  -      //...
  -    } );
  -  }
  -}
  -
  -// the class mixing in the trait
  -class MyClass extends SuperClass {
  -
  -  /**
  -   * @mixes MyTrait
  -   */
  -  constructor() {
  -    super();
  -
  -    // to initialize features of the trait
  -    this.initializeMyTrait();
  -  }
  -
  -  /**
  -   * Make eligible for garbage collection.
  -   */
  -  dispose() {
  -
  -    // if MyTrait requires/implements disposal
  -    this.disposeMyTrait();
  -  }
  -}
  -
  -// to mix MyTrait methods into the prototype, after inherit for es5 usages
  -MyTrait.mixInto( MyClass );
  -```
  -
  -</details>
  -</details>
  -
  +// 1. protected things should be underscored with `@mixin-protected` doc
  +// 2. 
   ## Model-View-Controller (MVC)
   
   Author: @jessegreenberg

zepumph added a commit to phetsims/scenery that referenced this issue Apr 30, 2024
Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
samreid added a commit to phetsims/phet-info that referenced this issue May 1, 2024
@samreid
Copy link
Member

samreid commented May 1, 2024

I updated the documentation. I wrote an agenda item for Thursday's developer meeting. Want to review? Can this issue be closed?

@samreid samreid assigned zepumph and unassigned samreid May 1, 2024
@zepumph
Copy link
Member Author

zepumph commented May 1, 2024

Looks great thanks.

@zepumph zepumph closed this as completed May 1, 2024
@phet-dev phet-dev reopened this May 1, 2024
@phet-dev
Copy link
Contributor

phet-dev commented May 1, 2024

Reopening because there is a TODO marked for this issue.

@samreid
Copy link
Member

samreid commented May 1, 2024

I'm working on this

@samreid samreid assigned samreid and unassigned zepumph May 1, 2024
samreid added a commit to phetsims/scenery that referenced this issue May 1, 2024
samreid added a commit to phetsims/sun that referenced this issue May 1, 2024
@samreid samreid assigned zepumph and unassigned samreid May 1, 2024
@samreid
Copy link
Member

samreid commented May 1, 2024

I committed my recommendations for these TODOs. @zepumph does it seem OK to you? Feel free to close

@zepumph
Copy link
Member Author

zepumph commented May 1, 2024

Excellent! Thanks so much. I totally forgot about those TODOs.

@zepumph zepumph closed this as completed May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants