Servo library support (#1343)
* ateempt at bringin servos * basic plumbing * avoid math map duplicate * missing parts annontation * pretify parts * extend appcompat layer * updated strings * more compat layer * annotations * don't rely on webmidi * updated pxt ref * bump pxt * adding whenUsed * updated v1 readme * more pins * more pins * compress the parts definition * update common packages
This commit is contained in:
		@@ -109,20 +109,31 @@
 | 
			
		||||
  "Math.atan|param|x": "A number",
 | 
			
		||||
  "Math.ceil": "Returns the smallest number greater than or equal to its numeric argument.",
 | 
			
		||||
  "Math.ceil|param|x": "A numeric expression.",
 | 
			
		||||
  "Math.constrain": "Constrains a number to be within a range",
 | 
			
		||||
  "Math.cos": "Returns the cosine of a number.",
 | 
			
		||||
  "Math.cos|param|x": "An angle in radians",
 | 
			
		||||
  "Math.exp": "Returns returns ``e^x``.",
 | 
			
		||||
  "Math.exp|param|x": "A number",
 | 
			
		||||
  "Math.floor": "Returns the greatest number less than or equal to its numeric argument.",
 | 
			
		||||
  "Math.floor|param|x": "A numeric expression.",
 | 
			
		||||
  "Math.icos": "Returns the cosine of an input angle. This is an 8-bit approximation.",
 | 
			
		||||
  "Math.icos|param|theta": "input angle from 0-255",
 | 
			
		||||
  "Math.idiv": "Returns the value of integer signed 32 bit division of two numbers.",
 | 
			
		||||
  "Math.idiv|param|x": "The first number",
 | 
			
		||||
  "Math.idiv|param|y": "The second number",
 | 
			
		||||
  "Math.imul": "Returns the value of integer signed 32 bit multiplication of two numbers.",
 | 
			
		||||
  "Math.imul|param|x": "The first number",
 | 
			
		||||
  "Math.imul|param|y": "The second number",
 | 
			
		||||
  "Math.isin": "Returns the sine of an input angle. This is an 8-bit approximation.",
 | 
			
		||||
  "Math.isin|param|theta": "input angle from 0-255",
 | 
			
		||||
  "Math.log": "Returns the natural logarithm (base e) of a number.",
 | 
			
		||||
  "Math.log|param|x": "A number",
 | 
			
		||||
  "Math.map": "Re-maps a number from one range to another. That is, a value of ``from low`` would get mapped to ``to low``, a value of ``from high`` to ``to high``, values in-between to values in-between, etc.",
 | 
			
		||||
  "Math.map|param|fromHigh": "the upper bound of the value's current range, eg: 1023",
 | 
			
		||||
  "Math.map|param|fromLow": "the lower bound of the value's current range",
 | 
			
		||||
  "Math.map|param|toHigh": "the upper bound of the value's target range, eg: 4",
 | 
			
		||||
  "Math.map|param|toLow": "the lower bound of the value's target range",
 | 
			
		||||
  "Math.map|param|value": "value to map in ranges",
 | 
			
		||||
  "Math.max": "Returns the larger of two supplied numeric expressions.",
 | 
			
		||||
  "Math.min": "Returns the smaller of two supplied numeric expressions.",
 | 
			
		||||
  "Math.pow": "Returns the value of a base expression taken to a specified power.",
 | 
			
		||||
@@ -402,6 +413,25 @@
 | 
			
		||||
  "parseFloat": "Convert a string to a number.",
 | 
			
		||||
  "parseInt": "Convert a string to an integer.",
 | 
			
		||||
  "pins": "Control currents in Pins for analog/digital signals, servos, i2c, ...",
 | 
			
		||||
  "pins.P0": "Pin P0",
 | 
			
		||||
  "pins.P1": "Pin P1",
 | 
			
		||||
  "pins.P10": "Pin P10",
 | 
			
		||||
  "pins.P11": "Pin P3",
 | 
			
		||||
  "pins.P12": "Pin P12",
 | 
			
		||||
  "pins.P13": "Pin P13",
 | 
			
		||||
  "pins.P14": "Pin P14",
 | 
			
		||||
  "pins.P15": "Pin P15",
 | 
			
		||||
  "pins.P16": "Pin P16",
 | 
			
		||||
  "pins.P19": "Pin P19",
 | 
			
		||||
  "pins.P2": "Pin P2",
 | 
			
		||||
  "pins.P20": "Pin P19",
 | 
			
		||||
  "pins.P3": "Pin P3",
 | 
			
		||||
  "pins.P4": "Pin P4",
 | 
			
		||||
  "pins.P5": "Pin P5",
 | 
			
		||||
  "pins.P6": "Pin P6",
 | 
			
		||||
  "pins.P7": "Pin P7",
 | 
			
		||||
  "pins.P8": "Pin P8",
 | 
			
		||||
  "pins.P9": "Pin P9",
 | 
			
		||||
  "pins.analogPitch": "Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.",
 | 
			
		||||
  "pins.analogPitch|param|frequency": "frequency to modulate in Hz.",
 | 
			
		||||
  "pins.analogPitch|param|ms": "duration of the pitch in milli seconds.",
 | 
			
		||||
 
 | 
			
		||||
@@ -143,6 +143,8 @@
 | 
			
		||||
  "LedSpriteProperty.Direction|block": "direction",
 | 
			
		||||
  "LedSpriteProperty.X|block": "x",
 | 
			
		||||
  "LedSpriteProperty.Y|block": "y",
 | 
			
		||||
  "Math.constrain|block": "constrain %value|between %low|and %high",
 | 
			
		||||
  "Math.map|block": "map %value|from low %fromLow|high %fromHigh|to low %toLow|high %toHigh",
 | 
			
		||||
  "Math.randomBoolean|block": "pick random true or false",
 | 
			
		||||
  "Math.randomRange|block": "pick random %min|to %limit",
 | 
			
		||||
  "Math|block": "Math",
 | 
			
		||||
@@ -208,6 +210,10 @@
 | 
			
		||||
  "Note.GSharp4|block": "G#4",
 | 
			
		||||
  "Note.GSharp5|block": "G#5",
 | 
			
		||||
  "Note.GSharp|block": "G#",
 | 
			
		||||
  "PinEvent.Fall|block": "fall",
 | 
			
		||||
  "PinEvent.PulseHigh|block": "pulse high",
 | 
			
		||||
  "PinEvent.PulseLow|block": "pulse low",
 | 
			
		||||
  "PinEvent.Rise|block": "rise",
 | 
			
		||||
  "PinEventType.Edge|block": "edge",
 | 
			
		||||
  "PinEventType.None|block": "none",
 | 
			
		||||
  "PinEventType.Pulse|block": "pulse",
 | 
			
		||||
@@ -349,6 +355,8 @@
 | 
			
		||||
  "serial.writeString|block": "serial|write string %text",
 | 
			
		||||
  "serial.writeValue|block": "serial|write value %name|= %value",
 | 
			
		||||
  "serial|block": "serial",
 | 
			
		||||
  "{id:category}AnalogInPin": "AnalogInPin",
 | 
			
		||||
  "{id:category}AnalogOutPin": "AnalogOutPin",
 | 
			
		||||
  "{id:category}Array": "Array",
 | 
			
		||||
  "{id:category}Arrays": "Arrays",
 | 
			
		||||
  "{id:category}Basic": "Basic",
 | 
			
		||||
@@ -356,6 +364,7 @@
 | 
			
		||||
  "{id:category}Buffer": "Buffer",
 | 
			
		||||
  "{id:category}Console": "Console",
 | 
			
		||||
  "{id:category}Control": "Control",
 | 
			
		||||
  "{id:category}DigitalInOutPin": "DigitalInOutPin",
 | 
			
		||||
  "{id:category}Game": "Game",
 | 
			
		||||
  "{id:category}Helpers": "Helpers",
 | 
			
		||||
  "{id:category}Image": "Image",
 | 
			
		||||
@@ -363,9 +372,11 @@
 | 
			
		||||
  "{id:category}Input": "Input",
 | 
			
		||||
  "{id:category}Led": "Led",
 | 
			
		||||
  "{id:category}Math": "Math",
 | 
			
		||||
  "{id:category}MicrobitPin": "MicrobitPin",
 | 
			
		||||
  "{id:category}Music": "Music",
 | 
			
		||||
  "{id:category}Number": "Number",
 | 
			
		||||
  "{id:category}Pins": "Pins",
 | 
			
		||||
  "{id:category}PwmOnlyPin": "PwmOnlyPin",
 | 
			
		||||
  "{id:category}Serial": "Serial",
 | 
			
		||||
  "{id:category}String": "String",
 | 
			
		||||
  "{id:category}Text": "Text"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
namespace Math {
 | 
			
		||||
 | 
			
		||||
    export const E = 2.718281828459045;
 | 
			
		||||
    export const LN2 = 0.6931471805599453;
 | 
			
		||||
    export const LN10 = 2.302585092994046;
 | 
			
		||||
    export const LOG2E = 1.4426950408889634;
 | 
			
		||||
    export const LOG10E = 0.4342944819032518;
 | 
			
		||||
    export const PI = 3.141592653589793;
 | 
			
		||||
    export const SQRT1_2 = 0.7071067811865476;
 | 
			
		||||
    export const SQRT2 = 1.4142135623730951;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Number {
 | 
			
		||||
    export const EPSILON = 2.220446049250313e-16;
 | 
			
		||||
}
 | 
			
		||||
@@ -13,7 +13,7 @@ namespace pins {
 | 
			
		||||
     * @param toHigh the upper bound of the value's target range, eg: 4
 | 
			
		||||
     */
 | 
			
		||||
    //% help=pins/map weight=23
 | 
			
		||||
    //% blockId=math_map block="map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh"
 | 
			
		||||
    //% blockId=pin_map block="map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh"
 | 
			
		||||
    export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number {
 | 
			
		||||
        return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										231
									
								
								libs/core/pinscompat.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								libs/core/pinscompat.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,231 @@
 | 
			
		||||
const enum PinEvent {
 | 
			
		||||
    //% block="pulse high"
 | 
			
		||||
    PulseHigh = DAL.MICROBIT_PIN_EVT_PULSE_HI,  // DEVICE_PIN_EVT_PULSE_HI
 | 
			
		||||
    //% block="pulse low"
 | 
			
		||||
    PulseLow = DAL.MICROBIT_PIN_EVT_PULSE_LO,  // DEVICE_PIN_EVT_PULSE_LO
 | 
			
		||||
    //% block="rise"
 | 
			
		||||
    Rise = DAL.MICROBIT_PIN_EVT_RISE,  // DEVICE_PIN_EVT_RISE
 | 
			
		||||
    //% block="fall"
 | 
			
		||||
    Fall = DAL.MICROBIT_PIN_EVT_FALL,  // DEVICE_PIN_EVT_FALL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//% noRefCounting fixedInstances
 | 
			
		||||
interface DigitalInOutPin {
 | 
			
		||||
    digitalRead(): boolean;
 | 
			
		||||
 | 
			
		||||
    digitalWrite(value: boolean): void;
 | 
			
		||||
 | 
			
		||||
    onPulsed(pulse: PulseValue, body: () => void): void;
 | 
			
		||||
 | 
			
		||||
    onEvent(event: PinEvent, body: () => void): void;
 | 
			
		||||
 | 
			
		||||
    pulseIn(value: PulseValue, maxDuration?: number): number;
 | 
			
		||||
 | 
			
		||||
    setPull(pull: PinPullMode): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//% noRefCounting fixedInstances
 | 
			
		||||
interface AnalogInPin extends DigitalInOutPin {
 | 
			
		||||
    analogRead(): number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//% noRefCounting fixedInstances
 | 
			
		||||
interface AnalogOutPin extends DigitalInOutPin {
 | 
			
		||||
    analogWrite(value: number): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//% noRefCounting fixedInstances
 | 
			
		||||
interface AnalogInOutPin extends AnalogInPin, AnalogOutPin {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//% noRefCounting fixedInstances
 | 
			
		||||
interface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin {
 | 
			
		||||
    //% parts=microservo trackArgs=0
 | 
			
		||||
    analogSetPeriod(period: number): void;
 | 
			
		||||
 | 
			
		||||
    //% parts=microservo trackArgs=0
 | 
			
		||||
    servoWrite(value: number): void;
 | 
			
		||||
 | 
			
		||||
    //% parts=microservo trackArgs=0
 | 
			
		||||
    servoSetPulse(duration: number): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//% noRefCounting fixedInstances
 | 
			
		||||
interface PwmPin extends PwmOnlyPin, DigitalInOutPin, AnalogInPin {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//% noRefCounting fixedInstances
 | 
			
		||||
class MicrobitPin implements AnalogInPin, AnalogOutPin, AnalogInOutPin, PwmOnlyPin {
 | 
			
		||||
    public id: number;
 | 
			
		||||
    constructor(id: number) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected digitalId(): DigitalPin {
 | 
			
		||||
        return <DigitalPin>this.id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected analogId(): AnalogPin {
 | 
			
		||||
        return <AnalogPin>this.id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    digitalRead(): boolean {
 | 
			
		||||
        return pins.digitalReadPin(this.digitalId()) != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    digitalWrite(value: boolean): void {
 | 
			
		||||
        pins.digitalWritePin(this.digitalId(), value ? 1 : 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onPulsed(pulse: PulseValue, body: () => void): void {
 | 
			
		||||
        pins.onPulsed(this.digitalId(), pulse, body);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onEvent(event: PinEvent, body: () => void): void {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pulseIn(value: PulseValue, maxDuration?: number): number {
 | 
			
		||||
        return pins.pulseIn(this.digitalId(), value, maxDuration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setPull(pull: PinPullMode): void {
 | 
			
		||||
        pins.setPull(this.digitalId(), pull);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogRead(): number {
 | 
			
		||||
        return pins.analogReadPin(this.analogId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogWrite(value: number): void {
 | 
			
		||||
        pins.analogWritePin(this.analogId(), value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogSetPeriod(period: number): void {
 | 
			
		||||
        pins.analogSetPeriod(this.analogId(), period);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    servoWrite(value: number): void {
 | 
			
		||||
        pins.servoWritePin(this.analogId(), value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    servoSetPulse(duration: number): void {
 | 
			
		||||
        pins.servoSetPulse(this.analogId(), duration);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace pins {
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P0
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P0: PwmPin = new MicrobitPin(DigitalPin.P0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P1
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P1: PwmPin = new MicrobitPin(DigitalPin.P1);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P2
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P2: PwmPin = new MicrobitPin(DigitalPin.P2);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P3
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P3: AnalogInPin = new MicrobitPin(DigitalPin.P3);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P4
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P4: AnalogInPin = new MicrobitPin(DigitalPin.P4);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P5
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P5: DigitalInOutPin = new MicrobitPin(DigitalPin.P5);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P6
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P6: DigitalInOutPin = new MicrobitPin(DigitalPin.P6);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P7
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P7: DigitalInOutPin = new MicrobitPin(DigitalPin.P7);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P8
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P8: DigitalInOutPin = new MicrobitPin(DigitalPin.P8);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P9
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P9: DigitalInOutPin = new MicrobitPin(DigitalPin.P9);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P10
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P10: AnalogInPin = new MicrobitPin(DigitalPin.P10);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P3
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P11: DigitalInOutPin = new MicrobitPin(DigitalPin.P11);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P12
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P12: DigitalInOutPin = new MicrobitPin(DigitalPin.P12);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P13
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P13: DigitalInOutPin = new MicrobitPin(DigitalPin.P13);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P14
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P14: DigitalInOutPin = new MicrobitPin(DigitalPin.P14);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P15
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P15: DigitalInOutPin = new MicrobitPin(DigitalPin.P15);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P16
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P16: DigitalInOutPin = new MicrobitPin(DigitalPin.P16);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P19
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P19: DigitalInOutPin = new MicrobitPin(DigitalPin.P19);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pin P19
 | 
			
		||||
     */
 | 
			
		||||
    //% fixedInstance whenUsed
 | 
			
		||||
    export const P20: DigitalInOutPin = new MicrobitPin(DigitalPin.P20);
 | 
			
		||||
}
 | 
			
		||||
@@ -13,10 +13,11 @@
 | 
			
		||||
        "dal.d.ts",
 | 
			
		||||
        "enums.d.ts",
 | 
			
		||||
        "shims.d.ts",
 | 
			
		||||
        "pxt-core.d.ts",
 | 
			
		||||
        "pxt-core.d.ts",        
 | 
			
		||||
        "core.cpp",
 | 
			
		||||
        "pxt-helpers.ts",
 | 
			
		||||
        "helpers.ts",
 | 
			
		||||
        "pinscompat.ts",
 | 
			
		||||
        "codal.cpp",
 | 
			
		||||
        "images.cpp",
 | 
			
		||||
        "basic.cpp",
 | 
			
		||||
 
 | 
			
		||||
@@ -111,16 +111,18 @@
 | 
			
		||||
                "orientation": "+Z"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "instantiation": {
 | 
			
		||||
            "kind": "function",
 | 
			
		||||
            "fullyQualifiedName": "pins.servoWritePin",
 | 
			
		||||
            "argumentRoles": [
 | 
			
		||||
                {
 | 
			
		||||
                    "pinInstantiationIdx": 0,
 | 
			
		||||
                    "partParameter": "name"
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        "instantiations": [
 | 
			
		||||
            {
 | 
			
		||||
                "kind": "function",
 | 
			
		||||
                "fullyQualifiedName": "pins.servoWritePin,pins.servoSetPulse,PwmOnlyPin.servoWrite,PwmOnlyPin.servoSetPulse,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse",
 | 
			
		||||
                "argumentRoles": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "pinInstantiationIdx": 0,
 | 
			
		||||
                        "partParameter": "name"
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "assembly": [
 | 
			
		||||
            {
 | 
			
		||||
                "part": true,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user