ant -f C:\\x3d-code\\www.web3d.org\\x3d\\stylesheets -Djdk.xml.entityExpansionLimit=120000 -Djdk.xml.maxGeneralEntitySizeLimit=50000000 -Djdk.xml.totalEntitySizeLimit=50000000 test.X3DJSAIL
versions:
=============
ant -version
Apache Ant(TM) version 1.10.15 compiled on August 25 2024
NetBeans ant directory is set under Tools > Options > Java
which ant
/cygdrive/c/apache-ant-1.10.15/bin/ant
=============
java -version
openjdk version "25.0.1" 2025-10-21
OpenJDK Runtime Environment (build 25.0.1+8-27)
OpenJDK 64-Bit Server VM (build 25.0.1+8-27, mixed mode, sharing)
which java
/cygdrive/c/Program Files/Java/OpenJDK/jdk-25.0.1/bin/java
=============
python -version
Python 3.13.5
which python
/cygdrive/c/Python313/python
=============
saxon -? help
SaxonJ-HE 12.8 from Saxonica
Usage: see https://www.saxonica.com/documentation/index.html#!using-xsl/commandline
Format: net.sf.saxon.Transform options params
Options available: -? -a -catalog -config -dtd -ea -expand -explain -export -ext -im -init -it -jit -json -l -lib -license -nogo -now -ns -o -opt -or -outval -p -quit -r -relocate -repeat -s -sa -scmin -strip -stublib -t -T -target -threads -TJ -Tlevel -Tout -TP -TPxsl -traceout -tree -u -val -versionmsg -warnings -x -xi -xmlversion -xsd -xsdversion -xsiloc -xsl -y --?
Use -XYZ:? for details of option XYZ
Params: 
  param=value           Set stylesheet string parameter
  +param=filename       Set stylesheet document parameter
  ?param=expression     Set stylesheet parameter using XPath
  !param=value          Set serialization parameter
$saxon.dir=C:\x3d-code\www.web3d.org\x3d\stylesheets\lib
=============
System environment variables:
  ANT_HOME=C:\apache-ant-1.10.15
 JAVA_HOME=C:\Program Files\Java\OpenJDK\jdk-25.0.1
PYTHONPATH=C:\x3d-code\www.web3d.org\x3d\stylesheets\python
javac source version     $java.source=17
Java/JVM version    $ant.java.version=25
Java/JVM detail version $java.version=25.0.1
Ant version              $ant.version=Apache Ant(TM) version 1.10.15 compiled on August 25 2024
=============
Check for node.js installation from https://nodejs.org
v22.16.0
=============
Check for locally bundled copy of X3DJSAIL at X3DJSAIL.4.0.full.jar
CLASSPATH=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\jars\X3DJSAIL.4.0.full.jar;
java java/jars/X3DJSAIL.4.0.full.jar -version
X3DJSAIL version date: 28 November 2025
Further detail on configuration settings:  https://savage.nps.edu/Savage/developers.html
===========================================
test.X3DJSAIL.clean:
===========================================
Preliminary cleanups
Could not find file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp_MeshLabLauncher.MeshLab.log.txt to delete.
Could not find file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp_MeshLabLauncher.stl to delete.
Could not find file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp_MeshLabLauncher.x3d to delete.
Could not find file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp_MeshLabRoundTrip.log.txt to delete.
Could not find file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp_RoundTrip.stl to delete.
Could not find file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp_RoundTrip.MeshLab.log.txt to delete.
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.java
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\flowers7.java
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\test\CameraExamples.java
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\test\HelloWorld.java
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\test\arc.java
test.mkdir:
compile.examples.java:
delete *.class bytecode...
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgram.class
compile SmokeTestProgram.java source... C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
Compiling 1 source file to C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
test.X3DJSAIL:
===========================================
helpful invocations for CommandLine debugging
org.web3d.x3d.jsail.CommandLine -version -help
Usage: java [-classpath X3DJSAIL.*.jar] org.web3d.x3d.jsail.CommandLine
       [-help | -version | -home | -javadoc | -resources | -hints | -regexes | -tooltips | -X3DUOM]
       [-properties [propertiesFile]]
       [sourceModel.x3d | sourceModel.exi [-fromEXI] | sourceModel.gz [-fromGZIP] | sourceModel.zip [-fromZIP]]
       [-canonical] [-validate] [-EXIFICIENT | -OpenEXI]
       [-Schematron | -Tidy | -toX3D | -toXML | -toClassicVrml | -toJava | -toJSON | -toPython | -toVRML97]
       [-toHTML | -toX3DOM | -toX_ITE | -toMarkdown | -toEXI | -toGZIP | -toZIP]
       [-tofile [resultFile.*]] [-toImage [snapshotName.*]]

-classpath X3DJSAIL.*.jar         # optional classpath, can be set as environment variable
org.web3d.x3d.jsail.CommandLine   # invoke CommandLine application
==================================#====== informational ======================
-help                             # provide this help message
-version                          # version date when this X3DJSAIL build was autogenerated
-home                             # launch X3DJSAIL home page
-javadoc                          # launch X3DJSAIL javadoc page
-resources                        # launch X3D Resources page
-hints                            # launch X3D Scene Authoring Hints page
-regex                            # launch X3D Regular Expressions page
-tooltips                         # launch X3D Tooltips page
-X3DUOM                           # launch X3D Unified Object Model (X3DUOM) page
 =================================#====== properties, inputs =================
-properties [propertiesFile]      # override X3DJSAIL properties (default file: X3DJSAIL.properties)
-EXIFICIENT                       # use Exificient (default) as EXI_ENGINE
-OpenEXI                          # use OpenEXI (Nagasena)   as EXI_ENGINE (testing in progress)
sourceModel.x3d                   # source model file name, X3D  format
sourceModel.exi [-fromEXI]        # source model file name, EXI  format
sourceModel.gz  [-fromGZIP]       # source model file name, GZIP format
sourceModel.zip [-fromZIP]        # source model file name, ZIP  format
==================================#====== operations =========================
-canonical                        # canonical XML output using X3D Canonicalization (c14n)
-validate                         # validate correctness of loaded model
-Schematron                       # X3D Schematron diagnostics and Quality Assurance (QA)
-Tidy                             # X3D-Tidy cleanup in .x3d (XML) format
-toX3D                            # output in .x3d (XML) format
-toXML                            # output in .xml (X3D) format
-toClassicVrml                    # output in .x3dv (ClassicVrml) X3D format
-toJava                           # output in .java source code using X3DJSAIL
-toJSON                           # output in .json (JavaScript Object Notation) format
-toPython                         # output in .py Python source code
-toVRML97                         # output in .wrl  (VRML97) format
-toHTML                           # output in .html  pretty-print documentation
-toX3DOM                          # output in .xhtml page with X3DOM display of X3D model
-toX_ITE                          # output in .html  page with X_ITE display of X3D model
-toMarkdown                       # output document metadata (meta tags) in .md (Markdown) format
-toEXI                            # output in .exi (Efficient XML Interchange) compressed-XML format
-toGZIP                           # output in .gz  (X3D XML) format, with gzip compression
-toZIP                            # output in .zip (X3D XML) format, with zip  compression
==================================#====== outputs ============================
-tofile  [resultFile.*]           # specify output filename (otherwise original name with extension)
-toImage [snapshotName.*]         # create output images for each Viewpoint using Blender

===========================================
org.web3d.x3d.jsail.CommandLine -properties C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties
CommandLine parameter: "-properties" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties" for properties file name root C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties includes 13 properties:
-- listing properties --
deleteIntermediateFiles=true
BLENDER_PATH=
XSLT_ENGINE=SAXON
overwriteExistingFiles=true
EXI_ENGINE=EXIFICIENT
SFImagePixelOutputHexadecimal=true
stripTrailingZeroes=true
normalizeCommentWhitespace=true
indentCharacter=SPACE
MESHLAB_PATH=
indentIncrement=2
validationExceptionAllowed=false
stripDefaultAttributes=true
------------------------
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties loading complete.
===========================================
compile.X3DJSAIL.tests:
Compiling test classes at java/tests
test.X3DJSAIL.FieldObjectTests:
Unit testing org.web3d.x3d.tests.FieldObjectTests
FieldObjectTests start...
FieldObjectTests.fieldObjectInitializationsTest() start...
Preliminary tests...
SFBoolTests...
MFBoolTests...
SFImageTests...
MFImageTests...
SFInt32Tests...
MFInt32Tests...
SFFloatTests...
SFDoubleTests...
SFStringTests...
SFTimeTests...
MFFloatTests...
MFDoubleTests...
MFStringTests...
MFTimeTests...
SFVec2fTests...
SFVec2dTests...
MFVec2fTests...
MFVec2dTests...
SFVec3fTests...
SFVec3fBboxSizeTests for bounding box (bbox) constraints...
SFVec3dTests...
MFVec3fTests...
MFVec3dTests...
SFVec4fTests...
SFVec4dTests...
MFVec4fTests...
MFVec4dTests...
SFColorTests...
MFColorTests...
SFColorRGBATests...
MFColorRGBATests...
SFRotationTests...
MFRotationTests...
SFMatrix3fTests...
SFMatrix3dTests...
MFMatrix3fTests...
MFMatrix3dTests...
SFMatrix4fTests...
SFMatrix4dTests...
MFMatrix4fTests...
MFMatrix4dTests...
FieldObjectTests.fieldObjectInitializationsTest() complete
FieldObjectTests complete
===========================================
compile.examples.java:
delete *.class bytecode...
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgram.class
compile SmokeTestProgram.java source... C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
Compiling 1 source file to C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
===========================================
test execution and self-validation of SmokeTestProgram and other examples:
compile.examples.java:
delete *.class bytecode...
Deleting C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgram.class
compile SmokeTestProgram.java source... C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
Compiling 1 source file to C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
test.SmokeTestProgram.java:
===========================================
ConfigurationProperties.getClassPath()=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples;C:\x3d-code\www.web3d.org\x3d\stylesheets\java\jars\X3DJSAIL.4.0.full.jar
===========================================
X3DUnifiedObjectModelJaxbTests.x3duomInspectionsTest() start...
X3DUnifiedObjectModelJaxbTests.x3duomInspectionsTest() complete
===========================================
X3DJSAIL version date: 28 November 2025
===========================================
SmokeTestProgram() Constructor
===========================================
buildModelSceneGraph(); // construct this model, testing many variations
*** x3dVersionComparisonTest for this model: supportsX3dVersion(X3D.VERSION_3_0)=true
Test duplicate detection: MFString(messageText.getString())="X3D Java" "SAI Library" "X3DJSAIL" "X3DJSAIL" hasDuplicateValues()=true
Test duplicate removal:   MFString(messageText.getString()).removeDuplicateValues()="X3D Java" "SAI Library" "X3DJSAIL" hasDuplicateValues()=false
===========================================
SpecialTest section:
      fontStyle1 getStyle()=BOLD getCssStyle()=test cssStyle attribute;
screenFontStyle3 getStyle()=BOLD getCssStyle()=test cssStyle attribute;
fontStyle1 justify="BEGIN" "MIDDLE"
fontStyle2 justify="END" "MIDDLE"
justify field smoke test #1 pass = true
justify field smoke test #2 pass = true
justify field smoke test #3 pass = true
Test addition of values to family field, duplicates should not be allowed:
*** warning, FontStyle.addFamily("SERIF") ignored since this duplicate value is already one of contained enumerations
*** warning, FontStyle.addFamily("SERIF") ignored since this duplicate value is already one of contained enumerations
    (new MFString(fontStyle1.getFamily()="SERIF" hasDuplicateValues()=false
pixelTexture.getImage=[0, 0, 0], getWidth=0, getHeight=0, getNumberComponents=0, getPixelsString()=
pixelTexture.getImage=[1, 3, 4, -16777080, 16711816, 65416], getWidth=1, getHeight=3, getNumberComponents=4, getPixelsString()=0xFF000088 0x00FF0088 0x0000FF88, isValid()=true, validate() diagnostic=''
layout.getAlign="LEFT" "BOTTOM"
layout field smoke tests = true (through manual debug checks)
Multiple tests pass for orthoViewpoint.fieldOfView=1.0 2.0 3.0 4.0=[1.0, 2.0, 3.0, 4.0] for (minimum_x, minimum_y, maximum_x, maximum_y)
Test improper invocation orthoViewpoint.setFieldOfView(4, 3, 2, 1);
ERROR_ILLEGAL_VALUE[org.web3d.x3d.jsail.Navigation.OrthoViewpoint] fieldOfView values(minimum_x=4.0, maximum_x=2.0, minimum_y=3.0, maximum_y=1.0) do not pass requirements (minimum_x < maximum_x) and (minimum_y < maximum_y)
unit test .x3d model loading HelloWorldNoXmlNoDoctype.x3d ...
[warning] This X3D document has no DOCTYPE statement which helps with scene validation, suggest adding.
          <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
          https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#Validation
unit test .x3d model loading HelloWorldNoXmlNoDoctype.x3d  loadSuccess=true
===========================================
===========================================
showSceneResults();     // test all serializer outputs
ConfigurationProperties.getPropertiesFileName()=X3DJSAIL.properties
X3DJSAIL.properties includes 13 properties:
-- listing properties --
deleteIntermediateFiles=true
BLENDER_PATH=
XSLT_ENGINE=SAXON
overwriteExistingFiles=true
EXI_ENGINE=EXIFICIENT
SFImagePixelOutputHexadecimal=true
stripTrailingZeroes=true
normalizeCommentWhitespace=true
indentCharacter=SPACE
MESHLAB_PATH=
indentIncrement=2
validationExceptionAllowed=false
stripDefaultAttributes=true
------------------------
X3DJSAIL.properties loading complete.

SmokeTestProgramOutput.java console output
===========================================
SmokeTestProgram validation results for resulting scene graph: 
no errors detected.
===========================================
x3dModel.toStringX3D()

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
<X3D class='x3dModel.class' id='x3dModel.id' profile='Full' style='x3dModel.style' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'>
  <!-- X3D model top-level comment -->
  <head>
    <!-- comment #1 -->
    <!-- comment #2 -->
    <!-- comment #3 -->
    <!-- comment #4 -->
    <component name='Navigation' level='3'/>
    <component name='Shaders' level='1'/>
    <component name='CADGeometry' level='2'/>
    <component name='DIS' level='2'/>
    <component name='HAnim' level='1'/>
    <component name='Grouping' level='1'/>
    <component name='Layering' level='1'/>
    <unit name='AngleUnitConversion' category='angle' conversionFactor='1.0'/>
    <unit name='LengthUnitConversion' category='length' conversionFactor='1.0'/>
    <unit name='ForceFromPoundsToNewtons' category='force' conversionFactor='4.4482'/>
    <meta content='SmokeTestProgramOutput.x3d' name='title'/>
    <meta content='continued development and testing in progress' name='info'/>
    <meta content='Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL)' name='description'/>
    <meta content='https://www.web3d.org/specifications/java/X3DJSAIL.html' name='reference'/>
    <meta content='SmokeTestProgramOutput.java' name='generator'/>
    <meta content='6 September 2016' name='created'/>
    <meta content='28 November 2025' name='modified'/>
    <meta content='X3D Java Scene Access Interface Library (X3DJSAIL)' name='generator'/>
    <meta content='https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java' name='generator'/>
    <meta content='Netbeans https://www.netbeans.org' name='generator'/>
    <meta content='Don Brutzman' name='creator'/>
    <meta content='https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d' name='reference'/>
    <meta content='Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:' name='reference'/>
    <meta content='SmokeTestProgramOutput.txt' name='reference'/>
    <meta content='SmokeTestProgramOutput.x3dv' name='reference'/>
    <meta content='SmokeTestProgramOutput.wrl' name='reference'/>
    <meta content='SmokeTestProgramOutput.html' name='reference'/>
    <meta content='https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d' name='reference'/>
    <meta content='https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d' name='identifier'/>
    <meta content='../license.html' name='license'/>
  </head>
  <Scene>
    <MetadataSet name='topLevelSceneMetadata'/>
    <ViewpointGroup description='Available viewpoints'>
      <Viewpoint DEF='DefaultView' description='Hello X3DJSAIL'/>
      <Viewpoint DEF='TopDownView' description='top-down view from above' orientation='1 0 0 -1.570796' position='0 100 0'/>
    </ViewpointGroup>
    <NavigationInfo type='"EXAMINE" "FLY" "ANY"'/>
    <WorldInfo DEF='WorldInfoDEF' class='worldInfoNode.class' id='worldInfoNode.id' style='worldInfoNode.style' title='SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)'/>
    <WorldInfo USE='WorldInfoDEF'/>
    <WorldInfo USE='WorldInfoDEF'/>
    <MetadataString DEF='scene.addChildMetadata' name='test' value='"Top-level root Metadata node beneath Scene needs to be one of &apos;-children&apos; in JSON encoding"'/>
    <LayerSet DEF='scene.addChildLayerSetTest'/>
    <Transform DEF='LogoGeometryTransform' translation='0 1.5 0'>
      <Anchor DEF='siteAnchor' description='select for X3D Java SAI Library (X3DJSAIL) description' url='"../X3DJSAIL.html" "https://www.web3d.org/specifications/java/X3DJSAIL.html"'>
        <Shape DEF='BoxShape' id='BoxShapeID'>
          <Appearance>
            <Material DEF='GreenMaterial' diffuseColor='0 1 1' emissiveColor='0.8 0 0' transparency='0.1'/>
            <ImageTexture url='"images/X3dJavaSceneAccessInterfaceSaiLibrary.png" "https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png"'/>
          </Appearance>
          <Box DEF='test-NMTOKEN_regex.0123456789' class='untextured'/>
        </Shape>
      </Anchor>
    </Transform>
    <Shape DEF='LineShape'>
      <Appearance>
        <Material emissiveColor='0.6 0.19607843 0.8'/>
      </Appearance>
      <IndexedLineSet coordIndex='0 1 2 3 4 0'>
        <!-- Coordinate 3-tuple point count: 6 -->
        <Coordinate point='0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0'/>
      </IndexedLineSet>
    </Shape>
    <PositionInterpolator DEF='BoxPathAnimator' key='0 0.125 0.375 0.625 0.875 1' keyValue='0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0'/>
    <TimeSensor DEF='OrbitClock' cycleInterval='8.0' loop='true'/>
    <ROUTE fromField='fraction_changed' fromNode='OrbitClock' toField='set_fraction' toNode='BoxPathAnimator'/>
    <ROUTE fromField='value_changed' fromNode='BoxPathAnimator' toField='set_translation' toNode='LogoGeometryTransform'/>
    <Transform DEF='TextTransform' translation='0 -1.5 0'>
      <Shape>
        <Appearance>
          <Material USE='GreenMaterial'/>
        </Appearance>
        <Text string='"X3D Java" "SAI Library" "X3DJSAIL"'>
          <!-- Comment example A, plain quotation marks: He said, "Immel did it!" -->
          <!-- Comment example B, XML character entities: He said, &quot;Immel did it!&quot; -->
          <MetadataSet name='EscapedQuotationMarksMetadataSet' containerField='metadata'>
            <MetadataString name='quotesTestC' value='"MFString example C, backslash-escaped quotes: He said, \"Immel did it!\""'/>
            <MetadataString name='extraChildTest' value='"checks MetadataSet addValue() method"'/>
          </MetadataSet>
          <FontStyle justify='"MIDDLE" "MIDDLE"'/>
        </Text>
      </Shape>
      <Collision>
        <!-- test containerField='proxy' -->
        <Shape DEF='ProxyShape'>
          <!-- alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;"' -->
          <!-- alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;" ""' -->
          <!-- alternative Java source: .setString(new String [] {"One, Two, Comment", "", "He said, \"Immel did it!\""}) -->
          <!-- reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html -->
          <Text string='"One, Two, Text" "" "He said, \"Immel did it!\" \"\""'/>
        </Shape>
      </Collision>
      <!-- It's a beautiful world -->
      <!-- ... for you! -->
      <!-- https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song) -->
    </Transform>
    <!-- repeatedly spin 180 degrees as a readable special effect -->
    <OrientationInterpolator DEF='SpinInterpolator' key='0 0.5 1' keyValue='0 1 0 4.712389 0 1 0 0 0 1 0 1.5707964'/>
    <TimeSensor DEF='SpinClock' cycleInterval='5.0' loop='true'/>
    <ROUTE fromField='fraction_changed' fromNode='SpinClock' toField='set_fraction' toNode='SpinInterpolator'/>
    <ROUTE fromField='value_changed' fromNode='SpinInterpolator' toField='rotation' toNode='TextTransform'/>
    <Group DEF='BackgroundGroup'>
      <Background DEF='GradualBackground'/>
      <Script DEF='colorTypeConversionScript'>
        <field name='colorInput' accessType='inputOnly' type='SFColor'/>
        <field name='colorsOutput' accessType='outputOnly' type='MFColor'/>
<![CDATA[
ecmascript:

function colorInput (eventValue) // Example source code
{
   colorsOutput = new MFColor(eventValue); // assigning value sends output event
// Browser.print('colorInput=' + eventValue + ',
//                colorsOutput=' + colorsOutput + '
');
// TODO check line wrapping when exporting/converting
}

]]>
      </Script>
      <ColorInterpolator DEF='ColorAnimator' key='0 0.5 1' keyValue='0.9411765 1 1 0.29411766 0 0.50980395 0.9411765 1 1'>
        <!-- AZURE to INDIGO and back again -->
      </ColorInterpolator>
      <TimeSensor DEF='ColorClock' cycleInterval='60.0' loop='true'/>
      <ROUTE fromField='colorsOutput' fromNode='colorTypeConversionScript' toField='skyColor' toNode='GradualBackground'/>
      <ROUTE fromField='value_changed' fromNode='ColorAnimator' toField='colorInput' toNode='colorTypeConversionScript'/>
      <ROUTE fromField='fraction_changed' fromNode='ColorClock' toField='set_fraction' toNode='ColorAnimator'/>
    </Group>
    <ProtoDeclare name='ArtDeco01' appinfo='tooltip: ArtDeco01Material prototype is a Material node'>
      <ProtoInterface>
        <field name='description' accessType='inputOutput' appinfo='tooltip for descriptionField' type='SFString' value='ArtDeco01Material prototype is a Material node'/>
        <field name='enabled' accessType='inputOutput' type='SFBool' value='true'/>
      </ProtoInterface>
      <ProtoBody>
        <!-- Initial node of ProtoBody determines prototype node type -->
        <Material ambientIntensity='0.25' diffuseColor='0.282435 0.085159 0.134462' shininess='0.127273' specularColor='0.276305 0.11431 0.139857'/>
        <!-- [SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()="Material" -->
        <!-- presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types -->
        <TouchSensor description='within ProtoBody'>
          <IS>
            <connect nodeField='description' protoField='description'/>
            <connect nodeField='enabled' protoField='enabled'/>
          </IS>
        </TouchSensor>
      </ProtoBody>
    </ProtoDeclare>
    <ExternProtoDeclare name='ArtDeco02' appinfo='this is a different Material node' url='"https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02" "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"'>
      <!-- [SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file." -->
      <field name='description' accessType='inputOutput' appinfo='tooltip for descriptionField' type='SFString'/>
    </ExternProtoDeclare>
    <!-- Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place -->
    <Shape DEF='TestShape1'>
      <Appearance DEF='TestAppearance1'>
        <!-- ArtDeco01Material prototype goes here... -->
        <ProtoInstance name='ArtDeco01' containerField='material'>
          <!-- [SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()="Material" -->
          <fieldValue name='description' value='ArtDeco01Material can substitute for a Material node'/>
        </ProtoInstance>
      </Appearance>
      <Sphere radius='0.001'/>
    </Shape>
    <Shape DEF='TestShape2'>
      <Appearance DEF='TestAppearance2'>
        <!-- ArtDeco02Material ProtoInstance goes here... -->
        <ProtoInstance DEF='ArtDeco02MaterialDEF' name='ArtDeco02' containerField='material'>
          <!-- [SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file." -->
        </ProtoInstance>
      </Appearance>
      <Cone bottomRadius='0.001' height='0.001'/>
    </Shape>
    <Shape DEF='TestShape3'>
      <Appearance DEF='TestAppearance3'>
        <!-- ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE. -->
        <ProtoInstance USE='ArtDeco02MaterialDEF' name='ArtDeco02' containerField='material'/>
      </Appearance>
      <Cylinder height='0.001' radius='0.001'/>
    </Shape>
    <Inline DEF='inlineScene' url='"newScene.x3d" "https://www.web3d.org/specifications/java/examples/newScene.x3d"'/>
    <IMPORT AS='WorldInfoDEF2' importedDEF='WorldInfoDEF' inlineDEF='inlineScene'/>
    <EXPORT AS='WorldInfoDEF3' localDEF='WorldInfoDEF'/>
    <ProtoDeclare name='MaterialModulator' appinfo='mimic a Material node and modulate fields as an animation effect' documentation='https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html'>
      <ProtoInterface>
        <field name='enabled' accessType='inputOutput' type='SFBool' value='true'/>
        <field name='diffuseColor' accessType='inputOutput' type='SFColor' value='0 0 0'/>
        <field name='emissiveColor' accessType='inputOutput' type='SFColor' value='0.05 0.05 0.5'/>
        <field name='specularColor' accessType='inputOutput' type='SFColor' value='0 0 0'/>
        <field name='transparency' accessType='inputOutput' type='SFFloat' value='0.0'/>
        <field name='shininess' accessType='inputOutput' type='SFFloat' value='0.0'/>
        <field name='ambientIntensity' accessType='inputOutput' type='SFFloat' value='0.0'/>
      </ProtoInterface>
      <ProtoBody>
        <Material DEF='MaterialNode'>
          <IS>
            <connect nodeField='diffuseColor' protoField='diffuseColor'/>
            <connect nodeField='emissiveColor' protoField='emissiveColor'/>
            <connect nodeField='specularColor' protoField='specularColor'/>
            <connect nodeField='transparency' protoField='transparency'/>
            <connect nodeField='shininess' protoField='shininess'/>
            <connect nodeField='ambientIntensity' protoField='ambientIntensity'/>
          </IS>
        </Material>
        <!-- Only first node (the node type for the prototype) is renderable, others are along for the ride -->
        <Script DEF='MaterialModulatorScript'>
          <field name='enabled' accessType='inputOutput' type='SFBool'/>
          <field name='diffuseColor' accessType='inputOutput' type='SFColor'/>
          <field name='newColor' accessType='outputOnly' type='SFColor'/>
          <field name='clockTrigger' accessType='inputOnly' type='SFTime'/>
          <IS>
            <connect nodeField='enabled' protoField='enabled'/>
            <connect nodeField='diffuseColor' protoField='diffuseColor'/>
          </IS>
<![CDATA[
ecmascript:
function initialize ()
{
    newColor = diffuseColor; // start with correct color
}
function set_enabled (newValue)
{
	enabled = newValue;
}
function clockTrigger (timeValue)
{
    if (!enabled) return;
    red   = newColor.r;
    green = newColor.g;
    blue  = newColor.b;

    // note different modulation rates for each color component, % is modulus operator
    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);
	if (enabled)
	{
		Browser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');
	}
}
]]>
        </Script>
      </ProtoBody>
    </ProtoDeclare>
    <!-- Test success: declarative statement createDeclarativeShapeTests() -->
    <Group DEF='DeclarativeGroupExample'>
      <Shape>
        <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/>
        <Appearance DEF='DeclarativeAppearanceExample'>
          <!-- DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance -->
          <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/>
        </Appearance>
        <Cone bottom='false' bottomRadius='0.05' height='0.1'/>
      </Shape>
      <!-- Test success: declarativeGroup.addChild() singleton pipeline method -->
    </Group>
    <!-- Test success: declarative statement addChild() -->
    <!-- Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!- - DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance - -> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance> -->
    <!-- Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/> -->
    <!-- Test success: x3dModel.findElementByNameValue("ArtDeco01", "ProtoDeclare") found -->
    <!-- Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoDeclare") found -->
    <!-- Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoInstance") found -->
    <Group DEF='TestFieldObjectsGroup'>
      <!-- testFieldObjects() results -->
      <!-- SFBool default=false, true=true, false=false, negate()=true -->
      <!-- MFBool default=, initial=true false true, negate()=false true false -->
      <!-- SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0 -->
      <!-- MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7 -->
      <!-- ... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear= -->
      <!-- SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true -->
      <!-- regex test SFVec3f().matches("1 2 3")=true, regex test SFVec3f().matches("1 2 3 4")=false, regex test (SFRotation.matches("0 0 0 0")=true, failure detecting illegal (zero axis) rotation value -->
    </Group>
    <Sound location='0 1.6 0'>
      <!-- set sound-ellipsoid location height at 1.6m to match typical avatar height -->
      <AudioClip description='chimes' url='"chimes.wav" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav"'>
        <!-- Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d -->
      </AudioClip>
    </Sound>
    <Sound location='0 1.6 0'>
      <!-- set sound-ellipsoid location height at 1.6m to match typical avatar height -->
      <MovieTexture containerField='source' description='mpgsys.mpg from ConformanceNist suite' url='"mpgsys.mpg" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg"'>
        <!-- Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d -->
        <!-- Expected containerField='source', allowed containerField values="texture" "source" "back" "bottom" "front" "left" "right" "top" "backTexture" "bottomTexture" "frontTexture" "leftTexture" "rightTexture" "topTexture" "children" -->
      </MovieTexture>
    </Sound>
    <!-- Test success: Anchor.isNode()=true, siteAnchor.isNode()=true -->
    <!-- Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false -->
    <!-- Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false -->
    <!-- Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true -->
    <!-- Test success: CommentsBlock.isNode()=false, testComments.isNode()=false -->
    <!-- Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true -->
    <Shape DEF='ExtrusionShape'>
      <!-- ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]' -->
      <!-- ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]' -->
      <Appearance DEF='TransparentAppearance'>
        <Material transparency='1.0'/>
      </Appearance>
      <Extrusion DEF='ExampleExtrusion'/>
    </Shape>
    <Group>
      <!-- Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes -->
      <ProtoDeclare name='NewWorldInfo'>
        <ProtoInterface>
          <field name='description' accessType='initializeOnly' type='SFString'/>
        </ProtoInterface>
        <ProtoBody>
          <WorldInfo/>
        </ProtoBody>
      </ProtoDeclare>
      <ProtoInstance DEF='Proto1' name='NewWorldInfo'>
        <fieldValue name='description' value='testing 1 2 3'/>
      </ProtoInstance>
      <Group DEF='Node2'>
        <!-- intentionally empty -->
      </Group>
      <ProtoInstance DEF='Proto3' name='NewWorldInfo'/>
      <Transform DEF='Node4'>
        <!-- intentionally empty -->
      </Transform>
      <!-- Test satisfactorily creates MFNode children array as an ordered list with mixed content -->
    </Group>
    <ProtoDeclare name='ShaderProto'>
      <ProtoBody>
        <ProgramShader/>
      </ProtoBody>
    </ProtoDeclare>
    <Shape>
      <Appearance>
        <!-- Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes -->
        <!-- Test satisfactorily creates MFNode shaders array as an ordered list with mixed content -->
        <ProgramShader DEF='TestShader1'>
          <ShaderProgram DEF='TestShader2'/>
        </ProgramShader>
        <ProtoInstance DEF='TestShader3' name='ShaderProto' containerField='shaders'/>
        <ComposedShader DEF='TestShader4'>
          <ShaderPart DEF='TestShader5'/>
        </ComposedShader>
      </Appearance>
    </Shape>
    <Transform DEF='SpecialtyNodes'>
      <CADLayer>
        <CADAssembly>
          <CADPart>
            <CADFace/>
          </CADPart>
        </CADAssembly>
      </CADLayer>
      <EspduTransform/>
      <ReceiverPdu/>
      <SignalPdu/>
      <TransmitterPdu/>
      <DISEntityManager>
        <DISEntityTypeMapping/>
      </DISEntityManager>
    </Transform>
    <EspduTransform>
      <WorldInfo/>
    </EspduTransform>
    <ReceiverPdu/>
    <SignalPdu/>
    <TransmitterPdu/>
    <DISEntityManager>
      <DISEntityTypeMapping/>
    </DISEntityManager>
    <LoadSensor>
      <!-- Contained nodes typically must be USE references for nodes previously DEFined in the scene -->
      <!-- The following nodes are test cases for all X3DUrlObject nodes -->
      <Anchor USE='siteAnchor'/>
      <Inline USE='inlineScene'/>
      <DISEntityTypeMapping/>
      <GeoMetadata/>
      <AudioClip containerField='children'/>
      <ImageCubeMapTexture containerField='children'/>
      <ImageTexture3D containerField='children'/>
      <ImageTexture containerField='children'/>
      <MovieTexture containerField='children'/>
      <Script DEF='DummyScript'>
<![CDATA[
ecmascript:
/* dummy test source code */
]]>
      </Script>
      <PackagedShader containerField='children'/>
      <ShaderPart containerField='children'/>
      <ShaderProgram containerField='children'/>
    </LoadSensor>
    <OrthoViewpoint DEF='SpecialTestOrthoViewpoint' fieldOfView='1 3 2 4'/>
  </Scene>
</X3D>

===========================================
x3dModel.toStringXML()

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
<X3D class='x3dModel.class' id='x3dModel.id' profile='Full' style='x3dModel.style' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'>
  <!-- X3D model top-level comment -->
  <head>
    <!-- comment #1 -->
    <!-- comment #2 -->
    <!-- comment #3 -->
    <!-- comment #4 -->
    <component name='Navigation' level='3'/>
    <component name='Shaders' level='1'/>
    <component name='CADGeometry' level='2'/>
    <component name='DIS' level='2'/>
    <component name='HAnim' level='1'/>
    <component name='Grouping' level='1'/>
    <component name='Layering' level='1'/>
    <unit name='AngleUnitConversion' category='angle' conversionFactor='1.0'/>
    <unit name='LengthUnitConversion' category='length' conversionFactor='1.0'/>
    <unit name='ForceFromPoundsToNewtons' category='force' conversionFactor='4.4482'/>
    <meta content='SmokeTestProgramOutput.x3d' name='title'/>
    <meta content='continued development and testing in progress' name='info'/>
    <meta content='Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL)' name='description'/>
    <meta content='https://www.web3d.org/specifications/java/X3DJSAIL.html' name='reference'/>
    <meta content='SmokeTestProgramOutput.java' name='generator'/>
    <meta content='6 September 2016' name='created'/>
    <meta content='28 November 2025' name='modified'/>
    <meta content='X3D Java Scene Access Interface Library (X3DJSAIL)' name='generator'/>
    <meta content='https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java' name='generator'/>
    <meta content='Netbeans https://www.netbeans.org' name='generator'/>
    <meta content='Don Brutzman' name='creator'/>
    <meta content='https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d' name='reference'/>
    <meta content='Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:' name='reference'/>
    <meta content='SmokeTestProgramOutput.txt' name='reference'/>
    <meta content='SmokeTestProgramOutput.x3dv' name='reference'/>
    <meta content='SmokeTestProgramOutput.wrl' name='reference'/>
    <meta content='SmokeTestProgramOutput.html' name='reference'/>
    <meta content='https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d' name='reference'/>
    <meta content='https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d' name='identifier'/>
    <meta content='../license.html' name='license'/>
  </head>
  <Scene>
    <MetadataSet name='topLevelSceneMetadata'/>
    <ViewpointGroup description='Available viewpoints'>
      <Viewpoint DEF='DefaultView' description='Hello X3DJSAIL'/>
      <Viewpoint DEF='TopDownView' description='top-down view from above' orientation='1 0 0 -1.570796' position='0 100 0'/>
    </ViewpointGroup>
    <NavigationInfo type='"EXAMINE" "FLY" "ANY"'/>
    <WorldInfo DEF='WorldInfoDEF' class='worldInfoNode.class' id='worldInfoNode.id' style='worldInfoNode.style' title='SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)'/>
    <WorldInfo USE='WorldInfoDEF'/>
    <WorldInfo USE='WorldInfoDEF'/>
    <MetadataString DEF='scene.addChildMetadata' name='test' value='"Top-level root Metadata node beneath Scene needs to be one of &apos;-children&apos; in JSON encoding"'/>
    <LayerSet DEF='scene.addChildLayerSetTest'/>
    <Transform DEF='LogoGeometryTransform' translation='0 1.5 0'>
      <Anchor DEF='siteAnchor' description='select for X3D Java SAI Library (X3DJSAIL) description' url='"../X3DJSAIL.html" "https://www.web3d.org/specifications/java/X3DJSAIL.html"'>
        <Shape DEF='BoxShape' id='BoxShapeID'>
          <Appearance>
            <Material DEF='GreenMaterial' diffuseColor='0 1 1' emissiveColor='0.8 0 0' transparency='0.1'/>
            <ImageTexture url='"images/X3dJavaSceneAccessInterfaceSaiLibrary.png" "https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png"'/>
          </Appearance>
          <Box DEF='test-NMTOKEN_regex.0123456789' class='untextured'/>
        </Shape>
      </Anchor>
    </Transform>
    <Shape DEF='LineShape'>
      <Appearance>
        <Material emissiveColor='0.6 0.19607843 0.8'/>
      </Appearance>
      <IndexedLineSet coordIndex='0 1 2 3 4 0'>
        <!-- Coordinate 3-tuple point count: 6 -->
        <Coordinate point='0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0'/>
      </IndexedLineSet>
    </Shape>
    <PositionInterpolator DEF='BoxPathAnimator' key='0 0.125 0.375 0.625 0.875 1' keyValue='0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0'/>
    <TimeSensor DEF='OrbitClock' cycleInterval='8.0' loop='true'/>
    <ROUTE fromField='fraction_changed' fromNode='OrbitClock' toField='set_fraction' toNode='BoxPathAnimator'/>
    <ROUTE fromField='value_changed' fromNode='BoxPathAnimator' toField='set_translation' toNode='LogoGeometryTransform'/>
    <Transform DEF='TextTransform' translation='0 -1.5 0'>
      <Shape>
        <Appearance>
          <Material USE='GreenMaterial'/>
        </Appearance>
        <Text string='"X3D Java" "SAI Library" "X3DJSAIL"'>
          <!-- Comment example A, plain quotation marks: He said, "Immel did it!" -->
          <!-- Comment example B, XML character entities: He said, &quot;Immel did it!&quot; -->
          <MetadataSet name='EscapedQuotationMarksMetadataSet' containerField='metadata'>
            <MetadataString name='quotesTestC' value='"MFString example C, backslash-escaped quotes: He said, \"Immel did it!\""'/>
            <MetadataString name='extraChildTest' value='"checks MetadataSet addValue() method"'/>
          </MetadataSet>
          <FontStyle justify='"MIDDLE" "MIDDLE"'/>
        </Text>
      </Shape>
      <Collision>
        <!-- test containerField='proxy' -->
        <Shape DEF='ProxyShape'>
          <!-- alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;"' -->
          <!-- alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;" ""' -->
          <!-- alternative Java source: .setString(new String [] {"One, Two, Comment", "", "He said, \"Immel did it!\""}) -->
          <!-- reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html -->
          <Text string='"One, Two, Text" "" "He said, \"Immel did it!\" \"\""'/>
        </Shape>
      </Collision>
      <!-- It's a beautiful world -->
      <!-- ... for you! -->
      <!-- https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song) -->
    </Transform>
    <!-- repeatedly spin 180 degrees as a readable special effect -->
    <OrientationInterpolator DEF='SpinInterpolator' key='0 0.5 1' keyValue='0 1 0 4.712389 0 1 0 0 0 1 0 1.5707964'/>
    <TimeSensor DEF='SpinClock' cycleInterval='5.0' loop='true'/>
    <ROUTE fromField='fraction_changed' fromNode='SpinClock' toField='set_fraction' toNode='SpinInterpolator'/>
    <ROUTE fromField='value_changed' fromNode='SpinInterpolator' toField='rotation' toNode='TextTransform'/>
    <Group DEF='BackgroundGroup'>
      <Background DEF='GradualBackground'/>
      <Script DEF='colorTypeConversionScript'>
        <field name='colorInput' accessType='inputOnly' type='SFColor'/>
        <field name='colorsOutput' accessType='outputOnly' type='MFColor'/>
<![CDATA[
ecmascript:

function colorInput (eventValue) // Example source code
{
   colorsOutput = new MFColor(eventValue); // assigning value sends output event
// Browser.print('colorInput=' + eventValue + ',
//                colorsOutput=' + colorsOutput + '
');
// TODO check line wrapping when exporting/converting
}

]]>
      </Script>
      <ColorInterpolator DEF='ColorAnimator' key='0 0.5 1' keyValue='0.9411765 1 1 0.29411766 0 0.50980395 0.9411765 1 1'>
        <!-- AZURE to INDIGO and back again -->
      </ColorInterpolator>
      <TimeSensor DEF='ColorClock' cycleInterval='60.0' loop='true'/>
      <ROUTE fromField='colorsOutput' fromNode='colorTypeConversionScript' toField='skyColor' toNode='GradualBackground'/>
      <ROUTE fromField='value_changed' fromNode='ColorAnimator' toField='colorInput' toNode='colorTypeConversionScript'/>
      <ROUTE fromField='fraction_changed' fromNode='ColorClock' toField='set_fraction' toNode='ColorAnimator'/>
    </Group>
    <ProtoDeclare name='ArtDeco01' appinfo='tooltip: ArtDeco01Material prototype is a Material node'>
      <ProtoInterface>
        <field name='description' accessType='inputOutput' appinfo='tooltip for descriptionField' type='SFString' value='ArtDeco01Material prototype is a Material node'/>
        <field name='enabled' accessType='inputOutput' type='SFBool' value='true'/>
      </ProtoInterface>
      <ProtoBody>
        <!-- Initial node of ProtoBody determines prototype node type -->
        <Material ambientIntensity='0.25' diffuseColor='0.282435 0.085159 0.134462' shininess='0.127273' specularColor='0.276305 0.11431 0.139857'/>
        <!-- [SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()="Material" -->
        <!-- presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types -->
        <TouchSensor description='within ProtoBody'>
          <IS>
            <connect nodeField='description' protoField='description'/>
            <connect nodeField='enabled' protoField='enabled'/>
          </IS>
        </TouchSensor>
      </ProtoBody>
    </ProtoDeclare>
    <ExternProtoDeclare name='ArtDeco02' appinfo='this is a different Material node' url='"https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02" "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"'>
      <!-- [SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file." -->
      <field name='description' accessType='inputOutput' appinfo='tooltip for descriptionField' type='SFString'/>
    </ExternProtoDeclare>
    <!-- Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place -->
    <Shape DEF='TestShape1'>
      <Appearance DEF='TestAppearance1'>
        <!-- ArtDeco01Material prototype goes here... -->
        <ProtoInstance name='ArtDeco01' containerField='material'>
          <!-- [SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()="Material" -->
          <fieldValue name='description' value='ArtDeco01Material can substitute for a Material node'/>
        </ProtoInstance>
      </Appearance>
      <Sphere radius='0.001'/>
    </Shape>
    <Shape DEF='TestShape2'>
      <Appearance DEF='TestAppearance2'>
        <!-- ArtDeco02Material ProtoInstance goes here... -->
        <ProtoInstance DEF='ArtDeco02MaterialDEF' name='ArtDeco02' containerField='material'>
          <!-- [SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file." -->
        </ProtoInstance>
      </Appearance>
      <Cone bottomRadius='0.001' height='0.001'/>
    </Shape>
    <Shape DEF='TestShape3'>
      <Appearance DEF='TestAppearance3'>
        <!-- ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE. -->
        <ProtoInstance USE='ArtDeco02MaterialDEF' name='ArtDeco02' containerField='material'/>
      </Appearance>
      <Cylinder height='0.001' radius='0.001'/>
    </Shape>
    <Inline DEF='inlineScene' url='"newScene.x3d" "https://www.web3d.org/specifications/java/examples/newScene.x3d"'/>
    <IMPORT AS='WorldInfoDEF2' importedDEF='WorldInfoDEF' inlineDEF='inlineScene'/>
    <EXPORT AS='WorldInfoDEF3' localDEF='WorldInfoDEF'/>
    <ProtoDeclare name='MaterialModulator' appinfo='mimic a Material node and modulate fields as an animation effect' documentation='https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html'>
      <ProtoInterface>
        <field name='enabled' accessType='inputOutput' type='SFBool' value='true'/>
        <field name='diffuseColor' accessType='inputOutput' type='SFColor' value='0 0 0'/>
        <field name='emissiveColor' accessType='inputOutput' type='SFColor' value='0.05 0.05 0.5'/>
        <field name='specularColor' accessType='inputOutput' type='SFColor' value='0 0 0'/>
        <field name='transparency' accessType='inputOutput' type='SFFloat' value='0.0'/>
        <field name='shininess' accessType='inputOutput' type='SFFloat' value='0.0'/>
        <field name='ambientIntensity' accessType='inputOutput' type='SFFloat' value='0.0'/>
      </ProtoInterface>
      <ProtoBody>
        <Material DEF='MaterialNode'>
          <IS>
            <connect nodeField='diffuseColor' protoField='diffuseColor'/>
            <connect nodeField='emissiveColor' protoField='emissiveColor'/>
            <connect nodeField='specularColor' protoField='specularColor'/>
            <connect nodeField='transparency' protoField='transparency'/>
            <connect nodeField='shininess' protoField='shininess'/>
            <connect nodeField='ambientIntensity' protoField='ambientIntensity'/>
          </IS>
        </Material>
        <!-- Only first node (the node type for the prototype) is renderable, others are along for the ride -->
        <Script DEF='MaterialModulatorScript'>
          <field name='enabled' accessType='inputOutput' type='SFBool'/>
          <field name='diffuseColor' accessType='inputOutput' type='SFColor'/>
          <field name='newColor' accessType='outputOnly' type='SFColor'/>
          <field name='clockTrigger' accessType='inputOnly' type='SFTime'/>
          <IS>
            <connect nodeField='enabled' protoField='enabled'/>
            <connect nodeField='diffuseColor' protoField='diffuseColor'/>
          </IS>
<![CDATA[
ecmascript:
function initialize ()
{
    newColor = diffuseColor; // start with correct color
}
function set_enabled (newValue)
{
	enabled = newValue;
}
function clockTrigger (timeValue)
{
    if (!enabled) return;
    red   = newColor.r;
    green = newColor.g;
    blue  = newColor.b;

    // note different modulation rates for each color component, % is modulus operator
    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);
	if (enabled)
	{
		Browser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');
	}
}
]]>
        </Script>
      </ProtoBody>
    </ProtoDeclare>
    <!-- Test success: declarative statement createDeclarativeShapeTests() -->
    <Group DEF='DeclarativeGroupExample'>
      <Shape>
        <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/>
        <Appearance DEF='DeclarativeAppearanceExample'>
          <!-- DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance -->
          <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/>
        </Appearance>
        <Cone bottom='false' bottomRadius='0.05' height='0.1'/>
      </Shape>
      <!-- Test success: declarativeGroup.addChild() singleton pipeline method -->
    </Group>
    <!-- Test success: declarative statement addChild() -->
    <!-- Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!- - DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance - -> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance> -->
    <!-- Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/> -->
    <!-- Test success: x3dModel.findElementByNameValue("ArtDeco01", "ProtoDeclare") found -->
    <!-- Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoDeclare") found -->
    <!-- Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoInstance") found -->
    <Group DEF='TestFieldObjectsGroup'>
      <!-- testFieldObjects() results -->
      <!-- SFBool default=false, true=true, false=false, negate()=true -->
      <!-- MFBool default=, initial=true false true, negate()=false true false -->
      <!-- SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0 -->
      <!-- MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7 -->
      <!-- ... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear= -->
      <!-- SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true -->
      <!-- regex test SFVec3f().matches("1 2 3")=true, regex test SFVec3f().matches("1 2 3 4")=false, regex test (SFRotation.matches("0 0 0 0")=true, failure detecting illegal (zero axis) rotation value -->
    </Group>
    <Sound location='0 1.6 0'>
      <!-- set sound-ellipsoid location height at 1.6m to match typical avatar height -->
      <AudioClip description='chimes' url='"chimes.wav" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav"'>
        <!-- Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d -->
      </AudioClip>
    </Sound>
    <Sound location='0 1.6 0'>
      <!-- set sound-ellipsoid location height at 1.6m to match typical avatar height -->
      <MovieTexture containerField='source' description='mpgsys.mpg from ConformanceNist suite' url='"mpgsys.mpg" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg"'>
        <!-- Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d -->
        <!-- Expected containerField='source', allowed containerField values="texture" "source" "back" "bottom" "front" "left" "right" "top" "backTexture" "bottomTexture" "frontTexture" "leftTexture" "rightTexture" "topTexture" "children" -->
      </MovieTexture>
    </Sound>
    <!-- Test success: Anchor.isNode()=true, siteAnchor.isNode()=true -->
    <!-- Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false -->
    <!-- Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false -->
    <!-- Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true -->
    <!-- Test success: CommentsBlock.isNode()=false, testComments.isNode()=false -->
    <!-- Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true -->
    <Shape DEF='ExtrusionShape'>
      <!-- ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]' -->
      <!-- ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]' -->
      <Appearance DEF='TransparentAppearance'>
        <Material transparency='1.0'/>
      </Appearance>
      <Extrusion DEF='ExampleExtrusion'/>
    </Shape>
    <Group>
      <!-- Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes -->
      <ProtoDeclare name='NewWorldInfo'>
        <ProtoInterface>
          <field name='description' accessType='initializeOnly' type='SFString'/>
        </ProtoInterface>
        <ProtoBody>
          <WorldInfo/>
        </ProtoBody>
      </ProtoDeclare>
      <ProtoInstance DEF='Proto1' name='NewWorldInfo'>
        <fieldValue name='description' value='testing 1 2 3'/>
      </ProtoInstance>
      <Group DEF='Node2'>
        <!-- intentionally empty -->
      </Group>
      <ProtoInstance DEF='Proto3' name='NewWorldInfo'/>
      <Transform DEF='Node4'>
        <!-- intentionally empty -->
      </Transform>
      <!-- Test satisfactorily creates MFNode children array as an ordered list with mixed content -->
    </Group>
    <ProtoDeclare name='ShaderProto'>
      <ProtoBody>
        <ProgramShader/>
      </ProtoBody>
    </ProtoDeclare>
    <Shape>
      <Appearance>
        <!-- Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes -->
        <!-- Test satisfactorily creates MFNode shaders array as an ordered list with mixed content -->
        <ProgramShader DEF='TestShader1'>
          <ShaderProgram DEF='TestShader2'/>
        </ProgramShader>
        <ProtoInstance DEF='TestShader3' name='ShaderProto' containerField='shaders'/>
        <ComposedShader DEF='TestShader4'>
          <ShaderPart DEF='TestShader5'/>
        </ComposedShader>
      </Appearance>
    </Shape>
    <Transform DEF='SpecialtyNodes'>
      <CADLayer>
        <CADAssembly>
          <CADPart>
            <CADFace/>
          </CADPart>
        </CADAssembly>
      </CADLayer>
      <EspduTransform/>
      <ReceiverPdu/>
      <SignalPdu/>
      <TransmitterPdu/>
      <DISEntityManager>
        <DISEntityTypeMapping/>
      </DISEntityManager>
    </Transform>
    <EspduTransform>
      <WorldInfo/>
    </EspduTransform>
    <ReceiverPdu/>
    <SignalPdu/>
    <TransmitterPdu/>
    <DISEntityManager>
      <DISEntityTypeMapping/>
    </DISEntityManager>
    <LoadSensor>
      <!-- Contained nodes typically must be USE references for nodes previously DEFined in the scene -->
      <!-- The following nodes are test cases for all X3DUrlObject nodes -->
      <Anchor USE='siteAnchor'/>
      <Inline USE='inlineScene'/>
      <DISEntityTypeMapping/>
      <GeoMetadata/>
      <AudioClip containerField='children'/>
      <ImageCubeMapTexture containerField='children'/>
      <ImageTexture3D containerField='children'/>
      <ImageTexture containerField='children'/>
      <MovieTexture containerField='children'/>
      <Script DEF='DummyScript'>
<![CDATA[
ecmascript:
/* dummy test source code */
]]>
      </Script>
      <PackagedShader containerField='children'/>
      <ShaderPart containerField='children'/>
      <ShaderProgram containerField='children'/>
    </LoadSensor>
    <OrthoViewpoint DEF='SpecialTestOrthoViewpoint' fieldOfView='1 3 2 4'/>
  </Scene>
</X3D>

===========================================
x3dModel.toStringClassicVRML()

#X3D V4.0 utf8
PROFILE Full
# [head]
COMPONENT Navigation:3
COMPONENT Shaders:1
COMPONENT CADGeometry:2
COMPONENT DIS:2
COMPONENT HAnim:1
COMPONENT Grouping:1
COMPONENT Layering:1
UNIT angle AngleUnitConversion 1.0
UNIT length LengthUnitConversion 1.0
UNIT force ForceFromPoundsToNewtons 4.4482


META "title" "SmokeTestProgramOutput.x3d"
META "info" "continued development and testing in progress"
META "description" "Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL)"
META "reference" "https://www.web3d.org/specifications/java/X3DJSAIL.html"
META "generator" "SmokeTestProgramOutput.java"
META "created" "6 September 2016"
META "modified" "28 November 2025"
META "generator" "X3D Java Scene Access Interface Library (X3DJSAIL)"
META "generator" "https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java"
META "generator" "Netbeans https://www.netbeans.org"
META "creator" "Don Brutzman"
META "reference" "https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d"
META "reference" "Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:"
META "reference" "SmokeTestProgramOutput.txt"
META "reference" "SmokeTestProgramOutput.x3dv"
META "reference" "SmokeTestProgramOutput.wrl"
META "reference" "SmokeTestProgramOutput.html"
META "reference" "https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"
META "identifier" "https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"
META "license" "../license.html"
# This model file was produced using X3DJSAIL https://www.web3d.org/specifications/java/X3DJSAIL.html
# comment #1
# comment #2
# comment #3
# comment #4
# [Scene]
MetadataSet { 
     name "topLevelSceneMetadata"
     }
ViewpointGroup { 
     description "Available viewpoints"
       children [
      DEF DefaultView Viewpoint { 
         description "Hello X3DJSAIL"
         }
DEF TopDownView Viewpoint { 
         description "top-down view from above"
         orientation 1 0 0 -1.570796
         position 0 100 0
         }
      ]
    
    
}
NavigationInfo { 
     type [ "EXAMINE" "FLY" "ANY" ]
     }
DEF WorldInfoDEF WorldInfo { 
      # class "worldInfoNode.class"
      # id "worldInfoNode.id"
      # style "worldInfoNode.style"
     title "SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)"
     }
USE WorldInfoDEF
USE WorldInfoDEF
DEF scene.addChildMetadata MetadataString { 
     name "test"
     value [ "Top-level root Metadata node beneath Scene needs to be one of &apos;-children&apos; in JSON encoding" ]
     }
DEF scene.addChildLayerSetTest LayerSet { 
     }
DEF LogoGeometryTransform Transform { 
     translation 0 1.5 0
       children [
      DEF siteAnchor Anchor { 
         description "select for X3D Java SAI Library (X3DJSAIL) description"
         url [ "../X3DJSAIL.html" "https://www.web3d.org/specifications/java/X3DJSAIL.html" ]
           children [
          DEF BoxShape Shape { 
              # id "BoxShapeID"
              appearance Appearance { 
                material DEF GreenMaterial Material { 
                 diffuseColor 0 1 1
                 emissiveColor 0.8 0 0
                 transparency 0.1
                 }
               texture ImageTexture { 
                 url [ "images/X3dJavaSceneAccessInterfaceSaiLibrary.png" "https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png" ]
                 }
              
              
}
             geometry DEF test-NMTOKEN_regex.0123456789 Box { 
                # class "untextured"
               }
            
            
}
          ]
        
        
}
      ]
    
    
}
DEF LineShape Shape { 
      appearance Appearance { 
        material Material { 
         emissiveColor 0.6 0.19607843 0.8
         }
      
      
}
     geometry IndexedLineSet { 
       coordIndex [ 0 1 2 3 4 0 ]
        coord Coordinate { 
         point [ 0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0 ]
         }
      
      
# Coordinate 3-tuple point count: 6
            }
    
    
}
DEF BoxPathAnimator PositionInterpolator { 
     key [ 0 0.125 0.375 0.625 0.875 1 ]
     keyValue [ 0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0 ]
     }
DEF OrbitClock TimeSensor { 
     cycleInterval 8.0
     loop TRUE
     }
ROUTE OrbitClock.fraction_changed TO BoxPathAnimator.set_fraction
    ROUTE BoxPathAnimator.value_changed TO LogoGeometryTransform.set_translation
    DEF TextTransform Transform { 
     translation 0 -1.5 0
       children [
      Shape { 
          appearance Appearance { 
            material USE GreenMaterial
          
          
}
         geometry Text { 
           string [ "X3D Java" "SAI Library" "X3DJSAIL" ]
            metadata MetadataSet { 
             name "EscapedQuotationMarksMetadataSet"
               value [
              MetadataString { 
                 name "quotesTestC"
                 value [ "MFString example C, backslash-escaped quotes: He said, \"Immel did it!\"" ]
                 }
MetadataString { 
                 name "extraChildTest"
                 value [ "checks MetadataSet addValue() method" ]
                 }
              ]
            
            
}
           fontStyle FontStyle { 
             justify [ "MIDDLE" "MIDDLE" ]
             }
          
          
# Comment example A, plain quotation marks: He said, "Immel did it!"
          # Comment example B, XML character entities: He said, &quot;Immel did it!&quot;
                    }
        
        
}
Collision { 
          proxy DEF ProxyShape Shape { 
            geometry Text { 
             string [ "One, Two, Text" "" "He said, \"Immel did it!\" \"\"" ]
             }
          
          
#  alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;"' 
          #  alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;" ""' 
          #  alternative Java source: .setString(new String [] {"One, Two, Comment", "", "He said, \"Immel did it!\""})
          #  reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html 
                    }
          children [
          # test containerField='proxy'
                      ]
        
        
}
# It's a beautiful world
        # ... for you!
        # https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song)
              ]
    
    
}
# repeatedly spin 180 degrees as a readable special effect
    DEF SpinInterpolator OrientationInterpolator { 
     key [ 0 0.5 1 ]
     keyValue [ 0 1 0 4.712389 0 1 0 0 0 1 0 1.5707964 ]
     }
DEF SpinClock TimeSensor { 
     cycleInterval 5.0
     loop TRUE
     }
ROUTE SpinClock.fraction_changed TO SpinInterpolator.set_fraction
    ROUTE SpinInterpolator.value_changed TO TextTransform.rotation
    DEF BackgroundGroup Group { 
       children [
      DEF GradualBackground Background { 
         }
DEF colorTypeConversionScript Script { 
          inputOnly SFColor colorInput
          outputOnly MFColor colorsOutput
        
          url [ "ecmascript:

function colorInput (eventValue) // Example source code
{
   colorsOutput = new MFColor(eventValue); // assigning value sends output event
// Browser.print('colorInput=' + eventValue + ',
//                colorsOutput=' + colorsOutput + '
');
// TODO check line wrapping when exporting/converting
}
" ]
}
DEF ColorAnimator ColorInterpolator { 
         key [ 0 0.5 1 ]
         keyValue [ 0.9411765 1 1 0.29411766 0 0.50980395 0.9411765 1 1 ]
         
        
# AZURE to INDIGO and back again
                }
DEF ColorClock TimeSensor { 
         cycleInterval 60.0
         loop TRUE
         }
ROUTE colorTypeConversionScript.colorsOutput TO GradualBackground.skyColor
        ROUTE ColorAnimator.value_changed TO colorTypeConversionScript.colorInput
        ROUTE ColorClock.fraction_changed TO ColorAnimator.set_fraction
              ]
    
    
}
PROTO ArtDeco01 [
           # [appinfo] "tooltip: ArtDeco01Material prototype is a Material node"
      # ProtoInterface
        inputOutput SFString description "ArtDeco01Material prototype is a Material node" # [appinfo] "tooltip for descriptionField"
      
        inputOutput SFBool enabled TRUE
         ] {
    
      # ProtoBody
      # Initial node of ProtoBody determines prototype node type
      Material { 
       ambientIntensity 0.25
       diffuseColor 0.282435 0.085159 0.134462
       shininess 0.127273
       specularColor 0.276305 0.11431 0.139857
       }
# [SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()="Material"
      #  presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types
      TouchSensor { 
        description IS description
        enabled IS enabled
       
      

      
}
}
    EXTERNPROTO ArtDeco02 [
           # [appinfo] "this is a different Material node"
      inputOutput SFString description # [appinfo] "tooltip for descriptionField"
    
# [SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file."
    ]
     [ "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02" 
"https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"
 ] # ExternProtoDeclare url complete

      # Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place
    DEF TestShape1 Shape { 
      appearance DEF TestAppearance1 Appearance { 
        material ArtDeco01 { 
          description "ArtDeco01Material can substitute for a Material node"
        
# [SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()="Material"
                }
      
      
# ArtDeco01Material prototype goes here...
            }
     geometry Sphere { 
       radius 0.001
       }
    
    
}
DEF TestShape2 Shape { 
      appearance DEF TestAppearance2 Appearance { 
        material DEF ArtDeco02MaterialDEF ArtDeco02 { 
        
# [SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file."
                }
      
      
# ArtDeco02Material ProtoInstance goes here...
            }
     geometry Cone { 
       bottomRadius 0.001
       height 0.001
       }
    
    
}
DEF TestShape3 Shape { 
      appearance DEF TestAppearance3 Appearance { 
        material USE ArtDeco02MaterialDEF
      
      
# ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE.
            }
     geometry Cylinder { 
       height 0.001
       radius 0.001
       }
    
    
}
DEF inlineScene Inline { 
     url [ "newScene.x3d" "https://www.web3d.org/specifications/java/examples/newScene.x3d" ]
     }
IMPORT inlineScene.WorldInfoDEF AS WorldInfoDEF2 
    EXPORT WorldInfoDEF AS WorldInfoDEF3 
    PROTO MaterialModulator [
           # [appinfo] "mimic a Material node and modulate fields as an animation effect"
      # [documentation] "https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html"
     
      # ProtoInterface
        inputOutput SFBool enabled TRUE
        
        inputOutput SFColor diffuseColor 0 0 0
        inputOutput SFColor emissiveColor 0.05 0.05 0.5
        inputOutput SFColor specularColor 0 0 0
        inputOutput SFFloat transparency 0.0
        inputOutput SFFloat shininess 0.0
        inputOutput SFFloat ambientIntensity 0.0 ] {
    
      # ProtoBody
      DEF MaterialNode Material { 
        ambientIntensity IS ambientIntensity
        diffuseColor IS diffuseColor
        emissiveColor IS emissiveColor
        shininess IS shininess
        specularColor IS specularColor
        transparency IS transparency
       
      

      
}
# Only first node (the node type for the prototype) is renderable, others are along for the ride
      DEF MaterialModulatorScript Script { 
        inputOutput SFBool enabled IS enabled
        inputOutput SFColor diffuseColor IS diffuseColor
        outputOnly SFColor newColor
        inputOnly SFTime clockTrigger
      

      
        url [ "ecmascript:
function initialize ()
{
    newColor = diffuseColor; // start with correct color
}
function set_enabled (newValue)
{
	enabled = newValue;
}
function clockTrigger (timeValue)
{
    if (!enabled) return;
    red   = newColor.r;
    green = newColor.g;
    blue  = newColor.b;

    // note different modulation rates for each color component, % is modulus operator
    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);
	if (enabled)
	{
		Browser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');
	}
}
" ]
}
}
    # Test success: declarative statement createDeclarativeShapeTests()
    DEF DeclarativeGroupExample Group { 
       children [
      Shape { 
          metadata DEF FindableMetadataStringTest MetadataString { 
           name "findThisNameValue"
           value [ "test case" ]
           }
         appearance DEF DeclarativeAppearanceExample Appearance { 
            material DEF MyMaterialModulator MaterialModulator {             }
          
          
# DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance
                    }
         geometry Cone { 
           bottom FALSE
           bottomRadius 0.05
           height 0.1
           }
        
        
}
# Test success: declarativeGroup.addChild() singleton pipeline method
              ]
    
    
}
# Test success: declarative statement addChild()
    # Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!-- DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance --> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance>
    # Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/>
    # Test success: x3dModel.findElementByNameValue("ArtDeco01", "ProtoDeclare") found
    # Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoDeclare") found
    # Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoInstance") found
    DEF TestFieldObjectsGroup Group { 
       children [
      # testFieldObjects() results
        # SFBool default=false, true=true, false=false, negate()=true
        # MFBool default=, initial=true false true, negate()=false true false
        # SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0
        # MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7
        # ... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear=
        # SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true
        # regex test SFVec3f().matches("1 2 3")=true, regex test SFVec3f().matches("1 2 3 4")=false, regex test (SFRotation.matches("0 0 0 0")=true, failure detecting illegal (zero axis) rotation value
              ]
    
    
}
Sound { 
     location 0 1.6 0
      source AudioClip { 
       description "chimes"
       url [ "chimes.wav" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav" ]
       
      
# Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d
            }
    
    
# set sound-ellipsoid location height at 1.6m to match typical avatar height
        }
Sound { 
     location 0 1.6 0
      source MovieTexture { 
       description "mpgsys.mpg from ConformanceNist suite"
       url [ "mpgsys.mpg" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg" ]
       
      
# Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d
      # Expected containerField='source', allowed containerField values="texture" "source" "back" "bottom" "front" "left" "right" "top" "backTexture" "bottomTexture" "frontTexture" "leftTexture" "rightTexture" "topTexture" "children"
            }
    
    
# set sound-ellipsoid location height at 1.6m to match typical avatar height
        }
# Test success: Anchor.isNode()=true, siteAnchor.isNode()=true
    # Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false
    # Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false
    # Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true
    # Test success: CommentsBlock.isNode()=false, testComments.isNode()=false
    # Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true
    DEF ExtrusionShape Shape { 
      appearance DEF TransparentAppearance Appearance { 
        material Material { 
         transparency 1.0
         }
      
      
}
     geometry DEF ExampleExtrusion Extrusion { 
       }
    
    
# ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]'
    # ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]'
        }
Group { 
       children [
      # Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes
        PROTO NewWorldInfo [
        
          # ProtoInterface
            initializeOnly SFString description "" ] {
        
          # ProtoBody
          WorldInfo { 
           }
}
        DEF Proto1 NewWorldInfo { 
          description "testing 1 2 3"
        
        }
DEF Node2 Group { 
           children [
          # intentionally empty
                      ]
        
        
}
DEF Proto3 NewWorldInfo {         }
DEF Node4 Transform { 
           children [
          # intentionally empty
                      ]
        
        
}
# Test satisfactorily creates MFNode children array as an ordered list with mixed content
              ]
    
    
}
PROTO ShaderProto [
     ] {
    
      # ProtoBody
      ProgramShader { 
       }
}
    Shape { 
      appearance Appearance { 
         shaders [
        DEF TestShader1 ProgramShader { 
             programs [
            DEF TestShader2 ShaderProgram { 
               }
            ]
          
          
}
DEF TestShader3 ShaderProto {           }
DEF TestShader4 ComposedShader { 
             parts [
            DEF TestShader5 ShaderPart { 
               }
            ]
          
          
}
        ]
      
      
# Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes
      # Test satisfactorily creates MFNode shaders array as an ordered list with mixed content
            }
    
    
}
DEF SpecialtyNodes Transform { 
       children [
      CADLayer { 
           children [
          CADAssembly { 
               children [
              CADPart { 
                   children [
                  CADFace { 
                     }
                  ]
                
                
}
              ]
            
            
}
          ]
        
        
}
EspduTransform { 
         }
ReceiverPdu { 
         }
SignalPdu { 
         }
TransmitterPdu { 
         }
DISEntityManager { 
           children [
          DISEntityTypeMapping { 
             }
          ]
        
        
}
      ]
    
    
}
EspduTransform { 
       children [
      WorldInfo { 
         }
      ]
    
    
}
ReceiverPdu { 
     }
SignalPdu { 
     }
TransmitterPdu { 
     }
DISEntityManager { 
       children [
      DISEntityTypeMapping { 
         }
      ]
    
    
}
LoadSensor { 
       children [
      # Contained nodes typically must be USE references for nodes previously DEFined in the scene
        # The following nodes are test cases for all X3DUrlObject nodes
        USE siteAnchor
USE inlineScene
DISEntityTypeMapping { 
         }
GeoMetadata { 
         }
AudioClip { 
         }
ImageCubeMapTexture { 
         }
ImageTexture3D { 
         }
ImageTexture { 
         }
MovieTexture { 
         }
DEF DummyScript Script { 
        
          url [ "ecmascript:
/* dummy test source code */
" ]
}
PackagedShader { 
         }
ShaderPart { 
         }
ShaderProgram { 
         }
      ]
    
    
}
DEF SpecialTestOrthoViewpoint OrthoViewpoint { 
     fieldOfView [ 1 3 2 4 ]
     }




# X3D model top-level comment 

===========================================
x3dModel.toStringVRML97()

#VRML V2.0 utf8
#PROFILE Full
# [head]
#COMPONENT Navigation:3
#COMPONENT Shaders:1
#COMPONENT CADGeometry:2
#COMPONENT DIS:2
#COMPONENT HAnim:1
#COMPONENT Grouping:1
#COMPONENT Layering:1
#UNIT angle AngleUnitConversion 1.0
#UNIT length LengthUnitConversion 1.0
#UNIT force ForceFromPoundsToNewtons 4.4482


#META "title" "SmokeTestProgramOutput.x3d"
#META "info" "continued development and testing in progress"
#META "description" "Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL)"
#META "reference" "https://www.web3d.org/specifications/java/X3DJSAIL.html"
#META "generator" "SmokeTestProgramOutput.java"
#META "created" "6 September 2016"
#META "modified" "28 November 2025"
#META "generator" "X3D Java Scene Access Interface Library (X3DJSAIL)"
#META "generator" "https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java"
#META "generator" "Netbeans https://www.netbeans.org"
#META "creator" "Don Brutzman"
#META "reference" "https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d"
#META "reference" "Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:"
#META "reference" "SmokeTestProgramOutput.txt"
#META "reference" "SmokeTestProgramOutput.x3dv"
#META "reference" "SmokeTestProgramOutput.wrl"
#META "reference" "SmokeTestProgramOutput.html"
#META "reference" "https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"
#META "identifier" "https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"
#META "license" "../license.html"
# This model file was produced using X3DJSAIL https://www.web3d.org/specifications/java/X3DJSAIL.html
# comment #1
# comment #2
# comment #3
# comment #4
# [Scene]
MetadataSet { 
     name "topLevelSceneMetadata"
     }
ViewpointGroup { 
     description "Available viewpoints"
       children [
      DEF DefaultView Viewpoint { 
         description "Hello X3DJSAIL"
         }
DEF TopDownView Viewpoint { 
         description "top-down view from above"
         orientation 1 0 0 -1.570796
         position 0 100 0
         }
      ]
    
    
}
NavigationInfo { 
     type [ "EXAMINE" "FLY" "ANY" ]
     }
DEF WorldInfoDEF WorldInfo { 
      # class "worldInfoNode.class"
      # id "worldInfoNode.id"
      # style "worldInfoNode.style"
     title "SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)"
     }
USE WorldInfoDEF
USE WorldInfoDEF
DEF scene.addChildMetadata MetadataString { 
     name "test"
     value [ "Top-level root Metadata node beneath Scene needs to be one of &apos;-children&apos; in JSON encoding" ]
     }
DEF scene.addChildLayerSetTest LayerSet { 
     }
DEF LogoGeometryTransform Transform { 
     translation 0 1.5 0
       children [
      DEF siteAnchor Anchor { 
         description "select for X3D Java SAI Library (X3DJSAIL) description"
         url [ "../X3DJSAIL.html" "https://www.web3d.org/specifications/java/X3DJSAIL.html" ]
           children [
          DEF BoxShape Shape { 
              # id "BoxShapeID"
              appearance Appearance { 
                material DEF GreenMaterial Material { 
                 diffuseColor 0 1 1
                 emissiveColor 0.8 0 0
                 transparency 0.1
                 }
               texture ImageTexture { 
                 url [ "images/X3dJavaSceneAccessInterfaceSaiLibrary.png" "https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png" ]
                 }
              
              
}
             geometry DEF test-NMTOKEN_regex.0123456789 Box { 
                # class "untextured"
               }
            
            
}
          ]
        
        
}
      ]
    
    
}
DEF LineShape Shape { 
      appearance Appearance { 
        material Material { 
         emissiveColor 0.6 0.19607843 0.8
         }
      
      
}
     geometry IndexedLineSet { 
       coordIndex [ 0 1 2 3 4 0 ]
        coord Coordinate { 
         point [ 0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0 ]
         }
      
      
# Coordinate 3-tuple point count: 6
            }
    
    
}
DEF BoxPathAnimator PositionInterpolator { 
     key [ 0 0.125 0.375 0.625 0.875 1 ]
     keyValue [ 0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0 ]
     }
DEF OrbitClock TimeSensor { 
     cycleInterval 8.0
     loop TRUE
     }
ROUTE OrbitClock.fraction_changed TO BoxPathAnimator.set_fraction
    ROUTE BoxPathAnimator.value_changed TO LogoGeometryTransform.set_translation
    DEF TextTransform Transform { 
     translation 0 -1.5 0
       children [
      Shape { 
          appearance Appearance { 
            material USE GreenMaterial
          
          
}
         geometry Text { 
           string [ "X3D Java" "SAI Library" "X3DJSAIL" ]
            metadata MetadataSet { 
             name "EscapedQuotationMarksMetadataSet"
               value [
              MetadataString { 
                 name "quotesTestC"
                 value [ "MFString example C, backslash-escaped quotes: He said, \"Immel did it!\"" ]
                 }
MetadataString { 
                 name "extraChildTest"
                 value [ "checks MetadataSet addValue() method" ]
                 }
              ]
            
            
}
           fontStyle FontStyle { 
             justify [ "MIDDLE" "MIDDLE" ]
             }
          
          
# Comment example A, plain quotation marks: He said, "Immel did it!"
          # Comment example B, XML character entities: He said, &quot;Immel did it!&quot;
                    }
        
        
}
Collision { 
          proxy DEF ProxyShape Shape { 
            geometry Text { 
             string [ "One, Two, Text" "" "He said, \"Immel did it!\" \"\"" ]
             }
          
          
#  alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;"' 
          #  alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;" ""' 
          #  alternative Java source: .setString(new String [] {"One, Two, Comment", "", "He said, \"Immel did it!\""})
          #  reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html 
                    }
          children [
          # test containerField='proxy'
                      ]
        
        
}
# It's a beautiful world
        # ... for you!
        # https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song)
              ]
    
    
}
# repeatedly spin 180 degrees as a readable special effect
    DEF SpinInterpolator OrientationInterpolator { 
     key [ 0 0.5 1 ]
     keyValue [ 0 1 0 4.712389 0 1 0 0 0 1 0 1.5707964 ]
     }
DEF SpinClock TimeSensor { 
     cycleInterval 5.0
     loop TRUE
     }
ROUTE SpinClock.fraction_changed TO SpinInterpolator.set_fraction
    ROUTE SpinInterpolator.value_changed TO TextTransform.rotation
    DEF BackgroundGroup Group { 
       children [
      DEF GradualBackground Background { 
         }
DEF colorTypeConversionScript Script { 
          inputOnly SFColor colorInput
          outputOnly MFColor colorsOutput
        
          url [ "ecmascript:

function colorInput (eventValue) // Example source code
{
   colorsOutput = new MFColor(eventValue); // assigning value sends output event
// Browser.print('colorInput=' + eventValue + ',
//                colorsOutput=' + colorsOutput + '
');
// TODO check line wrapping when exporting/converting
}
" ]
}
DEF ColorAnimator ColorInterpolator { 
         key [ 0 0.5 1 ]
         keyValue [ 0.9411765 1 1 0.29411766 0 0.50980395 0.9411765 1 1 ]
         
        
# AZURE to INDIGO and back again
                }
DEF ColorClock TimeSensor { 
         cycleInterval 60.0
         loop TRUE
         }
ROUTE colorTypeConversionScript.colorsOutput TO GradualBackground.skyColor
        ROUTE ColorAnimator.value_changed TO colorTypeConversionScript.colorInput
        ROUTE ColorClock.fraction_changed TO ColorAnimator.set_fraction
              ]
    
    
}
PROTO ArtDeco01 [
           # [appinfo] "tooltip: ArtDeco01Material prototype is a Material node"
      # ProtoInterface
        inputOutput SFString description "ArtDeco01Material prototype is a Material node" # [appinfo] "tooltip for descriptionField"
      
        inputOutput SFBool enabled TRUE
         ] {
    
      # ProtoBody
      # Initial node of ProtoBody determines prototype node type
      Material { 
       ambientIntensity 0.25
       diffuseColor 0.282435 0.085159 0.134462
       shininess 0.127273
       specularColor 0.276305 0.11431 0.139857
       }
# [SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()="Material"
      #  presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types
      TouchSensor { 
        description IS description
        enabled IS enabled
       
      

      
}
}
    EXTERNPROTO ArtDeco02 [
           # [appinfo] "this is a different Material node"
      inputOutput SFString description # [appinfo] "tooltip for descriptionField"
    
# [SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file."
    ]
     [ "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02" 
"https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"
 ] # ExternProtoDeclare url complete

      # Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place
    DEF TestShape1 Shape { 
      appearance DEF TestAppearance1 Appearance { 
        material ArtDeco01 { 
          description "ArtDeco01Material can substitute for a Material node"
        
# [SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()="Material"
                }
      
      
# ArtDeco01Material prototype goes here...
            }
     geometry Sphere { 
       radius 0.001
       }
    
    
}
DEF TestShape2 Shape { 
      appearance DEF TestAppearance2 Appearance { 
        material DEF ArtDeco02MaterialDEF ArtDeco02 { 
        
# [SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file."
                }
      
      
# ArtDeco02Material ProtoInstance goes here...
            }
     geometry Cone { 
       bottomRadius 0.001
       height 0.001
       }
    
    
}
DEF TestShape3 Shape { 
      appearance DEF TestAppearance3 Appearance { 
        material USE ArtDeco02MaterialDEF
      
      
# ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE.
            }
     geometry Cylinder { 
       height 0.001
       radius 0.001
       }
    
    
}
DEF inlineScene Inline { 
     url [ "newScene.x3d" "https://www.web3d.org/specifications/java/examples/newScene.x3d" ]
     }
IMPORT inlineScene.WorldInfoDEF AS WorldInfoDEF2 
    EXPORT WorldInfoDEF AS WorldInfoDEF3 
    PROTO MaterialModulator [
           # [appinfo] "mimic a Material node and modulate fields as an animation effect"
      # [documentation] "https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html"
     
      # ProtoInterface
        inputOutput SFBool enabled TRUE
        
        inputOutput SFColor diffuseColor 0 0 0
        inputOutput SFColor emissiveColor 0.05 0.05 0.5
        inputOutput SFColor specularColor 0 0 0
        inputOutput SFFloat transparency 0.0
        inputOutput SFFloat shininess 0.0
        inputOutput SFFloat ambientIntensity 0.0 ] {
    
      # ProtoBody
      DEF MaterialNode Material { 
        ambientIntensity IS ambientIntensity
        diffuseColor IS diffuseColor
        emissiveColor IS emissiveColor
        shininess IS shininess
        specularColor IS specularColor
        transparency IS transparency
       
      

      
}
# Only first node (the node type for the prototype) is renderable, others are along for the ride
      DEF MaterialModulatorScript Script { 
        inputOutput SFBool enabled IS enabled
        inputOutput SFColor diffuseColor IS diffuseColor
        outputOnly SFColor newColor
        inputOnly SFTime clockTrigger
      

      
        url [ "ecmascript:
function initialize ()
{
    newColor = diffuseColor; // start with correct color
}
function set_enabled (newValue)
{
	enabled = newValue;
}
function clockTrigger (timeValue)
{
    if (!enabled) return;
    red   = newColor.r;
    green = newColor.g;
    blue  = newColor.b;

    // note different modulation rates for each color component, % is modulus operator
    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);
	if (enabled)
	{
		Browser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');
	}
}
" ]
}
}
    # Test success: declarative statement createDeclarativeShapeTests()
    DEF DeclarativeGroupExample Group { 
       children [
      Shape { 
          metadata DEF FindableMetadataStringTest MetadataString { 
           name "findThisNameValue"
           value [ "test case" ]
           }
         appearance DEF DeclarativeAppearanceExample Appearance { 
            material DEF MyMaterialModulator MaterialModulator {             }
          
          
# DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance
                    }
         geometry Cone { 
           bottom FALSE
           bottomRadius 0.05
           height 0.1
           }
        
        
}
# Test success: declarativeGroup.addChild() singleton pipeline method
              ]
    
    
}
# Test success: declarative statement addChild()
    # Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!-- DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance --> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance>
    # Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/>
    # Test success: x3dModel.findElementByNameValue("ArtDeco01", "ProtoDeclare") found
    # Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoDeclare") found
    # Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoInstance") found
    DEF TestFieldObjectsGroup Group { 
       children [
      # testFieldObjects() results
        # SFBool default=false, true=true, false=false, negate()=true
        # MFBool default=, initial=true false true, negate()=false true false
        # SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0
        # MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7
        # ... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear=
        # SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true
        # regex test SFVec3f().matches("1 2 3")=true, regex test SFVec3f().matches("1 2 3 4")=false, regex test (SFRotation.matches("0 0 0 0")=true, failure detecting illegal (zero axis) rotation value
              ]
    
    
}
Sound { 
     location 0 1.6 0
      source AudioClip { 
       description "chimes"
       url [ "chimes.wav" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav" ]
       
      
# Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d
            }
    
    
# set sound-ellipsoid location height at 1.6m to match typical avatar height
        }
Sound { 
     location 0 1.6 0
      source MovieTexture { 
       description "mpgsys.mpg from ConformanceNist suite"
       url [ "mpgsys.mpg" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg" ]
       
      
# Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d
      # Expected containerField='source', allowed containerField values="texture" "source" "back" "bottom" "front" "left" "right" "top" "backTexture" "bottomTexture" "frontTexture" "leftTexture" "rightTexture" "topTexture" "children"
            }
    
    
# set sound-ellipsoid location height at 1.6m to match typical avatar height
        }
# Test success: Anchor.isNode()=true, siteAnchor.isNode()=true
    # Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false
    # Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false
    # Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true
    # Test success: CommentsBlock.isNode()=false, testComments.isNode()=false
    # Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true
    DEF ExtrusionShape Shape { 
      appearance DEF TransparentAppearance Appearance { 
        material Material { 
         transparency 1.0
         }
      
      
}
     geometry DEF ExampleExtrusion Extrusion { 
       }
    
    
# ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]'
    # ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]'
        }
Group { 
       children [
      # Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes
        PROTO NewWorldInfo [
        
          # ProtoInterface
            initializeOnly SFString description "" ] {
        
          # ProtoBody
          WorldInfo { 
           }
}
        DEF Proto1 NewWorldInfo { 
          description "testing 1 2 3"
        
        }
DEF Node2 Group { 
           children [
          # intentionally empty
                      ]
        
        
}
DEF Proto3 NewWorldInfo {         }
DEF Node4 Transform { 
           children [
          # intentionally empty
                      ]
        
        
}
# Test satisfactorily creates MFNode children array as an ordered list with mixed content
              ]
    
    
}
PROTO ShaderProto [
     ] {
    
      # ProtoBody
      ProgramShader { 
       }
}
    Shape { 
      appearance Appearance { 
         shaders [
        DEF TestShader1 ProgramShader { 
             programs [
            DEF TestShader2 ShaderProgram { 
               }
            ]
          
          
}
DEF TestShader3 ShaderProto {           }
DEF TestShader4 ComposedShader { 
             parts [
            DEF TestShader5 ShaderPart { 
               }
            ]
          
          
}
        ]
      
      
# Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes
      # Test satisfactorily creates MFNode shaders array as an ordered list with mixed content
            }
    
    
}
DEF SpecialtyNodes Transform { 
       children [
      CADLayer { 
           children [
          CADAssembly { 
               children [
              CADPart { 
                   children [
                  CADFace { 
                     }
                  ]
                
                
}
              ]
            
            
}
          ]
        
        
}
EspduTransform { 
         }
ReceiverPdu { 
         }
SignalPdu { 
         }
TransmitterPdu { 
         }
DISEntityManager { 
           children [
          DISEntityTypeMapping { 
             }
          ]
        
        
}
      ]
    
    
}
EspduTransform { 
       children [
      WorldInfo { 
         }
      ]
    
    
}
ReceiverPdu { 
     }
SignalPdu { 
     }
TransmitterPdu { 
     }
DISEntityManager { 
       children [
      DISEntityTypeMapping { 
         }
      ]
    
    
}
LoadSensor { 
       children [
      # Contained nodes typically must be USE references for nodes previously DEFined in the scene
        # The following nodes are test cases for all X3DUrlObject nodes
        USE siteAnchor
USE inlineScene
DISEntityTypeMapping { 
         }
GeoMetadata { 
         }
AudioClip { 
         }
ImageCubeMapTexture { 
         }
ImageTexture3D { 
         }
ImageTexture { 
         }
MovieTexture { 
         }
DEF DummyScript Script { 
        
          url [ "ecmascript:
/* dummy test source code */
" ]
}
PackagedShader { 
         }
ShaderPart { 
         }
ShaderProgram { 
         }
      ]
    
    
}
DEF SpecialTestOrthoViewpoint OrthoViewpoint { 
     fieldOfView [ 1 3 2 4 ]
     }




# X3D model top-level comment 

===========================================
Create .x3d (X3D XML Encoding) version of model
Note: toFileX3D() is overwriting prior file SmokeTestProgramOutput.x3d
helloWorld.toFileX3D("SmokeTestProgramOutput.x3d") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.x3d
===========================================
Create .xml (X3D XML Encoding) version of model
Note: toFileX3D() is overwriting prior file SmokeTestProgramOutput.xml
helloWorld.toFileXML("SmokeTestProgramOutput.xml") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.xml
===========================================
Create pretty-print .html documentation of model
Note: toFileStylesheetConversion(X3dExtrusionCrossSectionToSvg.xslt) is overwriting prior file SmokeTestProgramOutput.svg
Note: toFileStylesheetConversion(X3dToXhtml.xslt) is overwriting prior file SmokeTestProgramOutput.html
helloWorld.toFileHtmlDocumentation("SmokeTestProgramOutput.html") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.html
===========================================
Create .x3d (X3D XML Encoding) cleaned-up version of model using X3D Tidy
Note: toFileStylesheetConversion(X3dTidy.xslt) is overwriting prior file SmokeTestProgramOutputTidy.x3d
*** &lt;ProtoInstance USE='ArtDeco02MaterialDEF' containerField='material'/&gt; is missing name field, searched for ProtoInstance DEF='ArtDeco02MaterialDEF', found DEF name for USE='ArtDeco02MaterialDEF' name='ArtDeco02'
helloWorld.toFileX3dTidy("SmokeTestProgramOutputTidy.x3d") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutputTidy.x3d
===========================================
Create .md (Markdown) file for model meta information using X3dModelMetaToMarkdown.xslt
Note: toFileStylesheetConversion(X3dModelMetaToMarkdown.xslt) is overwriting prior file SmokeTestProgramOutput.md
helloWorld.toFileModelMetaMarkdown("SmokeTestProgramOutput.md") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.md
===========================================
Create X3D ClassicVRML Encoding of model
Note: toFileClassicVRML() is overwriting prior file SmokeTestProgramOutput.x3dv
helloWorld.toFileClassicVRML("SmokeTestProgramOutput.x3dv") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.x3dv
===========================================
Create VRML97 Encoding of model
Note: toFileVRML97() is overwriting prior file SmokeTestProgramOutput.wrl
helloWorld.toFileVRML97("SmokeTestProgramOutput.wrl") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.wrl
===========================================
Create pretty-print HTML documentation of model using ConfigurationProperties.getXsltEngine()=SAXON9HE and stylesheet X3dToXhtml.xslt
Note: toFileStylesheetConversion(X3dExtrusionCrossSectionToSvg.xslt) is overwriting prior file SmokeTestProgramOutput.svg
Note: toFileStylesheetConversion(X3dToXhtml.xslt) is overwriting prior file SmokeTestProgramOutput.html
helloWorld.toFileHtmlDocumentation("SmokeTestProgramOutput.html") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.html
===========================================
Create concise Java source of model using stylesheet X3dToJava.xslt
[meta] name='info' content='continued development and testing in progress'
helloWorld.toFileJava("SmokeTestProgramOutput.java") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.java
Test toStringJava()

[meta] name='info' content='continued development and testing in progress'
import org.web3d.x3d.jsail.Core.*;
import org.web3d.x3d.jsail.CADGeometry.*;
import org.web3d.x3d.jsail.CubeMapTexturing.*;
import org.web3d.x3d.jsail.DIS.*;
import org.web3d.x3d.jsail.EnvironmentalEffects.*;
import org.web3d.x3d.jsail.fields.*;
import org.web3d.x3d.jsail.Geometry3D.*;
import org.web3d.x3d.jsail.Geospatial.*;
import org.web3d.x3d.jsail.Grouping.*;
import org.web3d.x3d.jsail.Interpolation.*;
import org.web3d.x3d.jsail.Layering.*;
import org.web3d.x3d.jsail.Navigation.*;
import org.web3d.x3d.jsail.Networking.*;
import org.web3d.x3d.jsail.PointingDeviceSensor.*;
import org.web3d.x3d.jsail.Rendering.*;
import org.web3d.x3d.jsail.Scripting.*;
import org.web3d.x3d.jsail.Shaders.*;
import org.web3d.x3d.jsail.Shape.*;
import org.web3d.x3d.jsail.Sound.*;
import org.web3d.x3d.jsail.Text.*;
import org.web3d.x3d.jsail.Texturing.*;
import org.web3d.x3d.jsail.Texturing3D.*;
import org.web3d.x3d.jsail.Time.*;

// Javadoc metadata annotations follow, see below for X3DJSAIL Java source code.
/**
 * <p> Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL). </p>
 <p> Related links:  source temporaryJavaOutputFile.java, <a href="https://www.web3d.org/x3d/content/examples/X3dResources.html" target="_blank">X3D Resources</a>, <a href="https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html" target="_blank">X3D Scene Authoring Hints</a>, and <a href="https://www.web3d.org/x3d/content/X3dTooltips.html" target="_blank">X3D Tooltips</a>. </p>
	<table style="color:black; border:0px solid; border-spacing:10px 0px;">
        <caption>Scene Meta Information</caption>
		<tr style="background-color:silver; border-color:silver;">
			<td style="text-align:center; padding:10px 0px;"><i>meta tags</i></td>
			<td style="text-align:left;   padding:10px 0px;">temporaryJavaOutputFile&nbsp; Document Metadata </td>
		</tr>

		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> title </i> </td>
			<td> <a href="https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d">SmokeTestProgramOutput.x3d</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> info </i> </td>
			<td> continued development and testing in progress </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> description </i> </td>
			<td> Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL) </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> <a href="https://www.web3d.org/specifications/java/X3DJSAIL.html" target="_blank">https://www.web3d.org/specifications/java/X3DJSAIL.html</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> generator </i> </td>
			<td> SmokeTestProgramOutput.java </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> created </i> </td>
			<td> 6 September 2016 </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> modified </i> </td>
			<td> 28 November 2025 </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> generator </i> </td>
			<td> X3D Java Scene Access Interface Library (X3DJSAIL) </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> generator </i> </td>
			<td> <a href="https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java" target="_blank">https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> generator </i> </td>
			<td> Netbeans <a href="https://www.netbeans.org" target="_blank">https://www.netbeans.org</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> creator </i> </td>
			<td> Don Brutzman </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> <a href="https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d" target="_blank">https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation: </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> SmokeTestProgramOutput.txt </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> <a href="https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3dv">SmokeTestProgramOutput.x3dv</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> SmokeTestProgramOutput.wrl </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> <a href="https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.html">SmokeTestProgramOutput.html</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> reference </i> </td>
			<td> <a href="https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d" target="_blank">https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> identifier </i> </td>
			<td> <a href="https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d" target="_blank">https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> license </i> </td>
			<td> <a href="https://www.web3d.org/specifications/java/examples/../license.html">../license.html</a> </td>
		</tr>
		<tr style="background-color:silver; border-color:silver;">
			<td style="text-align:center;" colspan="2">  &nbsp; </td>
		</tr>
	</table>

	<p>
		This program uses the
		<a href="https://www.web3d.org/specifications/java/X3DJSAIL.html" target="_blank">X3D Java Scene Access Interface Library (X3DJSAIL)</a>.
		It has been produced using the 
		<a href="https://www.web3d.org/x3d/stylesheets/X3dToJava.xslt" target="_blank">X3dToJava.xslt</a>
		stylesheet
	       (<a href="https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/X3dToJava.xslt" target="_blank">version control</a>)
                which is used to create Java source code from an original <code>.x3d</code> model.
	</p>

	* @author Don Brutzman
 */

public class temporaryJavaOutputFile
{
	/** Default constructor to create this object. */
	public temporaryJavaOutputFile ()
	{
	  initialize();
	}

	/** Create and initialize the X3D model for this object. */
	public final void initialize()
	{
            try { // catch-all
  x3dModel = new X3D().setProfile(X3D.PROFILE_FULL).setVersion(X3D.VERSION_4_0).setCssClass("x3dModel.class").setHtmlId("x3dModel.id").setCssStyle("x3dModel.style")
  .addComments(" X3D model top-level comment ")
  .setHead(new head()
    .addComments(" comment #1 ")
    .addComments(" comment #2 ")
    .addComments(" comment #3 ")
    .addComments(" comment #4 ")
    .addComponent(new component().setName("Navigation").setLevel(3))
    .addComponent(new component().setName("Shaders").setLevel(1))
    .addComponent(new component().setName("CADGeometry").setLevel(2))
    .addComponent(new component().setName("DIS").setLevel(2))
    .addComponent(new component().setName("HAnim").setLevel(1))
    .addComponent(new component().setName("Grouping").setLevel(1))
    .addComponent(new component().setName("Layering").setLevel(1))
    .addUnit(new unit().setName("AngleUnitConversion").setCategory("angle").setConversionFactor(1.0))
    .addUnit(new unit().setName("LengthUnitConversion").setCategory("length").setConversionFactor(1.0))
    .addUnit(new unit().setName("ForceFromPoundsToNewtons").setCategory("force").setConversionFactor(4.4482))
    .addMeta(new meta().setName(meta.NAME_TITLE      ).setContent("SmokeTestProgramOutput.x3d"))
    .addMeta(new meta().setName(meta.NAME_INFO       ).setContent("continued development and testing in progress"))
    .addMeta(new meta().setName(meta.NAME_DESCRIPTION).setContent("Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL)"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("https://www.web3d.org/specifications/java/X3DJSAIL.html"))
    .addMeta(new meta().setName(meta.NAME_GENERATOR  ).setContent("SmokeTestProgramOutput.java"))
    .addMeta(new meta().setName(meta.NAME_CREATED    ).setContent("6 September 2016"))
    .addMeta(new meta().setName(meta.NAME_MODIFIED   ).setContent("28 November 2025"))
    .addMeta(new meta().setName(meta.NAME_GENERATOR  ).setContent("X3D Java Scene Access Interface Library (X3DJSAIL)"))
    .addMeta(new meta().setName(meta.NAME_GENERATOR  ).setContent("https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java"))
    .addMeta(new meta().setName(meta.NAME_GENERATOR  ).setContent("Netbeans https://www.netbeans.org"))
    .addMeta(new meta().setName(meta.NAME_CREATOR    ).setContent("Don Brutzman"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("SmokeTestProgramOutput.txt"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("SmokeTestProgramOutput.x3dv"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("SmokeTestProgramOutput.wrl"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("SmokeTestProgramOutput.html"))
    .addMeta(new meta().setName(meta.NAME_REFERENCE  ).setContent("https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"))
    .addMeta(new meta().setName(meta.NAME_IDENTIFIER ).setContent("https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"))
    .addMeta(new meta().setName(meta.NAME_LICENSE    ).setContent("../license.html")))
  .setScene(new Scene()
    .addMetadata(new MetadataSet().setName("topLevelSceneMetadata"))
    .addChild(new ViewpointGroup().setDescription("Available viewpoints")
      .addChild(new Viewpoint("DefaultView").setDescription("Hello X3DJSAIL"))
      .addChild(new Viewpoint("TopDownView").setDescription("top-down view from above").setOrientation(1.0,0.0,0.0,-1.570796).setPosition(0.0,100.0,0.0)))
    .addChild(new NavigationInfo().setType(new String[] {"EXAMINE","FLY","ANY"}))
    .addChild(new WorldInfo("WorldInfoDEF").setCssClass("worldInfoNode.class").setHtmlId("worldInfoNode.id").setCssStyle("worldInfoNode.style").setTitle("SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)"))
    .addChild(new WorldInfo().setUSE("WorldInfoDEF"))
    .addChild(new WorldInfo().setUSE("WorldInfoDEF"))
    .addMetadata(new MetadataString("scene.addChildMetadata").setName("test").setValue(new String[] {"Top-level root Metadata node beneath Scene needs to be one of '-children' in JSON encoding"}))
    .addLayerSet(new LayerSet("scene.addChildLayerSetTest"))
    .addChild(new Transform("LogoGeometryTransform").setTranslation(0.0,1.5,0.0)
      .addChild(new Anchor("siteAnchor").setDescription("select for X3D Java SAI Library (X3DJSAIL) description").setUrl(new String[] {"../X3DJSAIL.html","https://www.web3d.org/specifications/java/X3DJSAIL.html"})
        .addChild(new Shape("BoxShape").setHtmlId("BoxShapeID")
          .setAppearance(new Appearance()
            .setMaterial(new Material("GreenMaterial").setDiffuseColor(0.0,1.0,1.0).setEmissiveColor(0.8,0.0,0.0).setTransparency(0.1))
            .setTexture(new ImageTexture().setUrl(new String[] {"images/X3dJavaSceneAccessInterfaceSaiLibrary.png","https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png"})))
          .setGeometry(new Box("test-NMTOKEN_regex.0123456789").setCssClass("untextured")))))
    .addChild(new Shape("LineShape")
      .setAppearance(new Appearance()
        .setMaterial(new Material().setEmissiveColor(0.6,0.19607843,0.8)))
      .setGeometry(new IndexedLineSet().setCoordIndex(new int[] {0,1,2,3,4,0})
        .addComments(" Coordinate 3-tuple point count: 6 ")
        .setCoord(new Coordinate().setPoint(new MFVec3f(new double[] {0.0,1.5,0.0,2.0,1.5,0.0,2.0,1.5,-2.0,-2.0,1.5,-2.0,-2.0,1.5,0.0,0.0,1.5,0.0})))))
    .addChild(new PositionInterpolator("BoxPathAnimator").setKey(new double[] {0.0,0.125,0.375,0.625,0.875,1.0}).setKeyValue(new MFVec3f(new double[] {0.0,1.5,0.0,2.0,1.5,0.0,2.0,1.5,-2.0,-2.0,1.5,-2.0,-2.0,1.5,0.0,0.0,1.5,0.0})))
    .addChild(new TimeSensor("OrbitClock").setCycleInterval(8.0).setLoop(true))
    .addChild(new ROUTE().setFromNode("OrbitClock").setFromField("fraction_changed").setToNode("BoxPathAnimator").setToField("set_fraction"))
    .addChild(new ROUTE().setFromNode("BoxPathAnimator").setFromField("value_changed").setToNode("LogoGeometryTransform").setToField("set_translation"))
    .addChild(new Transform("TextTransform").setTranslation(0.0,-1.5,0.0)
      .addChild(new Shape()
        .setAppearance(new Appearance()
          .setMaterial(new Material().setUSE("GreenMaterial")))
        .setGeometry(new Text().setString(new String[] {"X3D Java","SAI Library","X3DJSAIL"})
          .addComments(" Comment example A, plain quotation marks: He said, \"Immel did it!\" ")
          .addComments(" Comment example B, XML character entities: He said, &quot;Immel did it!&quot; ")
          .setMetadata(new MetadataSet().setName("EscapedQuotationMarksMetadataSet")
            .setMetadata(new MetadataString().setName("quotesTestC").setValue(new String[] {"MFString example C, backslash-escaped quotes: He said, \"Immel did it!\""}))
            .setMetadata(new MetadataString().setName("extraChildTest").setValue(new String[] {"checks MetadataSet addValue() method"})))
          .setFontStyle(new FontStyle().setJustify(FontStyle.JUSTIFY_MIDDLE_MIDDLE))))
      .addChild(new Collision()
        .addComments(" test containerField='proxy' ")
        .addChild(new Shape("ProxyShape")
          .addComments(" alternative XML encoding: Text string='\"One, Two, Comment\" \"\" \"He said, \\&quot;Immel did it!\\&quot;\"' ")
          .addComments(" alternative XML encoding: Text string='\"One, Two, Comment\" \"\" \"He said, \\&quot;Immel did it!\\&quot;\" \"\"' ")
          .addComments(" alternative Java source: .setString(new String [] {\"One, Two, Comment\", \"\", \"He said, \\\"Immel did it!\\\"\"}) ")
          .addComments(" reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html ")
          .setGeometry(new Text().setString(new String[] {"One, Two, Text","","He said, \"Immel did it!\" \"\""}))))
      .addComments(" It's a beautiful world ")
      .addComments(" ... for you! ")
      .addComments(" https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song) "))
    .addComments(" repeatedly spin 180 degrees as a readable special effect ")
    .addChild(new OrientationInterpolator("SpinInterpolator").setKey(new double[] {0.0,0.5,1.0}).setKeyValue(new MFRotation(new double[] {0.0,1.0,0.0,4.712389,0.0,1.0,0.0,0.0,0.0,1.0,0.0,1.5707964})))
    .addChild(new TimeSensor("SpinClock").setCycleInterval(5.0).setLoop(true))
    .addChild(new ROUTE().setFromNode("SpinClock").setFromField("fraction_changed").setToNode("SpinInterpolator").setToField("set_fraction"))
    .addChild(new ROUTE().setFromNode("SpinInterpolator").setFromField("value_changed").setToNode("TextTransform").setToField("rotation"))
    .addChild(new Group("BackgroundGroup")
      .addChild(new Background("GradualBackground"))
      .addChild(new Script("colorTypeConversionScript").setSourceCode("""
ecmascript:

function colorInput (eventValue) // Example source code
{
   colorsOutput = new MFColor(eventValue); // assigning value sends output event
// Browser.print('colorInput=' + eventValue + ',
//                colorsOutput=' + colorsOutput + '
');
// TODO check line wrapping when exporting/converting
}
""")
        .addField(new field().setName("colorInput").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTONLY))
        .addField(new field().setName("colorsOutput").setType(field.TYPE_MFCOLOR).setAccessType(field.ACCESSTYPE_OUTPUTONLY)))
      .addChild(new ColorInterpolator("ColorAnimator").setKey(new double[] {0.0,0.5,1.0}).setKeyValue(new MFColor(new double[] {0.9411765,1.0,1.0,0.29411766,0.0,0.50980395,0.9411765,1.0,1.0}))
        .addComments(" AZURE to INDIGO and back again "))
      .addChild(new TimeSensor("ColorClock").setCycleInterval(60.0).setLoop(true))
      .addChild(new ROUTE().setFromNode("colorTypeConversionScript").setFromField("colorsOutput").setToNode("GradualBackground").setToField("skyColor"))
      .addChild(new ROUTE().setFromNode("ColorAnimator").setFromField("value_changed").setToNode("colorTypeConversionScript").setToField("colorInput"))
      .addChild(new ROUTE().setFromNode("ColorClock").setFromField("fraction_changed").setToNode("ColorAnimator").setToField("set_fraction")))
    .addChild(new ProtoDeclare("ArtDeco01").setName("ArtDeco01").setAppinfo("tooltip: ArtDeco01Material prototype is a Material node")
      .setProtoInterface(new ProtoInterface()
        .addField(new field().setName("description").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue("ArtDeco01Material prototype is a Material node").setAppinfo("tooltip for descriptionField"))
        .addField(new field().setName("enabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(true)))
      .setProtoBody(new ProtoBody()
        .addComments(" Initial node of ProtoBody determines prototype node type ")
        .addChild(new Material().setAmbientIntensity(0.25).setDiffuseColor(0.282435,0.085159,0.134462).setShininess(0.127273).setSpecularColor(0.276305,0.11431,0.139857))
        .addComments(" [SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()=\"Material\" ")
        .addComments(" presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types ")
        .addChild(new TouchSensor().setDescription("within ProtoBody")
          .setIS(new IS()
            .addConnect(new connect().setNodeField("description").setProtoField("description"))
            .addConnect(new connect().setNodeField("enabled").setProtoField("enabled"))))))
    .addChild(new ExternProtoDeclare("ArtDeco02").setName("ArtDeco02").setAppinfo("this is a different Material node").setUrl(new String[] {"https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"})
      .addComments(" [SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()=\"ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file.\" ")
      .addField(new field().setName("description").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("tooltip for descriptionField")))
    .addComments(" Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place ")
    .addChild(new Shape("TestShape1")
      .setAppearance(new Appearance("TestAppearance1")
        .addComments(" ArtDeco01Material prototype goes here... ")
        .setMaterial(new ProtoInstance("ArtDeco01").setContainerField("material")
          .addComments(" [SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()=\"Material\" ")
          .addFieldValue(new fieldValue().setName("description").setValue("ArtDeco01Material can substitute for a Material node"))))
      .setGeometry(new Sphere().setRadius(0.001)))
    .addChild(new Shape("TestShape2")
      .setAppearance(new Appearance("TestAppearance2")
        .addComments(" ArtDeco02Material ProtoInstance goes here... ")
        .setMaterial(new ProtoInstance("ArtDeco02", "ArtDeco02MaterialDEF").setContainerField("material")
          .addComments(" [SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()=\"ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file.\" ")))
      .setGeometry(new Cone().setBottomRadius(0.001).setHeight(0.001)))
    .addChild(new Shape("TestShape3")
      .setAppearance(new Appearance("TestAppearance3")
        .addComments(" ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE. ")
        .setMaterial(new ProtoInstance("ArtDeco02").setUSE("ArtDeco02MaterialDEF").setContainerField("material")))
      .setGeometry(new Cylinder().setHeight(0.001).setRadius(0.001)))
    .addChild(new Inline("inlineScene").setUrl(new String[] {"newScene.x3d","https://www.web3d.org/specifications/java/examples/newScene.x3d"}))
    .addChild(new IMPORT().setImportedDEF("WorldInfoDEF").setInlineDEF("inlineScene").setAS("WorldInfoDEF2"))
    .addChild(new EXPORT().setLocalDEF("WorldInfoDEF").setAS("WorldInfoDEF3"))
    .addChild(new ProtoDeclare("MaterialModulator").setName("MaterialModulator").setAppinfo("mimic a Material node and modulate fields as an animation effect").setDocumentation("https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html")
      .setProtoInterface(new ProtoInterface()
        .addField(new field().setName("enabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(true))
        .addField(new field().setName("diffuseColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(new SFColor(0.0,0.0,0.0)))
        .addField(new field().setName("emissiveColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(new SFColor(0.05,0.05,0.5)))
        .addField(new field().setName("specularColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(new SFColor(0.0,0.0,0.0)))
        .addField(new field().setName("transparency").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(0.0))
        .addField(new field().setName("shininess").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(0.0))
        .addField(new field().setName("ambientIntensity").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setValue(0.0)))
      .setProtoBody(new ProtoBody()
        .addChild(new Material("MaterialNode")
          .setIS(new IS()
            .addConnect(new connect().setNodeField("diffuseColor").setProtoField("diffuseColor"))
            .addConnect(new connect().setNodeField("emissiveColor").setProtoField("emissiveColor"))
            .addConnect(new connect().setNodeField("specularColor").setProtoField("specularColor"))
            .addConnect(new connect().setNodeField("transparency").setProtoField("transparency"))
            .addConnect(new connect().setNodeField("shininess").setProtoField("shininess"))
            .addConnect(new connect().setNodeField("ambientIntensity").setProtoField("ambientIntensity"))))
        .addComments(" Only first node (the node type for the prototype) is renderable, others are along for the ride ")
        .addChild(new Script("MaterialModulatorScript").setSourceCode("""
ecmascript:
function initialize ()
{
    newColor = diffuseColor; // start with correct color
}
function set_enabled (newValue)
{
	enabled = newValue;
}
function clockTrigger (timeValue)
{
    if (!enabled) return;
    red   = newColor.r;
    green = newColor.g;
    blue  = newColor.b;

    // note different modulation rates for each color component, % is modulus operator
    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);
	if (enabled)
	{
		Browser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');
	}
}
""")
          .addField(new field().setName("enabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTOUTPUT))
          .addField(new field().setName("diffuseColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT))
          .addField(new field().setName("newColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_OUTPUTONLY))
          .addField(new field().setName("clockTrigger").setType(field.TYPE_SFTIME).setAccessType(field.ACCESSTYPE_INPUTONLY))
          .setIS(new IS()
            .addConnect(new connect().setNodeField("enabled").setProtoField("enabled"))
            .addConnect(new connect().setNodeField("diffuseColor").setProtoField("diffuseColor"))))))
    .addComments(" Test success: declarative statement createDeclarativeShapeTests() ")
    .addChild(new Group("DeclarativeGroupExample")
      .addChild(new Shape()
        .setMetadata(new MetadataString("FindableMetadataStringTest").setName("findThisNameValue").setValue(new String[] {"test case"}))
        .setAppearance(new Appearance("DeclarativeAppearanceExample")
          .addComments(" DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance ")
          .setMaterial(new ProtoInstance("MaterialModulator", "MyMaterialModulator").setContainerField("material")))
        .setGeometry(new Cone().setBottom(false).setBottomRadius(0.05).setHeight(0.1)))
      .addComments(" Test success: declarativeGroup.addChild() singleton pipeline method "))
    .addComments(" Test success: declarative statement addChild() ")
    .addComments(" Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!- - DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance - -> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance> ")
    .addComments(" Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='\"test case\"'/> ")
    .addComments(" Test success: x3dModel.findElementByNameValue(\"ArtDeco01\", \"ProtoDeclare\") found ")
    .addComments(" Test success: x3dModel.findElementByNameValue(\"MaterialModulator\", \"ProtoDeclare\") found ")
    .addComments(" Test success: x3dModel.findElementByNameValue(\"MaterialModulator\", \"ProtoInstance\") found ")
    .addChild(new Group("TestFieldObjectsGroup")
      .addComments(" testFieldObjects() results ")
      .addComments(" SFBool default=false, true=true, false=false, negate()=true ")
      .addComments(" MFBool default=, initial=true false true, negate()=false true false ")
      .addComments(" SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0 ")
      .addComments(" MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7 ")
      .addComments(" ... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear= ")
      .addComments(" SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true ")
      .addComments(" regex test SFVec3f().matches(\"1 2 3\")=true, regex test SFVec3f().matches(\"1 2 3 4\")=false, regex test (SFRotation.matches(\"0 0 0 0\")=true, failure detecting illegal (zero axis) rotation value "))
    .addChild(new Sound().setLocation(0.0,1.6,0.0)
      .addComments(" set sound-ellipsoid location height at 1.6m to match typical avatar height ")
      .setSource(new AudioClip().setDescription("chimes").setUrl(new String[] {"chimes.wav","https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav"})
        .addComments(" Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d ")))
    .addChild(new Sound().setLocation(0.0,1.6,0.0)
      .addComments(" set sound-ellipsoid location height at 1.6m to match typical avatar height ")
      .setSource(new MovieTexture().setDescription("mpgsys.mpg from ConformanceNist suite").setUrl(new String[] {"mpgsys.mpg","https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg"})
        .addComments(" Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d ")
        .addComments(" Expected containerField='source', allowed containerField values=\"texture\" \"source\" \"back\" \"bottom\" \"front\" \"left\" \"right\" \"top\" \"backTexture\" \"bottomTexture\" \"frontTexture\" \"leftTexture\" \"rightTexture\" \"topTexture\" \"children\" ")))
    .addComments(" Test success: Anchor.isNode()=true, siteAnchor.isNode()=true ")
    .addComments(" Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false ")
    .addComments(" Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false ")
    .addComments(" Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true ")
    .addComments(" Test success: CommentsBlock.isNode()=false, testComments.isNode()=false ")
    .addComments(" Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true ")
    .addChild(new Shape("ExtrusionShape")
      .addComments(" ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]' ")
      .addComments(" ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]' ")
      .setAppearance(new Appearance("TransparentAppearance")
        .setMaterial(new Material().setTransparency(1.0)))
      .setGeometry(new Extrusion("ExampleExtrusion")))
    .addChild(new Group()
      .addComments(" Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes ")
      .addChild(new ProtoDeclare("NewWorldInfo").setName("NewWorldInfo")
        .setProtoInterface(new ProtoInterface()
          .addField(new field().setName("description").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY)))
        .setProtoBody(new ProtoBody()
          .addChild(new WorldInfo())))
      .addChild(new ProtoInstance("NewWorldInfo", "Proto1").setContainerField("children")
        .addFieldValue(new fieldValue().setName("description").setValue("testing 1 2 3")))
      .addChild(new Group("Node2")
        .addComments(" intentionally empty "))
      .addChild(new ProtoInstance("NewWorldInfo", "Proto3").setContainerField("children"))
      .addChild(new Transform("Node4")
        .addComments(" intentionally empty "))
      .addComments(" Test satisfactorily creates MFNode children array as an ordered list with mixed content "))
    .addChild(new ProtoDeclare("ShaderProto").setName("ShaderProto")
      .setProtoBody(new ProtoBody()
        .addChild(new ProgramShader())))
    .addChild(new Shape()
      .setAppearance(new Appearance()
        .addComments(" Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes ")
        .addComments(" Test satisfactorily creates MFNode shaders array as an ordered list with mixed content ")
        .addShaders(new ProgramShader("TestShader1")
          .addPrograms(new ShaderProgram("TestShader2")))
        .addShaders(new ProtoInstance("ShaderProto", "TestShader3").setContainerField("shaders"))
        .addShaders(new ComposedShader("TestShader4")
          .addParts(new ShaderPart("TestShader5")))))
    .addChild(new Transform("SpecialtyNodes")
      .addChild(new CADLayer()
        .addChild(new CADAssembly()
          .addChild(new CADPart()
            .addChild(new CADFace()))))
      .addChild(new EspduTransform())
      .addChild(new ReceiverPdu().setReceivedPower(0.0))
      .addChild(new SignalPdu())
      .addChild(new TransmitterPdu().setRelativeAntennaLocation(0.0,0.0,0.0).setTransmitFrequencyBandwidth(0.0))
      .addChild(new DISEntityManager()
        .addChild(new DISEntityTypeMapping())))
    .addChild(new EspduTransform()
      .addChild(new WorldInfo()))
    .addChild(new ReceiverPdu().setReceivedPower(0.0))
    .addChild(new SignalPdu())
    .addChild(new TransmitterPdu().setRelativeAntennaLocation(0.0,0.0,0.0).setTransmitFrequencyBandwidth(0.0))
    .addChild(new DISEntityManager()
      .addChild(new DISEntityTypeMapping()))
    .addChild(new LoadSensor()
      .addComments(" Contained nodes typically must be USE references for nodes previously DEFined in the scene ")
      .addComments(" The following nodes are test cases for all X3DUrlObject nodes ")
      .addChild(new Anchor().setUSE("siteAnchor"))
      .addChild(new Inline().setUSE("inlineScene"))
      .addChild(new DISEntityTypeMapping())
      .addChild(new GeoMetadata())
      .addChild(new AudioClip())
      .addChild(new ImageCubeMapTexture())
      .addChild(new ImageTexture3D())
      .addChild(new ImageTexture())
      .addChild(new MovieTexture())
      .addChild(new Script("DummyScript").setSourceCode("""
ecmascript:
/* dummy test source code */
"""))
      .addChild(new PackagedShader())
      .addChild(new ShaderPart())
      .addChild(new ShaderProgram()))
    .addChild(new OrthoViewpoint("SpecialTestOrthoViewpoint").setFieldOfView(new double[] {1.0,3.0,2.0,4.0})));
            }
            catch (Exception ex)
            {       
                System.err.println ("*** Further hints on X3DJSAIL errors and exceptions at");
                System.err.println ("*** https://www.web3d.org/specifications/java/X3DJSAIL.html");
                throw (ex);
            }
	}
	// end of initialize() method

	/** The initialized model object, created within initialize() method. */
	private X3D x3dModel;

	/** 
	 * Provide a 
	 * <a href="https://dzone.com/articles/java-copy-shallow-vs-deep-in-which-you-will-swim" target="_blank">shallow copy</a>
	 * of the X3D model.
	 * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/Core/X3D.html">X3D</a>
	 * @return temporaryJavaOutputFile model
	 */
	public X3D getX3dModel()
	{	  
		return x3dModel;
	}
	   
    /** 
     * Default main() method provided for test purposes, uses CommandLine to set global ConfigurationProperties for this object.
     * @param args array of input parameters, provided as arguments
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/Core/X3D.html#handleArguments-java.lang.String:A-">X3D.handleArguments(args)</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/Core/X3D.html#validationReport--">X3D.validationReport()</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/CommandLine.html">CommandLine</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/CommandLine.html#USAGE">CommandLine.USAGE</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/ConfigurationProperties.html">ConfigurationProperties</a>
     */
    public static void main(String args[])
    {
        System.out.println("Build this X3D model, showing validation diagnostics...");
        X3D thisExampleX3dModel = new temporaryJavaOutputFile().getX3dModel();
//      System.out.println("X3D model construction complete.");
	
        // next handle command line arguments
        boolean hasArguments = (args != null) && (args.length > 0);
        boolean validate = true; // default
        boolean argumentsLoadNewModel = false;
        String  fileName = new String();

        if (args != null)
        {
                for (String arg : args)
                {
                        if (arg.toLowerCase().startsWith("-v") || arg.toLowerCase().contains("validate"))
                        {
                                validate = true; // making sure
                        }
                        if (arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_X3D) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_CLASSICVRML) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_X3DB) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_VRML97) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_EXI) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_GZIP) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_ZIP) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_HTML) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_XHTML))
                        {
                                argumentsLoadNewModel = true;
                                fileName = arg;
                        }
                }
        }
        if      (argumentsLoadNewModel)
                System.out.println("WARNING: \"temporaryJavaOutputFile\" model invocation is attempting to load file \"" + fileName + "\" instead of simply validating itself... file loading ignored.");
        else if (hasArguments) // if no arguments provided, this method produces usage warning
                thisExampleX3dModel.handleArguments(args);
	
        if (validate)
        {
            //  System.out.println("--- TODO fix duplicated outputs ---"); // omit when duplicated outputs problem is solved/refactored
		String validationResults = thisExampleX3dModel.validationReport();
            //  System.out.println("-----------------------------------"); // omit when duplicated outputs problem is solved/refactored
                System.out.print("temporaryJavaOutputFile self-validation test confirmation: ");
                if (!validationResults.equals("success"))
                    System.out.println();
                System.out.println(validationResults.trim());

                // experimental: test X3DJSAIL output files
                // ./temporaryJavaOutputFile_JavaExport.* file validation is checked when building X3D Example Archives
                String filenameX3D  = "./temporaryJavaOutputFile_JavaExport.x3d"; 
                String filenameX3DV = "./temporaryJavaOutputFile_JavaExport.x3dv"; 
                String filenameJSON = "./temporaryJavaOutputFile_JavaExport.json";
                thisExampleX3dModel.toFileX3D        (filenameX3D);
                thisExampleX3dModel.toFileClassicVRML(filenameX3DV);
// TODO         thisExampleX3dModel.toFileJSON       (filenameJSON);
        }
    }
}

===========================================
Create JSON Encoding of model using stylesheet X3dToJson.xslt
Note: toFileStylesheetConversion(X3dToJson.xslt) is overwriting prior file SmokeTestProgramOutput.json
Script DEF=colorTypeConversionScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=MaterialModulatorScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=DummyScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=colorTypeConversionScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=MaterialModulatorScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=DummyScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
helloWorld.toFileJSON("SmokeTestProgramOutput.json") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.json
Test toStringJSON()

Script DEF=colorTypeConversionScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=MaterialModulatorScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=DummyScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=colorTypeConversionScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=MaterialModulatorScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=DummyScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
{ "X3D": {
    "encoding":"UTF-8",
    "@class":"x3dModel.class",
    "@profile":"Full",
    "@style":"x3dModel.style",
    "@version":"4.0",
    "@xsd:noNamespaceSchemaLocation":"https://www.web3d.org/specifications/x3d-4.0.xsd",
    "JSON schema":"https://www.web3d.org/specifications/x3d-4.0-JSONSchema.autogenerated.json",
    "-children":[
      {
        "#comment":"X3D model top-level comment"
      }
    ],
    "head": {
        "-children":[
          {
            "#comment":"comment #1"
          },
          {
            "#comment":"comment #2"
          },
          {
            "#comment":"comment #3"
          },
          {
            "#comment":"comment #4"
          }
        ],
        "component": [
          {
            "@name":"Navigation",
            "@level":3
          },
          {
            "@name":"Shaders",
            "@level":1
          },
          {
            "@name":"CADGeometry",
            "@level":2
          },
          {
            "@name":"DIS",
            "@level":2
          },
          {
            "@name":"HAnim",
            "@level":1
          },
          {
            "@name":"Grouping",
            "@level":1
          },
          {
            "@name":"Layering",
            "@level":1
          }
        ],
        "unit": [
          {
            "@name":"AngleUnitConversion",
            "@category":"angle",
            "@conversionFactor":1.0
          },
          {
            "@name":"LengthUnitConversion",
            "@category":"length",
            "@conversionFactor":1.0
          },
          {
            "@name":"ForceFromPoundsToNewtons",
            "@category":"force",
            "@conversionFactor":4.4482
          }
        ],
        "meta": [
          {
            "@name":"title",
            "@content":"SmokeTestProgramOutput.x3d"
          },
          {
            "@name":"info",
            "@content":"continued development and testing in progress"
          },
          {
            "@name":"description",
            "@content":"Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL)"
          },
          {
            "@name":"reference",
            "@content":"https://www.web3d.org/specifications/java/X3DJSAIL.html"
          },
          {
            "@name":"generator",
            "@content":"SmokeTestProgramOutput.java"
          },
          {
            "@name":"created",
            "@content":"6 September 2016"
          },
          {
            "@name":"modified",
            "@content":"28 November 2025"
          },
          {
            "@name":"generator",
            "@content":"X3D Java Scene Access Interface Library (X3DJSAIL)"
          },
          {
            "@name":"generator",
            "@content":"https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java"
          },
          {
            "@name":"generator",
            "@content":"Netbeans https://www.netbeans.org"
          },
          {
            "@name":"creator",
            "@content":"Don Brutzman"
          },
          {
            "@name":"reference",
            "@content":"https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d"
          },
          {
            "@name":"reference",
            "@content":"Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:"
          },
          {
            "@name":"reference",
            "@content":"SmokeTestProgramOutput.txt"
          },
          {
            "@name":"reference",
            "@content":"SmokeTestProgramOutput.x3dv"
          },
          {
            "@name":"reference",
            "@content":"SmokeTestProgramOutput.wrl"
          },
          {
            "@name":"reference",
            "@content":"SmokeTestProgramOutput.html"
          },
          {
            "@name":"reference",
            "@content":"https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"
          },
          {
            "@name":"identifier",
            "@content":"https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d"
          },
          {
            "@name":"license",
            "@content":"../license.html"
          },
          {
            "@name":"translated",
            "@content":"28 November 2025"
          },
          {
            "@name":"generator",
            "@content":"X3dToJson.xslt, https://www.web3d.org/x3d/stylesheets/X3dToJson.html"
          },
          {
            "@name":"reference",
            "@content":"X3D JSON encoding: https://www.web3d.org/wiki/index.php/X3D_JSON_Encoding"
          }
        ]
    },
    "Scene": {
        "-children":[
          { "MetadataSet":
            {
              "@name":"topLevelSceneMetadata"
            }
          },
          { "ViewpointGroup":
            {
              "@description":"Available viewpoints",
              "-children":[
                { "Viewpoint":
                  {
                    "@DEF":"DefaultView",
                    "@description":"Hello X3DJSAIL"
                  }
                },
                { "Viewpoint":
                  {
                    "@DEF":"TopDownView",
                    "@description":"top-down view from above",
                    "@orientation":[1,0,0,-1.570796],
                    "@position":[0,100,0]
                  }
                }
              ]
            }
          },
          { "NavigationInfo":
            {
              "@type":["EXAMINE","FLY","ANY"]
            }
          },
          { "WorldInfo":
            {
              "@DEF":"WorldInfoDEF",
              "@class":"worldInfoNode.class",
              "@style":"worldInfoNode.style",
              "@title":"SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)"
            }
          },
          { "WorldInfo":
            {
              "@USE":"WorldInfoDEF"
            }
          },
          { "WorldInfo":
            {
              "@USE":"WorldInfoDEF"
            }
          },
          { "MetadataString":
            {
              "@name":"test",
              "@DEF":"scene.addChildMetadata",
              "@value":["Top-level root Metadata node beneath Scene needs to be one of '-children' in JSON encoding"]
            }
          },
          { "LayerSet":
            {
              "@DEF":"scene.addChildLayerSetTest"
            }
          },
          { "Transform":
            {
              "@DEF":"LogoGeometryTransform",
              "@translation":[0,1.5,0],
              "-children":[
                { "Anchor":
                  {
                    "@DEF":"siteAnchor",
                    "@description":"select for X3D Java SAI Library (X3DJSAIL) description",
                    "@url":["../X3DJSAIL.html","https://www.web3d.org/specifications/java/X3DJSAIL.html"],
                    "-children":[
                      { "Shape":
                        {
                          "@DEF":"BoxShape",
                          "-appearance":
                            { "Appearance":
                              {
                                "-material":
                                  { "Material":
                                    {
                                      "@DEF":"GreenMaterial",
                                      "@diffuseColor":[0,1,1],
                                      "@emissiveColor":[0.8,0,0],
                                      "@transparency":0.1
                                    }
                                  },
                                "-texture":
                                  { "ImageTexture":
                                    {
                                      "@url":["images/X3dJavaSceneAccessInterfaceSaiLibrary.png","https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png"]
                                    }
                                  }
                              }
                            },
                          "-geometry":
                            { "Box":
                              {
                                "@DEF":"test-NMTOKEN_regex.0123456789",
                                "@class":"untextured"
                              }
                            }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          { "Shape":
            {
              "@DEF":"LineShape",
              "-appearance":
                { "Appearance":
                  {
                    "-material":
                      { "Material":
                        {
                          "@emissiveColor":[0.6,0.19607843,0.8]
                        }
                      }
                  }
                },
              "-geometry":
                { "IndexedLineSet":
                  {
                    "@coordIndex":[0,1,2,3,4,0],
                    "-children":[
                      {
                        "#comment":"Coordinate 3-tuple point count: 6"
                      }
                    ],
                    "-coord":
                      { "Coordinate":
                        {
                          "@point":[0,1.5,0,2,1.5,0,2,1.5,-2,-2,1.5,-2,-2,1.5,0,0,1.5,0]
                        }
                      }
                  }
                }
            }
          },
          { "PositionInterpolator":
            {
              "@DEF":"BoxPathAnimator",
              "@key":[0,0.125,0.375,0.625,0.875,1],
              "@keyValue":[0,1.5,0,2,1.5,0,2,1.5,-2,-2,1.5,-2,-2,1.5,0,0,1.5,0]
            }
          },
          { "TimeSensor":
            {
              "@DEF":"OrbitClock",
              "@cycleInterval":8.0,
              "@loop":true
            }
          },
          { "ROUTE":
            {
              "@fromField":"fraction_changed",
              "@fromNode":"OrbitClock",
              "@toField":"set_fraction",
              "@toNode":"BoxPathAnimator"
            }
          },
          { "ROUTE":
            {
              "@fromField":"value_changed",
              "@fromNode":"BoxPathAnimator",
              "@toField":"set_translation",
              "@toNode":"LogoGeometryTransform"
            }
          },
          { "Transform":
            {
              "@DEF":"TextTransform",
              "@translation":[0,-1.5,0],
              "-children":[
                { "Shape":
                  {
                    "-appearance":
                      { "Appearance":
                        {
                          "-material":
                            { "Material":
                              {
                                "@USE":"GreenMaterial"
                              }
                            }
                        }
                      },
                    "-geometry":
                      { "Text":
                        {
                          "@string":["X3D Java","SAI Library","X3DJSAIL"],
                          "-children":[
                            {
                              "#comment":"Comment example A, plain quotation marks: He said, \"Immel did it!\""
                            },
                            {
                              "#comment":"Comment example B, XML character entities: He said, &quot;Immel did it!&quot;"
                            }
                          ],
                          "-metadata":
                            { "MetadataSet":
                              {
                                "@name":"EscapedQuotationMarksMetadataSet",
                                "-value":[
                                  { "MetadataString":
                                    {
                                      "@name":"quotesTestC",
                                      "@value":["MFString example C, backslash-escaped quotes: He said, \"Immel did it!\""]
                                    }
                                  },
                                  { "MetadataString":
                                    {
                                      "@name":"extraChildTest",
                                      "@value":["checks MetadataSet addValue() method"]
                                    }
                                  }
                                ]
                              }
                            },
                          "-fontStyle":
                            { "FontStyle":
                              {
                                "@justify":["MIDDLE","MIDDLE"]
                              }
                            }
                        }
                      }
                  }
                },
                { "Collision":
                  {
                    "-children":[
                      {
                        "#comment":"test containerField='proxy'"
                      },
                      { "Shape":
                        {
                          "@DEF":"ProxyShape",
                          "-children":[
                            {
                              "#comment":"alternative XML encoding: Text string='\"One, Two, Comment\" \"\" \"He said, \\&quot;Immel did it!\\&quot;\"'"
                            },
                            {
                              "#comment":"alternative XML encoding: Text string='\"One, Two, Comment\" \"\" \"He said, \\&quot;Immel did it!\\&quot;\" \"\"'"
                            },
                            {
                              "#comment":"alternative Java source: .setString(new String [] {\"One, Two, Comment\", \"\", \"He said, \\\"\"Immel did it!\\\"\"\"})"
                            },
                            {
                              "#comment":"reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html"
                            }
                          ],
                          "-geometry":
                            { "Text":
                              {
                                "@string":["One, Two, Text","","He said, \"Immel did it!\" \"\""]
                              }
                            }
                        }
                      }
                    ]
                  }
                },
                {
                  "#comment":"It's a beautiful world"
                },
                {
                  "#comment":"... for you!"
                },
                {
                  "#comment":"https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song)"
                }
              ]
            }
          },
          {
            "#comment":"repeatedly spin 180 degrees as a readable special effect"
          },
          { "OrientationInterpolator":
            {
              "@DEF":"SpinInterpolator",
              "@key":[0,0.5,1],
              "@keyValue":[0,1,0,4.712389,0,1,0,0,0,1,0,1.5707964]
            }
          },
          { "TimeSensor":
            {
              "@DEF":"SpinClock",
              "@cycleInterval":5.0,
              "@loop":true
            }
          },
          { "ROUTE":
            {
              "@fromField":"fraction_changed",
              "@fromNode":"SpinClock",
              "@toField":"set_fraction",
              "@toNode":"SpinInterpolator"
            }
          },
          { "ROUTE":
            {
              "@fromField":"value_changed",
              "@fromNode":"SpinInterpolator",
              "@toField":"rotation",
              "@toNode":"TextTransform"
            }
          },
          { "Group":
            {
              "@DEF":"BackgroundGroup",
              "-children":[
                { "Background":
                  {
                    "@DEF":"GradualBackground"
                  }
                },
                { "Script":
                  {
                    "@DEF":"colorTypeConversionScript",
                    "field": [
                      {
                        "@name":"colorInput",
                        "@accessType":"inputOnly",
                        "@type":"SFColor"
                      },
                      {
                        "@name":"colorsOutput",
                        "@accessType":"outputOnly",
                        "@type":"MFColor"
                      }
                    ],
                    "#sourceCode":[
"",
"",
"ecmascript:",
"",
"function colorInput (eventValue) // Example source code",
"{",
"   colorsOutput = new MFColor(eventValue); // assigning value sends output event",
"// Browser.print('colorInput=' + eventValue + ',",
"//                colorsOutput=' + colorsOutput + '",
"');",
"// TODO check line wrapping when exporting/converting",
"}",
"",
"",
""
]
                  }
                },
                { "ColorInterpolator":
                  {
                    "@DEF":"ColorAnimator",
                    "@key":[0,0.5,1],
                    "@keyValue":[0.9411765,1,1,0.29411766,0,0.50980395,0.9411765,1,1],
                    "-children":[
                      {
                        "#comment":"AZURE to INDIGO and back again"
                      }
                    ]
                  }
                },
                { "TimeSensor":
                  {
                    "@DEF":"ColorClock",
                    "@cycleInterval":60.0,
                    "@loop":true
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"colorsOutput",
                    "@fromNode":"colorTypeConversionScript",
                    "@toField":"skyColor",
                    "@toNode":"GradualBackground"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"value_changed",
                    "@fromNode":"ColorAnimator",
                    "@toField":"colorInput",
                    "@toNode":"colorTypeConversionScript"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"fraction_changed",
                    "@fromNode":"ColorClock",
                    "@toField":"set_fraction",
                    "@toNode":"ColorAnimator"
                  }
                }
              ]
            }
          },
          { "ProtoDeclare":
            {
              "@name":"ArtDeco01",
              "@appinfo":"tooltip: ArtDeco01Material prototype is a Material node",
              "ProtoInterface": {
                  "field": [
                    {
                      "@name":"description",
                      "@accessType":"inputOutput",
                      "@appinfo":"tooltip for descriptionField",
                      "@type":"SFString",
                      "@value":"ArtDeco01Material prototype is a Material node"
                    },
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@type":"SFBool",
                      "@value":true
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    {
                      "#comment":"Initial node of ProtoBody determines prototype node type"
                    },
                    { "Material":
                      {
                        "@ambientIntensity":0.25,
                        "@diffuseColor":[0.282435,0.085159,0.134462],
                        "@shininess":0.127273,
                        "@specularColor":[0.276305,0.11431,0.139857]
                      }
                    },
                    {
                      "#comment":"[SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()=\"Material\""
                    },
                    {
                      "#comment":"presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types"
                    },
                    { "TouchSensor":
                      {
                        "@description":"within ProtoBody",
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"description",
                                "@protoField":"description"
                              },
                              {
                                "@nodeField":"enabled",
                                "@protoField":"enabled"
                              }
                            ]
                        }
                      }
                    }
                  ]
              }
            }
          },
          { "ExternProtoDeclare":
            {
              "@name":"ArtDeco02",
              "@appinfo":"this is a different Material node",
              "@url":["https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"],
              "-children":[
                {
                  "#comment":"[SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()=\"ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file.\""
                }
              ],
              "field": [
                {
                  "@name":"description",
                  "@accessType":"inputOutput",
                  "@appinfo":"tooltip for descriptionField",
                  "@type":"SFString"
                }
              ]
            }
          },
          {
            "#comment":"Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place"
          },
          { "Shape":
            {
              "@DEF":"TestShape1",
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TestAppearance1",
                    "-children":[
                      {
                        "#comment":"ArtDeco01Material prototype goes here..."
                      }
                    ],
                    "-material":
                      { "ProtoInstance":
                        {
                          "@name":"ArtDeco01",
                          "-children":[
                            {
                              "#comment":"[SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()=\"Material\""
                            }
                          ],
                          "fieldValue": [
                            {
                              "@name":"description",
                              "@value":"ArtDeco01Material can substitute for a Material node"
                            }
                          ]
                        }
                      }
                  }
                },
              "-geometry":
                { "Sphere":
                  {
                    "@radius":0.001
                  }
                }
            }
          },
          { "Shape":
            {
              "@DEF":"TestShape2",
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TestAppearance2",
                    "-children":[
                      {
                        "#comment":"ArtDeco02Material ProtoInstance goes here..."
                      }
                    ],
                    "-material":
                      { "ProtoInstance":
                        {
                          "@name":"ArtDeco02",
                          "@DEF":"ArtDeco02MaterialDEF",
                          "-children":[
                            {
                              "#comment":"[SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()=\"ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file.\""
                            }
                          ]
                        }
                      }
                  }
                },
              "-geometry":
                { "Cone":
                  {
                    "@bottomRadius":0.001,
                    "@height":0.001
                  }
                }
            }
          },
          { "Shape":
            {
              "@DEF":"TestShape3",
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TestAppearance3",
                    "-children":[
                      {
                        "#comment":"ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE."
                      }
                    ],
                    "-material":
                      { "ProtoInstance":
                        {
                          "@name":"ArtDeco02",
                          "@USE":"ArtDeco02MaterialDEF"
                        }
                      }
                  }
                },
              "-geometry":
                { "Cylinder":
                  {
                    "@height":0.001,
                    "@radius":0.001
                  }
                }
            }
          },
          { "Inline":
            {
              "@DEF":"inlineScene",
              "@url":["newScene.x3d","https://www.web3d.org/specifications/java/examples/newScene.x3d"]
            }
          },
          { "IMPORT":
            {
              "@AS":"WorldInfoDEF2",
              "@importedDEF":"WorldInfoDEF",
              "@inlineDEF":"inlineScene"
            }
          },
          { "EXPORT":
            {
              "@AS":"WorldInfoDEF3",
              "@localDEF":"WorldInfoDEF"
            }
          },
          { "ProtoDeclare":
            {
              "@name":"MaterialModulator",
              "@appinfo":"mimic a Material node and modulate fields as an animation effect",
              "@documentation":"https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html",
              "ProtoInterface": {
                  "field": [
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@type":"SFBool",
                      "@value":true
                    },
                    {
                      "@name":"diffuseColor",
                      "@accessType":"inputOutput",
                      "@type":"SFColor",
                      "@value":[0,0,0]
                    },
                    {
                      "@name":"emissiveColor",
                      "@accessType":"inputOutput",
                      "@type":"SFColor",
                      "@value":[0.05,0.05,0.5]
                    },
                    {
                      "@name":"specularColor",
                      "@accessType":"inputOutput",
                      "@type":"SFColor",
                      "@value":[0,0,0]
                    },
                    {
                      "@name":"transparency",
                      "@accessType":"inputOutput",
                      "@type":"SFFloat",
                      "@value":0.0
                    },
                    {
                      "@name":"shininess",
                      "@accessType":"inputOutput",
                      "@type":"SFFloat",
                      "@value":0.0
                    },
                    {
                      "@name":"ambientIntensity",
                      "@accessType":"inputOutput",
                      "@type":"SFFloat",
                      "@value":0.0
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    { "Material":
                      {
                        "@DEF":"MaterialNode",
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"diffuseColor",
                                "@protoField":"diffuseColor"
                              },
                              {
                                "@nodeField":"emissiveColor",
                                "@protoField":"emissiveColor"
                              },
                              {
                                "@nodeField":"specularColor",
                                "@protoField":"specularColor"
                              },
                              {
                                "@nodeField":"transparency",
                                "@protoField":"transparency"
                              },
                              {
                                "@nodeField":"shininess",
                                "@protoField":"shininess"
                              },
                              {
                                "@nodeField":"ambientIntensity",
                                "@protoField":"ambientIntensity"
                              }
                            ]
                        }
                      }
                    },
                    {
                      "#comment":"Only first node (the node type for the prototype) is renderable, others are along for the ride"
                    },
                    { "Script":
                      {
                        "@DEF":"MaterialModulatorScript",
                        "field": [
                          {
                            "@name":"enabled",
                            "@accessType":"inputOutput",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"diffuseColor",
                            "@accessType":"inputOutput",
                            "@type":"SFColor"
                          },
                          {
                            "@name":"newColor",
                            "@accessType":"outputOnly",
                            "@type":"SFColor"
                          },
                          {
                            "@name":"clockTrigger",
                            "@accessType":"inputOnly",
                            "@type":"SFTime"
                          }
                        ],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"enabled",
                                "@protoField":"enabled"
                              },
                              {
                                "@nodeField":"diffuseColor",
                                "@protoField":"diffuseColor"
                              }
                            ]
                        },
                        "#sourceCode":[
"",
"",
"ecmascript:",
"function initialize ()",
"{",
"    newColor = diffuseColor; // start with correct color",
"}",
"function set_enabled (newValue)",
"{",
"\tenabled = newValue;",
"}",
"function clockTrigger (timeValue)",
"{",
"    if (!enabled) return;",
"    red   = newColor.r;",
"    green = newColor.g;",
"    blue  = newColor.b;",
"",
"    // note different modulation rates for each color component, % is modulus operator",
"    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);",
"\tif (enabled)",
"\t{",
"\t\tBrowser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');",
"\t}",
"}",
"",
""
]
                      }
                    }
                  ]
              }
            }
          },
          {
            "#comment":"Test success: declarative statement createDeclarativeShapeTests()"
          },
          { "Group":
            {
              "@DEF":"DeclarativeGroupExample",
              "-children":[
                { "Shape":
                  {
                    "-value":[
                      { "MetadataString":
                        {
                          "@name":"findThisNameValue",
                          "@DEF":"FindableMetadataStringTest",
                          "@value":["test case"]
                        }
                      }
                    ],
                    "-appearance":
                      { "Appearance":
                        {
                          "@DEF":"DeclarativeAppearanceExample",
                          "-children":[
                            {
                              "#comment":"DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance"
                            }
                          ],
                          "-material":
                            { "ProtoInstance":
                              {
                                "@name":"MaterialModulator",
                                "@DEF":"MyMaterialModulator"
                              }
                            }
                        }
                      },
                    "-geometry":
                      { "Cone":
                        {
                          "@bottom":false,
                          "@bottomRadius":0.05,
                          "@height":0.1
                        }
                      }
                  }
                },
                {
                  "#comment":"Test success: declarativeGroup.addChild() singleton pipeline method"
                }
              ]
            }
          },
          {
            "#comment":"Test success: declarative statement addChild()"
          },
          {
            "#comment":"Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!- - DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance - -> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance>"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='\"test case\"'/>"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(\"ArtDeco01\", \"ProtoDeclare\") found"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(\"MaterialModulator\", \"ProtoDeclare\") found"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(\"MaterialModulator\", \"ProtoInstance\") found"
          },
          { "Group":
            {
              "@DEF":"TestFieldObjectsGroup",
              "-children":[
                {
                  "#comment":"testFieldObjects() results"
                },
                {
                  "#comment":"SFBool default=false, true=true, false=false, negate()=true"
                },
                {
                  "#comment":"MFBool default=, initial=true false true, negate()=false true false"
                },
                {
                  "#comment":"SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0"
                },
                {
                  "#comment":"MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7"
                },
                {
                  "#comment":"... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear="
                },
                {
                  "#comment":"SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true"
                },
                {
                  "#comment":"regex test SFVec3f().matches(\"1 2 3\")=true, regex test SFVec3f().matches(\"1 2 3 4\")=false, regex test (SFRotation.matches(\"0 0 0 0\")=true, failure detecting illegal (zero axis) rotation value"
                }
              ]
            }
          },
          { "Sound":
            {
              "@location":[0,1.6,0],
              "-children":[
                {
                  "#comment":"set sound-ellipsoid location height at 1.6m to match typical avatar height"
                }
              ],
              "-source":
                { "AudioClip":
                  {
                    "@description":"chimes",
                    "@url":["chimes.wav","https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav"],
                    "-children":[
                      {
                        "#comment":"Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d"
                      }
                    ]
                  }
                }
            }
          },
          { "Sound":
            {
              "@location":[0,1.6,0],
              "-children":[
                {
                  "#comment":"set sound-ellipsoid location height at 1.6m to match typical avatar height"
                }
              ],
              "-source":
                { "MovieTexture":
                  {
                    "@description":"mpgsys.mpg from ConformanceNist suite",
                    "@url":["mpgsys.mpg","https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg"],
                    "-children":[
                      {
                        "#comment":"Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d"
                      },
                      {
                        "#comment":"Expected containerField='source', allowed containerField values=\"texture\" \"source\" \"back\" \"bottom\" \"front\" \"left\" \"right\" \"top\" \"backTexture\" \"bottomTexture\" \"frontTexture\" \"leftTexture\" \"rightTexture\" \"topTexture\" \"children\""
                      }
                    ]
                  }
                }
            }
          },
          {
            "#comment":"Test success: Anchor.isNode()=true, siteAnchor.isNode()=true"
          },
          {
            "#comment":"Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false"
          },
          {
            "#comment":"Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false"
          },
          {
            "#comment":"Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true"
          },
          {
            "#comment":"Test success: CommentsBlock.isNode()=false, testComments.isNode()=false"
          },
          {
            "#comment":"Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true"
          },
          { "Shape":
            {
              "@DEF":"ExtrusionShape",
              "-children":[
                {
                  "#comment":"ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]'"
                },
                {
                  "#comment":"ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]'"
                }
              ],
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TransparentAppearance",
                    "-material":
                      { "Material":
                        {
                          "@transparency":1.0
                        }
                      }
                  }
                },
              "-geometry":
                { "Extrusion":
                  {
                    "@DEF":"ExampleExtrusion"
                  }
                }
            }
          },
          { "Group":
            {
              "-children":[
                {
                  "#comment":"Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes"
                },
                { "ProtoDeclare":
                  {
                    "@name":"NewWorldInfo",
                    "ProtoInterface": {
                        "field": [
                          {
                            "@name":"description",
                            "@accessType":"initializeOnly",
                            "@type":"SFString"
                          }
                        ]
                    },
                    "ProtoBody": {
                        "-children":[
                          { "WorldInfo":
                            {
                            }
                          }
                        ]
                    }
                  }
                },
                { "ProtoInstance":
                  {
                    "@name":"NewWorldInfo",
                    "@DEF":"Proto1",
                    "fieldValue": [
                      {
                        "@name":"description",
                        "@value":"testing 1 2 3"
                      }
                    ]
                  }
                },
                { "Group":
                  {
                    "@DEF":"Node2",
                    "-children":[
                      {
                        "#comment":"intentionally empty"
                      }
                    ]
                  }
                },
                { "ProtoInstance":
                  {
                    "@name":"NewWorldInfo",
                    "@DEF":"Proto3"
                  }
                },
                { "Transform":
                  {
                    "@DEF":"Node4",
                    "-children":[
                      {
                        "#comment":"intentionally empty"
                      }
                    ]
                  }
                },
                {
                  "#comment":"Test satisfactorily creates MFNode children array as an ordered list with mixed content"
                }
              ]
            }
          },
          { "ProtoDeclare":
            {
              "@name":"ShaderProto",
              "ProtoBody": {
                  "-children":[
                    { "ProgramShader":
                      {
                      }
                    }
                  ]
              }
            }
          },
          { "Shape":
            {
              "-appearance":
                { "Appearance":
                  {
                    "-children":[
                      {
                        "#comment":"Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes"
                      },
                      {
                        "#comment":"Test satisfactorily creates MFNode shaders array as an ordered list with mixed content"
                      }
                    ],
                    "-shaders":[
                      { "ProgramShader":
                        {
                          "@DEF":"TestShader1",
                          "-programs":[
                            { "ShaderProgram":
                              {
                                "@DEF":"TestShader2",
                                "@type":"VERTEX"
                              }
                            }
                          ]
                        }
                      },
                      { "ProtoInstance":
                        {
                          "@name":"ShaderProto",
                          "@DEF":"TestShader3"
                        }
                      },
                      { "ComposedShader":
                        {
                          "@DEF":"TestShader4",
                          "-parts":[
                            { "ShaderPart":
                              {
                                "@DEF":"TestShader5",
                                "@type":"VERTEX"
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
            }
          },
          { "Transform":
            {
              "@DEF":"SpecialtyNodes",
              "-children":[
                { "CADLayer":
                  {
                    "-children":[
                      { "CADAssembly":
                        {
                          "-children":[
                            { "CADPart":
                              {
                                "-children":[
                                  { "CADFace":
                                    {
                                    }
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                },
                { "EspduTransform":
                  {
                  }
                },
                { "ReceiverPdu":
                  {
                  }
                },
                { "SignalPdu":
                  {
                  }
                },
                { "TransmitterPdu":
                  {
                  }
                },
                { "DISEntityManager":
                  {
                    "-children":[
                      { "DISEntityTypeMapping":
                        {
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          { "EspduTransform":
            {
              "-children":[
                { "WorldInfo":
                  {
                  }
                }
              ]
            }
          },
          { "ReceiverPdu":
            {
            }
          },
          { "SignalPdu":
            {
            }
          },
          { "TransmitterPdu":
            {
            }
          },
          { "DISEntityManager":
            {
              "-children":[
                { "DISEntityTypeMapping":
                  {
                  }
                }
              ]
            }
          },
          { "LoadSensor":
            {
              "-children":[
                {
                  "#comment":"Contained nodes typically must be USE references for nodes previously DEFined in the scene"
                },
                {
                  "#comment":"The following nodes are test cases for all X3DUrlObject nodes"
                },
                { "Anchor":
                  {
                    "@USE":"siteAnchor"
                  }
                },
                { "Inline":
                  {
                    "@USE":"inlineScene"
                  }
                },
                { "DISEntityTypeMapping":
                  {
                  }
                },
                { "GeoMetadata":
                  {
                  }
                },
                { "AudioClip":
                  {
                  }
                },
                { "ImageCubeMapTexture":
                  {
                  }
                },
                { "ImageTexture3D":
                  {
                  }
                },
                { "ImageTexture":
                  {
                  }
                },
                { "MovieTexture":
                  {
                  }
                },
                { "Script":
                  {
                    "@DEF":"DummyScript",
                    "#sourceCode":[
"",
"",
"ecmascript:",
"/* dummy test source code */",
"",
""
]
                  }
                },
                { "PackagedShader":
                  {
                  }
                },
                { "ShaderPart":
                  {
                    "@type":"VERTEX"
                  }
                },
                { "ShaderProgram":
                  {
                    "@type":"VERTEX"
                  }
                }
              ]
            }
          },
          { "OrthoViewpoint":
            {
              "@DEF":"SpecialTestOrthoViewpoint",
              "@fieldOfView":[1,3,2,4]
            }
          }
        ],
        "-children":[
          { "ViewpointGroup":
            {
              "@description":"Available viewpoints",
              "-children":[
                { "Viewpoint":
                  {
                    "@DEF":"DefaultView",
                    "@description":"Hello X3DJSAIL"
                  }
                },
                { "Viewpoint":
                  {
                    "@DEF":"TopDownView",
                    "@description":"top-down view from above",
                    "@orientation":[1,0,0,-1.570796],
                    "@position":[0,100,0]
                  }
                }
              ]
            }
          },
          { "NavigationInfo":
            {
              "@type":["EXAMINE","FLY","ANY"]
            }
          },
          { "WorldInfo":
            {
              "@DEF":"WorldInfoDEF",
              "@class":"worldInfoNode.class",
              "@style":"worldInfoNode.style",
              "@title":"SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)"
            }
          },
          { "WorldInfo":
            {
              "@USE":"WorldInfoDEF"
            }
          },
          { "WorldInfo":
            {
              "@USE":"WorldInfoDEF"
            }
          },
          { "MetadataString":
            {
              "@name":"test",
              "@DEF":"scene.addChildMetadata",
              "@value":["Top-level root Metadata node beneath Scene needs to be one of '-children' in JSON encoding"]
            }
          },
          { "LayerSet":
            {
              "@DEF":"scene.addChildLayerSetTest"
            }
          },
          { "Transform":
            {
              "@DEF":"LogoGeometryTransform",
              "@translation":[0,1.5,0],
              "-children":[
                { "Anchor":
                  {
                    "@DEF":"siteAnchor",
                    "@description":"select for X3D Java SAI Library (X3DJSAIL) description",
                    "@url":["../X3DJSAIL.html","https://www.web3d.org/specifications/java/X3DJSAIL.html"],
                    "-children":[
                      { "Shape":
                        {
                          "@DEF":"BoxShape",
                          "-appearance":
                            { "Appearance":
                              {
                                "-material":
                                  { "Material":
                                    {
                                      "@DEF":"GreenMaterial",
                                      "@diffuseColor":[0,1,1],
                                      "@emissiveColor":[0.8,0,0],
                                      "@transparency":0.1
                                    }
                                  },
                                "-texture":
                                  { "ImageTexture":
                                    {
                                      "@url":["images/X3dJavaSceneAccessInterfaceSaiLibrary.png","https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png"]
                                    }
                                  }
                              }
                            },
                          "-geometry":
                            { "Box":
                              {
                                "@DEF":"test-NMTOKEN_regex.0123456789",
                                "@class":"untextured"
                              }
                            }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          { "Shape":
            {
              "@DEF":"LineShape",
              "-appearance":
                { "Appearance":
                  {
                    "-material":
                      { "Material":
                        {
                          "@emissiveColor":[0.6,0.19607843,0.8]
                        }
                      }
                  }
                },
              "-geometry":
                { "IndexedLineSet":
                  {
                    "@coordIndex":[0,1,2,3,4,0],
                    "-children":[
                      {
                        "#comment":"Coordinate 3-tuple point count: 6"
                      }
                    ],
                    "-coord":
                      { "Coordinate":
                        {
                          "@point":[0,1.5,0,2,1.5,0,2,1.5,-2,-2,1.5,-2,-2,1.5,0,0,1.5,0]
                        }
                      }
                  }
                }
            }
          },
          { "PositionInterpolator":
            {
              "@DEF":"BoxPathAnimator",
              "@key":[0,0.125,0.375,0.625,0.875,1],
              "@keyValue":[0,1.5,0,2,1.5,0,2,1.5,-2,-2,1.5,-2,-2,1.5,0,0,1.5,0]
            }
          },
          { "TimeSensor":
            {
              "@DEF":"OrbitClock",
              "@cycleInterval":8.0,
              "@loop":true
            }
          },
          { "ROUTE":
            {
              "@fromField":"fraction_changed",
              "@fromNode":"OrbitClock",
              "@toField":"set_fraction",
              "@toNode":"BoxPathAnimator"
            }
          },
          { "ROUTE":
            {
              "@fromField":"value_changed",
              "@fromNode":"BoxPathAnimator",
              "@toField":"set_translation",
              "@toNode":"LogoGeometryTransform"
            }
          },
          { "Transform":
            {
              "@DEF":"TextTransform",
              "@translation":[0,-1.5,0],
              "-children":[
                { "Shape":
                  {
                    "-appearance":
                      { "Appearance":
                        {
                          "-material":
                            { "Material":
                              {
                                "@USE":"GreenMaterial"
                              }
                            }
                        }
                      },
                    "-geometry":
                      { "Text":
                        {
                          "@string":["X3D Java","SAI Library","X3DJSAIL"],
                          "-children":[
                            {
                              "#comment":"Comment example A, plain quotation marks: He said, \"Immel did it!\""
                            },
                            {
                              "#comment":"Comment example B, XML character entities: He said, &quot;Immel did it!&quot;"
                            }
                          ],
                          "-metadata":
                            { "MetadataSet":
                              {
                                "@name":"EscapedQuotationMarksMetadataSet",
                                "-value":[
                                  { "MetadataString":
                                    {
                                      "@name":"quotesTestC",
                                      "@value":["MFString example C, backslash-escaped quotes: He said, \"Immel did it!\""]
                                    }
                                  },
                                  { "MetadataString":
                                    {
                                      "@name":"extraChildTest",
                                      "@value":["checks MetadataSet addValue() method"]
                                    }
                                  }
                                ]
                              }
                            },
                          "-fontStyle":
                            { "FontStyle":
                              {
                                "@justify":["MIDDLE","MIDDLE"]
                              }
                            }
                        }
                      }
                  }
                },
                { "Collision":
                  {
                    "-children":[
                      {
                        "#comment":"test containerField='proxy'"
                      },
                      { "Shape":
                        {
                          "@DEF":"ProxyShape",
                          "-children":[
                            {
                              "#comment":"alternative XML encoding: Text string='\"One, Two, Comment\" \"\" \"He said, \\&quot;Immel did it!\\&quot;\"'"
                            },
                            {
                              "#comment":"alternative XML encoding: Text string='\"One, Two, Comment\" \"\" \"He said, \\&quot;Immel did it!\\&quot;\" \"\"'"
                            },
                            {
                              "#comment":"alternative Java source: .setString(new String [] {\"One, Two, Comment\", \"\", \"He said, \\\"\"Immel did it!\\\"\"\"})"
                            },
                            {
                              "#comment":"reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html"
                            }
                          ],
                          "-geometry":
                            { "Text":
                              {
                                "@string":["One, Two, Text","","He said, \"Immel did it!\" \"\""]
                              }
                            }
                        }
                      }
                    ]
                  }
                },
                {
                  "#comment":"It's a beautiful world"
                },
                {
                  "#comment":"... for you!"
                },
                {
                  "#comment":"https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song)"
                }
              ]
            }
          },
          {
            "#comment":"repeatedly spin 180 degrees as a readable special effect"
          },
          { "OrientationInterpolator":
            {
              "@DEF":"SpinInterpolator",
              "@key":[0,0.5,1],
              "@keyValue":[0,1,0,4.712389,0,1,0,0,0,1,0,1.5707964]
            }
          },
          { "TimeSensor":
            {
              "@DEF":"SpinClock",
              "@cycleInterval":5.0,
              "@loop":true
            }
          },
          { "ROUTE":
            {
              "@fromField":"fraction_changed",
              "@fromNode":"SpinClock",
              "@toField":"set_fraction",
              "@toNode":"SpinInterpolator"
            }
          },
          { "ROUTE":
            {
              "@fromField":"value_changed",
              "@fromNode":"SpinInterpolator",
              "@toField":"rotation",
              "@toNode":"TextTransform"
            }
          },
          { "Group":
            {
              "@DEF":"BackgroundGroup",
              "-children":[
                { "Background":
                  {
                    "@DEF":"GradualBackground"
                  }
                },
                { "Script":
                  {
                    "@DEF":"colorTypeConversionScript",
                    "field": [
                      {
                        "@name":"colorInput",
                        "@accessType":"inputOnly",
                        "@type":"SFColor"
                      },
                      {
                        "@name":"colorsOutput",
                        "@accessType":"outputOnly",
                        "@type":"MFColor"
                      }
                    ],
                    "#sourceCode":[
"",
"",
"ecmascript:",
"",
"function colorInput (eventValue) // Example source code",
"{",
"   colorsOutput = new MFColor(eventValue); // assigning value sends output event",
"// Browser.print('colorInput=' + eventValue + ',",
"//                colorsOutput=' + colorsOutput + '",
"');",
"// TODO check line wrapping when exporting/converting",
"}",
"",
"",
""
]
                  }
                },
                { "ColorInterpolator":
                  {
                    "@DEF":"ColorAnimator",
                    "@key":[0,0.5,1],
                    "@keyValue":[0.9411765,1,1,0.29411766,0,0.50980395,0.9411765,1,1],
                    "-children":[
                      {
                        "#comment":"AZURE to INDIGO and back again"
                      }
                    ]
                  }
                },
                { "TimeSensor":
                  {
                    "@DEF":"ColorClock",
                    "@cycleInterval":60.0,
                    "@loop":true
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"colorsOutput",
                    "@fromNode":"colorTypeConversionScript",
                    "@toField":"skyColor",
                    "@toNode":"GradualBackground"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"value_changed",
                    "@fromNode":"ColorAnimator",
                    "@toField":"colorInput",
                    "@toNode":"colorTypeConversionScript"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"fraction_changed",
                    "@fromNode":"ColorClock",
                    "@toField":"set_fraction",
                    "@toNode":"ColorAnimator"
                  }
                }
              ]
            }
          },
          { "ProtoDeclare":
            {
              "@name":"ArtDeco01",
              "@appinfo":"tooltip: ArtDeco01Material prototype is a Material node",
              "ProtoInterface": {
                  "field": [
                    {
                      "@name":"description",
                      "@accessType":"inputOutput",
                      "@appinfo":"tooltip for descriptionField",
                      "@type":"SFString",
                      "@value":"ArtDeco01Material prototype is a Material node"
                    },
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@type":"SFBool",
                      "@value":true
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    {
                      "#comment":"Initial node of ProtoBody determines prototype node type"
                    },
                    { "Material":
                      {
                        "@ambientIntensity":0.25,
                        "@diffuseColor":[0.282435,0.085159,0.134462],
                        "@shininess":0.127273,
                        "@specularColor":[0.276305,0.11431,0.139857]
                      }
                    },
                    {
                      "#comment":"[SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()=\"Material\""
                    },
                    {
                      "#comment":"presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types"
                    },
                    { "TouchSensor":
                      {
                        "@description":"within ProtoBody",
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"description",
                                "@protoField":"description"
                              },
                              {
                                "@nodeField":"enabled",
                                "@protoField":"enabled"
                              }
                            ]
                        }
                      }
                    }
                  ]
              }
            }
          },
          { "ExternProtoDeclare":
            {
              "@name":"ArtDeco02",
              "@appinfo":"this is a different Material node",
              "@url":["https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"],
              "-children":[
                {
                  "#comment":"[SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()=\"ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file.\""
                }
              ],
              "field": [
                {
                  "@name":"description",
                  "@accessType":"inputOutput",
                  "@appinfo":"tooltip for descriptionField",
                  "@type":"SFString"
                }
              ]
            }
          },
          {
            "#comment":"Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place"
          },
          { "Shape":
            {
              "@DEF":"TestShape1",
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TestAppearance1",
                    "-children":[
                      {
                        "#comment":"ArtDeco01Material prototype goes here..."
                      }
                    ],
                    "-material":
                      { "ProtoInstance":
                        {
                          "@name":"ArtDeco01",
                          "-children":[
                            {
                              "#comment":"[SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()=\"Material\""
                            }
                          ],
                          "fieldValue": [
                            {
                              "@name":"description",
                              "@value":"ArtDeco01Material can substitute for a Material node"
                            }
                          ]
                        }
                      }
                  }
                },
              "-geometry":
                { "Sphere":
                  {
                    "@radius":0.001
                  }
                }
            }
          },
          { "Shape":
            {
              "@DEF":"TestShape2",
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TestAppearance2",
                    "-children":[
                      {
                        "#comment":"ArtDeco02Material ProtoInstance goes here..."
                      }
                    ],
                    "-material":
                      { "ProtoInstance":
                        {
                          "@name":"ArtDeco02",
                          "@DEF":"ArtDeco02MaterialDEF",
                          "-children":[
                            {
                              "#comment":"[SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()=\"ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file.\""
                            }
                          ]
                        }
                      }
                  }
                },
              "-geometry":
                { "Cone":
                  {
                    "@bottomRadius":0.001,
                    "@height":0.001
                  }
                }
            }
          },
          { "Shape":
            {
              "@DEF":"TestShape3",
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TestAppearance3",
                    "-children":[
                      {
                        "#comment":"ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE."
                      }
                    ],
                    "-material":
                      { "ProtoInstance":
                        {
                          "@name":"ArtDeco02",
                          "@USE":"ArtDeco02MaterialDEF"
                        }
                      }
                  }
                },
              "-geometry":
                { "Cylinder":
                  {
                    "@height":0.001,
                    "@radius":0.001
                  }
                }
            }
          },
          { "Inline":
            {
              "@DEF":"inlineScene",
              "@url":["newScene.x3d","https://www.web3d.org/specifications/java/examples/newScene.x3d"]
            }
          },
          { "IMPORT":
            {
              "@AS":"WorldInfoDEF2",
              "@importedDEF":"WorldInfoDEF",
              "@inlineDEF":"inlineScene"
            }
          },
          { "EXPORT":
            {
              "@AS":"WorldInfoDEF3",
              "@localDEF":"WorldInfoDEF"
            }
          },
          { "ProtoDeclare":
            {
              "@name":"MaterialModulator",
              "@appinfo":"mimic a Material node and modulate fields as an animation effect",
              "@documentation":"https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html",
              "ProtoInterface": {
                  "field": [
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@type":"SFBool",
                      "@value":true
                    },
                    {
                      "@name":"diffuseColor",
                      "@accessType":"inputOutput",
                      "@type":"SFColor",
                      "@value":[0,0,0]
                    },
                    {
                      "@name":"emissiveColor",
                      "@accessType":"inputOutput",
                      "@type":"SFColor",
                      "@value":[0.05,0.05,0.5]
                    },
                    {
                      "@name":"specularColor",
                      "@accessType":"inputOutput",
                      "@type":"SFColor",
                      "@value":[0,0,0]
                    },
                    {
                      "@name":"transparency",
                      "@accessType":"inputOutput",
                      "@type":"SFFloat",
                      "@value":0.0
                    },
                    {
                      "@name":"shininess",
                      "@accessType":"inputOutput",
                      "@type":"SFFloat",
                      "@value":0.0
                    },
                    {
                      "@name":"ambientIntensity",
                      "@accessType":"inputOutput",
                      "@type":"SFFloat",
                      "@value":0.0
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    { "Material":
                      {
                        "@DEF":"MaterialNode",
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"diffuseColor",
                                "@protoField":"diffuseColor"
                              },
                              {
                                "@nodeField":"emissiveColor",
                                "@protoField":"emissiveColor"
                              },
                              {
                                "@nodeField":"specularColor",
                                "@protoField":"specularColor"
                              },
                              {
                                "@nodeField":"transparency",
                                "@protoField":"transparency"
                              },
                              {
                                "@nodeField":"shininess",
                                "@protoField":"shininess"
                              },
                              {
                                "@nodeField":"ambientIntensity",
                                "@protoField":"ambientIntensity"
                              }
                            ]
                        }
                      }
                    },
                    {
                      "#comment":"Only first node (the node type for the prototype) is renderable, others are along for the ride"
                    },
                    { "Script":
                      {
                        "@DEF":"MaterialModulatorScript",
                        "field": [
                          {
                            "@name":"enabled",
                            "@accessType":"inputOutput",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"diffuseColor",
                            "@accessType":"inputOutput",
                            "@type":"SFColor"
                          },
                          {
                            "@name":"newColor",
                            "@accessType":"outputOnly",
                            "@type":"SFColor"
                          },
                          {
                            "@name":"clockTrigger",
                            "@accessType":"inputOnly",
                            "@type":"SFTime"
                          }
                        ],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"enabled",
                                "@protoField":"enabled"
                              },
                              {
                                "@nodeField":"diffuseColor",
                                "@protoField":"diffuseColor"
                              }
                            ]
                        },
                        "#sourceCode":[
"",
"",
"ecmascript:",
"function initialize ()",
"{",
"    newColor = diffuseColor; // start with correct color",
"}",
"function set_enabled (newValue)",
"{",
"\tenabled = newValue;",
"}",
"function clockTrigger (timeValue)",
"{",
"    if (!enabled) return;",
"    red   = newColor.r;",
"    green = newColor.g;",
"    blue  = newColor.b;",
"",
"    // note different modulation rates for each color component, % is modulus operator",
"    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);",
"\tif (enabled)",
"\t{",
"\t\tBrowser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');",
"\t}",
"}",
"",
""
]
                      }
                    }
                  ]
              }
            }
          },
          {
            "#comment":"Test success: declarative statement createDeclarativeShapeTests()"
          },
          { "Group":
            {
              "@DEF":"DeclarativeGroupExample",
              "-children":[
                { "Shape":
                  {
                    "-value":[
                      { "MetadataString":
                        {
                          "@name":"findThisNameValue",
                          "@DEF":"FindableMetadataStringTest",
                          "@value":["test case"]
                        }
                      }
                    ],
                    "-appearance":
                      { "Appearance":
                        {
                          "@DEF":"DeclarativeAppearanceExample",
                          "-children":[
                            {
                              "#comment":"DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance"
                            }
                          ],
                          "-material":
                            { "ProtoInstance":
                              {
                                "@name":"MaterialModulator",
                                "@DEF":"MyMaterialModulator"
                              }
                            }
                        }
                      },
                    "-geometry":
                      { "Cone":
                        {
                          "@bottom":false,
                          "@bottomRadius":0.05,
                          "@height":0.1
                        }
                      }
                  }
                },
                {
                  "#comment":"Test success: declarativeGroup.addChild() singleton pipeline method"
                }
              ]
            }
          },
          {
            "#comment":"Test success: declarative statement addChild()"
          },
          {
            "#comment":"Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!- - DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance - -> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance>"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='\"test case\"'/>"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(\"ArtDeco01\", \"ProtoDeclare\") found"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(\"MaterialModulator\", \"ProtoDeclare\") found"
          },
          {
            "#comment":"Test success: x3dModel.findElementByNameValue(\"MaterialModulator\", \"ProtoInstance\") found"
          },
          { "Group":
            {
              "@DEF":"TestFieldObjectsGroup",
              "-children":[
                {
                  "#comment":"testFieldObjects() results"
                },
                {
                  "#comment":"SFBool default=false, true=true, false=false, negate()=true"
                },
                {
                  "#comment":"MFBool default=, initial=true false true, negate()=false true false"
                },
                {
                  "#comment":"SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0"
                },
                {
                  "#comment":"MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7"
                },
                {
                  "#comment":"... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear="
                },
                {
                  "#comment":"SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true"
                },
                {
                  "#comment":"regex test SFVec3f().matches(\"1 2 3\")=true, regex test SFVec3f().matches(\"1 2 3 4\")=false, regex test (SFRotation.matches(\"0 0 0 0\")=true, failure detecting illegal (zero axis) rotation value"
                }
              ]
            }
          },
          { "Sound":
            {
              "@location":[0,1.6,0],
              "-children":[
                {
                  "#comment":"set sound-ellipsoid location height at 1.6m to match typical avatar height"
                }
              ],
              "-source":
                { "AudioClip":
                  {
                    "@description":"chimes",
                    "@url":["chimes.wav","https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav"],
                    "-children":[
                      {
                        "#comment":"Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d"
                      }
                    ]
                  }
                }
            }
          },
          { "Sound":
            {
              "@location":[0,1.6,0],
              "-children":[
                {
                  "#comment":"set sound-ellipsoid location height at 1.6m to match typical avatar height"
                }
              ],
              "-source":
                { "MovieTexture":
                  {
                    "@description":"mpgsys.mpg from ConformanceNist suite",
                    "@url":["mpgsys.mpg","https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg"],
                    "-children":[
                      {
                        "#comment":"Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d"
                      },
                      {
                        "#comment":"Expected containerField='source', allowed containerField values=\"texture\" \"source\" \"back\" \"bottom\" \"front\" \"left\" \"right\" \"top\" \"backTexture\" \"bottomTexture\" \"frontTexture\" \"leftTexture\" \"rightTexture\" \"topTexture\" \"children\""
                      }
                    ]
                  }
                }
            }
          },
          {
            "#comment":"Test success: Anchor.isNode()=true, siteAnchor.isNode()=true"
          },
          {
            "#comment":"Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false"
          },
          {
            "#comment":"Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false"
          },
          {
            "#comment":"Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true"
          },
          {
            "#comment":"Test success: CommentsBlock.isNode()=false, testComments.isNode()=false"
          },
          {
            "#comment":"Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true"
          },
          { "Shape":
            {
              "@DEF":"ExtrusionShape",
              "-children":[
                {
                  "#comment":"ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]'"
                },
                {
                  "#comment":"ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]'"
                }
              ],
              "-appearance":
                { "Appearance":
                  {
                    "@DEF":"TransparentAppearance",
                    "-material":
                      { "Material":
                        {
                          "@transparency":1.0
                        }
                      }
                  }
                },
              "-geometry":
                { "Extrusion":
                  {
                    "@DEF":"ExampleExtrusion"
                  }
                }
            }
          },
          { "Group":
            {
              "-children":[
                {
                  "#comment":"Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes"
                },
                { "ProtoDeclare":
                  {
                    "@name":"NewWorldInfo",
                    "ProtoInterface": {
                        "field": [
                          {
                            "@name":"description",
                            "@accessType":"initializeOnly",
                            "@type":"SFString"
                          }
                        ]
                    },
                    "ProtoBody": {
                        "-children":[
                          { "WorldInfo":
                            {
                            }
                          }
                        ]
                    }
                  }
                },
                { "ProtoInstance":
                  {
                    "@name":"NewWorldInfo",
                    "@DEF":"Proto1",
                    "fieldValue": [
                      {
                        "@name":"description",
                        "@value":"testing 1 2 3"
                      }
                    ]
                  }
                },
                { "Group":
                  {
                    "@DEF":"Node2",
                    "-children":[
                      {
                        "#comment":"intentionally empty"
                      }
                    ]
                  }
                },
                { "ProtoInstance":
                  {
                    "@name":"NewWorldInfo",
                    "@DEF":"Proto3"
                  }
                },
                { "Transform":
                  {
                    "@DEF":"Node4",
                    "-children":[
                      {
                        "#comment":"intentionally empty"
                      }
                    ]
                  }
                },
                {
                  "#comment":"Test satisfactorily creates MFNode children array as an ordered list with mixed content"
                }
              ]
            }
          },
          { "ProtoDeclare":
            {
              "@name":"ShaderProto",
              "ProtoBody": {
                  "-children":[
                    { "ProgramShader":
                      {
                      }
                    }
                  ]
              }
            }
          },
          { "Shape":
            {
              "-appearance":
                { "Appearance":
                  {
                    "-children":[
                      {
                        "#comment":"Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes"
                      },
                      {
                        "#comment":"Test satisfactorily creates MFNode shaders array as an ordered list with mixed content"
                      }
                    ],
                    "-shaders":[
                      { "ProgramShader":
                        {
                          "@DEF":"TestShader1",
                          "-programs":[
                            { "ShaderProgram":
                              {
                                "@DEF":"TestShader2",
                                "@type":"VERTEX"
                              }
                            }
                          ]
                        }
                      },
                      { "ProtoInstance":
                        {
                          "@name":"ShaderProto",
                          "@DEF":"TestShader3"
                        }
                      },
                      { "ComposedShader":
                        {
                          "@DEF":"TestShader4",
                          "-parts":[
                            { "ShaderPart":
                              {
                                "@DEF":"TestShader5",
                                "@type":"VERTEX"
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
            }
          },
          { "Transform":
            {
              "@DEF":"SpecialtyNodes",
              "-children":[
                { "CADLayer":
                  {
                    "-children":[
                      { "CADAssembly":
                        {
                          "-children":[
                            { "CADPart":
                              {
                                "-children":[
                                  { "CADFace":
                                    {
                                    }
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                },
                { "EspduTransform":
                  {
                  }
                },
                { "ReceiverPdu":
                  {
                  }
                },
                { "SignalPdu":
                  {
                  }
                },
                { "TransmitterPdu":
                  {
                  }
                },
                { "DISEntityManager":
                  {
                    "-children":[
                      { "DISEntityTypeMapping":
                        {
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          { "EspduTransform":
            {
              "-children":[
                { "WorldInfo":
                  {
                  }
                }
              ]
            }
          },
          { "ReceiverPdu":
            {
            }
          },
          { "SignalPdu":
            {
            }
          },
          { "TransmitterPdu":
            {
            }
          },
          { "DISEntityManager":
            {
              "-children":[
                { "DISEntityTypeMapping":
                  {
                  }
                }
              ]
            }
          },
          { "LoadSensor":
            {
              "-children":[
                {
                  "#comment":"Contained nodes typically must be USE references for nodes previously DEFined in the scene"
                },
                {
                  "#comment":"The following nodes are test cases for all X3DUrlObject nodes"
                },
                { "Anchor":
                  {
                    "@USE":"siteAnchor"
                  }
                },
                { "Inline":
                  {
                    "@USE":"inlineScene"
                  }
                },
                { "DISEntityTypeMapping":
                  {
                  }
                },
                { "GeoMetadata":
                  {
                  }
                },
                { "AudioClip":
                  {
                  }
                },
                { "ImageCubeMapTexture":
                  {
                  }
                },
                { "ImageTexture3D":
                  {
                  }
                },
                { "ImageTexture":
                  {
                  }
                },
                { "MovieTexture":
                  {
                  }
                },
                { "Script":
                  {
                    "@DEF":"DummyScript",
                    "#sourceCode":[
"",
"",
"ecmascript:",
"/* dummy test source code */",
"",
""
]
                  }
                },
                { "PackagedShader":
                  {
                  }
                },
                { "ShaderPart":
                  {
                    "@type":"VERTEX"
                  }
                },
                { "ShaderProgram":
                  {
                    "@type":"VERTEX"
                  }
                }
              ]
            }
          },
          { "OrthoViewpoint":
            {
              "@DEF":"SpecialTestOrthoViewpoint",
              "@fieldOfView":[1,3,2,4]
            }
          }
        ]
    }
  }
}

===========================================
Create Python source of model using stylesheet X3dToPython.xslt
Note: toFileStylesheetConversion(X3dToPython.xslt) is overwriting prior file SmokeTestProgramOutput.py
*** error in X3D4 model, overriding MetadataString DEF='FindableMetadataStringTest' having containerField='value' with corrected containerField='metadata' since  parent node is Shape ... please fix original X3D model
helloWorld.toFilePython("SmokeTestProgramOutput.py") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.py
Test toStringPython()

*** error in X3D4 model, overriding MetadataString DEF='FindableMetadataStringTest' having containerField='value' with corrected containerField='metadata' since  parent node is Shape ... please fix original X3D model
####################################################################################################
#
# Invoking X3D model self-test:
#
#   $ python SmokeTestProgramOutput.py
#
# Python package x3d.py package is available on PyPI for import.
#   This approach simplifies Python X3D deployment and use.
#   https://pypi.org/project/x3d
#
# Installation:
#       pip install x3d
# or
#       python -m pip install x3d
#
# Developer options for loading x3d package in other Python programs:
#
#    from x3d import *  # preferred approach, terser source that avoids x3d.* class
prefixes
#
# or
#    import x3d         # traditional way to subclass x3d package, all classes require
x3d.* prefix,
#                       # but python source is very verbose, for example x3d.Material
x3d.Shape etc.
#                       # X3dToPython.xslt stylesheet insertPackagePrefix=true supports
this option.
#
####################################################################################################

from x3d import *

newModel=X3D(class_='x3dModel.class',id_='x3dModel.id',profile='Full',style_='x3dModel.style',version='4.0',
  #  X3D model top-level comment 
head=head(
  children=[
    #  comment #1 
    #  comment #2 
    #  comment #3 
    #  comment #4 
component(name='Navigation',level=3),
component(name='Shaders',level=1),
component(name='CADGeometry',level=2),
component(name='DIS',level=2),
component(name='HAnim',level=1),
component(name='Grouping',level=1),
component(name='Layering',level=1),
unit(name='AngleUnitConversion',category='angle',conversionFactor=1.0),
unit(name='LengthUnitConversion',category='length',conversionFactor=1.0),
unit(name='ForceFromPoundsToNewtons',category='force',conversionFactor=4.4482),
meta(content='SmokeTestProgramOutput.x3d',name='title'),
meta(content='continued development and testing in progress',name='info'),
meta(content='Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access
Interface Library (X3DJSAIL)',name='description'),
meta(content='https://www.web3d.org/specifications/java/X3DJSAIL.html',name='reference'),
meta(content='SmokeTestProgramOutput.java',name='generator'),
meta(content='6 September 2016',name='created'),
meta(content='28 November 2025',name='modified'),
meta(content='X3D Java Scene Access Interface Library (X3DJSAIL)',name='generator'),
meta(content='https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java',name='generator'),
meta(content='Netbeans https://www.netbeans.org',name='generator'),
meta(content='Don Brutzman',name='creator'),
meta(content='https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d',name='reference'),
meta(content='Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:',name='reference'),
meta(content='SmokeTestProgramOutput.txt',name='reference'),
meta(content='SmokeTestProgramOutput.x3dv',name='reference'),
meta(content='SmokeTestProgramOutput.wrl',name='reference'),
meta(content='SmokeTestProgramOutput.html',name='reference'),
meta(content='https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d',name='reference'),
meta(content='https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d',name='identifier'),
meta(content='../license.html',name='license')]),
Scene=Scene(
children=[
MetadataSet(name='topLevelSceneMetadata'),
ViewpointGroup(description='Available viewpoints',
children=[
Viewpoint(DEF='DefaultView',description='Hello X3DJSAIL'),
Viewpoint(DEF='TopDownView',description='top-down view from above',orientation=(1,0,0,-1.570796),position=(0,100,0))]),
NavigationInfo(type=["EXAMINE","FLY","ANY"]),
WorldInfo(DEF='WorldInfoDEF',class_='worldInfoNode.class',id_='worldInfoNode.id',style_='worldInfoNode.style',title='SmokeTestProgram
produced by X3D Java SAI Library (X3DJSAIL)'),
WorldInfo(USE='WorldInfoDEF'),
WorldInfo(USE='WorldInfoDEF'),
MetadataString(DEF='scene.addChildMetadata',name='test',value=["Top-level root Metadata node beneath
Scene needs to be one of \'-children\' in JSON encoding"]),
LayerSet(DEF='scene.addChildLayerSetTest'),
Transform(DEF='LogoGeometryTransform',translation=(0,1.5,0),
children=[
Anchor(DEF='siteAnchor',description='select for X3D Java SAI Library (X3DJSAIL) description',url=["../X3DJSAIL.html","https://www.web3d.org/specifications/java/X3DJSAIL.html"],
children=[
Shape(DEF='BoxShape',id_='BoxShapeID',
appearance=Appearance(
material=Material(DEF='GreenMaterial',diffuseColor=(0,1,1),emissiveColor=(0.8,0,0),transparency=0.1),
texture=ImageTexture(url=["images/X3dJavaSceneAccessInterfaceSaiLibrary.png","https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png"])),
geometry=Box(DEF='test-NMTOKEN_regex.0123456789',class_='untextured'))])]),
Shape(DEF='LineShape',
appearance=Appearance(
material=Material(emissiveColor=(0.6,0.19607843,0.8))),
geometry=IndexedLineSet(coordIndex=[0,1,2,3,4,0],
        #  Coordinate 3-tuple point count: 6 
coord=Coordinate(point=[(0,1.5,0),(2,1.5,0),(2,1.5,-2),(-2,1.5,-2),(-2,1.5,0),(0,1.5,0)]))),
PositionInterpolator(DEF='BoxPathAnimator',key=[0,0.125,0.375,0.625,0.875,1],keyValue=[(0,1.5,0),(2,1.5,0),(2,1.5,-2),(-2,1.5,-2),(-2,1.5,0),(0,1.5,0)]),
TimeSensor(DEF='OrbitClock',cycleInterval=8.0,loop=True),
ROUTE(fromField='fraction_changed',fromNode='OrbitClock',toField='set_fraction',toNode='BoxPathAnimator'),
ROUTE(fromField='value_changed',fromNode='BoxPathAnimator',toField='set_translation',toNode='LogoGeometryTransform'),
Transform(DEF='TextTransform',translation=(0,-1.5,0),
children=[
Shape(
appearance=Appearance(
material=Material(USE='GreenMaterial')),
geometry=Text(string=["X3D Java","SAI Library","X3DJSAIL"],
          #  Comment example A, plain quotation marks: He said, "Immel did it!" 
          #  Comment example B, XML character entities: He said, &amp;quot;Immel did it!&amp;quot; 
metadata=MetadataSet(name='EscapedQuotationMarksMetadataSet',
value=[
MetadataString(name='quotesTestC',value=["MFString example C, backslash-escaped quotes: He said,
\"Immel did it!\""]),
MetadataString(name='extraChildTest',value=["checks MetadataSet addValue() method"])]),
fontStyle=FontStyle(justify=["MIDDLE","MIDDLE"]))),
Collision(
        #  test containerField='proxy' 
children=[
Shape(DEF='ProxyShape',
          #  alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&amp;quot;Immel
did it!\&amp;quot;"' 
          #  alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&amp;quot;Immel
did it!\&amp;quot;" ""' 
          #  alternative Java source: .setString(new String [] {"One, Two, Comment", "", "He said,
\"Immel did it!\""}) 
          #  reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html

geometry=Text(string=["One, Two, Text","","He said, \"Immel did it!\" \"\""]))])]
      #  It's a beautiful world 
      #  ... for you! 
      #  https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song) 
),
    #  repeatedly spin 180 degrees as a readable special effect 
OrientationInterpolator(DEF='SpinInterpolator',key=[0,0.5,1],keyValue=[(0,1,0,4.712389),(0,1,0,0),(0,1,0,1.5707964)]),
TimeSensor(DEF='SpinClock',cycleInterval=5.0,loop=True),
ROUTE(fromField='fraction_changed',fromNode='SpinClock',toField='set_fraction',toNode='SpinInterpolator'),
ROUTE(fromField='value_changed',fromNode='SpinInterpolator',toField='rotation',toNode='TextTransform'),
Group(DEF='BackgroundGroup',
children=[
Background(DEF='GradualBackground'),
Script(DEF='colorTypeConversionScript',
field=[
field(name='colorInput',accessType='inputOnly',type='SFColor'),
field(name='colorsOutput',accessType='outputOnly',type='MFColor')],

sourceCode="""
ecmascript:

function colorInput (eventValue) // Example source code
{
colorsOutput = new MFColor(eventValue); // assigning value sends output event
// Browser.print('colorInput=' + eventValue + ',
//                colorsOutput=' + colorsOutput + '
');
// TODO check line wrapping when exporting/converting
}
"""),
ColorInterpolator(DEF='ColorAnimator',key=[0,0.5,1],keyValue=[(0.9411765,1,1),(0.29411766,0,0.50980395),(0.9411765,1,1)],
        #  AZURE to INDIGO and back again 
),
TimeSensor(DEF='ColorClock',cycleInterval=60.0,loop=True),
ROUTE(fromField='colorsOutput',fromNode='colorTypeConversionScript',toField='skyColor',toNode='GradualBackground'),
ROUTE(fromField='value_changed',fromNode='ColorAnimator',toField='colorInput',toNode='colorTypeConversionScript'),
ROUTE(fromField='fraction_changed',fromNode='ColorClock',toField='set_fraction',toNode='ColorAnimator')]),
ProtoDeclare(name='ArtDeco01',appinfo='tooltip: ArtDeco01Material prototype is a Material node',
ProtoInterface=ProtoInterface(
field=[
field(name='description',accessType='inputOutput',appinfo='tooltip for descriptionField',type='SFString',value='ArtDeco01Material
prototype is a Material node'),
field(name='enabled',accessType='inputOutput',type='SFBool',value=True)]),
ProtoBody=ProtoBody(
        #  Initial node of ProtoBody determines prototype node type 
children=[
Material(ambientIntensity=0.25,diffuseColor=(0.282435,0.085159,0.134462),shininess=0.127273,specularColor=(0.276305,0.11431,0.139857)),
        #  [SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()="Material"

        #  presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody
after initial node, regardless of node types 
TouchSensor(description='within ProtoBody',
IS=IS(
connect=[
connect(nodeField='description',protoField='description'),
connect(nodeField='enabled',protoField='enabled')]))])),
ExternProtoDeclare(name='ArtDeco02',appinfo='this is a different Material node',url=["https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"],
      #  [SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE:
ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time.
TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare
file." 
field=[
field(name='description',accessType='inputOutput',appinfo='tooltip for descriptionField',type='SFString')]),
    #  Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when
ProtoInstance is added in wrong place 
Shape(DEF='TestShape1',
appearance=Appearance(DEF='TestAppearance1',
        #  ArtDeco01Material prototype goes here... 
material=ProtoInstance(name='ArtDeco01',
          #  [SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()="Material" 
fieldValue=[
fieldValue(name='description',value='ArtDeco01Material can substitute for a Material node')])),
geometry=Sphere(radius=0.001)),
Shape(DEF='TestShape2',
appearance=Appearance(DEF='TestAppearance2',
        #  ArtDeco02Material ProtoInstance goes here... 
material=ProtoInstance(DEF='ArtDeco02MaterialDEF',name='ArtDeco02',
          #  [SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE:
ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time.
TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare
file." 
)),
geometry=Cone(bottomRadius=0.001,height=0.001)),
Shape(DEF='TestShape3',
appearance=Appearance(DEF='TestAppearance3',
        #  ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as
part of ProtoInstance USE. 
material=ProtoInstance(USE='ArtDeco02MaterialDEF',name='ArtDeco02')),
geometry=Cylinder(height=0.001,radius=0.001)),
Inline(DEF='inlineScene',url=["newScene.x3d","https://www.web3d.org/specifications/java/examples/newScene.x3d"]),
IMPORT(AS='WorldInfoDEF2',importedDEF='WorldInfoDEF',inlineDEF='inlineScene'),
EXPORT(AS='WorldInfoDEF3',localDEF='WorldInfoDEF'),
ProtoDeclare(name='MaterialModulator',appinfo='mimic a Material node and modulate fields as an
animation effect',documentation='https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html',
ProtoInterface=ProtoInterface(
field=[
field(name='enabled',accessType='inputOutput',type='SFBool',value=True),
field(name='diffuseColor',accessType='inputOutput',type='SFColor',value=(0,0,0)),
field(name='emissiveColor',accessType='inputOutput',type='SFColor',value=(0.05,0.05,0.5)),
field(name='specularColor',accessType='inputOutput',type='SFColor',value=(0,0,0)),
field(name='transparency',accessType='inputOutput',type='SFFloat',value=0.0),
field(name='shininess',accessType='inputOutput',type='SFFloat',value=0.0),
field(name='ambientIntensity',accessType='inputOutput',type='SFFloat',value=0.0)]),
ProtoBody=ProtoBody(
children=[
Material(DEF='MaterialNode',
IS=IS(
connect=[
connect(nodeField='diffuseColor',protoField='diffuseColor'),
connect(nodeField='emissiveColor',protoField='emissiveColor'),
connect(nodeField='specularColor',protoField='specularColor'),
connect(nodeField='transparency',protoField='transparency'),
connect(nodeField='shininess',protoField='shininess'),
connect(nodeField='ambientIntensity',protoField='ambientIntensity')])),
        #  Only first node (the node type for the prototype) is renderable, others are along
for the ride 
Script(DEF='MaterialModulatorScript',
field=[
field(name='enabled',accessType='inputOutput',type='SFBool'),
field(name='diffuseColor',accessType='inputOutput',type='SFColor'),
field(name='newColor',accessType='outputOnly',type='SFColor'),
field(name='clockTrigger',accessType='inputOnly',type='SFTime')],
IS=IS(
connect=[
connect(nodeField='enabled',protoField='enabled'),
connect(nodeField='diffuseColor',protoField='diffuseColor')]),

sourceCode="""
ecmascript:
function initialize ()
{
newColor = diffuseColor; // start with correct color
}
function set_enabled (newValue)
{
	enabled = newValue;
}
function clockTrigger (timeValue)
{
if (!enabled) return;
red   = newColor.r;
green = newColor.g;
blue  = newColor.b;

// note different modulation rates for each color component, % is modulus operator
newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);
	if (enabled)
	{
		Browser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor='
+ newColor.toString() + '\n');
	}
}
""")])),
    #  Test success: declarative statement createDeclarativeShapeTests() 
Group(DEF='DeclarativeGroupExample',
children=[
Shape(
metadata=MetadataString(DEF='FindableMetadataStringTest',name='findThisNameValue',value=["test case"]),
appearance=Appearance(DEF='DeclarativeAppearanceExample',
          #  DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator
ProtoInstance 
material=ProtoInstance(DEF='MyMaterialModulator',name='MaterialModulator')),
geometry=Cone(bottom=False,bottomRadius=0.05,height=0.1))]
      #  Test success: declarativeGroup.addChild() singleton pipeline method 
),
    #  Test success: declarative statement addChild() 
    #  Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = &lt;Appearance
DEF='DeclarativeAppearanceExample'/&gt; i.e. &lt;Appearance DEF='DeclarativeAppearanceExample'&gt;
&lt;!- - DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator
ProtoInstance - -&gt; &lt;ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator'
containerField='material'/&gt; &lt;/Appearance&gt; 
    #  Test success: x3dModel.findElementByNameValue(findThisNameValue) = &lt;MetadataString
DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/&gt; 
    #  Test success: x3dModel.findElementByNameValue("ArtDeco01", "ProtoDeclare") found

    #  Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoDeclare")
found 
    #  Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoInstance")
found 
Group(DEF='TestFieldObjectsGroup',
      #  testFieldObjects() results 
      #  SFBool default=false, true=true, false=false, negate()=true 
      #  MFBool default=, initial=true false true, negate()=false true false 
      #  SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0

      #  MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5,
append(6)=0 1 2 3 4 5 6, size()=7 
      #  ... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20
4 6 8 10 12, clear= 
      #  SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232
0.5698029 0.68376344, regex matches()=true 
      #  regex test SFVec3f().matches("1 2 3")=true, regex test SFVec3f().matches("1 2 3 4")=false,
regex test (SFRotation.matches("0 0 0 0")=true, failure detecting illegal (zero axis)
rotation value 
),
Sound(location=(0,1.6,0),
      #  set sound-ellipsoid location height at 1.6m to match typical avatar height 
source=AudioClip(description='chimes',url=["chimes.wav","https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav"],
        #  Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d

)),
Sound(location=(0,1.6,0),
      #  set sound-ellipsoid location height at 1.6m to match typical avatar height 
source=MovieTexture(description='mpgsys.mpg from ConformanceNist suite',url=["mpgsys.mpg","https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg"],
        #  Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d

        #  Expected containerField='source', allowed containerField values="texture" "source"
"back" "bottom" "front" "left" "right" "top" "backTexture" "bottomTexture" "frontTexture"
"leftTexture" "rightTexture" "topTexture" "children" 
)),
    #  Test success: Anchor.isNode()=true, siteAnchor.isNode()=true 
    #  Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false 
    #  Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false 
    #  Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true 
    #  Test success: CommentsBlock.isNode()=false, testComments.isNode()=false 
    #  Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true 
Shape(DEF='ExtrusionShape',
      #  ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0,
-1.0, -1.0, -1.0, 1.0, 1.0, 1.0]' 
      #  ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]' 
appearance=Appearance(DEF='TransparentAppearance',
material=Material(transparency=1.0)),
geometry=Extrusion(DEF='ExampleExtrusion')),
Group(
      #  Test MFNode children array as an ordered list consisting of comments, statements,
ProtoInstance and nodes 
children=[
ProtoDeclare(name='NewWorldInfo',
ProtoInterface=ProtoInterface(
field=[
field(name='description',accessType='initializeOnly',type='SFString')]),
ProtoBody=ProtoBody(
children=[
WorldInfo(),])),
ProtoInstance(DEF='Proto1',name='NewWorldInfo',
fieldValue=[
fieldValue(name='description',value='testing 1 2 3')]),
Group(DEF='Node2',
        #  intentionally empty 
),
ProtoInstance(DEF='Proto3',name='NewWorldInfo'),
Transform(DEF='Node4',
        #  intentionally empty 
)]
      #  Test satisfactorily creates MFNode children array as an ordered list with mixed content

),
ProtoDeclare(name='ShaderProto',
ProtoBody=ProtoBody(
children=[
ProgramShader(),])),
Shape(
appearance=Appearance(
        #  Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance
and nodes 
        #  Test satisfactorily creates MFNode shaders array as an ordered list with mixed content

shaders=[
ProgramShader(DEF='TestShader1',
programs=[
ShaderProgram(DEF='TestShader2')]),
ProtoInstance(DEF='TestShader3',name='ShaderProto'),
ComposedShader(DEF='TestShader4',
parts=[
ShaderPart(DEF='TestShader5')])])),
Transform(DEF='SpecialtyNodes',
children=[
CADLayer(
children=[
CADAssembly(
children=[
CADPart(
children=[
CADFace(),])])]),
EspduTransform(),
ReceiverPdu(receivedPower=0.0),
SignalPdu(),
TransmitterPdu(relativeAntennaLocation=(0,0,0),transmitFrequencyBandwidth=0.0),
DISEntityManager(
children=[
DISEntityTypeMapping(),])]),
EspduTransform(
children=[
WorldInfo(),]),
ReceiverPdu(receivedPower=0.0),
SignalPdu(),
TransmitterPdu(relativeAntennaLocation=(0,0,0),transmitFrequencyBandwidth=0.0),
DISEntityManager(
children=[
DISEntityTypeMapping(),]),
LoadSensor(
      #  Contained nodes typically must be USE references for nodes previously DEFined in
the scene 
      #  The following nodes are test cases for all X3DUrlObject nodes 
children=[
Anchor(USE='siteAnchor'),
Inline(USE='inlineScene'),
DISEntityTypeMapping(),
GeoMetadata(),
AudioClip(),
ImageCubeMapTexture(),
ImageTexture3D(),
ImageTexture(),
MovieTexture(),
Script(DEF='DummyScript'),
PackagedShader(),
ShaderPart(),
ShaderProgram(),]),
OrthoViewpoint(DEF='SpecialTestOrthoViewpoint',fieldOfView=(1,3,2,4))])
) # X3D model complete

####################################################################################################
# Self-test diagnostics
####################################################################################################

print('Self-test diagnostics for SmokeTestProgramOutput.py:')
if        metaDiagnostics(newModel): # built-in utility method in X3D class
print(metaDiagnostics(newModel)) # display meta info, hint, warning, error, TODO values
in this model
# print('check newModel.XML() serialization...')
newModelXML= newModel.XML() # test export method XML() for exceptions during export
newModel.XMLvalidate()
# print(newModelXML) # diagnostic

try:
#   print('check newModel.VRML() serialization...')
newModelVRML=newModel.VRML() # test export method VRML() for exceptions during export
# print(prependLineNumbers(newModelVRML)) # debug
print("Python-to-VRML export of VRML output successful", flush=True)
except Exception as err: # usually BaseException
# https://stackoverflow.com/questions/18176602/how-to-get-the-name-of-an-exception-that-was-caught-in-python
print("*** Python-to-VRML export of VRML output failed:", type(err).__name__, err)
if newModelVRML: # may have failed to generate
print(prependLineNumbers(newModelVRML, err.lineno))

try:
#   print('check newModel.JSON() serialization...')
newModelJSON=newModel.JSON() # test export method JSON() for exceptions during export
#   print(prependLineNumbers(newModelJSON)) # debug
print("Python-to-JSON export of JSON output successful (under development)")
except Exception as err: # usually SyntaxError
print("*** Python-to-JSON export of JSON output failed:", type(err).__name__, err)
if newModelJSON: # may have failed to generate
print(prependLineNumbers(newModelJSON,err.lineno))

print("python SmokeTestProgramOutput.py load and self-test diagnostics complete.")

===========================================
Create displayable scene page rendered with X3DOM using stylesheet X3dToX3domX_ITE.xslt
Note: toFileStylesheetConversion(X3dToX3domX_ITE.xslt) is overwriting prior file SmokeTestProgramOutputX3dom.xhtml
helloWorld.toFileX3DOM("SmokeTestProgramOutputX3dom.xhtml") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutputX3dom.xhtml
===========================================
Create displayable scene page rendered with X_ITE (formerly Cobweb) using stylesheet X3dToX3domX_ITE.xslt
Note: toFileStylesheetConversion(X3dToX3domX_ITE.xslt) is overwriting prior file SmokeTestProgramOutputX_ITE.html
helloWorld.toFileX3DOM("SmokeTestProgramOutputX_ITE.html") success: true
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutputX_ITE.html
===========================================
Reload and provide text output using Java DOM, which includes default attribute values
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
===========================================
Test success: x3dLoader.loadX3DfromXML(SmokeTestProgramOutput.x3d), x3dLoader.getX3dObjectTree()
===========================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "https://www.web3d.org/specifications/x3d-3.3.dtd">
<X3D class='x3dModel.class' id='x3dModel.id' profile='Full' style='x3dModel.style' version='4.0' xmlns:ds='https://www.web3d.org/2000/09/xmldsig#' xmlns:xenc='https://www.web3d.org/2001/04/xmlenc#' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'>
  <!-- X3D model top-level comment -->
  <head>
    <!-- comment #1 -->
    <!-- comment #2 -->
    <!-- comment #3 -->
    <!-- comment #4 -->
    <component level='3' name='Navigation'/>
    <component level='1' name='Shaders'/>
    <component level='2' name='CADGeometry'/>
    <component level='2' name='DIS'/>
    <component level='1' name='HAnim'/>
    <component level='1' name='Grouping'/>
    <component level='1' name='Layering'/>
    <unit category='angle' conversionFactor='1.0' name='AngleUnitConversion'/>
    <unit category='length' conversionFactor='1.0' name='LengthUnitConversion'/>
    <unit category='force' conversionFactor='4.4482' name='ForceFromPoundsToNewtons'/>
    <meta content='SmokeTestProgramOutput.x3d' name='title'/>
    <meta content='continued development and testing in progress' name='info'/>
    <meta content='Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface Library (X3DJSAIL)' name='description'/>
    <meta content='https://www.web3d.org/specifications/java/X3DJSAIL.html' name='reference'/>
    <meta content='SmokeTestProgramOutput.java' name='generator'/>
    <meta content='6 September 2016' name='created'/>
    <meta content='28 November 2025' name='modified'/>
    <meta content='X3D Java Scene Access Interface Library (X3DJSAIL)' name='generator'/>
    <meta content='https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java' name='generator'/>
    <meta content='Netbeans https://www.netbeans.org' name='generator'/>
    <meta content='Don Brutzman' name='creator'/>
    <meta content='https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d' name='reference'/>
    <meta content='Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation:' name='reference'/>
    <meta content='SmokeTestProgramOutput.txt' name='reference'/>
    <meta content='SmokeTestProgramOutput.x3dv' name='reference'/>
    <meta content='SmokeTestProgramOutput.wrl' name='reference'/>
    <meta content='SmokeTestProgramOutput.html' name='reference'/>
    <meta content='https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d' name='reference'/>
    <meta content='https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d' name='identifier'/>
    <meta content='../license.html' name='license'/>
  </head>
  <Scene>
    <MetadataSet containerField='value' name='topLevelSceneMetadata'/>
    <ViewpointGroup center='0 0 0' containerField='children' description='Available viewpoints' displayed='true' retainUserOffsets='false' size='0 0 0'>
      <Viewpoint DEF='DefaultView' centerOfRotation='0 0 0' containerField='children' description='Hello X3DJSAIL' farDistance='-1' fieldOfView='0.7854' jump='true' nearDistance='-1' orientation='0 0 1 0' position='0 0 10' retainUserOffsets='false' viewAll='false'/>
      <Viewpoint DEF='TopDownView' centerOfRotation='0 0 0' containerField='children' description='top-down view from above' farDistance='-1' fieldOfView='0.7854' jump='true' nearDistance='-1' orientation='1 0 0 -1.570796' position='0 100 0' retainUserOffsets='false' viewAll='false'/>
    </ViewpointGroup>
    <NavigationInfo avatarSize='0.25 1.6 0.75' containerField='children' headlight='true' speed='1' transitionTime='1.0' transitionType='"LINEAR"' type='"EXAMINE" "FLY" "ANY"' visibilityLimit='0'/>
    <WorldInfo DEF='WorldInfoDEF' class='worldInfoNode.class' containerField='children' id='worldInfoNode.id' style='worldInfoNode.style' title='SmokeTestProgram produced by X3D Java SAI Library (X3DJSAIL)'/>
    <WorldInfo USE='WorldInfoDEF' containerField='children'/>
    <WorldInfo USE='WorldInfoDEF' containerField='children'/>
    <MetadataString DEF='scene.addChildMetadata' containerField='value' name='test' value='"Top-level root Metadata node beneath Scene needs to be one of '-children' in JSON encoding"'/>
    <LayerSet DEF='scene.addChildLayerSetTest' activeLayer='0' containerField='children' order='0'/>
    <Transform DEF='LogoGeometryTransform' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' center='0 0 0' containerField='children' rotation='0 0 1 0' scale='1 1 1' scaleOrientation='0 0 1 0' translation='0 1.5 0' visible='true'>
      <Anchor DEF='siteAnchor' autoRefresh='0' autoRefreshTimeLimit='3600' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' description='select for X3D Java SAI Library (X3DJSAIL) description' load='true' url='"../X3DJSAIL.html" "https://www.web3d.org/specifications/java/X3DJSAIL.html"' visible='true'>
        <Shape DEF='BoxShape' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' id='BoxShapeID' visible='true'>
          <Appearance alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
            <Material DEF='GreenMaterial' ambientIntensity='0.2' containerField='material' diffuseColor='0 1 1' emissiveColor='0.8 0 0' normalScale='1' occlusionStrength='1' shininess='0.2' specularColor='0 0 0' transparency='0.1'/>
            <ImageTexture autoRefresh='0' autoRefreshTimeLimit='3600' containerField='texture' load='true' repeatS='true' repeatT='true' url='"images/X3dJavaSceneAccessInterfaceSaiLibrary.png" "https://www.web3d.org/specifications/java/examples/images/X3dJavaSceneAccessInterfaceSaiLibrary.png"'/>
          </Appearance>
          <Box DEF='test-NMTOKEN_regex.0123456789' class='untextured' containerField='geometry' size='2 2 2' solid='true'/>
        </Shape>
      </Anchor>
    </Transform>
    <Shape DEF='LineShape' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
      <Appearance alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
        <Material ambientIntensity='0.2' containerField='material' diffuseColor='0.8 0.8 0.8' emissiveColor='0.6 0.19607843 0.8' normalScale='1' occlusionStrength='1' shininess='0.2' specularColor='0 0 0' transparency='0'/>
      </Appearance>
      <IndexedLineSet colorPerVertex='true' containerField='geometry' coordIndex='0 1 2 3 4 0'>
        <!-- Coordinate 3-tuple point count: 6 -->
        <Coordinate containerField='coord' point='0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0'/>
      </IndexedLineSet>
    </Shape>
    <PositionInterpolator DEF='BoxPathAnimator' containerField='children' key='0 0.125 0.375 0.625 0.875 1' keyValue='0 1.5 0 2 1.5 0 2 1.5 -2 -2 1.5 -2 -2 1.5 0 0 1.5 0'/>
    <TimeSensor DEF='OrbitClock' containerField='children' cycleInterval='8.0' enabled='true' loop='true' pauseTime='0' resumeTime='0' startTime='0' stopTime='0'/>
    <ROUTE fromField='fraction_changed' fromNode='OrbitClock' toField='set_fraction' toNode='BoxPathAnimator'/>
    <ROUTE fromField='value_changed' fromNode='BoxPathAnimator' toField='set_translation' toNode='LogoGeometryTransform'/>
    <Transform DEF='TextTransform' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' center='0 0 0' containerField='children' rotation='0 0 1 0' scale='1 1 1' scaleOrientation='0 0 1 0' translation='0 -1.5 0' visible='true'>
      <Shape bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
        <Appearance alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
          <Material USE='GreenMaterial' ambientIntensity='0.2' containerField='material' diffuseColor='0.8 0.8 0.8' emissiveColor='0 0 0' normalScale='1' occlusionStrength='1' shininess='0.2' specularColor='0 0 0' transparency='0'/>
        </Appearance>
        <Text containerField='geometry' maxExtent='0.0' solid='false' string='"X3D Java" "SAI Library" "X3DJSAIL"'>
          <!-- Comment example A, plain quotation marks: He said, "Immel did it!" -->
          <!-- Comment example B, XML character entities: He said, &quot;Immel did it!&quot; -->
          <MetadataSet containerField='metadata' name='EscapedQuotationMarksMetadataSet'>
            <MetadataString containerField='value' name='quotesTestC' value='"MFString example C, backslash-escaped quotes: He said, \"Immel did it!\""'/>
            <MetadataString containerField='value' name='extraChildTest' value='"checks MetadataSet addValue() method"'/>
          </MetadataSet>
          <FontStyle containerField='fontStyle' family='"SERIF"' horizontal='true' justify='"MIDDLE" "MIDDLE"' leftToRight='true' size='1.0' spacing='1.0' style='PLAIN' topToBottom='true'/>
        </Text>
      </Shape>
      <Collision bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' enabled='true' visible='true'>
        <!-- test containerField='proxy' -->
        <Shape DEF='ProxyShape' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
          <!-- alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;"' -->
          <!-- alternative XML encoding: Text string='"One, Two, Comment" "" "He said, \&quot;Immel did it!\&quot;" ""' -->
          <!-- alternative Java source: .setString(new String [] {"One, Two, Comment", "", "He said, \"Immel did it!\""}) -->
          <!-- reference: https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/StringArrayEncodingExamplesIndex.html -->
          <Text containerField='geometry' maxExtent='0.0' solid='false' string='"One, Two, Text" "" "He said, \"Immel did it!\" \"\""'/>
        </Shape>
      </Collision>
      <!-- It's a beautiful world -->
      <!-- ... for you! -->
      <!-- https://en.wikipedia.org/wiki/Beautiful_World_(Devo_song) -->
    </Transform>
    <!-- repeatedly spin 180 degrees as a readable special effect -->
    <OrientationInterpolator DEF='SpinInterpolator' containerField='children' key='0 0.5 1' keyValue='0 1 0 4.712389 0 1 0 0 0 1 0 1.5707964'/>
    <TimeSensor DEF='SpinClock' containerField='children' cycleInterval='5.0' enabled='true' loop='true' pauseTime='0' resumeTime='0' startTime='0' stopTime='0'/>
    <ROUTE fromField='fraction_changed' fromNode='SpinClock' toField='set_fraction' toNode='SpinInterpolator'/>
    <ROUTE fromField='value_changed' fromNode='SpinInterpolator' toField='rotation' toNode='TextTransform'/>
    <Group DEF='BackgroundGroup' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'>
      <Background DEF='GradualBackground' containerField='children' skyColor='0 0 0' transparency='0'/>
      <Script DEF='colorTypeConversionScript' autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' directOutput='false' load='true' mustEvaluate='false'>
        <field accessType='inputOnly' name='colorInput' type='SFColor'/>
        <field accessType='outputOnly' name='colorsOutput' type='MFColor'/>
        <![CDATA[
ecmascript:

function colorInput (eventValue) // Example source code
{
   colorsOutput = new MFColor(eventValue); // assigning value sends output event
// Browser.print('colorInput=' + eventValue + ',
//                colorsOutput=' + colorsOutput + '
');
// TODO check line wrapping when exporting/converting
}

]]>
      </Script>
      <ColorInterpolator DEF='ColorAnimator' containerField='children' key='0 0.5 1' keyValue='0.9411765 1 1 0.29411766 0 0.50980395 0.9411765 1 1'>
        <!-- AZURE to INDIGO and back again -->
      </ColorInterpolator>
      <TimeSensor DEF='ColorClock' containerField='children' cycleInterval='60.0' enabled='true' loop='true' pauseTime='0' resumeTime='0' startTime='0' stopTime='0'/>
      <ROUTE fromField='colorsOutput' fromNode='colorTypeConversionScript' toField='skyColor' toNode='GradualBackground'/>
      <ROUTE fromField='value_changed' fromNode='ColorAnimator' toField='colorInput' toNode='colorTypeConversionScript'/>
      <ROUTE fromField='fraction_changed' fromNode='ColorClock' toField='set_fraction' toNode='ColorAnimator'/>
    </Group>
    <ProtoDeclare appinfo='tooltip: ArtDeco01Material prototype is a Material node' name='ArtDeco01'>
      <ProtoInterface>
        <field accessType='inputOutput' appinfo='tooltip for descriptionField' name='description' type='SFString' value='ArtDeco01Material prototype is a Material node'/>
        <field accessType='inputOutput' name='enabled' type='SFBool' value='true'/>
      </ProtoInterface>
      <ProtoBody>
        <!-- Initial node of ProtoBody determines prototype node type -->
        <Material ambientIntensity='0.25' containerField='material' diffuseColor='0.282435 0.085159 0.134462' emissiveColor='0 0 0' normalScale='1' occlusionStrength='1' shininess='0.127273' specularColor='0.276305 0.11431 0.139857' transparency='0'/>
        <!-- [SmokeTestProgram diagnostic] should be connected to scene graph: artDeco01ProtoDeclare.getNodeType()="Material" -->
        <!-- presence of follow-on TouchSensor shows that additional nodes are allowed in ProtoBody after initial node, regardless of node types -->
        <TouchSensor containerField='children' description='within ProtoBody' enabled='true'>
          <IS>
            <connect nodeField='description' protoField='description'/>
            <connect nodeField='enabled' protoField='enabled'/>
          </IS>
        </TouchSensor>
      </ProtoBody>
    </ProtoDeclare>
    <ExternProtoDeclare appinfo='this is a different Material node' name='ArtDeco02' url='"https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3d#ArtDeco02" "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter14Prototypes/ArtDecoPrototypesExcerpt.x3dv#ArtDeco02"'>
      <!-- [SmokeTestProgram diagnostic] artDeco02ExternProtoDeclare.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file." -->
      <field accessType='inputOutput' appinfo='tooltip for descriptionField' name='description' type='SFString'/>
    </ExternProtoDeclare>
    <!-- Tested ArtDeco01ProtoInstance, ArtDeco02ProtoInstance for improper node type when ProtoInstance is added in wrong place -->
    <Shape DEF='TestShape1' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
      <Appearance DEF='TestAppearance1' alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
        <!-- ArtDeco01Material prototype goes here... -->
        <ProtoInstance containerField='material' name='ArtDeco01'>
          <!-- [SmokeTestProgram diagnostic] ArtDeco01ProtoInstance.getNodeType()="Material" -->
          <fieldValue name='description' value='ArtDeco01Material can substitute for a Material node'/>
        </ProtoInstance>
      </Appearance>
      <Sphere containerField='geometry' radius='0.001' solid='true'/>
    </Shape>
    <Shape DEF='TestShape2' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
      <Appearance DEF='TestAppearance2' alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
        <!-- ArtDeco02Material ProtoInstance goes here... -->
        <ProtoInstance DEF='ArtDeco02MaterialDEF' containerField='material' name='ArtDeco02'>
          <!-- [SmokeTestProgram diagnostic] ArtDeco02ProtoInstance.getNodeType()="ERROR_UNKNOWN_EXTERNPROTODECLARE_NODE_TYPE: ExternProtoDeclare name='ArtDeco02' type cannot be remotely accessed at run time. TODO X3DJSAIL needs to add further capability that retrieves the ExternProtoDeclare file." -->
        </ProtoInstance>
      </Appearance>
      <Cone bottom='true' bottomRadius='0.001' containerField='geometry' height='0.001' side='true' solid='true'/>
    </Shape>
    <Shape DEF='TestShape3' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
      <Appearance DEF='TestAppearance3' alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
        <!-- ArtDeco02Material ProtoInstance USE goes here. Note that name field is REQUIRED as part of ProtoInstance USE. -->
        <ProtoInstance USE='ArtDeco02MaterialDEF' containerField='material' name='ArtDeco02'/>
      </Appearance>
      <Cylinder bottom='true' containerField='geometry' height='0.001' radius='0.001' side='true' solid='true' top='true'/>
    </Shape>
    <Inline DEF='inlineScene' autoRefresh='0' autoRefreshTimeLimit='3600' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' global='false' load='true' url='"newScene.x3d" "https://www.web3d.org/specifications/java/examples/newScene.x3d"' visible='true'/>
    <IMPORT AS='WorldInfoDEF2' importedDEF='WorldInfoDEF' inlineDEF='inlineScene'/>
    <EXPORT AS='WorldInfoDEF3' localDEF='WorldInfoDEF'/>
    <ProtoDeclare appinfo='mimic a Material node and modulate fields as an animation effect' documentation='https://x3dgraphics.com/examples/X3dForWebAuthors/Chapter14Prototypes/MaterialModulatorIndex.html' name='MaterialModulator'>
      <ProtoInterface>
        <field accessType='inputOutput' name='enabled' type='SFBool' value='true'/>
        <field accessType='inputOutput' name='diffuseColor' type='SFColor' value='0 0 0'/>
        <field accessType='inputOutput' name='emissiveColor' type='SFColor' value='0.05 0.05 0.5'/>
        <field accessType='inputOutput' name='specularColor' type='SFColor' value='0 0 0'/>
        <field accessType='inputOutput' name='transparency' type='SFFloat' value='0.0'/>
        <field accessType='inputOutput' name='shininess' type='SFFloat' value='0.0'/>
        <field accessType='inputOutput' name='ambientIntensity' type='SFFloat' value='0.0'/>
      </ProtoInterface>
      <ProtoBody>
        <Material DEF='MaterialNode' ambientIntensity='0.2' containerField='material' diffuseColor='0.8 0.8 0.8' emissiveColor='0 0 0' normalScale='1' occlusionStrength='1' shininess='0.2' specularColor='0 0 0' transparency='0'>
          <IS>
            <connect nodeField='diffuseColor' protoField='diffuseColor'/>
            <connect nodeField='emissiveColor' protoField='emissiveColor'/>
            <connect nodeField='specularColor' protoField='specularColor'/>
            <connect nodeField='transparency' protoField='transparency'/>
            <connect nodeField='shininess' protoField='shininess'/>
            <connect nodeField='ambientIntensity' protoField='ambientIntensity'/>
          </IS>
        </Material>
        <!-- Only first node (the node type for the prototype) is renderable, others are along for the ride -->
        <Script DEF='MaterialModulatorScript' autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' directOutput='false' load='true' mustEvaluate='false'>
          <field accessType='inputOutput' name='enabled' type='SFBool'/>
          <field accessType='inputOutput' name='diffuseColor' type='SFColor'/>
          <field accessType='outputOnly' name='newColor' type='SFColor'/>
          <field accessType='inputOnly' name='clockTrigger' type='SFTime'/>
          <IS>
            <connect nodeField='enabled' protoField='enabled'/>
            <connect nodeField='diffuseColor' protoField='diffuseColor'/>
          </IS>
          <![CDATA[
ecmascript:
function initialize ()
{
    newColor = diffuseColor; // start with correct color
}
function set_enabled (newValue)
{
	enabled = newValue;
}
function clockTrigger (timeValue)
{
    if (!enabled) return;
    red   = newColor.r;
    green = newColor.g;
    blue  = newColor.b;

    // note different modulation rates for each color component, % is modulus operator
    newColor = new SFColor ((red + 0.02) % 1, (green + 0.03) % 1, (blue + 0.04) % 1);
	if (enabled)
	{
		Browser.print ('diffuseColor=(' + red + ',' + green + ',' + blue + ') newColor=' + newColor.toString() + '\n');
	}
}
]]>
        </Script>
      </ProtoBody>
    </ProtoDeclare>
    <!-- Test success: declarative statement createDeclarativeShapeTests() -->
    <Group DEF='DeclarativeGroupExample' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'>
      <Shape bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
        <MetadataString DEF='FindableMetadataStringTest' containerField='value' name='findThisNameValue' value='"test case"'/>
        <Appearance DEF='DeclarativeAppearanceExample' alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
          <!-- DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance -->
          <ProtoInstance DEF='MyMaterialModulator' containerField='material' name='MaterialModulator'/>
        </Appearance>
        <Cone bottom='false' bottomRadius='0.05' containerField='geometry' height='0.1' side='true' solid='true'/>
      </Shape>
      <!-- Test success: declarativeGroup.addChild() singleton pipeline method -->
    </Group>
    <!-- Test success: declarative statement addChild() -->
    <!-- Test success: x3dModel.findNodeByDEF(DeclarativeAppearanceExample) = <Appearance DEF='DeclarativeAppearanceExample'/> i.e. <Appearance DEF='DeclarativeAppearanceExample'> <!- - DeclarativeMaterialExample gets overridden by subsequently added MaterialModulator ProtoInstance - -> <ProtoInstance DEF='MyMaterialModulator' name='MaterialModulator' containerField='material'/> </Appearance> -->
    <!-- Test success: x3dModel.findElementByNameValue(findThisNameValue) = <MetadataString DEF='FindableMetadataStringTest' name='findThisNameValue' value='"test case"'/> -->
    <!-- Test success: x3dModel.findElementByNameValue("ArtDeco01", "ProtoDeclare") found -->
    <!-- Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoDeclare") found -->
    <!-- Test success: x3dModel.findElementByNameValue("MaterialModulator", "ProtoInstance") found -->
    <Group DEF='TestFieldObjectsGroup' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'>
      <!-- testFieldObjects() results -->
      <!-- SFBool default=false, true=true, false=false, negate()=true -->
      <!-- MFBool default=, initial=true false true, negate()=false true false -->
      <!-- SFFloat default=0.0, initial=1.0, setValue(2)=2.0, setValue(3.0f)=3.0, setValue(4.0)=4.0 -->
      <!-- MFFloat default=, initial=1 2 3, append(5)=1 2 3 5, inserts(3,4)(0,0)=0 1 2 3 4 5, append(6)=0 1 2 3 4 5 6, size()=7 -->
      <!-- ... get1Value[3]=3.0, remove[1]=0 2 3 4 5 6, set1Value(0,10)=10 2 3 4 5 6, multiply(2)=20 4 6 8 10 12, clear= -->
      <!-- SFVec3f default=0 0 0, initial=1 2 3, setValue=4 5 6, multiply(2)=8 10 12, normalize()=0.45584232 0.5698029 0.68376344, regex matches()=true -->
      <!-- regex test SFVec3f().matches("1 2 3")=true, regex test SFVec3f().matches("1 2 3 4")=false, regex test (SFRotation.matches("0 0 0 0")=true, failure detecting illegal (zero axis) rotation value -->
    </Group>
    <Sound containerField='children' direction='0 0 1' enabled='true' intensity='1' location='0 1.6 0' maxBack='10' maxFront='10' minBack='1' minFront='1' priority='0' spatialize='true'>
      <!-- set sound-ellipsoid location height at 1.6m to match typical avatar height -->
      <AudioClip autoRefresh='0' autoRefreshTimeLimit='3600' containerField='source' description='chimes' enabled='true' gain='1' load='true' loop='false' pauseTime='0' pitch='1.0' resumeTime='0' startTime='0' stopTime='0' url='"chimes.wav" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/chimes.wav"'>
        <!-- Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Sounds/AudioClip/default.x3d -->
      </AudioClip>
    </Sound>
    <Sound containerField='children' direction='0 0 1' enabled='true' intensity='1' location='0 1.6 0' maxBack='10' maxFront='10' minBack='1' minFront='1' priority='0' spatialize='true'>
      <!-- set sound-ellipsoid location height at 1.6m to match typical avatar height -->
      <MovieTexture autoRefresh='0' autoRefreshTimeLimit='3600' containerField='source' description='mpgsys.mpg from ConformanceNist suite' load='true' loop='false' pauseTime='0' pitch='1.0' repeatS='true' repeatT='true' resumeTime='0' speed='1.0' startTime='0' stopTime='0' url='"mpgsys.mpg" "https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpgsys.mpg"'>
        <!-- Scene example fragment from https://www.web3d.org/x3d/content/examples/ConformanceNist/Appearance/MovieTexture/mpeg1-systems.x3d -->
        <!-- Expected containerField='source', allowed containerField values="texture" "source" "back" "bottom" "front" "left" "right" "top" "backTexture" "bottomTexture" "frontTexture" "leftTexture" "rightTexture" "topTexture" "children" -->
      </MovieTexture>
    </Sound>
    <!-- Test success: Anchor.isNode()=true, siteAnchor.isNode()=true -->
    <!-- Test success: Anchor.isStatement()=false, siteAnchor.isStatement()=false -->
    <!-- Test success: ROUTE.isNode()=false, orbitPositionROUTE.isNode()=false -->
    <!-- Test success: ROUTE.isStatement()=true, orbitPositionROUTE.isStatement()=true -->
    <!-- Test success: CommentsBlock.isNode()=false, testComments.isNode()=false -->
    <!-- Test failure: CommentsBlock.isStatement()=true, testComments.isStatement()=true -->
    <Shape DEF='ExtrusionShape' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
      <!-- ExampleExtrusion isCrossSectionClosed()=true, crossSection='[1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]' -->
      <!-- ExampleExtrusion isSpineClosed()=false, spine='[0.0, 0.0, 0.0, 0.0, 1.0, 0.0]' -->
      <Appearance DEF='TransparentAppearance' alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
        <Material ambientIntensity='0.2' containerField='material' diffuseColor='0.8 0.8 0.8' emissiveColor='0 0 0' normalScale='1' occlusionStrength='1' shininess='0.2' specularColor='0 0 0' transparency='1.0'/>
      </Appearance>
      <Extrusion DEF='ExampleExtrusion' beginCap='true' ccw='true' containerField='geometry' convex='true' creaseAngle='0' crossSection='1 1 1 -1 -1 -1 -1 1 1 1' endCap='true' orientation='0 0 1 0' scale='1 1' solid='true' spine='0 0 0 0 1 0'/>
    </Shape>
    <Group bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'>
      <!-- Test MFNode children array as an ordered list consisting of comments, statements, ProtoInstance and nodes -->
      <ProtoDeclare name='NewWorldInfo'>
        <ProtoInterface>
          <field accessType='initializeOnly' name='description' type='SFString'/>
        </ProtoInterface>
        <ProtoBody>
          <WorldInfo containerField='children'/>
        </ProtoBody>
      </ProtoDeclare>
      <ProtoInstance DEF='Proto1' containerField='children' name='NewWorldInfo'>
        <fieldValue name='description' value='testing 1 2 3'/>
      </ProtoInstance>
      <Group DEF='Node2' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'>
        <!-- intentionally empty -->
      </Group>
      <ProtoInstance DEF='Proto3' containerField='children' name='NewWorldInfo'/>
      <Transform DEF='Node4' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' center='0 0 0' containerField='children' rotation='0 0 1 0' scale='1 1 1' scaleOrientation='0 0 1 0' translation='0 0 0' visible='true'>
        <!-- intentionally empty -->
      </Transform>
      <!-- Test satisfactorily creates MFNode children array as an ordered list with mixed content -->
    </Group>
    <ProtoDeclare name='ShaderProto'>
      <ProtoBody>
        <ProgramShader containerField='shaders'/>
      </ProtoBody>
    </ProtoDeclare>
    <Shape bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' castShadow='true' containerField='children' visible='true'>
      <Appearance alphaCutoff='0.5' alphaMode='AUTO' containerField='appearance'>
        <!-- Test MFNode shaders array as an ordered list consisting of comments, ProtoInstance and nodes -->
        <!-- Test satisfactorily creates MFNode shaders array as an ordered list with mixed content -->
        <ProgramShader DEF='TestShader1' containerField='shaders'>
          <ShaderProgram DEF='TestShader2' autoRefresh='0' autoRefreshTimeLimit='3600' containerField='programs' load='true' type='VERTEX'/>
        </ProgramShader>
        <ProtoInstance DEF='TestShader3' containerField='shaders' name='ShaderProto'/>
        <ComposedShader DEF='TestShader4' containerField='shaders'>
          <ShaderPart DEF='TestShader5' autoRefresh='0' autoRefreshTimeLimit='3600' containerField='parts' load='true' type='VERTEX'/>
        </ComposedShader>
      </Appearance>
    </Shape>
    <Transform DEF='SpecialtyNodes' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' center='0 0 0' containerField='children' rotation='0 0 1 0' scale='1 1 1' scaleOrientation='0 0 1 0' translation='0 0 0' visible='true'>
      <CADLayer bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'>
        <CADAssembly bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'>
          <CADPart bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' center='0 0 0' containerField='children' rotation='0 0 1 0' scale='1 1 1' scaleOrientation='0 0 1 0' translation='0 0 0' visible='true'>
            <CADFace bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' visible='true'/>
          </CADPart>
        </CADAssembly>
      </CADLayer>
      <EspduTransform address='localhost' applicationID='0' articulationParameterCount='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' center='0 0 0' collisionType='0' containerField='children' deadReckoning='0' detonationLocation='0 0 0' detonationRelativeLocation='0 0 0' detonationResult='0' enabled='true' entityCategory='0' entityCountry='0' entityDomain='0' entityExtra='0' entityID='0' entityKind='0' entitySpecific='0' entitySubcategory='0' eventApplicationID='0' eventEntityID='0' eventNumber='0' eventSiteID='0' fireMissionIndex='0' fired1='false' fired2='false' firingRange='0' firingRate='0' forceID='0' fuse='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' linearAcceleration='0 0 0' linearVelocity='0 0 0' multicastRelayPort='0' munitionApplicationID='0' munitionEndPoint='0 0 0' munitionEntityID='0' munitionQuantity='0' munitionSiteID='0' munitionStartPoint='0 0 0' networkMode='standAlone' port='0' readInterval='0.1' rotation='0 0 1 0' rtpHeaderExpected='false' scale='1 1 1' scaleOrientation='0 0 1 0' siteID='0' translation='0 0 0' visible='true' warhead='0' writeInterval='1.0'/>
      <ReceiverPdu address='localhost' applicationID='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' enabled='true' entityID='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' multicastRelayPort='0' networkMode='standAlone' port='0' radioID='0' readInterval='0.1' receivedPower='0.0' receiverState='0' rtpHeaderExpected='false' siteID='0' transmitterApplicationID='0' transmitterEntityID='0' transmitterRadioID='0' transmitterSiteID='0' visible='true' whichGeometry='1' writeInterval='1.0'/>
      <SignalPdu address='localhost' applicationID='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' dataLength='0' enabled='true' encodingScheme='0' entityID='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' multicastRelayPort='0' networkMode='standAlone' port='0' radioID='0' readInterval='0.1' rtpHeaderExpected='false' sampleRate='0' samples='0' siteID='0' tdlType='0' visible='true' whichGeometry='1' writeInterval='1.0'/>
      <TransmitterPdu address='localhost' antennaLocation='0 0 0' antennaPatternLength='0' antennaPatternType='0' applicationID='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' cryptoKeyID='0' cryptoSystem='0' enabled='true' entityID='0' frequency='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' inputSource='0' lengthOfModulationParameters='0' modulationTypeDetail='0' modulationTypeMajor='0' modulationTypeSpreadSpectrum='0' modulationTypeSystem='0' multicastRelayPort='0' networkMode='standAlone' port='0' power='0.0' radioEntityTypeCategory='0' radioEntityTypeCountry='0' radioEntityTypeDomain='0' radioEntityTypeKind='0' radioEntityTypeNomenclature='0' radioEntityTypeNomenclatureVersion='0' radioID='0' readInterval='0.1' relativeAntennaLocation='0 0 0' rtpHeaderExpected='false' siteID='0' transmitFrequencyBandwidth='0.0' transmitState='0' visible='true' whichGeometry='1' writeInterval='1.0'/>
      <DISEntityManager address='localhost' applicationID='0' containerField='children' port='0' siteID='0'>
        <DISEntityTypeMapping autoRefresh='0' autoRefreshTimeLimit='3600' category='0' containerField='children' country='0' domain='0' extra='0' kind='0' load='true' specific='0' subcategory='0'/>
      </DISEntityManager>
    </Transform>
    <EspduTransform address='localhost' applicationID='0' articulationParameterCount='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' center='0 0 0' collisionType='0' containerField='children' deadReckoning='0' detonationLocation='0 0 0' detonationRelativeLocation='0 0 0' detonationResult='0' enabled='true' entityCategory='0' entityCountry='0' entityDomain='0' entityExtra='0' entityID='0' entityKind='0' entitySpecific='0' entitySubcategory='0' eventApplicationID='0' eventEntityID='0' eventNumber='0' eventSiteID='0' fireMissionIndex='0' fired1='false' fired2='false' firingRange='0' firingRate='0' forceID='0' fuse='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' linearAcceleration='0 0 0' linearVelocity='0 0 0' multicastRelayPort='0' munitionApplicationID='0' munitionEndPoint='0 0 0' munitionEntityID='0' munitionQuantity='0' munitionSiteID='0' munitionStartPoint='0 0 0' networkMode='standAlone' port='0' readInterval='0.1' rotation='0 0 1 0' rtpHeaderExpected='false' scale='1 1 1' scaleOrientation='0 0 1 0' siteID='0' translation='0 0 0' visible='true' warhead='0' writeInterval='1.0'>
      <WorldInfo containerField='children'/>
    </EspduTransform>
    <ReceiverPdu address='localhost' applicationID='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' enabled='true' entityID='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' multicastRelayPort='0' networkMode='standAlone' port='0' radioID='0' readInterval='0.1' receivedPower='0.0' receiverState='0' rtpHeaderExpected='false' siteID='0' transmitterApplicationID='0' transmitterEntityID='0' transmitterRadioID='0' transmitterSiteID='0' visible='true' whichGeometry='1' writeInterval='1.0'/>
    <SignalPdu address='localhost' applicationID='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' dataLength='0' enabled='true' encodingScheme='0' entityID='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' multicastRelayPort='0' networkMode='standAlone' port='0' radioID='0' readInterval='0.1' rtpHeaderExpected='false' sampleRate='0' samples='0' siteID='0' tdlType='0' visible='true' whichGeometry='1' writeInterval='1.0'/>
    <TransmitterPdu address='localhost' antennaLocation='0 0 0' antennaPatternLength='0' antennaPatternType='0' applicationID='0' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' cryptoKeyID='0' cryptoSystem='0' enabled='true' entityID='0' frequency='0' geoCoords='0 0 0' geoSystem='"GD" "WE"' inputSource='0' lengthOfModulationParameters='0' modulationTypeDetail='0' modulationTypeMajor='0' modulationTypeSpreadSpectrum='0' modulationTypeSystem='0' multicastRelayPort='0' networkMode='standAlone' port='0' power='0.0' radioEntityTypeCategory='0' radioEntityTypeCountry='0' radioEntityTypeDomain='0' radioEntityTypeKind='0' radioEntityTypeNomenclature='0' radioEntityTypeNomenclatureVersion='0' radioID='0' readInterval='0.1' relativeAntennaLocation='0 0 0' rtpHeaderExpected='false' siteID='0' transmitFrequencyBandwidth='0.0' transmitState='0' visible='true' whichGeometry='1' writeInterval='1.0'/>
    <DISEntityManager address='localhost' applicationID='0' containerField='children' port='0' siteID='0'>
      <DISEntityTypeMapping autoRefresh='0' autoRefreshTimeLimit='3600' category='0' containerField='children' country='0' domain='0' extra='0' kind='0' load='true' specific='0' subcategory='0'/>
    </DISEntityManager>
    <LoadSensor containerField='children' enabled='true' timeOut='0'>
      <!-- Contained nodes typically must be USE references for nodes previously DEFined in the scene -->
      <!-- The following nodes are test cases for all X3DUrlObject nodes -->
      <Anchor USE='siteAnchor' autoRefresh='0' autoRefreshTimeLimit='3600' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' load='true' visible='true'/>
      <Inline USE='inlineScene' autoRefresh='0' autoRefreshTimeLimit='3600' bboxCenter='0 0 0' bboxDisplay='false' bboxSize='-1 -1 -1' containerField='children' global='false' load='true' visible='true'/>
      <DISEntityTypeMapping autoRefresh='0' autoRefreshTimeLimit='3600' category='0' containerField='children' country='0' domain='0' extra='0' kind='0' load='true' specific='0' subcategory='0'/>
      <GeoMetadata autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true'/>
      <AudioClip autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' enabled='true' gain='1' load='true' loop='false' pauseTime='0' pitch='1.0' resumeTime='0' startTime='0' stopTime='0'/>
      <ImageCubeMapTexture autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true'/>
      <ImageTexture3D autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true' repeatR='false' repeatS='false' repeatT='false'/>
      <ImageTexture autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true' repeatS='true' repeatT='true'/>
      <MovieTexture autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true' loop='false' pauseTime='0' pitch='1.0' repeatS='true' repeatT='true' resumeTime='0' speed='1.0' startTime='0' stopTime='0'/>
      <Script DEF='DummyScript' autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' directOutput='false' load='true' mustEvaluate='false'>
        <![CDATA[
ecmascript:
/* dummy test source code */
]]>
      </Script>
      <PackagedShader autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true'/>
      <ShaderPart autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true' type='VERTEX'/>
      <ShaderProgram autoRefresh='0' autoRefreshTimeLimit='3600' containerField='children' load='true' type='VERTEX'/>
    </LoadSensor>
    <OrthoViewpoint DEF='SpecialTestOrthoViewpoint' centerOfRotation='0 0 0' containerField='children' farDistance='-1' fieldOfView='1 3 2 4' jump='true' nearDistance='-1' orientation='0 0 1 0' position='0 0 10' retainUserOffsets='false' viewAll='false'/>
  </Scene>
</X3D>
===========================================
Test success: x3dLoader.getDomDocument() and x3dLoader.toStringX3D(domDocument)
Now test x3dLoader.toX3dModelInstance(domDocument)
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
Note: toFileX3D() is overwriting prior file SmokeTestProgramOutput_ReloadedDOM.x3d
Test success: x3dLoader.toX3dModelInstance(domDocument), save SmokeTestProgramOutput_ReloadedDOM.x3d
x3dLoader validation result: no issues reported.
===========================================
Test loadModelFromFileX3D(String) and loadModelFromFileX3D(File)
checking .x3d encoding SmokeTestProgramOutput.x3d
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
newX3DModel SmokeTestProgramOutput.x3d loadSuccess=true, isEmpty()=false, validate()=success
checking .xml encoding SmokeTestProgramOutput.xml
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
newX3DModel SmokeTestProgramOutput.xml loadSuccess=true, isEmpty()=false, validate()=success
===========================================
===========================================
Check file sizes for various forms of compression
Source file SmokeTestProgramOutput.x3d 23133 bytes
===========================================
Test toFileEXI() with EXIficient
SmokeTestProgramOutput_EXIFICIENT.exi  filesize 3736 bytes, compression 16.15% of original
===========================================
Test fromFileEXI() with EXIficient
Note: fromFileEXI() is overwriting prior file SmokeTestProgramOutput_EXIFICIENT.exi
EXI decompressed examples\temp.exiInputTransformed.x3d size=31033 bytes
[warning] This X3D document has no DOCTYPE statement which helps with scene validation, suggest adding.
          <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
          https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#Validation
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
  fromFileEXIsuccess=true for SmokeTestProgramOutput_EXIFICIENT.exi
exiModel.validate() results:  success
===========================================
Test toFileEXI() with OpenEXI: testing in progress
SmokeTestProgramOutputOPENEXI.exi  filesize 3736 bytes, compression 16.15% of original
===========================================
Test fromFileEXI() with OpenEXI: TODO testing in progress, not fully implemented yet
===========================================
Test toFileGZIP()
SmokeTestProgramOutput.gz  filesize 6163 bytes, compression 26.64% of original
===========================================
Test toFileZip()
SmokeTestProgramOutput.zip filesize 6417 bytes, compression 27.74% of original
===========================================
===========================================
Test CommandLine invocations
CommandLine [-help]
Usage: java [-classpath X3DJSAIL.*.jar] org.web3d.x3d.jsail.CommandLine
       [-help | -version | -home | -javadoc | -resources | -hints | -regexes | -tooltips | -X3DUOM]
       [-properties [propertiesFile]]
       [sourceModel.x3d | sourceModel.exi [-fromEXI] | sourceModel.gz [-fromGZIP] | sourceModel.zip [-fromZIP]]
       [-canonical] [-validate] [-EXIFICIENT | -OpenEXI]
       [-Schematron | -Tidy | -toX3D | -toXML | -toClassicVrml | -toJava | -toJSON | -toPython | -toVRML97]
       [-toHTML | -toX3DOM | -toX_ITE | -toMarkdown | -toEXI | -toGZIP | -toZIP]
       [-tofile [resultFile.*]] [-toImage [snapshotName.*]]

-classpath X3DJSAIL.*.jar         # optional classpath, can be set as environment variable
org.web3d.x3d.jsail.CommandLine   # invoke CommandLine application
==================================#====== informational ======================
-help                             # provide this help message
-version                          # version date when this X3DJSAIL build was autogenerated
-home                             # launch X3DJSAIL home page
-javadoc                          # launch X3DJSAIL javadoc page
-resources                        # launch X3D Resources page
-hints                            # launch X3D Scene Authoring Hints page
-regex                            # launch X3D Regular Expressions page
-tooltips                         # launch X3D Tooltips page
-X3DUOM                           # launch X3D Unified Object Model (X3DUOM) page
 =================================#====== properties, inputs =================
-properties [propertiesFile]      # override X3DJSAIL properties (default file: X3DJSAIL.properties)
-EXIFICIENT                       # use Exificient (default) as EXI_ENGINE
-OpenEXI                          # use OpenEXI (Nagasena)   as EXI_ENGINE (testing in progress)
sourceModel.x3d                   # source model file name, X3D  format
sourceModel.exi [-fromEXI]        # source model file name, EXI  format
sourceModel.gz  [-fromGZIP]       # source model file name, GZIP format
sourceModel.zip [-fromZIP]        # source model file name, ZIP  format
==================================#====== operations =========================
-canonical                        # canonical XML output using X3D Canonicalization (c14n)
-validate                         # validate correctness of loaded model
-Schematron                       # X3D Schematron diagnostics and Quality Assurance (QA)
-Tidy                             # X3D-Tidy cleanup in .x3d (XML) format
-toX3D                            # output in .x3d (XML) format
-toXML                            # output in .xml (X3D) format
-toClassicVrml                    # output in .x3dv (ClassicVrml) X3D format
-toJava                           # output in .java source code using X3DJSAIL
-toJSON                           # output in .json (JavaScript Object Notation) format
-toPython                         # output in .py Python source code
-toVRML97                         # output in .wrl  (VRML97) format
-toHTML                           # output in .html  pretty-print documentation
-toX3DOM                          # output in .xhtml page with X3DOM display of X3D model
-toX_ITE                          # output in .html  page with X_ITE display of X3D model
-toMarkdown                       # output document metadata (meta tags) in .md (Markdown) format
-toEXI                            # output in .exi (Efficient XML Interchange) compressed-XML format
-toGZIP                           # output in .gz  (X3D XML) format, with gzip compression
-toZIP                            # output in .zip (X3D XML) format, with zip  compression
==================================#====== outputs ============================
-tofile  [resultFile.*]           # specify output filename (otherwise original name with extension)
-toImage [snapshotName.*]         # create output images for each Viewpoint using Blender

===========================================
CommandLine [SmokeTestProgramOutput.x3d, -canonicalize, -toFile, SmokeTestProgramOutputCanonical.xml]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-canonicalize" for X3D and XML canonicalization (C14N)
CommandLine parameter: "-toFile" "SmokeTestProgramOutputCanonical.xml" for result file name SmokeTestProgramOutputCanonical.xml
CommandLine invocation: new X3dCanonicalizer(C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.x3d,SmokeTestProgramOutputCanonical.xml)
...x3dCanonicalizer.isCanonical()=false
Note: x3dCanonicalizer is overwriting prior file SmokeTestProgramOutputCanonical.xml
now check result...
CommandLine [SmokeTestProgramOutputCanonical.xml, -validate]
parameter: source file SmokeTestProgramOutputCanonical.xml filesize 23002 bytes
CommandLine parameter: "-validate" for model validation
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
validate results: success, no problems noted
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -toX3D, -toFile, SmokeTestProgramOutput_CommandLine.x3d]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toX3D" for conversion to X3D encoding
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine.x3d" for result file name SmokeTestProgramOutput_CommandLine.x3d
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to X3D:
Note: toFileX3D() is overwriting prior file SmokeTestProgramOutput_CommandLine.x3d
file conversion successful: SmokeTestProgramOutput_CommandLine.x3d (23132 bytes)
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -toVRML97, -toFile, SmokeTestProgramOutput_CommandLine.wrl]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toVRML97" for conversion to VRML97 encoding
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine.wrl" for result file name SmokeTestProgramOutput_CommandLine.wrl
convert to VRML97 using X3dToVrml97.xslt:
[info] &lt;meta name='info' content='continued development and testing in progress'/&gt;
[warning] Metadata nodes are not supported as a child of Text node in VRML97 encoding. The child MetadataSet node has been moved to immediately follow the parent Text. Additional Metadata* leaf node(s) follow that are similarly adjusted. [check X3D source or VRML output to find questionable &lt;Text/&gt; with parent Shape]
[warning] IS/connect ignored for nodeField='description' since not a supported field in VRML97 for parent TouchSensor [check X3D source or VRML output to find questionable TouchSensor]
[warning] Script field 'enabled' has accessType 'inputOutput' (exposedField), which is only allowed in X3D Script node, not VRML97 Script node. Using exposedField anyway, may cause errors. [field 'enabled' parent  DEF='MaterialModulatorScript']
[warning] Script field 'diffuseColor' has accessType 'inputOutput' (exposedField), which is only allowed in X3D Script node, not VRML97 Script node. Using exposedField anyway, may cause errors. [field 'diffuseColor' parent  DEF='MaterialModulatorScript']
[warning] ProtoInterface &lt;field name='description'/&gt; is unreferenced in ProtoBody with no corresponding IS/connect/@protoField [check X3D source or VRML output to find questionable field 'description' parent ProtoDeclare NewWorldInfo]
[warning] no ROUTE found for LoadSensor output  [check X3D source or VRML output to find questionable LoadSensor]
[error] SFFloat attribute fieldOfView='1 3 2 4' must contain only 1 value [OrthoViewpoint node DEF='SpecialTestOrthoViewpoint']
Note: fileStylesheetConversion() is overwriting prior file SmokeTestProgramOutput_CommandLine.wrl
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -toX3DV, -toFile, SmokeTestProgramOutput_CommandLine.x3dv]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toX3DV" for conversion to ClassicVRML encoding
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine.x3dv" for result file name SmokeTestProgramOutput_CommandLine.x3dv
convert to ClassicVRML using X3dToX3dvClassicVrmlEncoding.xslt:
Note: fileStylesheetConversion() is overwriting prior file SmokeTestProgramOutput_CommandLine.x3dv
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -toMarkdown, -toFile, SmokeTestProgramOutputCatalog.md]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toMarkdown" for producing .md model meta information markdown
CommandLine parameter: "-toFile" "SmokeTestProgramOutputCatalog.md" for result file name SmokeTestProgramOutputCatalog.md
convert to .md model meta information markdown, include subdirectories in meta links: true
Note: fileStylesheetConversion() is overwriting prior file SmokeTestProgramOutputCatalog.md
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -toMarkdown, -toFile, SmokeTestProgramOutput.md]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toMarkdown" for producing .md model meta information markdown
CommandLine parameter: "-toFile" "SmokeTestProgramOutput.md" for result file name SmokeTestProgramOutput.md
convert to .md model meta information markdown, include subdirectories in meta links: true
Note: fileStylesheetConversion() is overwriting prior file SmokeTestProgramOutput.md
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -EXIFICIENT, -toEXI, -toFile, SmokeTestProgramOutput_CommandLine_EXIFICIENT.exi]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-EXIFICIENT" invoked ConfigurationProperties.setExiEngine(EXIFICIENT);
CommandLine parameter: "-toEXI" for conversion to compressed EXI containing model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine_EXIFICIENT.exi" for result file name SmokeTestProgramOutput_CommandLine_EXIFICIENT.exi
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to EXI using EXIFICIENT:
source: SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput_CommandLine_EXIFICIENT.exi filesize 3734 bytes, compression 16.14% of original
===========================================
CommandLine [SmokeTestProgramOutput_CommandLine_EXIFICIENT.exi, -EXIFICIENT, -fromEXI, -toFile, SmokeTestProgramOutput_CommandLine_EXIFICIENT.RoundTrip.x3d]
parameter: source file SmokeTestProgramOutput_CommandLine_EXIFICIENT.exi filesize 3734 bytes
CommandLine parameter: "-EXIFICIENT" invoked ConfigurationProperties.setExiEngine(EXIFICIENT);
CommandLine parameter: "-fromEXI" for conversion from compressed EXI containing model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine_EXIFICIENT.RoundTrip.x3d" for result file name SmokeTestProgramOutput_CommandLine_EXIFICIENT.RoundTrip.x3d
Note: fromFileEXI() is overwriting prior file SmokeTestProgramOutput_CommandLine_EXIFICIENT.exi
EXI decompressed examples\temp.exiInputTransformed.x3d size=31032 bytes
[warning] This X3D document has no DOCTYPE statement which helps with scene validation, suggest adding.
          <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
          https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#Validation
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
load result: true
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -OpenEXI, -toEXI, -toFile, SmokeTestProgramOutput_CommandLine.OPENEXI.exi]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-OpenEXI" invoked ConfigurationProperties.setExiEngine(OPENEXI);
  [warning] "OPENEXI" testing in progress, can also use EXIFICIENT instead.
CommandLine parameter: "-toEXI" for conversion to compressed EXI containing model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine.OPENEXI.exi" for result file name SmokeTestProgramOutput_CommandLine.OPENEXI.exi
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to EXI using OPENEXI:
source: SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput_CommandLine.OPENEXI.exi filesize 3796 bytes, compression 16.41% of original
===========================================
CommandLine [SmokeTestProgramOutput_CommandLine.OPENEXI.exi, -OpenEXI, -fromEXI, -toFile, SmokeTestProgramOutput_CommandLine.OPENEXI.RoundTrip.x3d]
parameter: source file SmokeTestProgramOutput_CommandLine.OPENEXI.exi filesize 3796 bytes
CommandLine parameter: "-OpenEXI" invoked ConfigurationProperties.setExiEngine(OPENEXI);
  [warning] "OPENEXI" testing in progress, can also use EXIFICIENT instead.
CommandLine parameter: "-fromEXI" for conversion from compressed EXI containing model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine.OPENEXI.RoundTrip.x3d" for result file name SmokeTestProgramOutput_CommandLine.OPENEXI.RoundTrip.x3d
Note: fromFileEXI() is overwriting prior file SmokeTestProgramOutput_CommandLine.OPENEXI.exi
EXI decompressed examples\temp.exiInputTransformed.x3d size=31211 bytes
[warning] This X3D document has no DOCTYPE statement which helps with scene validation, suggest adding.
          <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
          https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#Validation
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
load result: true
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -toGZIP, -toFile, SmokeTestProgramOutput_CommandLine.x3d.gz]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toGZIP" for conversion to compressed GZIP containing model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine.x3d.gz" for result file name SmokeTestProgramOutput_CommandLine.x3d.gz
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to GZIP:
source: SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput_CommandLine.x3d.gz  filesize 6160 bytes, compression 26.63% of original
===========================================
CommandLine [SmokeTestProgramOutput_CommandLine.x3d.gz, -fromGZIP]
parameter: source file SmokeTestProgramOutput_CommandLine.x3d.gz filesize 6160 bytes
CommandLine parameter: "-fromGZIP" for conversion from compressed GZIP containing model
  fromFileGZIP() output modelFileName SmokeTestProgramOutput_CommandLine.x3d
Note: fromFileGZIP() is overwriting prior file SmokeTestProgramOutput_CommandLine.x3d
gunzipped SmokeTestProgramOutput_CommandLine.x3d size=23132 bytes
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
load result: true
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -toZIP, -toFile, SmokeTestProgramOutput_CommandLine.x3d.zip]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toZIP" for conversion to compressed ZIP containing model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLine.x3d.zip" for result file name SmokeTestProgramOutput_CommandLine.x3d.zip
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to ZIP:
source: SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput_CommandLine.x3d.zip filesize 6414 bytes, compression 27.73% of original
===========================================
CommandLine [SmokeTestProgramOutput_CommandLine.x3d.zip, -fromZIP, -toFile, SmokeTestProgramOutput_CommandLineUnzipped.x3d]
parameter: source file SmokeTestProgramOutput_CommandLine.x3d.zip filesize 6414 bytes
CommandLine parameter: "-fromZIP" for conversion from compressed ZIP containing model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLineUnzipped.x3d" for result file name SmokeTestProgramOutput_CommandLineUnzipped.x3d
[warning] fromFileZIP() modelFileName was empty, unzipping found initial X3D file to load: SmokeTestProgramOutput.x3d
Note: fromFileZIP() is overwriting prior file SmokeTestProgramOutput_CommandLineUnzipped.x3d
Unzipped SmokeTestProgramOutput_CommandLineUnzipped.x3d size=23132 bytes
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
load result: true
===========================================
CommandLine [SmokeTestProgramOutput.x3d, -schematron, -toFile, SmokeTestProgramOutput_CommandLineSchematron.txt]
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-schematron" to produce X3D Schematron diagnostics for .x3d model
CommandLine parameter: "-toFile" "SmokeTestProgramOutput_CommandLineSchematron.txt" for result file name SmokeTestProgramOutput_CommandLineSchematron.txt
First creating intermediate SVRL file using stylesheet X3dSchematronValidityChecks.xslt
Note: fileStylesheetConversion() is overwriting prior file SmokeTestProgramOutput_CommandLineSchematron.txt.svrl
   intermediate SVRL file SmokeTestProgramOutput_CommandLineSchematron.txt.svrl fileExists=true
... Next creating final report file using stylesheet SvrlReportText.xslt
Note: fileStylesheetConversion() is overwriting prior file SmokeTestProgramOutput_CommandLineSchematron.txt
Resulting result file: SmokeTestProgramOutput_CommandLineSchematron.txt exists=true
===========================================
x3dModel.toStringX3dSchematronReport() output:
Note: toFileStylesheetConversion(X3dSchematronValidityChecks.xslt) is overwriting prior file temporarySchematronOutputFile.svrl

===========================================
x3dModel.toFileX3dSchematronReport("SmokeTestProgramOutput_CommandLineSchematron2.txt") output:
Note: toFileStylesheetConversion(X3dSchematronValidityChecks.xslt) is overwriting prior file SmokeTestProgramOutput_CommandLineSchematron2.svrl
Note: toFileStylesheetConversion(SvrlReportText.xslt) is overwriting prior file SmokeTestProgramOutput_CommandLineSchematron2.txt
===========================================
ConfigurationProperties.setDebugModeActive(true);
x3dModel.validate() results with ConfigurationProperties.setDebugModeActive(true): 
ProtoInstance ArtDeco01 DEF='' has corresponding ProtoDeclare
ProtoInstance ArtDeco02 DEF='ArtDeco02MaterialDEF' has corresponding ExternProtoDeclare (but node type is unconfirmed)
ProtoInstance ArtDeco02 USE='ArtDeco02MaterialDEF' has corresponding ExternProtoDeclare (but node type is unconfirmed)
ProtoInstance MaterialModulator DEF='MyMaterialModulator' has corresponding ProtoDeclare
ProtoInstance NewWorldInfo DEF='Proto1' has corresponding ProtoDeclare
ProtoInstance NewWorldInfo DEF='Proto3' has corresponding ProtoDeclare
ProtoInstance ShaderProto DEF='TestShader3' has corresponding ProtoDeclare

===========================================
SmokeTestProgram complete.
===========================================
testBlenderLauncher();  // check Blender capabilities
Blender default path=[Blender path not set]
Blender.checkBlenderPath() updated path=C:\Program Files\Blender Foundation\Blender 4.5\
=================================
BlenderLauncher.hasBlender()=true
=================================
Blender version=Blender 4.5.1 LTS
===========================================
BlenderLauncher.run("-help")
Usage: java [-classpath X3DJSAIL.*.jar] org.web3d.x3d.jsail.BlenderLauncher sourceFile [-convert [resultFile]] [-toImage [snapshotName.*]] [-home | -help | -version | -properties fileName.properties | -BLENDER_PATH directoryPath]
https://www.blender.org
Blender help:
Blender 4.5.1 LTS
Usage: blender [args ...] [file] [args ...]
Render Options:
-b or --background 
	Run in background (often used for UI-less rendering).
	The audio device is disabled in background-mode by default
	and can be re-enabled by passing in '-setaudio Default' afterwards.
-a or --render-anim 
	Render frames from start to end (inclusive).
-S or --scene <name>
	Set the active scene <name> for rendering.
-f or --render-frame <frame>
	Render frame <frame> and save it.
	* +<frame> start frame relative, -<frame> end frame relative.
	* A comma separated list of frames can also be used (no spaces).
	* A range of frames can be expressed using '..' separator between the first and last frames (inclusive).

-s or --frame-start <frame>
	Set start to frame <frame>, supports +/- for relative frames too.
-e or --frame-end <frame>
	Set end to frame <frame>, supports +/- for relative frames too.
-j or --frame-jump <frames>
	Set number of frames to step forward after each rendered frame.
-o or --render-output <path>
	Set the render path and file name.
	Use '//' at the start of the path to render relative to the blend-file.
	You can use path templating features such as '{blend_name}' in the path.
	See Blender's documentation on path templates for more details.
	The '#' characters are replaced by the frame number, and used to define zero padding.
	* 'animation_##_test.png' becomes 'animation_01_test.png'
	* 'test-######.png' becomes 'test-000001.png'
	When the filename does not contain '#', the suffix '####' is added to the filename.
	The frame number will be added at the end of the filename, eg:
	# blender -b animation.blend -o //render_ -F PNG -x 1 -a
	'//render_' becomes '//render_####', writing frames as '//render_0001.png'
-E or --engine <engine>
	Specify the render engine.
	Use '-E help' to list available engines.
-t or --threads <threads>
	Use amount of <threads> for rendering and other operations
	[1-1024], 0 to use the systems processor count.
Cycles Render Options:
	Cycles add-on options must be specified following a double dash.
--cycles-device <device>
	Set the device used for rendering.
	Valid options are: 'CPU' 'CUDA' 'OPTIX' 'HIP' 'ONEAPI' 'METAL'.
	Append +CPU to a GPU device to render on both CPU and GPU.
	Example:
	# blender -b file.blend -f 20 -- --cycles-device OPTIX
--cycles-print-stats
	Log statistics about render memory and time usage.
Format Options:
-F or --render-format <format>
	Set the render format.
	Valid options are:
	'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP' 'HDR' 'TIFF'.
	Formats that can be compiled into Blender, not available on all systems:
	'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'FFMPEG' 'CINEON' 'DPX' 'JP2' 'WEBP'.
-x or --use-extension <bool>
	Set option to add the file extension to the end of the file.

Animation Playback Options:
-a <options> <file(s)>
	Instead of showing Blender's user interface, this runs Blender as an animation player,
	to view movies and image sequences rendered in Blender (ignored if '-b' is set).
	Playback Arguments:
	-p <sx> <sy>
		Open with lower left corner at <sx>, <sy>.
	-m
		Read from disk (Do not buffer).
	-f <fps> <fps_base>
		Specify FPS to start with.
	-j <frame>
		Set frame step to <frame>.
	-s <frame>
		Play from <frame>.
	-e <frame>
		Play until <frame>.
	-c <cache_memory>
		Amount of memory in megabytes to allow for caching images during playback.
		Zero disables (clamping to a fixed number of frames instead).

Window Options:
-w or --window-border 
	Force opening with borders.
-W or --window-fullscreen 
	Force opening in full-screen mode.
-p or --window-geometry <sx> <sy> <w> <h>
	Open with lower left corner at <sx>, <sy> and width and height as <w>, <h>.
-M or --window-maximized 
	Force opening maximized.
-con or --start-console 
	Start with the console window open (ignored if '-b' is set), (Windows only).
--no-native-pixels 
	Do not use native pixel size, for high resolution displays (MacBook 'Retina').
--no-window-focus 
	Open behind other windows and without taking focus.

Python Options:
-y or --enable-autoexec 
	Enable automatic Python script execution.
-Y or --disable-autoexec 
	Disable automatic Python script execution (Python-drivers & startup scripts), (default).

-P or --python <filepath>
	Run the given Python script file.
--python-text <name>
	Run the given Python script text block.
--python-expr <expression>
	Run the given expression as a Python script.
--python-console 
	Run Blender with an interactive console.
--python-exit-code <code>
	Set the exit-code in [0..255] to exit if a Python exception is raised
	(only for scripts executed from the command line), zero disables.
--python-use-system-env 
	Allow Python to use system environment variables such as 'PYTHONPATH' and the user site-packages directory.
--addons <addon(s)>
	Comma separated list (no spaces) of add-ons to enable in addition to any default add-ons.

Network Options:
--online-mode 
	Allow internet access, overriding the preference.
--offline-mode 
	Disallow internet access, overriding the preference.

Logging Options:
--log <match>
	Enable logging categories, taking a single comma separated argument.
	Multiple categories can be matched using a '.*' suffix,
	so '--log "wm.*"' logs every kind of window-manager message.
	Sub-string can be matched using a '*' prefix and suffix,
	so '--log "*undo*"' logs every kind of undo-related message.
	Use "^" prefix to ignore, so '--log "*,^wm.operator.*"' logs all except for 'wm.operators.*'
	Use "*" to log everything.
--log-level <level>
	Set the logging verbosity level (higher for more details) defaults to 1,
	use -1 to log all levels.
--log-show-basename 
	Only show file name in output (not the leading path).
--log-show-backtrace 
	Show a back trace for each log message (debug builds only).
--log-show-timestamp 
	Show a timestamp for each log message in seconds since start.
--log-file <filepath>
	Set a file to output the log to.

Debug Options:
-d or --debug 
	Turn debugging on.
	* Enables memory error detection
	* Disables mouse grab (to interact with a debugger in some cases)
	* Keeps Python's 'sys.stdin' rather than setting it to None
--debug-value <value>
	Set debug value of <value> on startup.

--debug-events 
	Enable debug messages for the event system.
--debug-ffmpeg 
	Enable debug messages from FFmpeg library.
--debug-handlers 
	Enable debug messages for event handling.
--debug-libmv 
	Enable debug messages from libmv library.
--debug-cycles 
	Enable debug messages from Cycles.
--debug-memory 
	Enable fully guarded memory allocation and debugging.
--debug-jobs 
	Enable time profiling for background jobs.
--debug-python 
	Enable debug messages for Python.
--debug-depsgraph 
	Enable all debug messages from dependency graph.
--debug-depsgraph-eval 
	Enable debug messages from dependency graph related on evaluation.
--debug-depsgraph-build 
	Enable debug messages from dependency graph related on graph construction.
--debug-depsgraph-tag 
	Enable debug messages from dependency graph related on tagging.
--debug-depsgraph-no-threads 
	Switch dependency graph to a single threaded evaluation.
--debug-depsgraph-time 
	Enable debug messages from dependency graph related on timing.
--debug-depsgraph-pretty 
	Enable colors for dependency graph debug messages.
--debug-depsgraph-uid 
	Verify validness of session-wide identifiers assigned to ID data-blocks.
--debug-ghost 
	Enable debug messages for Ghost (Linux only).
--debug-wintab 
	Enable debug messages for Wintab.
--debug-gpu 
	Enable GPU debug context and information for OpenGL 4.3+.
--debug-gpu-force-workarounds 
	Enable workarounds for typical GPU issues and disable all GPU extensions.
--debug-gpu-compile-shaders 
	Compile all statically defined shaders to test platform compatibility.
--debug-gpu-vulkan-local-read 
	Force Vulkan dynamic rendering local read when supported by device.
--debug-wm 
	Enable debug messages for the window manager, shows all operators in search, shows keymap errors.
--debug-xr 
	Enable debug messages for virtual reality contexts.
	Enables the OpenXR API validation layer, (OpenXR) debug messages and general information prints.
--debug-xr-time 
	Enable debug messages for virtual reality frame rendering times.
--debug-all 
	Enable all debug messages.
--debug-io 
	Enable debug messages for I/O (Collada, ...).

--debug-fpe 
	Enable floating-point exceptions.
--debug-exit-on-error 
	Immediately exit when internal errors are detected.
--debug-freestyle 
	Enable debug messages for Freestyle.
--disable-crash-handler 
	Disable the crash handler.
--disable-abort-handler 
	Disable the abort handler.
--verbose <verbose>
	Set the logging verbosity level for debug messages that support it.
-q or --quiet 
	Suppress status printing (warnings & errors are still printed).

GPU Options:
--gpu-backend 
	Force to use a specific GPU backend. Valid options: 'opengl' or 'vulkan'.
--gpu-compilation-subprocesses 
	Override the Max Compilation Subprocesses setting (OpenGL only).
--profile-gpu 
	Enable CPU & GPU performance profiling for GPU debug groups
	(Outputs a profile.json file in the Trace Event Format to the current directory)

Misc Options:
--open-last 
	Open the most recently opened blend file, instead of the default startup file.
--app-template <template>
	Set the application template (matching the directory name), use 'default' for none.
--factory-startup 
	Skip reading the 'startup.blend' in the users home directory.
--enable-event-simulate 
	Enable event simulation testing feature 'bpy.types.Window.event_simulate'.

--env-system-datafiles 
	Set the BLENDER_SYSTEM_DATAFILES environment variable.
--env-system-scripts 
	Set the BLENDER_SYSTEM_SCRIPTS environment variable.
--env-system-extensions 
	Set the BLENDER_SYSTEM_EXTENSIONS environment variable.
--env-system-python 
	Set the BLENDER_SYSTEM_PYTHON environment variable.

-noaudio 
	Force sound system to None.
-setaudio 
	Force sound system to a specific device.
	'None' 'Default' 'SDL' 'OpenAL' 'CoreAudio' 'JACK' 'PulseAudio' 'WASAPI'.

-c or --command <command>
	Run a command which consumes all remaining arguments.
	Use '-c help' to list all other commands.
	Pass '--help' after the command to see its help text.
	This implies '--background' mode.

-h or --help 
	Print this help text and exit.
/? 
	Print this help text and exit (Windows only).
-r or --register 
	Register blend-file extension for current user, then exit (Windows & Linux only).
--register-allusers 
	Register blend-file extension for all users, then exit (Windows & Linux only).
--unregister 
	Unregister blend-file extension for current user, then exit (Windows & Linux only).
--unregister-allusers 
	Unregister blend-file extension for all users, then exit (Windows & Linux only).
-v or --version 
	Print Blender version and exit.
-- 
	End option processing, following arguments passed unchanged. Access via Python's 'sys.argv'.

Other Options:
--disable-depsgraph-on-file-load 
	Background mode: Do not systematically build and evaluate ViewLayers' dependency graphs
	when loading a blend-file in background mode ('-b' or '-c' options).
	Scripts requiring evaluated data then need to explicitly ensure that
	an evaluated depsgraph is available
	(e.g. by calling 'depsgraph = context.evaluated_depsgraph_get()').
	NOTE: this is a temporary option, in the future depsgraph will never be
	automatically generated on file load in background mode.
--disable-liboverride-auto-resync 
	Do not perform library override automatic resync when loading a new blend-file.
	NOTE: this is an alternative way to get the same effect as when setting the
	'No Override Auto Resync' User Preferences Debug option.

Argument Parsing:
	Arguments must be separated by white space, eg:
	# blender -ba test.blend
	...will exit since '-ba' is an unknown argument.
Argument Order:
	Arguments are executed in the order they are given. eg:
	# blender --background test.blend --render-frame 1 --render-output "/tmp"
	...will not render to '/tmp' because '--render-frame 1' renders before the output path is set.
	# blender --background --render-output /tmp test.blend --render-frame 1
	...will not render to '/tmp' because loading the blend-file overwrites the render output that was set.
	# blender --background test.blend --render-output /tmp --render-frame 1
	...works as expected.
Environment Variables:
  $BLENDER_USER_RESOURCES  Replace default directory of all user files.
                           Other 'BLENDER_USER_*' variables override when set.
  $BLENDER_USER_CONFIG     Directory for user configuration files.
  $BLENDER_USER_SCRIPTS    Directory for user scripts.
  $BLENDER_USER_EXTENSIONS Directory for user extensions.
  $BLENDER_USER_DATAFILES  Directory for user data files (icons, translations, ..).
  $BLENDER_SYSTEM_RESOURCES  Replace default directory of all bundled resource files.
  $BLENDER_SYSTEM_SCRIPTS    Directories to add extra scripts.
  $BLENDER_SYSTEM_EXTENSIONS Directory for system extensions repository.
  $BLENDER_SYSTEM_DATAFILES  Directory to replace bundled datafiles.
  $BLENDER_SYSTEM_PYTHON     Directory to replace bundled Python libraries.
  $BLENDER_CUSTOM_SPLASH     Full path to an image that replaces the splash screen.
  $BLENDER_CUSTOM_SPLASH_BANNER Full path to an image to overlay on the splash screen.
  $OCIO                      Path to override the OpenColorIO configuration file.
  $TEMP                      Store temporary files here (MS-Windows).
                             The path must reference an existing directory or it will be ignored.
===========================================
BlenderLauncher.run("-BLENDER_PATH", "C:\Program Files\Blender Foundation\Blender 4.5\")
parameters: "-BLENDER_PATH" "C:\Program Files\Blender Foundation\Blender 4.5\" for setting Blender path
===========================================
BlenderLauncher.run("-properties X3DJSAIL.properties")
BlenderLauncher parameter: "-properties" "X3DJSAIL.properties" for properties file name root X3DJSAIL
X3DJSAIL.properties includes 13 properties:
-- listing properties --
deleteIntermediateFiles=true
BLENDER_PATH=
XSLT_ENGINE=SAXON
overwriteExistingFiles=true
EXI_ENGINE=EXIFICIENT
SFImagePixelOutputHexadecimal=true
stripTrailingZeroes=true
normalizeCommentWhitespace=true
indentCharacter=SPACE
MESHLAB_PATH=
indentIncrement=2
validationExceptionAllowed=false
stripDefaultAttributes=true
------------------------
X3DJSAIL.properties loading complete.
===========================================
BlenderLauncher.run("CleatClamp.x3d -toImage")
BlenderLauncher parameter: source file CleatClamp.x3d filesize 172233 bytes
BlenderLauncher parameter: "-toImage" for creating screenshot image of default viewpoint
       [diagnostic] System java.class.path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples;C:\x3d-code\www.web3d.org\x3d\stylesheets\java\jars\X3DJSAIL.4.0.full.jar
[diagnostic] jarPath=jar:file:X3DJSAIL.4.0.full.jar!/, filePath=/python/blenderScripts/BlenderX3dToPng.py

executeCommand("C:\Program Files\Blender Foundation\Blender 4.5\blender.exe --background --factory-startup --python C:\Users\donbr\AppData\Local\Temp\BlenderX3dToPng10892001607912856128.py -- CleatClamp.x3d")
executeCommand() response:
Blender 4.5.1 LTS (hash b0a72b245dcf built 2025-07-29 06:36:07)
BlenderX3dToPng.py start...

BlenderX3dToPng.py is a Blender Python script to load <model>.x3d and output image snapshot(s) as <model>.viewpoint.blender.png

Example invocations:
/cygdrive/c/x3d-code/www.web3d.org/x3d/stylesheets/java/src/python/blenderScripts
$ ant blender.python.run.BlenderX3dToPng.py
$ blender.exe --background --factory-startup --python BlenderX3dToPng.py LPD17.x3d products/

Command line: 7 args ['C:\\Program Files\\Blender Foundation\\Blender 4.5\\blender.exe', '--background', '--factory-startup', '--python', 'C:\\Users\\donbr\\AppData\\Local\\Temp\\BlenderX3dToPng10892001607912856128.py', '--', 'CleatClamp.x3d']
sourceFile=CleatClamp.x3d outputPath=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples

Clean up initial view...
Importing CleatClamp.x3d ...

Blender quit

expected result: CleatClamp.png
CommandLine.run("CleatClamp.x3d -toImage") tests pass through
parameter: source file CleatClamp.x3d filesize 172233 bytes
CommandLine parameter: "-toImage" for creating screenshot image of default viewpoint
Pass through to BlenderLauncher...
BlenderLauncher parameter: source file CleatClamp.x3d filesize 172233 bytes
BlenderLauncher parameter: "-toImage" for creating screenshot image of default viewpoint
executeCommand("C:\Program Files\Blender Foundation\Blender 4.5\blender.exe --background --factory-startup --python C:\Users\donbr\AppData\Local\Temp\BlenderX3dToPng10892001607912856128.py -- CleatClamp.x3d")
executeCommand() response:
Blender 4.5.1 LTS (hash b0a72b245dcf built 2025-07-29 06:36:07)
BlenderX3dToPng.py start...

BlenderX3dToPng.py is a Blender Python script to load <model>.x3d and output image snapshot(s) as <model>.viewpoint.blender.png

Example invocations:
/cygdrive/c/x3d-code/www.web3d.org/x3d/stylesheets/java/src/python/blenderScripts
$ ant blender.python.run.BlenderX3dToPng.py
$ blender.exe --background --factory-startup --python BlenderX3dToPng.py LPD17.x3d products/

Command line: 7 args ['C:\\Program Files\\Blender Foundation\\Blender 4.5\\blender.exe', '--background', '--factory-startup', '--python', 'C:\\Users\\donbr\\AppData\\Local\\Temp\\BlenderX3dToPng10892001607912856128.py', '--', 'CleatClamp.x3d']
sourceFile=CleatClamp.x3d outputPath=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples

Clean up initial view...
Importing CleatClamp.x3d ...

Blender quit

expected result: CleatClamp.png
CommandLine.run("CleatClamp.x3d -toJava   -toFile CleatClamp.java") tests pass through
parameter: source file CleatClamp.x3d filesize 172233 bytes
CommandLine parameter: "-toJava" for conversion to Java source code
CommandLine parameter: "-toFile" "CleatClamp.java" for result file name CleatClamp.java
convert to Java using X3dToJava.xslt:
[diagnostic] Output file path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.java

       [diagnostic] System java.class.path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples;C:\x3d-code\www.web3d.org\x3d\stylesheets\java\jars\X3DJSAIL.4.0.full.jar
[diagnostic] jarPath=jar:file:X3DJSAIL.4.0.full.jar!/, filePath=/stylesheets/X3dToJava.xslt

no className provided, using normalized meta title value='CleatClamp'
[meta] name='warning' content='Do not use for climbing or yachting.'
[diagnostic] Output file path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.java

CommandLine.run("CleatClamp.x3d -toJSON   -toFile CleatClamp.json") tests pass through
parameter: source file CleatClamp.x3d filesize 172233 bytes
CommandLine parameter: "-toJSON" for conversion to JSON encoding
CommandLine parameter: "-toFile" "CleatClamp.json" for result file name CleatClamp.json
convert to JSON using X3dToJson.xslt:
[diagnostic] Output file path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.json

       [diagnostic] System java.class.path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples;C:\x3d-code\www.web3d.org\x3d\stylesheets\java\jars\X3DJSAIL.4.0.full.jar
[diagnostic] jarPath=jar:file:X3DJSAIL.4.0.full.jar!/, filePath=/stylesheets/X3dToJson.xslt

[diagnostic] Output file path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.json
Note: fileStylesheetConversion() is overwriting prior file CleatClamp.json
CommandLine.run("CleatClamp.x3d -toPython -toFile CleatClamp.py")   tests pass through
parameter: source file CleatClamp.x3d filesize 172233 bytes
CommandLine parameter: "-toPython" for conversion to Python source code
CommandLine parameter: "-toFile" "CleatClamp.py" for result file name CleatClamp.py
convert to Python using X3dToPython.xslt:
[diagnostic] Output file path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.py

       [diagnostic] System java.class.path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples;C:\x3d-code\www.web3d.org\x3d\stylesheets\java\jars\X3DJSAIL.4.0.full.jar
[diagnostic] jarPath=jar:file:X3DJSAIL.4.0.full.jar!/, filePath=/stylesheets/X3dToPython.xslt

[diagnostic] Output file path=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.py
Note: fileStylesheetConversion() is overwriting prior file CleatClamp.py
parameter: source file CleatClamp.x3d filesize 172233 bytes
CommandLine parameter: "-toPython" for conversion to Python source code
[Warning] Prior conversion flag overridden by -Tidy
CommandLine parameter: "-Tidy" for producing X3D-Tidy cleanup of .x3d model
[Error]  [org.web3d.x3d.jsail.CommandLine] multiple source file names found, "CleatClamp.x3d" and "CleatClamp.Tidy.x3d"
Usage: java [-classpath X3DJSAIL.*.jar] org.web3d.x3d.jsail.CommandLine
       [-help | -version | -home | -javadoc | -resources | -hints | -regexes | -tooltips | -X3DUOM]
       [-properties [propertiesFile]]
       [sourceModel.x3d | sourceModel.exi [-fromEXI] | sourceModel.gz [-fromGZIP] | sourceModel.zip [-fromZIP]]
       [-canonical] [-validate] [-EXIFICIENT | -OpenEXI]
       [-Schematron | -Tidy | -toX3D | -toXML | -toClassicVrml | -toJava | -toJSON | -toPython | -toVRML97]
       [-toHTML | -toX3DOM | -toX_ITE | -toMarkdown | -toEXI | -toGZIP | -toZIP]
       [-tofile [resultFile.*]] [-toImage [snapshotName.*]]
parameter: source file CleatClamp.x3d filesize 172233 bytes
CommandLine parameter: "-toPython" for conversion to Python source code
[Warning] Prior conversion flag overridden by -schematron
CommandLine parameter: "-schematron" to produce X3D Schematron diagnostics for .x3d model
[Error]  [org.web3d.x3d.jsail.CommandLine] multiple source file names found, "CleatClamp.x3d" and "CleatClamp.txt"
Usage: java [-classpath X3DJSAIL.*.jar] org.web3d.x3d.jsail.CommandLine
       [-help | -version | -home | -javadoc | -resources | -hints | -regexes | -tooltips | -X3DUOM]
       [-properties [propertiesFile]]
       [sourceModel.x3d | sourceModel.exi [-fromEXI] | sourceModel.gz [-fromGZIP] | sourceModel.zip [-fromZIP]]
       [-canonical] [-validate] [-EXIFICIENT | -OpenEXI]
       [-Schematron | -Tidy | -toX3D | -toXML | -toClassicVrml | -toJava | -toJSON | -toPython | -toVRML97]
       [-toHTML | -toX3DOM | -toX_ITE | -toMarkdown | -toEXI | -toGZIP | -toZIP]
       [-tofile [resultFile.*]] [-toImage [snapshotName.*]]
===========================================
TODO testMeshLabLauncher();  // check MeshLab capabilities
===========================================
SmokeTestProgram self validation: 

<meta content='continued development and testing in progress' name='info'/>

ProtoInstance ArtDeco01 DEF='' has corresponding ProtoDeclare
ProtoInstance ArtDeco02 DEF='ArtDeco02MaterialDEF' has corresponding ExternProtoDeclare (but node type is unconfirmed)
ProtoInstance ArtDeco02 USE='ArtDeco02MaterialDEF' has corresponding ExternProtoDeclare (but node type is unconfirmed)
ProtoInstance MaterialModulator DEF='MyMaterialModulator' has corresponding ProtoDeclare
ProtoInstance NewWorldInfo DEF='Proto1' has corresponding ProtoDeclare
ProtoInstance NewWorldInfo DEF='Proto3' has corresponding ProtoDeclare
ProtoInstance ShaderProto DEF='TestShader3' has corresponding ProtoDeclare

===========================================
Quick test of CommandLine capability:
Usage: java [-classpath X3DJSAIL.*.jar] org.web3d.x3d.jsail.CommandLine
       [-help | -version | -home | -javadoc | -resources | -hints | -regexes | -tooltips | -X3DUOM]
       [-properties [propertiesFile]]
       [sourceModel.x3d | sourceModel.exi [-fromEXI] | sourceModel.gz [-fromGZIP] | sourceModel.zip [-fromZIP]]
       [-canonical] [-validate] [-EXIFICIENT | -OpenEXI]
       [-Schematron | -Tidy | -toX3D | -toXML | -toClassicVrml | -toJava | -toJSON | -toPython | -toVRML97]
       [-toHTML | -toX3DOM | -toX_ITE | -toMarkdown | -toEXI | -toGZIP | -toZIP]
       [-tofile [resultFile.*]] [-toImage [snapshotName.*]]

-classpath X3DJSAIL.*.jar         # optional classpath, can be set as environment variable
org.web3d.x3d.jsail.CommandLine   # invoke CommandLine application
==================================#====== informational ======================
-help                             # provide this help message
-version                          # version date when this X3DJSAIL build was autogenerated
-home                             # launch X3DJSAIL home page
-javadoc                          # launch X3DJSAIL javadoc page
-resources                        # launch X3D Resources page
-hints                            # launch X3D Scene Authoring Hints page
-regex                            # launch X3D Regular Expressions page
-tooltips                         # launch X3D Tooltips page
-X3DUOM                           # launch X3D Unified Object Model (X3DUOM) page
 =================================#====== properties, inputs =================
-properties [propertiesFile]      # override X3DJSAIL properties (default file: X3DJSAIL.properties)
-EXIFICIENT                       # use Exificient (default) as EXI_ENGINE
-OpenEXI                          # use OpenEXI (Nagasena)   as EXI_ENGINE (testing in progress)
sourceModel.x3d                   # source model file name, X3D  format
sourceModel.exi [-fromEXI]        # source model file name, EXI  format
sourceModel.gz  [-fromGZIP]       # source model file name, GZIP format
sourceModel.zip [-fromZIP]        # source model file name, ZIP  format
==================================#====== operations =========================
-canonical                        # canonical XML output using X3D Canonicalization (c14n)
-validate                         # validate correctness of loaded model
-Schematron                       # X3D Schematron diagnostics and Quality Assurance (QA)
-Tidy                             # X3D-Tidy cleanup in .x3d (XML) format
-toX3D                            # output in .x3d (XML) format
-toXML                            # output in .xml (X3D) format
-toClassicVrml                    # output in .x3dv (ClassicVrml) X3D format
-toJava                           # output in .java source code using X3DJSAIL
-toJSON                           # output in .json (JavaScript Object Notation) format
-toPython                         # output in .py Python source code
-toVRML97                         # output in .wrl  (VRML97) format
-toHTML                           # output in .html  pretty-print documentation
-toX3DOM                          # output in .xhtml page with X3DOM display of X3D model
-toX_ITE                          # output in .html  page with X_ITE display of X3D model
-toMarkdown                       # output document metadata (meta tags) in .md (Markdown) format
-toEXI                            # output in .exi (Efficient XML Interchange) compressed-XML format
-toGZIP                           # output in .gz  (X3D XML) format, with gzip compression
-toZIP                            # output in .zip (X3D XML) format, with zip  compression
==================================#====== outputs ============================
-tofile  [resultFile.*]           # specify output filename (otherwise original name with extension)
-toImage [snapshotName.*]         # create output images for each Viewpoint using Blender

===========================================
test.examples.java:
===========================================
compile SmokeTestProgramOutput.java source...
     (i.e. new source program which was just produced by SmokeTestProgram execution)
Compiling 1 source file to C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
test SmokeTestProgramOutput.java execution and self-validation:
Build this X3D model, showing validation diagnostics...
SmokeTestProgramOutput self-validation test confirmation: 
<meta content='continued development and testing in progress' name='info'/>
Note: toFileX3D() is overwriting prior file ./SmokeTestProgramOutput_JavaExport.x3d
Note: toFileClassicVRML() is overwriting prior file ./SmokeTestProgramOutput_JavaExport.x3dv
Deleting: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.class
===========================================
translation input: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d
..expected output: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json
Script DEF=colorTypeConversionScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=MaterialModulatorScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=DummyScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=colorTypeConversionScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=MaterialModulatorScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=DummyScript contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Error checking with jslint: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json
jslint:C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json:512:1:JavaScript URL.
jslint:C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json:910:1:JavaScript URL.
jslint:C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json:1415:1:JavaScript URL.
jslint:C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json:1446:9:Duplicate '-children'.
jslint:C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json:1781:1:JavaScript URL.
jslint:C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json:2179:1:JavaScript URL.
jslint:C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json:2684:1:JavaScript URL.
Java Result: 1
Error checking with json-schema-validator: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.json
--- BEGIN C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.json---
validation: FAILURE
[ {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/X3D"
  },
  "instance" : {
    "pointer" : "/X3D"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"@class\",\"@style\"]",
  "unwanted" : [ "@class", "@style" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/X3D/properties/@version"
  },
  "instance" : {
    "pointer" : "/X3D/@version"
  },
  "domain" : "validation",
  "keyword" : "enum",
  "message" : "instance value (\"4.0\") not found in enum (possible values: [\"3.0\",\"3.1\",\"3.2\",\"3.3\"])",
  "value" : "4.0",
  "enum" : [ "3.0", "3.1", "3.2", "3.3" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/WorldInfo"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/2/WorldInfo"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"@class\",\"@style\"]",
  "unwanted" : [ "@class", "@style" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/Box"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/7/Transform/-children/0/Anchor/-children/0/Shape/-geometry/Box"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"@class\"]",
  "unwanted" : [ "@class" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/Script"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/19/Group/-children/1/Script"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"#sourceCode\"]",
  "unwanted" : [ "#sourceCode" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/IMPORT"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/27/IMPORT"
  },
  "domain" : "validation",
  "keyword" : "type",
  "message" : "instance type (object) does not match any allowed primitive type (allowed: [\"array\"])",
  "found" : "object",
  "expected" : [ "array" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/EXPORT"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/28/EXPORT"
  },
  "domain" : "validation",
  "keyword" : "type",
  "message" : "instance type (object) does not match any allowed primitive type (allowed: [\"array\"])",
  "found" : "object",
  "expected" : [ "array" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/Script"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/29/ProtoDeclare/ProtoBody/-children/2/Script"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"#sourceCode\"]",
  "unwanted" : [ "#sourceCode" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/Shape"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/31/Group/-children/0/Shape"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"-value\"]",
  "unwanted" : [ "-value" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/51/Transform/-children/5/DISEntityManager/-children/0"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"DISEntityTypeMapping\"]",
  "unwanted" : [ "DISEntityTypeMapping" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/56/DISEntityManager/-children/0"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"DISEntityTypeMapping\"]",
  "unwanted" : [ "DISEntityTypeMapping" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/2"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"Anchor\"]",
  "unwanted" : [ "Anchor" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/3"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"Inline\"]",
  "unwanted" : [ "Inline" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/4"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"DISEntityTypeMapping\"]",
  "unwanted" : [ "DISEntityTypeMapping" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/5"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"GeoMetadata\"]",
  "unwanted" : [ "GeoMetadata" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/6"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"AudioClip\"]",
  "unwanted" : [ "AudioClip" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/7"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"ImageCubeMapTexture\"]",
  "unwanted" : [ "ImageCubeMapTexture" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/8"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"ImageTexture3D\"]",
  "unwanted" : [ "ImageTexture3D" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/9"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"ImageTexture\"]",
  "unwanted" : [ "ImageTexture" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/10"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"MovieTexture\"]",
  "unwanted" : [ "MovieTexture" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/11"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"Script\"]",
  "unwanted" : [ "Script" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/12"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"PackagedShader\"]",
  "unwanted" : [ "PackagedShader" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/13"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"ShaderPart\"]",
  "unwanted" : [ "ShaderPart" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/C:/x3d-code/www.web3d.org/specifications/x3d-3.3-JSONSchema.json#",
    "pointer" : "/definitions/-commentRoute/items"
  },
  "instance" : {
    "pointer" : "/X3D/Scene/-children/57/LoadSensor/-children/14"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "object instance has properties which are not allowed by the schema: [\"ShaderProgram\"]",
  "unwanted" : [ "ShaderProgram" ]
} ]
--- END C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.json---
Java Result: 100
===========================================
SmokeTestProgramOutput.x3d
1 file(s) have been successfully validated.
1 file(s) have been successfully validated.
===========================================
ClassicVRML validation: castle-model-converter.exe C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3dv --validate --enable-downloads
castle-model-converter: Warning: VRML/X3D: Prototype "ArtDeco02" referenced by external prototype "ArtDeco02" doesn't have field "description"
castle-model-converter: Warning: VRML/X3D: Inline node name "inlineScene" not found (or nothing was EXPORTed from it), cannot IMPORT
castle-model-converter: Warning: X3D: Invalid X3D file: Invalid sequence in a string: "\n". Backslash must be followed by another backslash or double quote, for SFString and MFString (in X3D classic (VRML) encoding) and for MFString (in X3D XML encoding).
Exception "Exception":
Validation failed (consult the warnings above), exiting with non-zero status
Result: 1
===========================================
SmokeTestProgramOutput_CommandLine.x3d
1 file(s) have been successfully validated.
1 file(s) have been successfully validated.
matches SmokeTestProgramOutput.x3d: false
===========================================
SmokeTestProgramOutput.xml
1 file(s) have been successfully validated.
1 file(s) have been successfully validated.
matches SmokeTestProgramOutput.x3d: true
===========================================
SmokeTestProgramOutput_ReloadedDOM.x3d
1 file(s) have been successfully validated.
1 file(s) have been successfully validated.
matches SmokeTestProgramOutput.x3d: false
ClassicVRML validation: castle-model-converter.exe C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3dv --validate --enable-downloads
castle-model-converter: Warning: VRML/X3D: Prototype "ArtDeco02" referenced by external prototype "ArtDeco02" doesn't have field "description"
castle-model-converter: Warning: VRML/X3D: Inline node name "inlineScene" not found (or nothing was EXPORTed from it), cannot IMPORT
castle-model-converter: Warning: X3D: Invalid X3D file: Invalid sequence in a string: "\n". Backslash must be followed by another backslash or double quote, for SFString and MFString (in X3D classic (VRML) encoding) and for MFString (in X3D XML encoding).
Exception "Exception":
Validation failed (consult the warnings above), exiting with non-zero status
Result: 1
===========================================
compile.X3DJSAIL.tests:
Compiling test classes at java/tests
test.X3DJSAIL.unitTests:
===========================================
ant antfile=java/build.xml target=test.junit5.directly
X3DJSAIL: X3D Java SAI Library.antVersionCheck:
X3DJSAIL: X3D Java SAI Library.test.junit5.directly:
FieldObjectTests start...
FieldObjectTests.fieldObjectInitializationsTest() start...
Preliminary tests...
SFBoolTests...
MFBoolTests...
SFImageTests...
MFImageTests...
SFInt32Tests...
MFInt32Tests...
SFFloatTests...
SFDoubleTests...
SFStringTests...
SFTimeTests...
MFFloatTests...
MFDoubleTests...
MFStringTests...
MFTimeTests...
SFVec2fTests...
SFVec2dTests...
MFVec2fTests...
MFVec2dTests...
SFVec3fTests...
SFVec3fBboxSizeTests for bounding box (bbox) constraints...
SFVec3dTests...
MFVec3fTests...
MFVec3dTests...
SFVec4fTests...
SFVec4dTests...
MFVec4fTests...
MFVec4dTests...
SFColorTests...
MFColorTests...
SFColorRGBATests...
MFColorRGBATests...
SFRotationTests...
MFRotationTests...
SFMatrix3fTests...
SFMatrix3dTests...
MFMatrix3fTests...
MFMatrix3dTests...
SFMatrix4fTests...
SFMatrix4dTests...
MFMatrix4fTests...
MFMatrix4dTests...
FieldObjectTests.fieldObjectInitializationsTest() complete
FieldObjectTests complete
===========================================
test.EXI:
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d -EXIFICIENT -toEXI -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.exificient.exi
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-EXIFICIENT" invoked ConfigurationProperties.setExiEngine(EXIFICIENT);
CommandLine parameter: "-toEXI" for conversion to compressed EXI containing model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.exificient.exi" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.exificient.exi
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to EXI using EXIFICIENT:
source: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput.exificient.exi filesize 3734 bytes, compression 16.14% of original
===========================================
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.exificient.exi -EXIFICIENT -fromEXI -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ExificientRoundTrip.x3d
parameter: source file SmokeTestProgramOutput.exificient.exi filesize 3734 bytes
CommandLine parameter: "-EXIFICIENT" invoked ConfigurationProperties.setExiEngine(EXIFICIENT);
CommandLine parameter: "-fromEXI" for conversion from compressed EXI containing model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ExificientRoundTrip.x3d" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ExificientRoundTrip.x3d
Note: fromFileEXI() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.exificient.exi
EXI decompressed examples\temp.exiInputTransformed.x3d size=31032 bytes
[warning] This X3D document has no DOCTYPE statement which helps with scene validation, suggest adding.
          <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
          https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#Validation
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
load result: true
===========================================
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d -OpenEXI -toEXI -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.openexi.exi
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-OpenEXI" invoked ConfigurationProperties.setExiEngine(OPENEXI);
  [warning] "OPENEXI" testing in progress, can also use EXIFICIENT instead.
CommandLine parameter: "-toEXI" for conversion to compressed EXI containing model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.openexi.exi" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.openexi.exi
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to EXI using OPENEXI:
source: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput.openexi.exi filesize 3796 bytes, compression 16.41% of original
===========================================
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.openexi.exi -OpenEXI -fromEXI -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.OpenExiRoundTrip.x3d
parameter: source file SmokeTestProgramOutput.openexi.exi filesize 3796 bytes
CommandLine parameter: "-OpenEXI" invoked ConfigurationProperties.setExiEngine(OPENEXI);
  [warning] "OPENEXI" testing in progress, can also use EXIFICIENT instead.
CommandLine parameter: "-fromEXI" for conversion from compressed EXI containing model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.OpenExiRoundTrip.x3d" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.OpenExiRoundTrip.x3d
Note: fromFileEXI() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.openexi.exi
EXI decompressed examples\temp.exiInputTransformed.x3d size=31211 bytes
[warning] This X3D document has no DOCTYPE statement which helps with scene validation, suggest adding.
          <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
          https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#Validation
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
load result: true
===========================================
===========================================
test.mkdir:
test.X3dToJava.xslt.one:
===========================================
org.web3d.x3d.jsail.CommandLine test/HelloWorld.x3d -toJava -toFile test/HelloWorld.java
compile HelloWorld.java source...
Compiling 1 source file to C:\x3d-code\www.web3d.org\x3d\stylesheets\test
test HelloWorld.java execution and self-validation:
Build this X3D model, showing validation diagnostics...
HelloWorld self-validation test confirmation: success
Note: toFileX3D() is overwriting prior file ./HelloWorld_JavaExport.x3d
Note: toFileClassicVRML() is overwriting prior file ./HelloWorld_JavaExport.x3dv
===========================================
test.X3dToJava.xslt:
translation input: test/CameraExamples.x3d
..expected output: test/CameraExamples.java
[meta] name='TODO' content='Schematron rules, backed up by initialize() checks'
compile...
Compiling 1 source file to C:\x3d-code\www.web3d.org\x3d\stylesheets\test
test CameraExamples.java execution and self-validation:
Build this X3D model, showing validation diagnostics...
CameraExamples self-validation test confirmation: 
<meta content='Schematron rules, backed up by initialize() checks' name='TODO'/>

ROUTE toNode='MoveAimPoint3.1' was not found in connected scene graph. 
<ROUTE fromNode='BoxPath' fromField='value_changed' toNode='MoveAimPoint3.1' toField='goalAimPoint'/>
ROUTE toNode='MoveAimPoint3.2' was not found in connected scene graph. 
<ROUTE fromNode='BoxPath' fromField='value_changed' toNode='MoveAimPoint3.2' toField='goalAimPoint'/>
ROUTE toNode='MoveAimPoint3.3' was not found in connected scene graph. 
<ROUTE fromNode='BoxPath' fromField='value_changed' toNode='MoveAimPoint3.3' toField='goalAimPoint'/>
Note: toFileX3D() is overwriting prior file ./CameraExamples_JavaExport.x3d
Note: toFileClassicVRML() is overwriting prior file ./CameraExamples_JavaExport.x3dv
===========================================
org.web3d.x3d.jsail.CommandLine test/arc.x3d -toJava -toFile test/arc.java
parameter: source file arc.x3d filesize 7672 bytes
CommandLine parameter: "-toJava" for conversion to Java source code
CommandLine parameter: "-toFile" "test/arc.java" for result file name test/arc.java
convert to Java using X3dToJava.xslt:
no className provided, using normalized meta title value='arc'
compile arc.java source...
Compiling 1 source file to C:\x3d-code\www.web3d.org\x3d\stylesheets\test
test arc.java execution and self-validation:
Build this X3D model, showing validation diagnostics...
arc self-validation test confirmation: success
Note: toFileX3D() is overwriting prior file ./arc_JavaExport.x3d
Note: toFileClassicVRML() is overwriting prior file ./arc_JavaExport.x3dv
===========================================
===========================================
test.X3DJSAIL.BlenderLauncher:
===========================================
org.web3d.x3d.jsail.BlenderLauncher -version
Blender version: Blender 4.5.1 LTS
===========================================
org.web3d.x3d.jsail.BlenderLauncher -help
Usage: java [-classpath X3DJSAIL.*.jar] org.web3d.x3d.jsail.BlenderLauncher sourceFile [-convert [resultFile]] [-toImage [snapshotName.*]] [-home | -help | -version | -properties fileName.properties | -BLENDER_PATH directoryPath]
https://www.blender.org
Blender help:
Blender 4.5.1 LTS
Usage: blender [args ...] [file] [args ...]
Render Options:
-b or --background 
	Run in background (often used for UI-less rendering).
	The audio device is disabled in background-mode by default
	and can be re-enabled by passing in '-setaudio Default' afterwards.
-a or --render-anim 
	Render frames from start to end (inclusive).
-S or --scene <name>
	Set the active scene <name> for rendering.
-f or --render-frame <frame>
	Render frame <frame> and save it.
	* +<frame> start frame relative, -<frame> end frame relative.
	* A comma separated list of frames can also be used (no spaces).
	* A range of frames can be expressed using '..' separator between the first and last frames (inclusive).

-s or --frame-start <frame>
	Set start to frame <frame>, supports +/- for relative frames too.
-e or --frame-end <frame>
	Set end to frame <frame>, supports +/- for relative frames too.
-j or --frame-jump <frames>
	Set number of frames to step forward after each rendered frame.
-o or --render-output <path>
	Set the render path and file name.
	Use '//' at the start of the path to render relative to the blend-file.
	You can use path templating features such as '{blend_name}' in the path.
	See Blender's documentation on path templates for more details.
	The '#' characters are replaced by the frame number, and used to define zero padding.
	* 'animation_##_test.png' becomes 'animation_01_test.png'
	* 'test-######.png' becomes 'test-000001.png'
	When the filename does not contain '#', the suffix '####' is added to the filename.
	The frame number will be added at the end of the filename, eg:
	# blender -b animation.blend -o //render_ -F PNG -x 1 -a
	'//render_' becomes '//render_####', writing frames as '//render_0001.png'
-E or --engine <engine>
	Specify the render engine.
	Use '-E help' to list available engines.
-t or --threads <threads>
	Use amount of <threads> for rendering and other operations
	[1-1024], 0 to use the systems processor count.
Cycles Render Options:
	Cycles add-on options must be specified following a double dash.
--cycles-device <device>
	Set the device used for rendering.
	Valid options are: 'CPU' 'CUDA' 'OPTIX' 'HIP' 'ONEAPI' 'METAL'.
	Append +CPU to a GPU device to render on both CPU and GPU.
	Example:
	# blender -b file.blend -f 20 -- --cycles-device OPTIX
--cycles-print-stats
	Log statistics about render memory and time usage.
Format Options:
-F or --render-format <format>
	Set the render format.
	Valid options are:
	'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP' 'HDR' 'TIFF'.
	Formats that can be compiled into Blender, not available on all systems:
	'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'FFMPEG' 'CINEON' 'DPX' 'JP2' 'WEBP'.
-x or --use-extension <bool>
	Set option to add the file extension to the end of the file.

Animation Playback Options:
-a <options> <file(s)>
	Instead of showing Blender's user interface, this runs Blender as an animation player,
	to view movies and image sequences rendered in Blender (ignored if '-b' is set).
	Playback Arguments:
	-p <sx> <sy>
		Open with lower left corner at <sx>, <sy>.
	-m
		Read from disk (Do not buffer).
	-f <fps> <fps_base>
		Specify FPS to start with.
	-j <frame>
		Set frame step to <frame>.
	-s <frame>
		Play from <frame>.
	-e <frame>
		Play until <frame>.
	-c <cache_memory>
		Amount of memory in megabytes to allow for caching images during playback.
		Zero disables (clamping to a fixed number of frames instead).

Window Options:
-w or --window-border 
	Force opening with borders.
-W or --window-fullscreen 
	Force opening in full-screen mode.
-p or --window-geometry <sx> <sy> <w> <h>
	Open with lower left corner at <sx>, <sy> and width and height as <w>, <h>.
-M or --window-maximized 
	Force opening maximized.
-con or --start-console 
	Start with the console window open (ignored if '-b' is set), (Windows only).
--no-native-pixels 
	Do not use native pixel size, for high resolution displays (MacBook 'Retina').
--no-window-focus 
	Open behind other windows and without taking focus.

Python Options:
-y or --enable-autoexec 
	Enable automatic Python script execution.
-Y or --disable-autoexec 
	Disable automatic Python script execution (Python-drivers & startup scripts), (default).

-P or --python <filepath>
	Run the given Python script file.
--python-text <name>
	Run the given Python script text block.
--python-expr <expression>
	Run the given expression as a Python script.
--python-console 
	Run Blender with an interactive console.
--python-exit-code <code>
	Set the exit-code in [0..255] to exit if a Python exception is raised
	(only for scripts executed from the command line), zero disables.
--python-use-system-env 
	Allow Python to use system environment variables such as 'PYTHONPATH' and the user site-packages directory.
--addons <addon(s)>
	Comma separated list (no spaces) of add-ons to enable in addition to any default add-ons.

Network Options:
--online-mode 
	Allow internet access, overriding the preference.
--offline-mode 
	Disallow internet access, overriding the preference.

Logging Options:
--log <match>
	Enable logging categories, taking a single comma separated argument.
	Multiple categories can be matched using a '.*' suffix,
	so '--log "wm.*"' logs every kind of window-manager message.
	Sub-string can be matched using a '*' prefix and suffix,
	so '--log "*undo*"' logs every kind of undo-related message.
	Use "^" prefix to ignore, so '--log "*,^wm.operator.*"' logs all except for 'wm.operators.*'
	Use "*" to log everything.
--log-level <level>
	Set the logging verbosity level (higher for more details) defaults to 1,
	use -1 to log all levels.
--log-show-basename 
	Only show file name in output (not the leading path).
--log-show-backtrace 
	Show a back trace for each log message (debug builds only).
--log-show-timestamp 
	Show a timestamp for each log message in seconds since start.
--log-file <filepath>
	Set a file to output the log to.

Debug Options:
-d or --debug 
	Turn debugging on.
	* Enables memory error detection
	* Disables mouse grab (to interact with a debugger in some cases)
	* Keeps Python's 'sys.stdin' rather than setting it to None
--debug-value <value>
	Set debug value of <value> on startup.

--debug-events 
	Enable debug messages for the event system.
--debug-ffmpeg 
	Enable debug messages from FFmpeg library.
--debug-handlers 
	Enable debug messages for event handling.
--debug-libmv 
	Enable debug messages from libmv library.
--debug-cycles 
	Enable debug messages from Cycles.
--debug-memory 
	Enable fully guarded memory allocation and debugging.
--debug-jobs 
	Enable time profiling for background jobs.
--debug-python 
	Enable debug messages for Python.
--debug-depsgraph 
	Enable all debug messages from dependency graph.
--debug-depsgraph-eval 
	Enable debug messages from dependency graph related on evaluation.
--debug-depsgraph-build 
	Enable debug messages from dependency graph related on graph construction.
--debug-depsgraph-tag 
	Enable debug messages from dependency graph related on tagging.
--debug-depsgraph-no-threads 
	Switch dependency graph to a single threaded evaluation.
--debug-depsgraph-time 
	Enable debug messages from dependency graph related on timing.
--debug-depsgraph-pretty 
	Enable colors for dependency graph debug messages.
--debug-depsgraph-uid 
	Verify validness of session-wide identifiers assigned to ID data-blocks.
--debug-ghost 
	Enable debug messages for Ghost (Linux only).
--debug-wintab 
	Enable debug messages for Wintab.
--debug-gpu 
	Enable GPU debug context and information for OpenGL 4.3+.
--debug-gpu-force-workarounds 
	Enable workarounds for typical GPU issues and disable all GPU extensions.
--debug-gpu-compile-shaders 
	Compile all statically defined shaders to test platform compatibility.
--debug-gpu-vulkan-local-read 
	Force Vulkan dynamic rendering local read when supported by device.
--debug-wm 
	Enable debug messages for the window manager, shows all operators in search, shows keymap errors.
--debug-xr 
	Enable debug messages for virtual reality contexts.
	Enables the OpenXR API validation layer, (OpenXR) debug messages and general information prints.
--debug-xr-time 
	Enable debug messages for virtual reality frame rendering times.
--debug-all 
	Enable all debug messages.
--debug-io 
	Enable debug messages for I/O (Collada, ...).

--debug-fpe 
	Enable floating-point exceptions.
--debug-exit-on-error 
	Immediately exit when internal errors are detected.
--debug-freestyle 
	Enable debug messages for Freestyle.
--disable-crash-handler 
	Disable the crash handler.
--disable-abort-handler 
	Disable the abort handler.
--verbose <verbose>
	Set the logging verbosity level for debug messages that support it.
-q or --quiet 
	Suppress status printing (warnings & errors are still printed).

GPU Options:
--gpu-backend 
	Force to use a specific GPU backend. Valid options: 'opengl' or 'vulkan'.
--gpu-compilation-subprocesses 
	Override the Max Compilation Subprocesses setting (OpenGL only).
--profile-gpu 
	Enable CPU & GPU performance profiling for GPU debug groups
	(Outputs a profile.json file in the Trace Event Format to the current directory)

Misc Options:
--open-last 
	Open the most recently opened blend file, instead of the default startup file.
--app-template <template>
	Set the application template (matching the directory name), use 'default' for none.
--factory-startup 
	Skip reading the 'startup.blend' in the users home directory.
--enable-event-simulate 
	Enable event simulation testing feature 'bpy.types.Window.event_simulate'.

--env-system-datafiles 
	Set the BLENDER_SYSTEM_DATAFILES environment variable.
--env-system-scripts 
	Set the BLENDER_SYSTEM_SCRIPTS environment variable.
--env-system-extensions 
	Set the BLENDER_SYSTEM_EXTENSIONS environment variable.
--env-system-python 
	Set the BLENDER_SYSTEM_PYTHON environment variable.

-noaudio 
	Force sound system to None.
-setaudio 
	Force sound system to a specific device.
	'None' 'Default' 'SDL' 'OpenAL' 'CoreAudio' 'JACK' 'PulseAudio' 'WASAPI'.

-c or --command <command>
	Run a command which consumes all remaining arguments.
	Use '-c help' to list all other commands.
	Pass '--help' after the command to see its help text.
	This implies '--background' mode.

-h or --help 
	Print this help text and exit.
/? 
	Print this help text and exit (Windows only).
-r or --register 
	Register blend-file extension for current user, then exit (Windows & Linux only).
--register-allusers 
	Register blend-file extension for all users, then exit (Windows & Linux only).
--unregister 
	Unregister blend-file extension for current user, then exit (Windows & Linux only).
--unregister-allusers 
	Unregister blend-file extension for all users, then exit (Windows & Linux only).
-v or --version 
	Print Blender version and exit.
-- 
	End option processing, following arguments passed unchanged. Access via Python's 'sys.argv'.

Other Options:
--disable-depsgraph-on-file-load 
	Background mode: Do not systematically build and evaluate ViewLayers' dependency graphs
	when loading a blend-file in background mode ('-b' or '-c' options).
	Scripts requiring evaluated data then need to explicitly ensure that
	an evaluated depsgraph is available
	(e.g. by calling 'depsgraph = context.evaluated_depsgraph_get()').
	NOTE: this is a temporary option, in the future depsgraph will never be
	automatically generated on file load in background mode.
--disable-liboverride-auto-resync 
	Do not perform library override automatic resync when loading a new blend-file.
	NOTE: this is an alternative way to get the same effect as when setting the
	'No Override Auto Resync' User Preferences Debug option.

Argument Parsing:
	Arguments must be separated by white space, eg:
	# blender -ba test.blend
	...will exit since '-ba' is an unknown argument.
Argument Order:
	Arguments are executed in the order they are given. eg:
	# blender --background test.blend --render-frame 1 --render-output "/tmp"
	...will not render to '/tmp' because '--render-frame 1' renders before the output path is set.
	# blender --background --render-output /tmp test.blend --render-frame 1
	...will not render to '/tmp' because loading the blend-file overwrites the render output that was set.
	# blender --background test.blend --render-output /tmp --render-frame 1
	...works as expected.
Environment Variables:
  $BLENDER_USER_RESOURCES  Replace default directory of all user files.
                           Other 'BLENDER_USER_*' variables override when set.
  $BLENDER_USER_CONFIG     Directory for user configuration files.
  $BLENDER_USER_SCRIPTS    Directory for user scripts.
  $BLENDER_USER_EXTENSIONS Directory for user extensions.
  $BLENDER_USER_DATAFILES  Directory for user data files (icons, translations, ..).
  $BLENDER_SYSTEM_RESOURCES  Replace default directory of all bundled resource files.
  $BLENDER_SYSTEM_SCRIPTS    Directories to add extra scripts.
  $BLENDER_SYSTEM_EXTENSIONS Directory for system extensions repository.
  $BLENDER_SYSTEM_DATAFILES  Directory to replace bundled datafiles.
  $BLENDER_SYSTEM_PYTHON     Directory to replace bundled Python libraries.
  $BLENDER_CUSTOM_SPLASH     Full path to an image that replaces the splash screen.
  $BLENDER_CUSTOM_SPLASH_BANNER Full path to an image to overlay on the splash screen.
  $OCIO                      Path to override the OpenColorIO configuration file.
  $TEMP                      Store temporary files here (MS-Windows).
                             The path must reference an existing directory or it will be ignored.
===========================================
org.web3d.x3d.jsail.BlenderLauncher -properties C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties
BlenderLauncher parameter: "-properties" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties" for properties file name root C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties includes 13 properties:
-- listing properties --
deleteIntermediateFiles=true
BLENDER_PATH=
XSLT_ENGINE=SAXON
overwriteExistingFiles=true
EXI_ENGINE=EXIFICIENT
SFImagePixelOutputHexadecimal=true
stripTrailingZeroes=true
normalizeCommentWhitespace=true
indentCharacter=SPACE
MESHLAB_PATH=
indentIncrement=2
validationExceptionAllowed=false
stripDefaultAttributes=true
------------------------
C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties loading complete.
===========================================
System environment variable env.BLENDER_PATH=C:\Program Files\Blender Foundation\Blender 4.5\
org.web3d.x3d.jsail.BlenderLauncher -BLENDER_PATH C:\Program Files\Blender Foundation\Blender 4.5\
parameters: "-BLENDER_PATH" "C:\Program Files\Blender Foundation\Blender 4.5\" for setting Blender path
===========================================
org.web3d.x3d.jsail.BlenderLauncher C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.x3d -toImage
BlenderLauncher parameter: source file CleatClamp.x3d filesize 172233 bytes
BlenderLauncher parameter: "-toImage" for creating screenshot image of default viewpoint
executeCommand("C:\Program Files\Blender Foundation\Blender 4.5\blender.exe --background --factory-startup --python C:\Users\donbr\AppData\Local\Temp\BlenderX3dToPng13396224352966918770.py -- C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.x3d")
executeCommand() response:
Blender 4.5.1 LTS (hash b0a72b245dcf built 2025-07-29 06:36:07)
BlenderX3dToPng.py start...

BlenderX3dToPng.py is a Blender Python script to load <model>.x3d and output image snapshot(s) as <model>.viewpoint.blender.png

Example invocations:
/cygdrive/c/x3d-code/www.web3d.org/x3d/stylesheets/java/src/python/blenderScripts
$ ant blender.python.run.BlenderX3dToPng.py
$ blender.exe --background --factory-startup --python BlenderX3dToPng.py LPD17.x3d products/

Command line: 7 args ['C:\\Program Files\\Blender Foundation\\Blender 4.5\\blender.exe', '--background', '--factory-startup', '--python', 'C:\\Users\\donbr\\AppData\\Local\\Temp\\BlenderX3dToPng13396224352966918770.py', '--', 'C:\\x3d-code\\www.web3d.org\\x3d\\stylesheets\\java\\examples/CleatClamp.x3d']
sourceFile=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.x3d outputPath=C:\x3d-code\www.web3d.org\x3d\stylesheets

Clean up initial view...
Importing C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.x3d ...

Blender quit

expected result: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.png
===========================================
now test .stl to image (not yet supported):
org.web3d.x3d.jsail.BlenderLauncher C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.stl -toImage
parameter: source file CleatClamp.stl filesize 542534 bytes
CommandLine parameter: "-toImage" for creating screenshot image of default viewpoint
Pass through to BlenderLauncher...
BlenderLauncher parameter: source file CleatClamp.stl filesize 542534 bytes
BlenderLauncher parameter: "-toImage" for creating screenshot image of default viewpoint
executeCommand("C:\Program Files\Blender Foundation\Blender 4.5\blender.exe --background --factory-startup --python C:\Users\donbr\AppData\Local\Temp\BlenderX3dToPng10764429089021554374.py -- C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.stl")
executeCommand() response:
Blender 4.5.1 LTS (hash b0a72b245dcf built 2025-07-29 06:36:07)
BlenderX3dToPng.py start...

BlenderX3dToPng.py is a Blender Python script to load <model>.x3d and output image snapshot(s) as <model>.viewpoint.blender.png

Example invocations:
/cygdrive/c/x3d-code/www.web3d.org/x3d/stylesheets/java/src/python/blenderScripts
$ ant blender.python.run.BlenderX3dToPng.py
$ blender.exe --background --factory-startup --python BlenderX3dToPng.py LPD17.x3d products/

Command line: 7 args ['C:\\Program Files\\Blender Foundation\\Blender 4.5\\blender.exe', '--background', '--factory-startup', '--python', 'C:\\Users\\donbr\\AppData\\Local\\Temp\\BlenderX3dToPng10764429089021554374.py', '--', 'C:\\x3d-code\\www.web3d.org\\x3d\\stylesheets\\java\\examples/CleatClamp.stl']
sourceFile=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.stl outputPath=C:\x3d-code\www.web3d.org\x3d\stylesheets

Clean up initial view...
Importing C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.stl ...

Blender quit

expected result: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.png
===========================================
test.X3DJSAIL.MeshlabLauncher:
===========================================
org.web3d.x3d.jsail.MeshLabLauncher -version

For MeshLab releases starting in 2021, meshlabserver is discontinued. See https://stackoverflow.com/questions/65825861/where-is-meshlabserver-exe-in-2020-12
Capabilities are in PyMeshLab which requires Python language support. See https://github.com/cnr-isti-vclab/PyMeshLab
===========================================
org.web3d.x3d.jsail.MeshLabLauncher -help

For MeshLab releases starting in 2021, meshlabserver is discontinued. See https://stackoverflow.com/questions/65825861/where-is-meshlabserver-exe-in-2020-12
Capabilities are in PyMeshLab which requires Python language support. See https://github.com/cnr-isti-vclab/PyMeshLab
===========================================
org.web3d.x3d.jsail.MeshLabLauncher -properties C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/X3DJSAIL.properties

For MeshLab releases starting in 2021, meshlabserver is discontinued. See https://stackoverflow.com/questions/65825861/where-is-meshlabserver-exe-in-2020-12
Capabilities are in PyMeshLab which requires Python language support. See https://github.com/cnr-isti-vclab/PyMeshLab
===========================================
System environment variable env.MESHLAB_PATH=${env.MESHLAB_PATH}
org.web3d.x3d.jsail.MeshLabLauncher -MESHLAB_PATH ${env.MESHLAB_PATH}

For MeshLab releases starting in 2021, meshlabserver is discontinued. See https://stackoverflow.com/questions/65825861/where-is-meshlabserver-exe-in-2020-12
Capabilities are in PyMeshLab which requires Python language support. See https://github.com/cnr-isti-vclab/PyMeshLab
===========================================
Convert CleatClamp.stl to .x3d version ...
org.web3d.x3d.jsail.MeshLabLauncher C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.stl C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncher.x3d

For MeshLab releases starting in 2021, meshlabserver is discontinued. See https://stackoverflow.com/questions/65825861/where-is-meshlabserver-exe-in-2020-12
Capabilities are in PyMeshLab which requires Python language support. See https://github.com/cnr-isti-vclab/PyMeshLab
and then canonicalize ...
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncher.x3d -canonicalize C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncherCanonicalize.x3d
[Error]  [org.web3d.x3d.jsail.CommandLine] file not found: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncher.x3d
and then tidy ...
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.x3d C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncherTidy.x3d
[Error]  [org.web3d.x3d.jsail.CommandLine] file not found: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncher.x3d
and then .java version ...
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.x3d C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncher.x3d
parameter: source file CleatClamp.x3d filesize 172233 bytes
CommandLine parameter: "-toJava" for conversion to Java source code
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.java" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.java
convert to Java using X3dToJava.xslt:
no className provided, using normalized meta title value='CleatClamp'
[meta] name='warning' content='Do not use for climbing or yachting.'
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\CleatClamp.java
===========================================
... and then back to .stl for visual comparison
org.web3d.x3d.jsail.MeshLabLauncher C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp.stl C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/CleatClamp_MeshLabLauncher.stl

For MeshLab releases starting in 2021, meshlabserver is discontinued. See https://stackoverflow.com/questions/65825861/where-is-meshlabserver-exe-in-2020-12
Capabilities are in PyMeshLab which requires Python language support. See https://github.com/cnr-isti-vclab/PyMeshLab
===========================================
Continuing with individual tests
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d -toZIP -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ant.zip
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toZIP" for conversion to compressed ZIP containing model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ant.zip" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ant.zip
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to ZIP:
source: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput.ant.zip filesize 6526 bytes, compression 28.21% of original
===========================================
org.web3d.x3d.jsail.CommandLine C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/flowers7.x3d -toJava -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/flowers7.java
parameter: source file flowers7.x3d filesize 19101 bytes
CommandLine parameter: "-toJava" for conversion to Java source code
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/flowers7.java" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/flowers7.java
convert to Java using X3dToJava.xslt:
no className provided, using normalized meta title value='flowers7'
compile flowers7.java source...
Compiling 3 source files to C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
test flowers7.java execution and self-validation:
Error: Could not find or load main class flowers7
Caused by: java.lang.ClassNotFoundException: flowers7
Java Result: 1
===========================================
org.web3d.x3d.jsail.CommandLine flowers7.x3d -toJSON -toFile /flowers7.json
    in directory C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples
parameter: source file flowers7.x3d filesize 19101 bytes
CommandLine parameter: "-toJSON" for conversion to JSON encoding
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/flowers7.json" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/flowers7.json
convert to JSON using X3dToJson.xslt:
Script DEF=UrlSelector contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Script DEF=Animate contains CDATA source-code text, copied as "#sourceCode" using "strings" mode
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\flowers7.json
===========================================
org.web3d.x3d.jsail.CommandLine -toGZIP -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ant.gz
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toGZIP" for conversion to compressed GZIP containing model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ant.gz" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ant.gz
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to GZIP:
source: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.x3d filesize 23133 bytes
result: SmokeTestProgramOutput.ant.gz  filesize 6160 bytes, compression 26.63% of original
===========================================
org.web3d.x3d.jsail.CommandLine -toGZIP -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.ant.gz
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toX3D" for conversion to X3D encoding
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.x3d" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.x3d
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to X3D:
Note: toFileX3D() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.x3d
file conversion successful: SmokeTestProgramOutput_CommandLine.x3d (23132 bytes)
===========================================
org.web3d.x3d.jsail.CommandLine -toXML -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.xml
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toXML" for conversion to XML encoding
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.xml" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.xml
Parsing using Document Object Model (DOM) based X3DLoaderDOM...
[X3DLoaderDOM] <meta name='info' content='continued development and testing in progress'/>
convert to XML:
Note: toFileX3D() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.xml
file conversion successful: SmokeTestProgramOutput_CommandLine.xml (23132 bytes)
===========================================
org.web3d.x3d.jsail.CommandLine -toHTML -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.html (pretty print)
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-toHTML" for producing .html pretty-print documentation
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.html" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.html
convert to HTML files using X3dToXhtml.xslt:
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput_CommandLine.html
===========================================
org.web3d.x3d.jsail.CommandLine -markdown -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.md
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-markdown" for producing .md model meta information markdown
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.md" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput_CommandLine.md
convert to .md model meta information markdown, include subdirectories in meta links: true
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput_CommandLine.md
## Model Metadata for SmokeTestProgramOutput.x3d

|    attribute | value      |
| ------------ | ---------- |
| `title` | [SmokeTestProgramOutput.x3d](SmokeTestProgramOutput.x3d) |
| `info` | continued development and testing in progress |
| `description` | Example SmokeTestProgram creates an X3D model using the X3D Java Scene Access Interface
Library (X3DJSAIL) |
| `reference` | [https://www.web3d.org/specifications/java/X3DJSAIL.html](https://www.web3d.org/specifications/java/X3DJSAIL.html) |
| `generator` | SmokeTestProgramOutput.java |
| `created` | 6 September 2016 |
| `modified` | 28 November 2025 |
| `generator` | X3D Java Scene Access Interface Library (X3DJSAIL) |
| `generator` | [https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java](https://www.web3d.org/specifications/java/examples/SmokeTestProgram.java) |
| `generator` | Netbeans https://www.netbeans.org |
| `creator` | Don Brutzman |
| `reference` | [https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d](https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/java/examples/SmokeTestProgramOutput.x3d) |
| `reference` | Console output, ClassicVRML encoding, VRML97 encoding and pretty-print documentation: |
| `reference` | [SmokeTestProgramOutput.txt](SmokeTestProgramOutput.txt) |
| `reference` | [SmokeTestProgramOutput.x3dv](SmokeTestProgramOutput.x3dv) |
| `reference` | [SmokeTestProgramOutput.wrl](SmokeTestProgramOutput.wrl) |
| `reference` | [SmokeTestProgramOutput.html](SmokeTestProgramOutput.html) |
| `reference` | [https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d](https://savage.nps.edu/X3dValidator?url=https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d) |
| `identifier` | [https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d](https://www.web3d.org/specifications/java/examples/SmokeTestProgramOutput.x3d) |
| `license` | [../license.html](../license.html) |

[SmokeTestProgramOutput.README.md](SmokeTestProgramOutput.README.md) contains additional file links and information.
===========================================
org.web3d.x3d.jsail.CommandLine -schematron -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputSchematron.txt
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-schematron" to produce X3D Schematron diagnostics for .x3d model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputSchematron_CommandLine.txt" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputSchematron_CommandLine.txt
First creating intermediate SVRL file using stylesheet X3dSchematronValidityChecks.xslt
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutputSchematron_CommandLine.txt.svrl
   intermediate SVRL file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputSchematron_CommandLine.txt.svrl fileExists=true
... Next creating final report file using stylesheet SvrlReportText.xslt
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutputSchematron_CommandLine.txt
Resulting result file: C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputSchematron_CommandLine.txt exists=true
===========================================
org.web3d.x3d.jsail.CommandLine -schematron -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputSchematron.txt
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-schematron" to produce X3D Schematron diagnostics for .x3d model

First creating intermediate SVRL file using stylesheet X3dSchematronValidityChecks.xslt
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutput.txt.svrl
   intermediate SVRL file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutput.txt.svrl fileExists=true
... Next creating final report file using stylesheet SvrlReportText.xslt
Note: fileStylesheetConversion() is overwriting prior file C:\Users\donbr\AppData\Local\Temp\tempFile13973303117800104232.txt
===========================================
org.web3d.x3d.jsail.CommandLine -tidy -toFile C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputTidy.CommandLine.x3d
parameter: source file SmokeTestProgramOutput.x3d filesize 23133 bytes
CommandLine parameter: "-tidy" for producing X3D-Tidy cleanup of .x3d model
CommandLine parameter: "-toFile" "C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputTidy_CommandLine.x3d" for result file name C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples/SmokeTestProgramOutputTidy_CommandLine.x3d
convert to X3D Tidy cleaned-up version
*** &lt;ProtoInstance USE='ArtDeco02MaterialDEF' containerField='material'/&gt; is missing name field, searched for ProtoInstance DEF='ArtDeco02MaterialDEF', found DEF name for USE='ArtDeco02MaterialDEF' name='ArtDeco02'
Note: fileStylesheetConversion() is overwriting prior file C:\x3d-code\www.web3d.org\x3d\stylesheets\java\examples\SmokeTestProgramOutputTidy_CommandLine.x3d
===========================================
test X3DUnifiedObjectModel JAXB invocations
compile.X3DJSAIL.tests:
Compiling test classes at java/tests
test.X3DUnifiedObjectModelJaxbTests:
Unit testing org.web3d.x3d.tests.X3DUnifiedObjectModelJaxbTests
$java.classes.dir=C:\x3d-code\www.web3d.org\x3d\stylesheets\java\classes
X3DUnifiedObjectModelJaxbTests start...
X3DUnifiedObjectModelJaxbTests.x3duomInspectionsTest() start...
Preliminary tests...
X3DUOM:
x3duomInstanceXml.length()=1968580
X3DUnifiedObjectModelJaxbTests.x3duomInspectionsTest() complete
X3DUnifiedObjectModelJaxbTests complete
===========================================
build.test.X3DJSAIL.txt holds output results
===========================================
BUILD SUCCESSFUL (total time: 2 minutes 29 seconds)
