diff --git a/src/Accessibility.ts b/src/Accessibility.ts index b2813cf..0e6d33c 100644 --- a/src/Accessibility.ts +++ b/src/Accessibility.ts @@ -16,6 +16,8 @@ import { SmokingPolicy, smokingPolicies } from './SmokingPolicy'; import { getPrefixedQuantitySchemaDefinition, Volume, VolumeSchemaDefinition } from './Quantity'; import { WifiAccessibility, getWifiAccessibilitySchemaDefinition } from './WifiAccessibility'; import getPrefixedSchemaDefinition from './lib/getPrefixedSchemaDefinition'; +import { InteractionMode } from './InteractionMode'; +import { getInteractableSchemaDefinition, Interactable } from './Interactable'; /** * Describes the general wheelchair accessibility of the place. This is a human-rated value. @@ -46,7 +48,7 @@ export const wheelchairAccessibilityGrades = ['fully', 'partially', 'not']; /** * Describes the physical (and sometimes human rated) accessibility of a place. */ -export interface Accessibility { +export interface Accessibility extends Interactable { /// @deprecated Use `wheelchairAccessibilityGrade`, `media`, and other properties instead. accessibleWith?: PersonalProfile; /// @deprecated Use `wheelchairAccessibilityGrade`, `media`, and other properties instead. @@ -240,4 +242,5 @@ export const getAccessibilitySchemaDefinition: () => Record = { + name: { en: 'Reaction test' }, + description: { en: 'Listen to a tone while watching a chart on a screen' }, + languages: ['en'], + optional: false, + required: true, + speak: false, + morseCode: false, + clap: false, + wave: false, + signLanguage: false, + qrCode: false, + headphone: false, + cable: false, + tactile: false, + brailleText: false, + brailleKeyboard: false, + twoHanded: false, + singleHanded: false, + leftHanded: false, + rightHanded: false, + handwriting: false, + keyboard: false, + keypad: false, + mouse: false, + click: false, + doubleClick: false, + tripleClick: false, + tap: false, + trackball: false, + pushSwitch: false, + pedal: false, + pullSwitch: false, + pullstring: false, + tactileGuides: false, + highContrast: false, + touchscreen: false, + touch: false, + press: false, + drag: false, + dragAndDropGesture: false, + activationTimeInterval: { value: 0.5, unit: 's' }, + attentionSpan: { value: 5, unit: 's' }, + pushButton: false, + stateCount: 1, + joystick: true, + turn: false, + turnKnob: false, + pinch: false, + tearApart: false, + squeeze: false, + rotate: false, + tilt: false, + move: false, + tongue: false, + lick: false, + smell: false, + scratch: false, + sipAndPuff: false, + pinchFingerGesture: false, + rotateTwoFingersGesture: false, + swipeFingerGesture: false, + swipeTwoFingersGesture: false, + swipeThreeFingersGesture: false, + rhythm: false, + headPointer: false, + eyeTracker: false, + wheel: false, + wireless: false, + photo: false, + video: false, + soundRecording: false, + faceRecognition: false, + fingerprintScan: false, + irisScan: false, + haptic: false, + raisedText: false, + voiceActivation: false, + visualRecognition: false, + isEasyToUnderstand: true, + necessaryGripHeight: { value: 1, unit: 'm' }, + necessaryEyeHeight: { value: 0.8, unit: 'm' }, + activationForce: { value: 0.1, unit: 'N' }, + feedback: [{ + vibration: true, + }], + techSufficient: [{ + uris: ['https://example.com/tech/1'], + }], + techSupported: [{ + uris: ['https://example.com/tech/1'], + }], + url: { + en: 'https://example.com/devices/42/input', + }, + instructionsUrl: { + en: 'https://example.com/devices/42/input/howto', + }, + apiDocumentationUrl: { + en: 'https://example.com/api/documentation', + }, +}; + +export default actionModeFixture; + +const definition = getActionModeSchemaDefinition(); + +describe('ActionMode schema', () => { + it('validates a completely specified object', () => { + expectValidFixture(definition, actionModeFixture); + }); +}); diff --git a/src/ActionMode.ts b/src/ActionMode.ts new file mode 100644 index 0000000..30db2a1 --- /dev/null +++ b/src/ActionMode.ts @@ -0,0 +1,572 @@ +import SimpleSchema from 'simpl-schema'; +import BooleanField from './BooleanField'; +import { IetfLanguageTag, ietfLanguageTagsAndSignLanguageCodes } from './ietfLanguageTags'; +import { getPrefixedArraySchemaDefinition } from './lib/getPrefixedSchemaDefinition'; +import { getLocalizedStringSchemaDefinition, LocalizedString } from './LocalizedString'; +import { getPerceptionModeSchemaDefinition, PerceptionMode } from './PerceptionMode'; +import { + Force, + ForceSchemaDefinition, + getPrefixedQuantitySchemaDefinition, + Length, + LengthSchemaDefinition, + TimeInterval, + TimeIntervalSchemaDefinition, +} from './Quantity'; +import { getTechCombinationSchemaDefinition, TechCombination } from './TechCombination'; + +/** + * Describes necessary abilities and modes inputting information. + */ +export type ActionMode = { + /** + * Describes which output is meant. Helpful if there are multiple outputs. + */ + name?: LocalizedString; + + /** + * Describes the output as human-readable text. + */ + description?: LocalizedString; + + /** + * Input languages supported. + */ + languages?: IetfLanguageTag[]; + + /** + * `true` if the action is optional, `false` if it is required. + */ + optional?: boolean; + + /** + * `false` if the action is optional, `true` if it is required. + */ + required?: boolean; + + /** + * Force needed for the described input method. + */ + activationForce?: Force; + + /** + * Time interval needed for activation/engagement. + */ + activationTimeInterval?: TimeInterval; + + /** + * Attention time needed for activation/engagement. + */ + attentionSpan?: TimeInterval; + + /** + * How is feedback given for an input? + */ + feedback?: PerceptionMode[]; + + /** + * The ability to speak is supported or needed. + */ + speak?: boolean; + + /** + * Morse code input is supported or needed. + */ + morseCode?: boolean; + + /** + * Clapping your hands is supported or needed. + */ + clap?: boolean; + + /** + * Waving your hands is supported or needed. + */ + wave?: boolean; + + /** + * The ability to use sign language is supported or needed. + */ + signLanguage?: boolean; + + /** + * A QR code is supported or needed. + */ + qrCode?: boolean; + + /** + * Headphones are supported or needed. + */ + headphone?: boolean; + + /** + * A cable is supported or needed. + */ + cable?: boolean; + + /** + * URL where you can use the input mechanism, e.g. on your phone. + */ + url?: LocalizedString; + + /** + * URL describing how to use the input mechanism. + */ + instructionsUrl?: LocalizedString; + + /** + * Tactile input is supported or needed. + */ + tactile?: boolean; + + /** + * Haptic input is supported or needed. + */ + haptic?: boolean; + + /** + * The ability to read braille is supported or needed. + */ + brailleText?: boolean; + + /** + * The ability to write textual content with a braille keyboard is supported or needed. + */ + brailleKeyboard?: boolean; + + /** + * You can or must give input with both hands. + */ + twoHanded?: boolean; + + /** + * You can or must give input with one hand. + */ + singleHanded?: boolean; + + /** + * You can or must give input with your left hand. + */ + leftHanded?: boolean; + + /** + * You can or must give input with your right hand. + */ + rightHanded?: boolean; + + /** + * The ability to write textual content by hand is supported or needed. + */ + handwriting?: boolean; + + /** + * The ability to write textual content by typing on a keyboard is supported or needed. + */ + keyboard?: boolean; + + /** + * The ability to write numbers by typing on a keypad is supported or needed. + */ + keypad?: boolean; + + /** + * The ability to use a mouse is supported or needed. + */ + mouse?: boolean; + + /** + * The ability to click a button with a finger is supported or needed. + */ + click?: boolean; + + /** + * The ability to click a button with a finger is supported or needed. + */ + doubleClick?: boolean; + + /** + * The ability to click a button with a finger is supported or needed. + */ + tripleClick?: boolean; + + /** + * The ability to tap an element with a finger is supported or needed. + */ + tap?: boolean; + + /** + * The ability to use a trackball is supported or needed. + */ + trackball?: boolean; + + /** + * The ability to use a push switch is supported or needed. + */ + pushSwitch?: boolean; + + /** + * The ability to use a push button is supported or needed. + */ + pushButton?: boolean; + + /** + * State count for a button or switch, for example 2 for a toggle button, 3 for a 3-way button. + */ + stateCount?: number; + + /** + * The ability to use a pedal is supported or needed. + */ + pedal?: boolean; + + /** + * The ability to use a pull switch is supported or needed. + */ + pullSwitch?: boolean; + + /** + * The ability to use a pullstring is supported or needed. + */ + pullstring?: boolean; + + /** + * The input has tactile guides, for example around buttons. + */ + tactileGuides?: boolean; + + /** + * The input has high contrast elements, for example around buttons. + */ + highContrast?: boolean; + + /** + * Touchscreen input is supported or needed. + */ + touchscreen?: boolean; + + /** + * Touch input is supported or needed. + */ + touch?: boolean; + + /** + * The ability to apply force to an object is supported or needed. + */ + press?: boolean; + + /** + * The ability to tear something apart is supported or needed. + */ + tearApart?: boolean; + + /** + * The ability to use a joystick is supported or needed. + */ + joystick?: boolean; + + /** + * The ability to turn a knob is supported or needed. + */ + turnKnob?: boolean; + + /** + * The ability to drag an object is supported or needed. + */ + drag?: boolean; + + /** + * The ability to turn an object is supported or needed. + */ + turn?: boolean; + + /** + * The ability to pinch an object is supported or needed. + */ + pinch?: boolean; + + /** + * The ability to squeeze an object is supported or needed. + */ + squeeze?: boolean; + + /** + * The ability to rotate an object is supported or needed. + */ + rotate?: boolean; + + /** + * The ability to tilt an object is supported or needed. + */ + tilt?: boolean; + + /** + * The ability to move an object is supported or needed. + */ + move?: boolean; + + /** + * The ability to move an object with your tongue is supported or needed. + */ + tongue?: boolean; + + /** + * The ability to lick an object with your tongue is supported or needed (e.g. a lollipop) + */ + lick?: boolean; + + /** + * The ability to smell is supported or needed. + */ + smell?: boolean; + + /** + * The ability to scratch is supported or needed. + */ + scratch?: boolean; + + /** + * The ability to use a sip and puff switch is supported or needed. + */ + sipAndPuff?: boolean; + + /** + * The ability to use a pinch finger gesture is supported or needed. + */ + pinchFingerGesture?: boolean; + + /** + * The ability to do a virtual drag-and-drop finger/mouse gesture is supported or needed. + */ + dragAndDropGesture?: boolean; + + /** + * The ability to use a two-finger rotation gesture is supported or needed. + */ + rotateTwoFingersGesture?: boolean; + + /** + * The ability to use a swipe finger gesture is supported or needed. + */ + swipeFingerGesture?: boolean; + + /** + * The ability to use a three-finger swipe gesture is supported or needed. + */ + swipeTwoFingersGesture?: boolean; + + /** + * The ability to use a three-finger swipe gesture is supported or needed. + */ + swipeThreeFingersGesture?: boolean; + + /** + * The ability to use rhythm input is supported or needed. + */ + rhythm?: boolean; + + /** + * The ability to use a head pointer is supported or needed. + */ + headPointer?: boolean; + + /** + * The ability to use an eye tracker is supported or needed. + */ + eyeTracker?: boolean; + + /** + * The input features a wheel. + */ + wheel?: boolean; + + /** + * The input is wireless. + */ + wireless?: boolean; + + /** + * The input makes a photo. + */ + photo?: boolean; + + /** + * The input makes a video. + */ + video?: boolean; + + /** + * The input makes a sound recording. + */ + soundRecording?: boolean; + + /** + * The input uses face recognition. + */ + faceRecognition?: boolean; + + /** + * The input uses a fingerprint scanner. + */ + fingerprintScan?: boolean; + + /** + * The input uses an iris scanner. + */ + irisScan?: boolean; + + /** + * `true` if the controls or signs have raised letters, `false` if not. + */ + raisedText?: boolean; + + /** + * `true` if the control is activated by voice, `false` if not. + */ + voiceActivation?: boolean; + + /** + * `true` if the input user interface needs or supports visual input, `false` if not. + */ + visualRecognition?: boolean; + + /** + * The height you need to grip to perceive the content/output/signal. + */ + necessaryGripHeight?: Length; + + /** + * How tall do you have to be to perceive the content/output/signal. + */ + necessaryEyeHeight?: Length; + + /** + * The input API documentation URL. + */ + apiDocumentationUrl?: LocalizedString; + + /** + * `true` if the input is easy to understand, `false` if people might face difficulties trying to + * understand how the input works, or `undefined` if this is unknown or irrelevant. + */ + isEasyToUnderstand?: boolean; + + /** + * Technology combinations that are sufficient to make use of the output. + */ + techSufficient?: TechCombination[]; + + /** + * Technologies that are sufficient to make use of the output. + */ + techSupported?: TechCombination[]; +}; + +export const getActionModeSchemaDefinition: () => Record = () => ({ + optional: BooleanField, + required: BooleanField, + ...getLocalizedStringSchemaDefinition('name'), + ...getLocalizedStringSchemaDefinition('description'), + ...getLocalizedStringSchemaDefinition('url'), + ...getLocalizedStringSchemaDefinition('instructionsUrl', { + regEx: SimpleSchema.RegEx.Url, + }), + ...getLocalizedStringSchemaDefinition('apiDocumentationUrl', { + regEx: SimpleSchema.RegEx.Url, + }), + languages: { + type: Array, + defaultValue: [], + optional: true, + }, + 'languages.$': { + type: String, + allowedValues: ietfLanguageTagsAndSignLanguageCodes, + }, + speak: BooleanField, + morseCode: BooleanField, + signLanguage: BooleanField, + tactile: BooleanField, + haptic: BooleanField, + brailleText: BooleanField, + brailleKeyboard: BooleanField, + twoHanded: BooleanField, + singleHanded: BooleanField, + leftHanded: BooleanField, + rightHanded: BooleanField, + handwriting: BooleanField, + click: BooleanField, + doubleClick: BooleanField, + tripleClick: BooleanField, + tap: BooleanField, + tactileGuides: BooleanField, + touch: BooleanField, + drag: BooleanField, + press: BooleanField, + pinch: BooleanField, + clap: BooleanField, + wave: BooleanField, + squeeze: BooleanField, + rotate: BooleanField, + tilt: BooleanField, + move: BooleanField, + tongue: BooleanField, + pinchFingerGesture: BooleanField, + rotateTwoFingersGesture: BooleanField, + swipeFingerGesture: BooleanField, + swipeTwoFingersGesture: BooleanField, + swipeThreeFingersGesture: BooleanField, + dragAndDropGesture: BooleanField, + rhythm: BooleanField, + keypad: BooleanField, + keyboard: BooleanField, + mouse: BooleanField, + trackball: BooleanField, + pushSwitch: BooleanField, + pushButton: BooleanField, + stateCount: { + type: Number, + min: 1, + optional: true, + }, + pedal: BooleanField, + pullSwitch: BooleanField, + pullstring: BooleanField, + touchscreen: BooleanField, + joystick: BooleanField, + sipAndPuff: BooleanField, + turn: BooleanField, + turnKnob: BooleanField, + tearApart: BooleanField, + lick: BooleanField, + smell: BooleanField, + scratch: BooleanField, + headPointer: BooleanField, + eyeTracker: BooleanField, + wheel: BooleanField, + wireless: BooleanField, + qrCode: BooleanField, + knob: BooleanField, + headphone: BooleanField, + cable: BooleanField, + phone: BooleanField, + photo: BooleanField, + video: BooleanField, + highContrast: BooleanField, + soundRecording: BooleanField, + faceRecognition: BooleanField, + fingerprintScan: BooleanField, + irisScan: BooleanField, + isEasyToUnderstand: BooleanField, + ...getPrefixedQuantitySchemaDefinition('heightFromFloor', LengthSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('necessaryGripHeight', LengthSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('necessaryEyeHeight', LengthSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('activationForce', ForceSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('activationTimeInterval', TimeIntervalSchemaDefinition), + ...getPrefixedArraySchemaDefinition('techSufficient', getTechCombinationSchemaDefinition()), + ...getPrefixedArraySchemaDefinition('techSupported', getTechCombinationSchemaDefinition()), + ...getPrefixedArraySchemaDefinition('feedback', getPerceptionModeSchemaDefinition()), + raisedText: BooleanField, + voiceActivation: BooleanField, + visualRecognition: BooleanField, + ...getPrefixedQuantitySchemaDefinition('attentionSpan', TimeIntervalSchemaDefinition), +}); diff --git a/src/Door.test.ts b/src/Door.test.ts index 6a573a3..70ca516 100644 --- a/src/Door.test.ts +++ b/src/Door.test.ts @@ -1,6 +1,7 @@ import { Door, getDoorSchemaDefinition } from './Door'; import { Complete } from './Complete'; import expectValidFixture from './lib/expectValidFixture'; +import interactionModeFixture from './InteractionMode.test'; const doorFixture: Complete = { turningSpaceInFront: '<90cm', @@ -27,6 +28,7 @@ const doorFixture: Complete = { hasIntercom: false, needsIntercom: false, access: ['private'], + interactions: [interactionModeFixture], }; export default doorFixture; diff --git a/src/Door.ts b/src/Door.ts index 655fcaf..712d053 100644 --- a/src/Door.ts +++ b/src/Door.ts @@ -1,4 +1,7 @@ import { AccessType, accessTypes } from './AccessType'; +import BooleanField from './BooleanField'; +import { getInteractableSchemaDefinition, Interactable } from './Interactable'; +import getPrefixedSchemaDefinition from './lib/getPrefixedSchemaDefinition'; import { ForceSchemaDefinition, getPrefixedQuantitySchemaDefinition, @@ -11,7 +14,7 @@ import { * Describes the door of a place's entrance or to one of its facilities (e.g. to a shower, or to * an elevator) */ -export interface Door { +export interface Door extends Interactable { /** * Turning space in front of the door. */ @@ -221,4 +224,5 @@ export const getDoorSchemaDefinition: () => Record = ( ...getPrefixedQuantitySchemaDefinition('openingForce', ForceSchemaDefinition), ...getPrefixedQuantitySchemaDefinition('closingSpeed', SpeedSchemaDefinition), ...getPrefixedQuantitySchemaDefinition('latchingSpeed', SpeedSchemaDefinition), + ...getInteractableSchemaDefinition(), }); diff --git a/src/EntranceProperties.test.ts b/src/EntranceProperties.test.ts index 0a495ae..9f790a6 100644 --- a/src/EntranceProperties.test.ts +++ b/src/EntranceProperties.test.ts @@ -3,6 +3,7 @@ import doorFixture from './Door.test'; import stairsFixture from './Stairs.test'; import { Complete } from './Complete'; import expectValidFixture from './lib/expectValidFixture'; +import interactionModeFixture from './InteractionMode.test'; const entrancePropertiesFixture: Complete = { name: { en: 'string' }, @@ -21,6 +22,7 @@ const entrancePropertiesFixture: Complete = { intercomEquipmentId: 'idHere', needsAppointment: true, placeInfoId: '1234', + interactions: [interactionModeFixture], }; export default entrancePropertiesFixture; diff --git a/src/EntranceProperties.ts b/src/EntranceProperties.ts index f2e5d90..ba8a8ff 100644 --- a/src/EntranceProperties.ts +++ b/src/EntranceProperties.ts @@ -3,11 +3,12 @@ import { Stairs, getStairsSchemaDefinition } from './Stairs'; import { getLocalizedStringSchemaDefinition, LocalizedString } from './LocalizedString'; import { getPrefixedQuantitySchemaDefinition, Slope, SlopeSchemaDefinition } from './Quantity'; import getPrefixedSchemaDefinition from './lib/getPrefixedSchemaDefinition'; +import { getInteractableSchemaDefinition, Interactable } from './Interactable'; /** * Describes an entrance to a place. */ -export interface EntranceProperties { +export interface EntranceProperties extends Interactable { /** * Name of the entrance (helpful if there are multiple entrances). */ @@ -122,4 +123,5 @@ SchemaDefinition type: String, optional: true, }, + ...getInteractableSchemaDefinition(), }); diff --git a/src/EquipmentProperties.test.ts b/src/EquipmentProperties.test.ts index f7c5603..6bcfde2 100644 --- a/src/EquipmentProperties.test.ts +++ b/src/EquipmentProperties.test.ts @@ -65,6 +65,36 @@ const equipmentPropertiesFixture: Complete = { accessibilityControl: ['fullSwitchControl'], accessibilityFeature: ['braille'], accessibilityHazard: ['noFlashingHazard'], + interactions: [ + { + name: { en: 'On reaching a floor' }, + optional: true, + perception: [{ + speech: true, + }], + }, + { + name: { en: 'Selecting a floor' }, + required: true, + action: [{ + pushButton: true, + activationForce: '0.1N', + activationTimeInterval: '0.2s', + feedback: [{ + hapticClick: true, + beep: true, + }], + }], + }, + { + name: { en: 'Elevator movement' }, + required: true, + perception: [{ + vibration: true, + acceleration: '1m/s^2', + }], + }, + ], }; export default equipmentPropertiesFixture; diff --git a/src/EquipmentProperties.ts b/src/EquipmentProperties.ts index 60a9595..3ae7f0a 100644 --- a/src/EquipmentProperties.ts +++ b/src/EquipmentProperties.ts @@ -12,6 +12,8 @@ import { W3CAccessMode, w3cAccessModes } from './W3CAccessMode'; import { W3CAccessibilityFeature, w3cAccessibilityFeatures } from './W3CAccessibilityFeature'; import { W3CAccessibilityHazard, w3cAccessibilityHazards } from './W3CAccessibilityHazard'; import { w3cAccessibilityControls, W3CAccessibilityControl } from './W3CAccessibilityControl'; +import { getInteractionModeSchemaDefinition } from './InteractionMode'; +import { getInteractableSchemaDefinition, Interactable } from './Interactable'; export type EquipmentTypes = | 'bed' @@ -629,4 +631,5 @@ SchemaDefinition type: String, allowedValues: w3cAccessibilityHazards, }, + ...getInteractableSchemaDefinition(), }); diff --git a/src/GrabBars.test.ts b/src/GrabBars.test.ts index e66e4fe..ad49eef 100644 --- a/src/GrabBars.test.ts +++ b/src/GrabBars.test.ts @@ -1,6 +1,7 @@ import { GrabBars, getGrabBarsSchemaDefinition } from './GrabBars'; import { Complete } from './Complete'; import expectValidFixture from './lib/expectValidFixture'; +import interactionModeFixture from './InteractionMode.test'; const grabBarsFixture: Complete = { onUsersLeftSide: true, @@ -8,6 +9,7 @@ const grabBarsFixture: Complete = { topHeightFromFloor: '80cm', distanceBetweenBars: '80cm', foldable: true, + interactions: [interactionModeFixture], }; export default grabBarsFixture; diff --git a/src/GrabBars.ts b/src/GrabBars.ts index 5c2105c..81d2003 100644 --- a/src/GrabBars.ts +++ b/src/GrabBars.ts @@ -1,8 +1,9 @@ import { t } from 'ttag'; import getPrefixedSchemaDefinition from './lib/getPrefixedSchemaDefinition'; +import { getInteractableSchemaDefinition, Interactable } from './Interactable'; import { getPrefixedQuantitySchemaDefinition, Length, LengthSchemaDefinition } from './Quantity'; -export interface GrabBars { +export interface GrabBars extends Interactable { /** * `true` if there is a folding handle on left side (from the perspective of somebody using the * toilet), `false` if not, `undefined` if condition is unknown. @@ -42,4 +43,5 @@ export const getGrabBarsSchemaDefinition: () => Record type: Boolean, optional: true, }, + ...getInteractableSchemaDefinition(), }); diff --git a/src/InputModeExperimental.ts b/src/InputModeExperimental.ts deleted file mode 100644 index f40e8b3..0000000 --- a/src/InputModeExperimental.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { IetfLanguageTag } from './ietfLanguageTags'; -import { Force } from './Quantity'; - -/** - * EXPERIMENTAL. Describes necessary abilities and modes inputting information. - */ -export type InputMode = { - /** - * The ability to speak is supported or needed. - */ - speech?: boolean, - - spokenLanguages?: IetfLanguageTag[], - - signLanguage?: boolean, - - /** - * Tactile input is supported or needed. - */ - tactile?: boolean, - - /** - * The ability to read braille is supported or needed. - */ - readBraille?: boolean, - - /** - * The ability to write textual content by hand is supported or needed. - */ - handwriting?: boolean, - - /** - * The ability to write textual content by typing on a keyboard is supported or needed. - */ - keyboard?: boolean, - - /** - * The ability to use a mouse is supported or needed. - */ - - mouse?: boolean, - - /** - * The ability to use a trackball is supported or needed. - */ - trackball?: boolean, - - /** - * The ability to use a push switch is supported or needed. - */ - pushSwitch?: boolean, - - /** - * The ability to use a pull switch is supported or needed. - */ - pullSwitch?: boolean, - - /** - * The ability to use a pullstring is supported or needed. - */ - pullstring?: boolean, - - /** - * The input has active force feedback. - */ - forceFeedback?: boolean, - - /** - * The input has haptic active feedback. - */ - - hapticFeedback?: boolean, - - /** - * The input has tactile guides, for example around buttons. - */ - tactileGuides?: boolean, - - /** - * Touchscreen input is supported or needed. - */ - touchscreen?: boolean, - - /** - * Touch input is supported or needed. - */ - touch?: boolean, - - /** - * The ability to apply force to an object is supported or needed. - */ - press?: boolean, - - /** - * Force needed when pressing buttons / objects. - */ - necessaryForce?: Force, -}; diff --git a/src/Interactable.ts b/src/Interactable.ts new file mode 100644 index 0000000..4c2fcff --- /dev/null +++ b/src/Interactable.ts @@ -0,0 +1,13 @@ +import { getInteractionModeSchemaDefinition, InteractionMode } from './InteractionMode'; +import { getPrefixedArraySchemaDefinition } from './lib/getPrefixedSchemaDefinition'; + +export interface Interactable { + /** + * Indicates how the object can be interacted with. + */ + interactions?: InteractionMode[]; +} + +export const getInteractableSchemaDefinition: () => Record = () => ({ + ...getPrefixedArraySchemaDefinition('interactions', getInteractionModeSchemaDefinition()), +}); diff --git a/src/InteractionMode.test.ts b/src/InteractionMode.test.ts new file mode 100644 index 0000000..a045ef2 --- /dev/null +++ b/src/InteractionMode.test.ts @@ -0,0 +1,29 @@ +import { Complete } from './Complete'; +import expectValidFixture from './lib/expectValidFixture'; +import { getInteractionModeSchemaDefinition, InteractionMode } from './InteractionMode'; + +const interactionModeFixture: Complete = { + name: { en: 'Reaction test' }, + description: { en: 'A test to see how fast you can react' }, + action: [{ + touch: true, + }], + perception: [{ + light: true, + music: true, + educationLevel: 1, + }], + languages: ['en'], + optional: false, + required: true, +}; + +export default interactionModeFixture; + +const definition = getInteractionModeSchemaDefinition(); + +describe('InteractionMode schema', () => { + it('validates a completely specified object', () => { + expectValidFixture(definition, interactionModeFixture); + }); +}); diff --git a/src/InteractionMode.ts b/src/InteractionMode.ts new file mode 100644 index 0000000..a251a7f --- /dev/null +++ b/src/InteractionMode.ts @@ -0,0 +1,65 @@ +import { ActionMode, getActionModeSchemaDefinition } from './ActionMode'; +import BooleanField from './BooleanField'; +import { IetfLanguageTag, ietfLanguageTagsAndSignLanguageCodes } from './ietfLanguageTags'; +import { getPrefixedArraySchemaDefinition } from './lib/getPrefixedSchemaDefinition'; +import { getLocalizedStringSchemaDefinition, LocalizedString } from './LocalizedString'; +import { getPerceptionModeSchemaDefinition, PerceptionMode } from './PerceptionMode'; + +/** + * Describes the door of a place's entrance or to one of its facilities (e.g. to a shower, or to + * an elevator) + */ +export interface InteractionMode { + /** + * Describes which output is meant. Helpful if there are multiple outputs. + */ + name?: LocalizedString; + + /** + * Describes the output as human-readable text. + */ + description?: LocalizedString; + + /** + * Input languages supported. + */ + languages?: IetfLanguageTag[]; + + /** + * Perception modes supported to facilitate the interaction. + */ + perception?: PerceptionMode[]; + + /** + * Action modes that are absolutely necessary to facilitate the interaction, e.g. ‘pushing a + * button’. + */ + action?: ActionMode[]; + + /** + * `true` if the interaction is optional, `false` if it is required. + */ + optional?: boolean; + + /** + * `false` if the interaction is optional, `true` if it is required. + */ + required?: boolean; +} + +export const getInteractionModeSchemaDefinition: () => Record = () => ({ + ...getLocalizedStringSchemaDefinition('name'), + ...getLocalizedStringSchemaDefinition('description'), + ...getPrefixedArraySchemaDefinition('action', getActionModeSchemaDefinition()), + ...getPrefixedArraySchemaDefinition('perception', getPerceptionModeSchemaDefinition()), + languages: { + type: Array, + optional: true, + }, + 'languages.$': { + type: String, + allowedValues: ietfLanguageTagsAndSignLanguageCodes, + }, + optional: BooleanField, + required: BooleanField, +}); diff --git a/src/PerceptionMode.test.ts b/src/PerceptionMode.test.ts new file mode 100644 index 0000000..1a854d6 --- /dev/null +++ b/src/PerceptionMode.test.ts @@ -0,0 +1,103 @@ +import { Complete } from './Complete'; +import expectValidFixture from './lib/expectValidFixture'; +import { getPerceptionModeSchemaDefinition, PerceptionMode } from './PerceptionMode'; + +const perceptionModeFixture: Complete = { + speech: false, + activationSignal: false, + alarm: false, + read: false, + forceFeedback: false, + vibration: false, + led: false, + breathing: false, + hapticClick: false, + audibleClick: false, + music: false, + beep: false, + bing: false, + pitchedTone: false, + haptic: false, + rhythmic: false, + handwritten: false, + flash: false, + morse: false, + pictograms: false, + numbers: false, + animation: false, + sound: false, + signLanguage: false, + tactile: false, + braille: false, + tactileGuides: false, + screen: false, + chart: false, + highContrast: false, + blackAndWhite: false, + static: false, + colorCode: false, + colorGradient: false, + qrCode: false, + headphone: true, + cable: false, + radio: true, + byod: true, + urgent: false, + info: false, + warning: false, + light: true, + fullBody: true, + isEasyToUnderstand: true, + needsHighConcentration: true, + dedicatedScreenForSubtitles: false, + subtitles: false, + audioDescription: false, + realTimeCaptioning: false, + plainLanguageOption: true, + contentWarning: { en: 'Content warning' }, + name: { en: 'Reaction test' }, + description: { en: 'Listen to a tone while watching a chart on a screen' }, + languages: ['en'], + force: { value: 0.5, unit: 'N' }, + acceleration: { value: 0.5, unit: 'm/s^2' }, + soundVolume: { value: 50, unit: 'dB' }, + brightness: { value: 0.5, unit: 'nits' }, + ambientNoiseLevel: { value: 30, unit: 'dB' }, + frequency: { value: 440, unit: 'Hz' }, + framerate: { value: 48000, unit: 'kHz' }, + fontSize: { value: 4, unit: 'mm' }, + foregroundColors: ['red', 'green', 'blue'], + backgroundColors: ['white'], + flashingHazard: false, + techSufficient: [{ + uris: ['https://example.com/tech/1'], + }], + techSupported: [{ + uris: ['https://example.com/tech/1'], + }], + url: { + en: 'https://example.com/devices/42/output', + }, + instructionsUrl: { + en: 'https://example.com/devices/42/output/howto', + }, + apiDocumentationUrl: 'https://example.com/api/documentation', + necessaryGripHeight: { value: 150, unit: 'cm' }, + necessaryEyeHeight: { value: 90, unit: 'cm' }, + audioIsComprehensible: true, + optional: false, + required: true, + attentionSpan: { value: 10, unit: 's' }, + duration: { value: 1, unit: 'h' }, + educationLevel: 3, +}; + +export default perceptionModeFixture; + +const definition = getPerceptionModeSchemaDefinition(); + +describe('PerceptionMode schema', () => { + it('validates a completely specified object', () => { + expectValidFixture(definition, perceptionModeFixture); + }); +}); diff --git a/src/PerceptionMode.ts b/src/PerceptionMode.ts new file mode 100644 index 0000000..d67d75e --- /dev/null +++ b/src/PerceptionMode.ts @@ -0,0 +1,551 @@ +import BooleanField from './BooleanField'; +import htmlColorSchemaDefinition from './htmlColorSchemaDefinition'; +import { IetfLanguageTag, ietfLanguageTagsAndSignLanguageCodes } from './ietfLanguageTags'; +import { getPrefixedArraySchemaDefinition } from './lib/getPrefixedSchemaDefinition'; +import { getLocalizedStringSchemaDefinition, LocalizedString } from './LocalizedString'; +import { + Force, + Length, + getPrefixedQuantitySchemaDefinition, + LengthSchemaDefinition, + Volume, + VolumeSchemaDefinition, + Hertz, + HertzSchemaDefinition, + Brightness, + BrightnessSchemaDefinition, + ForceSchemaDefinition, + TimeIntervalSchemaDefinition, + TimeInterval, + Acceleration, + AccelerationSchemaDefinition, +} from './Quantity'; +import { getTechCombinationSchemaDefinition, TechCombination } from './TechCombination'; + +/** + * Describes necessary abilities and modes for information output. + */ +export type PerceptionMode = { + /** + * Describes which output is meant. Helpful if there are multiple signals/outputs/content + * lements. + */ + name?: LocalizedString; + + /** + * Describes the content/output/signal as human-readable text. + */ + description?: LocalizedString; + + /** + * Content languages supported. + */ + languages?: IetfLanguageTag[]; + + /** + * `true` if the perception is optional, `false` if it is required. + */ + optional?: boolean; + + /** + * `false` if the perception is optional, `true` if it is required. + */ + required?: boolean; + + /** + * The ability to understand speech is supported or needed. + */ + speech?: boolean; + + /** + * The output is an activation/engagement signal. + */ + activationSignal?: boolean; + + /** + * The output is urgent. + */ + urgent?: boolean; + + /** + * The output is an information without high urgency. + */ + info?: boolean; + + /** + * The output is an alarm. + */ + alarm?: boolean; + + /** + * The output is a warning. + */ + warning?: boolean; + + /** + * The output is a light. + */ + light?: boolean; + + /** + * The ability to read is supported or needed. + */ + read?: boolean; + + /** + * The content/output/signal has active force feedback. + */ + forceFeedback?: boolean; + + /** + * Feedback force applied to the user. + */ + force?: Force; + + /** + * Feedback force applied to the user. + */ + acceleration?: Acceleration; + + /** + * The content/output/signal has active vibration feedback. + */ + vibration?: boolean; + + /** + * The content/output/signal has active vibration feedback. + */ + soundVolume?: Volume; + + /** + * The content/output/signal affects your full body. + */ + fullBody?: boolean; + + /** + * The output is an LED. + */ + led?: boolean; + + /** + * The light looks like it is breathing. + */ + breathing?: boolean; + + /** + * The output's brightness. + */ + brightness?: Brightness; + + /** + * Ambient noise level in dB(A) relative to a reference pressure of 0.00002 Pa. Median over a + * 10-second period at least. + */ + ambientNoiseLevel?: Volume; + + /** + * The output has a haptic click feedback. + */ + hapticClick?: boolean; + + /** + * The output has an acoustic click feedback. + */ + audibleClick?: boolean; + + /** + * The output uses music. + */ + music?: boolean; + + /** + * The output uses one or more beeps as signal. + */ + beep?: boolean; + + /** + * The output uses one or more bing-like signals. + */ + bing?: boolean; + + /** + * The output uses a pitched tone as signal. + */ + pitchedTone?: boolean; + + /** + * The output is haptic. + */ + haptic?: boolean; + + /** + * The output is rhythmic. + */ + rhythmic?: boolean; + + /** + * `true` if the output is usually static and does not change over time, `false` if it is dynamic + * and changes over time. + */ + static?: boolean; + + /** + * Time interval in which the output is active. + */ + duration?: TimeInterval; + + /** + * Attention time span needed to understand the output. + */ + attentionSpan?: TimeInterval; + + /** + * The output needs high concentration to understand. + */ + needsHighConcentration?: boolean; + + /** + * The output has a dedicated screen for subtitles. + */ + dedicatedScreenForSubtitles?: boolean, + + /** + * The output has subtitles. + */ + subtitles?: boolean; + + /** + * The output has audio description. + */ + audioDescription?: boolean; + + /** + * The output has realtime captioning. + */ + realTimeCaptioning?: boolean; + + /** + * The output has a plain language option. + */ + plainLanguageOption?: boolean; + + /** + * Education level needed to understand the output. + * + * http://www.ibe.unesco.org/en/glossary-curriculum-terminology/l/levels-education + * + * - early childhood education (level 0) + * - primary education (level 1) + * - lower secondary education (level 2) + * - upper secondary education (level 3) + * - postsecondary non-tertiary education (level 4) + * - short-cycle tertiary education (level 5) + * - bachelor’s or equivalent level (level 6) + * - master’s or equivalent level (level 7) + * - doctor or equivalent level (level 8). + */ + educationLevel?: Number; + + /** + * The content is handwritten. + */ + handwritten?: boolean; + + /** + * The output is a flashing light. + */ + flash?: boolean; + + /** + * `true` if the output is a flashing hazard, `false` if there is explicitly no flashing hazard + * and someone / something ensures this. This can be relevant for people with epilepsy. + */ + flashingHazard?: boolean; + + /** + * The frequency of the output, for tones or flashes. + */ + frequency?: Hertz; + + /** + * The output uses morse code. + */ + morse?: boolean; + + /** + * The output uses one or more pictograms. + */ + pictograms?: boolean; + + /** + * The output uses one or more numbers. + */ + numbers?: boolean; + + /** + * The output is animated. + */ + animation?: boolean; + + /** + * The framerate of animations. + */ + framerate?: Hertz; + + /** + * The output is acoustic. + */ + sound?: boolean; + + /** + * The ability to understand sign language is supported or needed. + */ + signLanguage?: boolean; + + /** + * The output is tactile. + */ + tactile?: boolean; + + /** + * The ability to read braille is supported or needed. + */ + braille?: boolean; + + /** + * The output has tactile guides, for example around buttons. + */ + tactileGuides?: boolean; + + /** + * The output is displayed on a screen. + */ + screen?: boolean; + + /** + * The output uses one or more charts. + */ + chart?: boolean; + + /** + * The output is displayed in high contrast. + */ + highContrast?: boolean; + + /** + * Font size used in the output. + */ + fontSize?: Length; + + /** + * The output uses black and white colors. + */ + blackAndWhite?: boolean; + + /** + * The output uses a discrete color code. + */ + colorCode?: boolean; + + /** + * The output uses a color gradient. + */ + colorGradient?: boolean; + + /** + * Foreground output HTML colors (for example, the text or icon color). + */ + foregroundColors?: string[]; + + /** + * Background output HTML colors (for example, the background behind a text or icon). + */ + backgroundColors?: string[]; + + /** + * A QR code is supported or needed. + */ + qrCode?: boolean; + + /** + * Headphones are supported or needed. + */ + headphone?: boolean; + + /** + * A cable is supported or needed. + */ + cable?: boolean; + + /** + * A radio connection is supported or needed (e.g. WiFi, Bluetooth, NFC, etc.) + */ + radio?: boolean; + + /** + * `true` if you can or have to perceive the content with a device that you own. + */ + byod?: boolean; + + /** + * Technology combinations that are sufficient to make use of the content/output/signal. + */ + techSufficient?: TechCombination[]; + + /** + * Technologies that are sufficient to make use of the content/output/signal. + */ + techSupported?: TechCombination[]; + + /** + * URL where you can see or make use of the content/output/signal, e.g. on your phone. + */ + url?: LocalizedString; + + /** + * URL describing how to make use of the content/output/signal. + */ + instructionsUrl?: LocalizedString; + + /** + * The input API documentation URL. + */ + apiDocumentationUrl?: string; + + /** + * `true` if the input is easy to understand, `false` if people might face difficulties trying to + * understand how the input works, or `undefined` if this is unknown or irrelevant. + */ + isEasyToUnderstand?: boolean; + + /** + * The height you need to grip to perceive the content/output/signal. + */ + necessaryGripHeight?: Length; + + /** + * How tall do you have to be to perceive the content/output/signal. + */ + necessaryEyeHeight?: Length; + + /** + * `true` if the system’s audio quality is good enough for understanding speech, `false` if it is + * difficult. + */ + audioIsComprehensible?: boolean; + + /** + * Lists potential content warnings you have to expect here. User interfaces should not show the + * content warning directly, but should instead show a button to show the content warning. + */ + contentWarning?: LocalizedString; +}; + +export const getPerceptionModeSchemaDefinition: () => Record = () => ({ + languages: { + type: Array, + defaultValue: [], + optional: true, + }, + 'languages.$': { + type: String, + allowedValues: ietfLanguageTagsAndSignLanguageCodes, + }, + backgroundColors: { + type: Array, + optional: true, + }, + foregroundColors: { + type: Array, + optional: true, + }, + 'backgroundColors.$': htmlColorSchemaDefinition, + 'foregroundColors.$': htmlColorSchemaDefinition, + educationLevel: { + type: Number, + optional: true, + allowedValues: [0, 1, 2, 3, 4, 5, 6, 7, 8], + }, + ...getLocalizedStringSchemaDefinition('contentWarning'), + light: BooleanField, + needsHighConcentration: BooleanField, + ...getPrefixedQuantitySchemaDefinition('attentionSpan', TimeIntervalSchemaDefinition), + audioIsComprehensible: BooleanField, + optional: BooleanField, + required: BooleanField, + activationSignal: BooleanField, + alarm: BooleanField, + warning: BooleanField, + info: BooleanField, + urgent: BooleanField, + animation: BooleanField, + animationFramerate: BooleanField, + static: BooleanField, + byod: BooleanField, + audibleClick: BooleanField, + beep: BooleanField, + bing: BooleanField, + blackAndWhite: BooleanField, + braille: BooleanField, + breathing: BooleanField, + button: BooleanField, + cable: BooleanField, + radio: BooleanField, + chart: BooleanField, + colorCode: BooleanField, + colorGradient: BooleanField, + flash: BooleanField, + flashingHazard: BooleanField, + fontSize: BooleanField, + forceFeedback: BooleanField, + handwritten: BooleanField, + haptic: BooleanField, + hapticClick: BooleanField, + headphone: BooleanField, + highContrast: BooleanField, + isEasyToUnderstand: BooleanField, + dedicatedScreenForSubtitles: BooleanField, + subtitles: BooleanField, + audioDescription: BooleanField, + realTimeCaptioning: BooleanField, + plainLanguageOption: BooleanField, + led: BooleanField, + morse: BooleanField, + music: BooleanField, + numbers: BooleanField, + pictograms: BooleanField, + pitchedTone: BooleanField, + qrCode: BooleanField, + read: BooleanField, + rhythmic: BooleanField, + screen: BooleanField, + signLanguage: BooleanField, + sound: BooleanField, + speech: BooleanField, + tactile: BooleanField, + tactileGuides: BooleanField, + vibration: BooleanField, + fullBody: BooleanField, + apiDocumentationUrl: { + type: String, + optional: true, + }, + ...getLocalizedStringSchemaDefinition('description'), + ...getLocalizedStringSchemaDefinition('instructionsUrl'), + ...getLocalizedStringSchemaDefinition('name'), + ...getLocalizedStringSchemaDefinition('url'), + ...getPrefixedQuantitySchemaDefinition('ambientNoiseLevel', VolumeSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('brightness', BrightnessSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('fontSize', LengthSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('force', ForceSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('acceleration', AccelerationSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('framerate', HertzSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('frequency', HertzSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('soundVolume', VolumeSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('necessaryGripHeight', LengthSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('necessaryEyeHeight', LengthSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('antentionSpan', TimeIntervalSchemaDefinition), + ...getPrefixedQuantitySchemaDefinition('duration', TimeIntervalSchemaDefinition), + ...getPrefixedArraySchemaDefinition('techSufficient', getTechCombinationSchemaDefinition()), + ...getPrefixedArraySchemaDefinition('techSupported', getTechCombinationSchemaDefinition()), +}); diff --git a/src/QueueSystem.ts b/src/QueueSystem.ts index 844cf77..65b5f77 100644 --- a/src/QueueSystem.ts +++ b/src/QueueSystem.ts @@ -1,8 +1,11 @@ import SimpleSchema from 'simpl-schema'; import { EquipmentInfo, getEquipmentInfoSchemaDefinition } from './EquipmentInfo'; import getPrefixedSchemaDefinition from './lib/getPrefixedSchemaDefinition'; +import { getInteractionModeSchemaDefinition, InteractionMode } from './InteractionMode'; +import { Interactable } from './Interactable'; +import { getInteractionModeSchemaDefinition } from './InteractionMode'; -export interface QueueSystem { +export interface QueueSystem extends Interactable { /** * `true` if the queueing uses rails / cattle bars, `false` if not. */ @@ -72,4 +75,5 @@ export const getQueueSystemSchemaDefinition: () => Record = { en: 'A room with a view.', zh: '有景观的房间。', }, + interactions: [{ + name: { en: 'Looking through the window' }, + action: [{ + necessaryEyeHeight: '100cm', + }], + }], }; export default roomFixture; diff --git a/src/Room.ts b/src/Room.ts index 4f995d6..0fd0f39 100644 --- a/src/Room.ts +++ b/src/Room.ts @@ -1,8 +1,10 @@ import { getStructuredAddressSchemaDefinition, StructuredAddress } from './Address'; import getPrefixedSchemaDefinition from './lib/getPrefixedSchemaDefinition'; +import { Interactable } from './Interactable'; +import { getInteractionModeSchemaDefinition } from './InteractionMode'; import { getLocalizedStringSchemaDefinition, LocalizedString } from './LocalizedString'; -export interface Room { +export interface Room extends Interactable { /** * `true` if the room's relevant facilities are completely accessible while using a wheelchair, * `false` if not, `undefined` if the condition is unknown or difficult to assess. @@ -28,4 +30,5 @@ export const getRoomSchemaDefinition: () => Record = ( }, ...getPrefixedSchemaDefinition('address', getStructuredAddressSchemaDefinition()), ...getLocalizedStringSchemaDefinition('description'), + ...getPrefixedArraySchemaDefinition('interactions', getInteractionModeSchemaDefinition()), }); diff --git a/src/TechCombination.test.ts b/src/TechCombination.test.ts new file mode 100644 index 0000000..576371b --- /dev/null +++ b/src/TechCombination.test.ts @@ -0,0 +1,23 @@ +import { TechCombination, getTechCombinationSchemaDefinition } from './TechCombination'; +import { Complete } from './Complete'; +import expectValidFixture from './lib/expectValidFixture'; + +const techCombinationFixture: Complete = { + uris: [ + 'wikidata:Q117266', // for a banana connector (https://www.wikidata.org/wiki/Q117266) + 'openstreetmap:way/123', // for tying the tech to a specific location on the planet + 'wikipedia:Banana connector', // for a banana connector (https://en.wikipedia.org/wiki/Banana_connector) + ], + name: { en: 'Banana connector' }, + description: { en: 'You need a banana connector to connect your assistive tech to something else.' }, +}; + +export default techCombinationFixture; + +const definition = getTechCombinationSchemaDefinition(); + +describe('TechCombination schema', () => { + it('validates a completely specified object', () => { + expectValidFixture(definition, techCombinationFixture); + }); +}); diff --git a/src/TechCombination.ts b/src/TechCombination.ts new file mode 100644 index 0000000..1beaf67 --- /dev/null +++ b/src/TechCombination.ts @@ -0,0 +1,46 @@ +import { getLocalizedStringSchemaDefinition, LocalizedString } from './LocalizedString'; + +/** + * Describes a combination of technologies that are used together to achieve a specific goal. + */ +export interface TechCombination { + /** + * Localizable name/title of the combination. Can describe in which mode or for what goal the + * tech is used. + */ + + name?: LocalizedString; + + /** + * Localizable description of the combination. Can describe in which mode or for what goal the + * tech is used. + */ + + description?: LocalizedString; + + /** + * URIs of technologies that are combined together to form this tech combination. Use RDF if + * possible. + * + * Supported prefix examples: + * + * - `wikidata:Q117266` for a banana connector (https://www.wikidata.org/wiki/Q117266) + * - `openstreetmap:way/123` for tying the tech to a specific location on the planet + * - `wikipedia:Banana connector` for a banana connector (https://en.wikipedia.org/wiki/Banana_connector) + */ + + uris: string[]; +} + +export const getTechCombinationSchemaDefinition: () => Record = () => ({ + ...getLocalizedStringSchemaDefinition('name'), + ...getLocalizedStringSchemaDefinition('description'), + uris: { + type: Array, + defaultValue: [], + optional: true, + }, + 'uris.$': { + type: String, + }, +}); diff --git a/src/index.ts b/src/index.ts index 45d23fc..8392bee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ export { getIsoAlphaThreeCountryCodes }; export { getPrefixedSchemaDefinition }; export * from './Accessibility'; +export * from './ActionMode'; export * from './Address'; export * from './AnimalPolicy'; export * from './CurrencyValue'; @@ -20,12 +21,15 @@ export * from './EquipmentProperties'; export * from './GrabBars'; export * from './Geometry'; export * from './Surface'; +export * from './Interactable'; +export * from './InteractionMode'; export * from './LocalizedString'; export * from './Media'; export * from './Mirror'; export * from './Parking'; export * from './Pathways'; export * from './Payment'; +export * from './PerceptionMode'; export * from './PersonalProfile'; export * from './PlaceInfo'; export * from './PlaceProperties'; @@ -37,6 +41,7 @@ export * from './SmokingPolicy'; export * from './Staff'; export * from './Stairs'; export * from './Tables'; +export * from './TechCombination'; export * from './Toilet'; export * from './Quantity'; export * from './QueueSystem';